diff --git a/.buildconfig.yml b/.buildconfig.yml index ff1b8c0a179..921004f478a 100644 --- a/.buildconfig.yml +++ b/.buildconfig.yml @@ -23,10 +23,6 @@ projects: path: components/concept/awesomebar description: 'An abstract definition of an awesomebar component.' publish: true - lib-auth: - path: components/lib/biometric-prompt - description: 'Component for authentication using biometric' - publish: true concept-base: path: components/concept/base description: 'A component for basic interfaces needed by multiple components and that do not warrant a standalone component.' @@ -375,6 +371,10 @@ projects: path: components/support/webextensions description: 'A component containing building blocks for features implemented as web extensions.' publish: true + lib-auth: + path: components/lib/auth + description: 'A component for various kinds of authenticating mechanisms.' + publish: true lib-crash: path: components/lib/crash description: 'A generic crash reporter library that can report crashes to multiple services.' diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 0f906d7ffcc..6da91ca32e0 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -31,9 +31,9 @@ object Versions { const val disklrucache = "2.0.2" const val leakcanary = "2.8.1" - const val mozilla_appservices = "93.2.2" + const val mozilla_appservices = "93.4.0" - const val mozilla_glean = "44.1.1" + const val mozilla_glean = "50.0.1" const val material = "1.2.1" diff --git a/buildSrc/src/main/java/Gecko.kt b/buildSrc/src/main/java/Gecko.kt index c9d88df2155..4f003d3c254 100644 --- a/buildSrc/src/main/java/Gecko.kt +++ b/buildSrc/src/main/java/Gecko.kt @@ -9,7 +9,7 @@ object Gecko { /** * GeckoView Version. */ - const val version = "103.0.20220607093440" + const val version = "103.0.20220609065921" /** * GeckoView channel diff --git a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/glean/GeckoAdapter.kt b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/glean/GeckoAdapter.kt index 9630faf81c9..ed87bf37de1 100644 --- a/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/glean/GeckoAdapter.kt +++ b/components/browser/engine-gecko/src/main/java/mozilla/components/browser/engine/gecko/glean/GeckoAdapter.kt @@ -32,7 +32,7 @@ class GeckoAdapter : RuntimeTelemetry.Delegate { metric.value.forEach { labelIndex -> categorical[labelIndex.toInt()].add(1) } } } else { - GleanGeckoMetricsMapping.getHistogram(metric.name)?.accumulateSamples(metric.value) + GleanGeckoMetricsMapping.getHistogram(metric.name)?.accumulateSamples(metric.value.toList()) } } diff --git a/components/feature/app-links/src/main/res/values-yo/strings.xml b/components/feature/app-links/src/main/res/values-yo/strings.xml new file mode 100644 index 00000000000..3e8e9f2f91f --- /dev/null +++ b/components/feature/app-links/src/main/res/values-yo/strings.xml @@ -0,0 +1,9 @@ + + + + Ṣi nínú… + + Ṣi + + Fagile + diff --git a/components/feature/autofill/src/main/res/values-yo/strings.xml b/components/feature/autofill/src/main/res/values-yo/strings.xml new file mode 100644 index 00000000000..0240b3ea950 --- /dev/null +++ b/components/feature/autofill/src/main/res/values-yo/strings.xml @@ -0,0 +1,31 @@ + + + + Ṣi sílẹ̀ %1$s + + + (Kò sí orúkọ àmúlò) + + + + Iṣẹ́ ìmúdájú kùnà + + + Bẹ́ẹ̀ni + + + Bẹ́ẹ̀ kọ́ + + + Ṣàwárí %1$s + + diff --git a/components/feature/contextmenu/src/main/res/values-yo/strings.xml b/components/feature/contextmenu/src/main/res/values-yo/strings.xml new file mode 100644 index 00000000000..7b1aff38bcb --- /dev/null +++ b/components/feature/contextmenu/src/main/res/values-yo/strings.xml @@ -0,0 +1,27 @@ + + + + Pín ìtọ́kasí + + Pín àwòrán + + Ṣe àdàkọ ìtọ́kasí + + Fi àwòrán pamọ́ + + Táàbù tuntún wà ní ṣíṣí + + Ṣe àyípadà + + Fikún àwọn olùbásọ̀rọ̀ + + Ṣe àwárí + + Àwárí ìkọ̀kọ̀ + + Pín + + Ímeèlì + + Ìpè + diff --git a/components/feature/media/src/main/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeature.kt b/components/feature/media/src/main/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeature.kt index 0b4b4fdf38d..4e8aa099b2d 100644 --- a/components/feature/media/src/main/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeature.kt +++ b/components/feature/media/src/main/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeature.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.map +import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.store.BrowserStore import mozilla.components.lib.state.ext.flowScoped @@ -22,7 +23,8 @@ import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged */ class MediaSessionFullscreenFeature( private val activity: Activity, - private val store: BrowserStore + private val store: BrowserStore, + private val tabId: String?, ) : LifecycleAwareFeature { private var scope: CoroutineScope? = null @@ -48,7 +50,7 @@ class MediaSessionFullscreenFeature( return } - if (store.state.selectedTabId == activeState.id) { + if (store.state.findCustomTabOrSelectedTab(tabId)?.id == activeState.id) { when (activeState.mediaSessionState?.elementMetadata?.portrait) { true -> activity.requestedOrientation = diff --git a/components/feature/media/src/test/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeatureTest.kt b/components/feature/media/src/test/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeatureTest.kt index bcfcef2f606..fd1cff3afe2 100644 --- a/components/feature/media/src/test/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeatureTest.kt +++ b/components/feature/media/src/test/java/mozilla/components/feature/media/fullscreen/MediaSessionFullscreenFeatureTest.kt @@ -9,17 +9,22 @@ import android.content.pm.ActivityInfo import android.os.Build import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.browser.state.action.ContentAction +import mozilla.components.browser.state.action.CustomTabListAction import mozilla.components.browser.state.action.MediaSessionAction import mozilla.components.browser.state.action.TabListAction import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.MediaSessionState +import mozilla.components.browser.state.state.SessionState +import mozilla.components.browser.state.state.createCustomTab import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.mediasession.MediaSession +import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.libstate.ext.waitUntilIdle import mozilla.components.support.test.mock import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test @@ -55,7 +60,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -84,7 +90,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -113,7 +120,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -144,7 +152,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -181,7 +190,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -230,7 +240,8 @@ class MediaSessionFullscreenFeatureTest { val store = BrowserStore(initialState) val feature = MediaSessionFullscreenFeature( activity, - store + store, + null ) feature.start() @@ -254,4 +265,59 @@ class MediaSessionFullscreenFeatureTest { assertEquals(ActivityInfo.SCREEN_ORIENTATION_USER, activity.requestedOrientation) } + + @Suppress("Deprecation") + @Test + @Config(sdk = [Build.VERSION_CODES.N]) + fun `GIVEN the currently selected tab is in pip mode WHEN a custom tab loads THEN display custom tab in device's current orientation`() { + val activity = Robolectric.buildActivity(Activity::class.java).setup().get() + val elementMetadata = MediaSession.ElementMetadata() + val initialState = BrowserState( + tabs = listOf( + createTab( + "https://www.mozilla.org", id = "tab1", + mediaSessionState = MediaSessionState( + mock(), + elementMetadata = elementMetadata, + playbackState = MediaSession.PlaybackState.PLAYING, + fullscreen = true + ) + ) + ), + selectedTabId = "tab1" + ) + val store = BrowserStore(initialState) + + val feature = MediaSessionFullscreenFeature( + activity, + store, + null + ) + + feature.start() + activity.enterPictureInPictureMode() + store.waitUntilIdle() + + store.dispatch(ContentAction.PictureInPictureChangedAction("tab1", true)) + store.waitUntilIdle() + assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, activity.requestedOrientation) + + val customTab = createCustomTab( + "https://www.mozilla.org", + source = SessionState.Source.Internal.CustomTab, + id = "tab2" + ) + store.dispatch(CustomTabListAction.AddCustomTabAction(customTab)).joinBlocking() + val externalActivity = Robolectric.buildActivity(Activity::class.java).setup().get() + assertEquals(1, store.state.customTabs.size) + store.waitUntilIdle() + val featureForExternalAppBrowser = MediaSessionFullscreenFeature( + externalActivity, + store, + "tab2" + ) + featureForExternalAppBrowser.start() + + assertNotEquals(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, externalActivity.requestedOrientation) + } } diff --git a/components/feature/prompts/src/main/res/values-cy/strings.xml b/components/feature/prompts/src/main/res/values-cy/strings.xml index b6ee2da9969..16cbbdc70f3 100644 --- a/components/feature/prompts/src/main/res/values-cy/strings.xml +++ b/components/feature/prompts/src/main/res/values-cy/strings.xml @@ -113,4 +113,14 @@ Diweddaru dyddiad dod i ben cerdyn? Bydd rhif y cerdyn yn cael ei amgryptio. Ni fydd y cod diogelwch yn cael ei gadw. + + + + Dewiswch gyfeiriadau + + Ehangu awgrymiadau cyfeiriadau + + Lleihau awgrymiadau cyfeiriadau + + Rheoli cyfeiriadau diff --git a/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml b/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml index 01bee4c8559..d14a88501bf 100644 --- a/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml +++ b/components/feature/prompts/src/main/res/values-fy-rNL/strings.xml @@ -113,4 +113,14 @@ Ferrindatum kaart bywurkje? It kaartnûmer sil fersifere wurde. De befeiligingskoade wurdt net bewarre. + + + + Adressen selektearje + + Foarstelde adressen útklappe + + Foarstelde adressen ynklappe + + Adressen beheare diff --git a/components/lib/biometric-prompt/build.gradle b/components/lib/auth/build.gradle similarity index 100% rename from components/lib/biometric-prompt/build.gradle rename to components/lib/auth/build.gradle diff --git a/components/lib/biometric-prompt/proguard-rules.pro b/components/lib/auth/proguard-rules.pro similarity index 100% rename from components/lib/biometric-prompt/proguard-rules.pro rename to components/lib/auth/proguard-rules.pro diff --git a/components/lib/auth/src/main/AndroidManifest.xml b/components/lib/auth/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..e22c4b80752 --- /dev/null +++ b/components/lib/auth/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/AuthenticationCallbacks.kt b/components/lib/auth/src/main/java/mozilla/components/lib/auth/AuthenticationDelegate.kt similarity index 55% rename from components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/AuthenticationCallbacks.kt rename to components/lib/auth/src/main/java/mozilla/components/lib/auth/AuthenticationDelegate.kt index 651e417b1a3..c1cb5265c39 100644 --- a/components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/AuthenticationCallbacks.kt +++ b/components/lib/auth/src/main/java/mozilla/components/lib/auth/AuthenticationDelegate.kt @@ -7,20 +7,23 @@ package mozilla.components.lib.auth /** * Callbacks for BiometricPrompt Authentication */ -interface AuthenticationCallbacks { +interface AuthenticationDelegate { /** - * Called when a biometric (e.g. fingerprint, face, etc.) is presented but not recognized as belonging to the user. + * Called when a biometric (e.g. fingerprint, face, etc.) + * is presented but not recognized as belonging to the user. */ - val onAuthFailure: () -> Unit + fun onAuthFailure() /** - * Called when a biometric (e.g. fingerprint, face, etc.) is recognized, indicating that the user has successfully authenticated. + * Called when a biometric (e.g. fingerprint, face, etc.) is recognized, + * indicating that the user has successfully authenticated. */ - val onAuthSuccess: () -> Unit + fun onAuthSuccess() /** * Called when an unrecoverable error has been encountered and authentication has stopped. + * @param errorText A human-readable error string that can be shown on an UI */ - val onAuthError: (errorText: String) -> Unit + fun onAuthError(errorText: String) } diff --git a/components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/BiometricPromptFeature.kt b/components/lib/auth/src/main/java/mozilla/components/lib/auth/BiometricPromptAuth.kt similarity index 85% rename from components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/BiometricPromptFeature.kt rename to components/lib/auth/src/main/java/mozilla/components/lib/auth/BiometricPromptAuth.kt index a5328f1986b..62074dc05bc 100644 --- a/components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/BiometricPromptFeature.kt +++ b/components/lib/auth/src/main/java/mozilla/components/lib/auth/BiometricPromptAuth.kt @@ -16,15 +16,16 @@ import mozilla.components.support.base.log.logger.Logger /** * A [LifecycleAwareFeature] for the Android Biometric API to prompt for user authentication. + * The prompt also requests support for the device PIN as a fallback authentication mechanism. * * @param context Android context. * @param fragment The fragment on which this feature will live. - * @param authenticationCallbacks Callbacks for BiometricPrompt. + * @param authenticationDelegate Callbacks for BiometricPrompt. */ -class BiometricPromptFeature( +class BiometricPromptAuth( private val context: Context, private val fragment: Fragment, - private val authenticationCallbacks: AuthenticationCallbacks + private val authenticationDelegate: AuthenticationDelegate ) : LifecycleAwareFeature { private val logger = Logger(javaClass.simpleName) @@ -61,17 +62,17 @@ class BiometricPromptFeature( internal inner class PromptCallback : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { logger.error("onAuthenticationError: errorMessage $errString errorCode=$errorCode") - authenticationCallbacks.onAuthError(errString.toString()) + authenticationDelegate.onAuthError(errString.toString()) } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { logger.debug("onAuthenticationSucceeded") - authenticationCallbacks.onAuthSuccess() + authenticationDelegate.onAuthSuccess() } override fun onAuthenticationFailed() { logger.error("onAuthenticationFailed") - authenticationCallbacks.onAuthFailure() + authenticationDelegate.onAuthFailure() } } } diff --git a/components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/BiometricUtils.kt b/components/lib/auth/src/main/java/mozilla/components/lib/auth/BiometricUtils.kt similarity index 100% rename from components/lib/biometric-prompt/src/main/java/mozilla.components.lib.auth/BiometricUtils.kt rename to components/lib/auth/src/main/java/mozilla/components/lib/auth/BiometricUtils.kt diff --git a/components/lib/biometric-prompt/src/test/java/mozilla.components.lib.auth/BiometricPromptFeatureTest.kt b/components/lib/auth/src/test/java/mozilla/components/lib/auth/BiometricPromptAuthTest.kt similarity index 80% rename from components/lib/biometric-prompt/src/test/java/mozilla.components.lib.auth/BiometricPromptFeatureTest.kt rename to components/lib/auth/src/test/java/mozilla/components/lib/auth/BiometricPromptAuthTest.kt index 90e669fe0d1..2e9b15cb813 100644 --- a/components/lib/biometric-prompt/src/test/java/mozilla.components.lib.auth/BiometricPromptFeatureTest.kt +++ b/components/lib/auth/src/test/java/mozilla/components/lib/auth/BiometricPromptAuthTest.kt @@ -27,9 +27,9 @@ import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config @RunWith(RobolectricTestRunner::class) -class BiometricPromptFeatureTest { +class BiometricPromptAuthTest { - private lateinit var biometricPromptFeature: BiometricPromptFeature + private lateinit var biometricPromptAuth: BiometricPromptAuth private lateinit var biometricManager: BiometricManager private lateinit var fragment: Fragment private lateinit var biometricUtils: BiometricUtils @@ -38,17 +38,19 @@ class BiometricPromptFeatureTest { fun setup() { fragment = createAddedTestFragment { Fragment() } biometricUtils = spy(BiometricUtils()) - biometricPromptFeature = spy( - BiometricPromptFeature( + biometricPromptAuth = spy( + BiometricPromptAuth( testContext, fragment, - object : AuthenticationCallbacks { - override val onAuthFailure: () -> Unit - get() = {} - override val onAuthSuccess: () -> Unit - get() = { } - override val onAuthError: (errorText: String) -> Unit - get() = {} + object : AuthenticationDelegate { + override fun onAuthFailure() { + } + + override fun onAuthSuccess() { + } + + override fun onAuthError(errorText: String) { + } } ) ) @@ -96,33 +98,33 @@ class BiometricPromptFeatureTest { @Test fun `prompt is created and destroyed on start and stop`() { - assertNull(biometricPromptFeature.biometricPrompt) + assertNull(biometricPromptAuth.biometricPrompt) - biometricPromptFeature.start() + biometricPromptAuth.start() - assertNotNull(biometricPromptFeature.biometricPrompt) + assertNotNull(biometricPromptAuth.biometricPrompt) - biometricPromptFeature.stop() + biometricPromptAuth.stop() - assertNull(biometricPromptFeature.biometricPrompt) + assertNull(biometricPromptAuth.biometricPrompt) } @Test fun `requestAuthentication invokes biometric prompt`() { val prompt: BiometricPrompt = mock() - biometricPromptFeature.biometricPrompt = prompt + biometricPromptAuth.biometricPrompt = prompt - biometricPromptFeature.requestAuthentication("title", "subtitle") + biometricPromptAuth.requestAuthentication("title", "subtitle") verify(prompt).authenticate(any()) } @Test fun `promptCallback fires feature callbacks`() { - val promptCallback: BiometricPromptFeature.PromptCallback = mock() + val promptCallback: BiometricPromptAuth.PromptCallback = mock() val prompt = BiometricPrompt(fragment, promptCallback) - biometricPromptFeature.biometricPrompt = prompt + biometricPromptAuth.biometricPrompt = prompt promptCallback.onAuthenticationError(BiometricPrompt.ERROR_CANCELED, "") diff --git a/components/lib/biometric-prompt/src/main/AndroidManifest.xml b/components/lib/biometric-prompt/src/main/AndroidManifest.xml deleted file mode 100644 index 8baf6b5450e..00000000000 --- a/components/lib/biometric-prompt/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/components/lib/biometric-prompt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/components/lib/biometric-prompt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker deleted file mode 100644 index cf1c399ea81..00000000000 --- a/components/lib/biometric-prompt/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker +++ /dev/null @@ -1,2 +0,0 @@ -mock-maker-inline -// This allows mocking final classes (classes are final by default in Kotlin) diff --git a/components/lib/biometric-prompt/src/test/resources/robolectric.properties b/components/lib/biometric-prompt/src/test/resources/robolectric.properties deleted file mode 100644 index 89a6c8b4c2e..00000000000 --- a/components/lib/biometric-prompt/src/test/resources/robolectric.properties +++ /dev/null @@ -1 +0,0 @@ -sdk=28 \ No newline at end of file diff --git a/components/lib/crash/docs/metrics.md b/components/lib/crash/docs/metrics.md index 886f2f65664..acae2363603 100644 --- a/components/lib/crash/docs/metrics.md +++ b/components/lib/crash/docs/metrics.md @@ -1,4 +1,4 @@ - + # Metrics @@ -26,5 +26,5 @@ In addition to those built-in metrics, the following metrics are added to the pi Data categories are [defined here](https://wiki.mozilla.org/Firefox/Data_Collection). - + diff --git a/components/lib/crash/src/test/java/mozilla/components/lib/crash/service/GleanCrashReporterServiceTest.kt b/components/lib/crash/src/test/java/mozilla/components/lib/crash/service/GleanCrashReporterServiceTest.kt index 89731046ecd..aa0532e231c 100644 --- a/components/lib/crash/src/test/java/mozilla/components/lib/crash/service/GleanCrashReporterServiceTest.kt +++ b/components/lib/crash/src/test/java/mozilla/components/lib/crash/service/GleanCrashReporterServiceTest.kt @@ -35,7 +35,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -62,14 +62,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialValue ) } } @@ -80,7 +76,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -105,14 +101,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialValue ) } } @@ -123,7 +115,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -148,14 +140,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialValue ) } } @@ -166,7 +154,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -191,14 +179,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue()!! - initialValue ) } } @@ -209,7 +193,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.CAUGHT_EXCEPTION_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.CAUGHT_EXCEPTION_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -234,14 +218,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.CAUGHT_EXCEPTION_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.CAUGHT_EXCEPTION_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.CAUGHT_EXCEPTION_KEY].testGetValue()!! - initialValue ) } } @@ -249,24 +229,24 @@ class GleanCrashReporterServiceTest { @Test fun `GleanCrashReporterService correctly handles multiple crashes in a single file`() { val initialExceptionValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } val initialMainProcessNativeCrashValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } val initialForegroundChildProcessNativeCrashValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } val initialBackgroundChildProcessNativeCrashValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -320,29 +300,25 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 2, - CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue() - initialExceptionValue + CrashMetrics.crashCount[GleanCrashReporterService.UNCAUGHT_EXCEPTION_KEY].testGetValue()!! - initialExceptionValue ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialMainProcessNativeCrashValue + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialMainProcessNativeCrashValue ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialForegroundChildProcessNativeCrashValue + CrashMetrics.crashCount[GleanCrashReporterService.FOREGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialForegroundChildProcessNativeCrashValue ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialBackgroundChildProcessNativeCrashValue + CrashMetrics.crashCount[GleanCrashReporterService.BACKGROUND_CHILD_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialBackgroundChildProcessNativeCrashValue ) } } @@ -369,7 +345,7 @@ class GleanCrashReporterServiceTest { // tests or even between test classes, so we compensate by capturing the initial value // to compare to. val initialValue = try { - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! } catch (e: NullPointerException) { 0 } @@ -398,14 +374,10 @@ class GleanCrashReporterServiceTest { run { GleanCrashReporterService(context) - assertTrue( - "Glean must record a value", - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testHasValue() - ) assertEquals( "Glean must record correct value", 1, - CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue() - initialValue + CrashMetrics.crashCount[GleanCrashReporterService.MAIN_PROCESS_NATIVE_CODE_CRASH_KEY].testGetValue()!! - initialValue ) } } diff --git a/components/service/glean/src/main/java/mozilla/components/service/glean/Glean.kt b/components/service/glean/src/main/java/mozilla/components/service/glean/Glean.kt index 73162898e5c..e168fb0aaa6 100644 --- a/components/service/glean/src/main/java/mozilla/components/service/glean/Glean.kt +++ b/components/service/glean/src/main/java/mozilla/components/service/glean/Glean.kt @@ -8,7 +8,7 @@ import android.content.Context import androidx.annotation.MainThread import androidx.annotation.VisibleForTesting import mozilla.components.service.glean.config.Configuration -import mozilla.components.service.glean.private.RecordedExperimentData +import mozilla.components.service.glean.private.RecordedExperiment import mozilla.telemetry.glean.Glean as GleanCore typealias BuildInfo = mozilla.telemetry.glean.BuildInfo @@ -77,14 +77,6 @@ object Glean { GleanCore.setUploadEnabled(enabled) } - /** - * Get whether or not Glean is allowed to record and upload data. - */ - @Suppress("DEPRECATION") - fun getUploadEnabled(): Boolean { - return GleanCore.getUploadEnabled() - } - /** * Indicate that an experiment is running. Glean will then add an * experiment annotation to the environment which is sent with pings. This @@ -132,11 +124,11 @@ object Glean { * Returns the stored data for the requested active experiment, for testing purposes only. * * @param experimentId the id of the experiment to look for. - * @return the [RecordedExperimentData] for the experiment + * @return the [RecordedExperiment] for the experiment * @throws [NullPointerException] if the requested experiment is not active or data is corrupt. */ @VisibleForTesting(otherwise = VisibleForTesting.NONE) - fun testGetExperimentData(experimentId: String): RecordedExperimentData { + fun testGetExperimentData(experimentId: String): RecordedExperiment { return GleanCore.testGetExperimentData(experimentId) } } diff --git a/components/service/glean/src/main/java/mozilla/components/service/glean/net/ConceptFetchHttpUploader.kt b/components/service/glean/src/main/java/mozilla/components/service/glean/net/ConceptFetchHttpUploader.kt index c60941469c6..c9fcec27965 100644 --- a/components/service/glean/src/main/java/mozilla/components/service/glean/net/ConceptFetchHttpUploader.kt +++ b/components/service/glean/src/main/java/mozilla/components/service/glean/net/ConceptFetchHttpUploader.kt @@ -12,7 +12,7 @@ import mozilla.components.concept.fetch.Request import mozilla.components.concept.fetch.toMutableHeaders import mozilla.components.support.base.log.logger.Logger import mozilla.telemetry.glean.net.HeadersList -import mozilla.telemetry.glean.net.HttpResponse +import mozilla.telemetry.glean.net.HttpStatus import mozilla.telemetry.glean.net.RecoverableFailure import mozilla.telemetry.glean.net.UploadResult import java.io.IOException @@ -70,7 +70,7 @@ class ConceptFetchHttpUploader( performUpload(client.value, request) } catch (e: IOException) { logger.warn("IOException while uploading ping", e) - RecoverableFailure + RecoverableFailure(0) } } @@ -101,7 +101,7 @@ class ConceptFetchHttpUploader( internal fun performUpload(client: Client, request: Request): UploadResult { logger.debug("Submitting ping to: ${request.url}") client.fetch(request).use { response -> - return HttpResponse(response.status) + return HttpStatus(response.status) } } } diff --git a/components/service/glean/src/main/java/mozilla/components/service/glean/private/MetricAliases.kt b/components/service/glean/src/main/java/mozilla/components/service/glean/private/MetricAliases.kt index 72411df214d..c61f66b4fc6 100644 --- a/components/service/glean/src/main/java/mozilla/components/service/glean/private/MetricAliases.kt +++ b/components/service/glean/src/main/java/mozilla/components/service/glean/private/MetricAliases.kt @@ -4,10 +4,12 @@ package mozilla.components.service.glean.private +typealias CommonMetricData = mozilla.telemetry.glean.private.CommonMetricData +typealias EventExtraKey = mozilla.telemetry.glean.private.EventExtraKey +typealias EventExtras = mozilla.telemetry.glean.private.EventExtras typealias Lifetime = mozilla.telemetry.glean.private.Lifetime typealias NoExtraKeys = mozilla.telemetry.glean.private.NoExtraKeys typealias NoExtras = mozilla.telemetry.glean.private.NoExtras -typealias EventExtras = mozilla.telemetry.glean.private.EventExtras typealias NoReasonCodes = mozilla.telemetry.glean.private.NoReasonCodes typealias BooleanMetricType = mozilla.telemetry.glean.private.BooleanMetricType @@ -22,11 +24,11 @@ typealias MemoryDistributionMetricType = mozilla.telemetry.glean.private.MemoryD typealias MemoryUnit = mozilla.telemetry.glean.private.MemoryUnit typealias PingType = mozilla.telemetry.glean.private.PingType typealias QuantityMetricType = mozilla.telemetry.glean.private.QuantityMetricType -typealias RecordedExperimentData = mozilla.telemetry.glean.private.RecordedExperimentData +typealias RecordedExperiment = mozilla.telemetry.glean.private.RecordedExperiment typealias StringListMetricType = mozilla.telemetry.glean.private.StringListMetricType typealias StringMetricType = mozilla.telemetry.glean.private.StringMetricType -typealias TimespanMetricType = mozilla.telemetry.glean.private.TimespanMetricType typealias TimeUnit = mozilla.telemetry.glean.private.TimeUnit +typealias TimespanMetricType = mozilla.telemetry.glean.private.TimespanMetricType typealias TimingDistributionMetricType = mozilla.telemetry.glean.private.TimingDistributionMetricType typealias UrlMetricType = mozilla.telemetry.glean.private.UrlMetricType typealias UuidMetricType = mozilla.telemetry.glean.private.UuidMetricType diff --git a/components/service/glean/src/main/java/mozilla/components/service/glean/testing/ErrorType.kt b/components/service/glean/src/main/java/mozilla/components/service/glean/testing/ErrorType.kt new file mode 100644 index 00000000000..8f4e53d5010 --- /dev/null +++ b/components/service/glean/src/main/java/mozilla/components/service/glean/testing/ErrorType.kt @@ -0,0 +1,10 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package mozilla.components.service.glean.testing + +/** + * Different types of errors that can be reported through Glean's error reporting metrics. + */ +typealias ErrorType = mozilla.telemetry.glean.testing.ErrorType diff --git a/components/service/glean/src/test/java/mozilla/components/service/glean/GleanTest.kt b/components/service/glean/src/test/java/mozilla/components/service/glean/GleanTest.kt index 17131be33e1..0977262f077 100644 --- a/components/service/glean/src/test/java/mozilla/components/service/glean/GleanTest.kt +++ b/components/service/glean/src/test/java/mozilla/components/service/glean/GleanTest.kt @@ -7,6 +7,7 @@ package mozilla.components.service.glean import android.content.Context import androidx.test.core.app.ApplicationProvider import mozilla.components.service.glean.private.BooleanMetricType +import mozilla.components.service.glean.private.CommonMetricData import mozilla.components.service.glean.private.Lifetime import mozilla.components.service.glean.testing.GleanTestRule import org.junit.Assert.assertTrue @@ -27,15 +28,17 @@ class GleanTest { fun `Glean correctly initializes and records a metric`() { // Define a 'booleanMetric' boolean metric, which will be stored in "store1" val booleanMetric = BooleanMetricType( - disabled = false, - category = "telemetry", - lifetime = Lifetime.Application, - name = "boolean_metric", - sendInPings = listOf("store1") + CommonMetricData( + disabled = false, + category = "telemetry", + lifetime = Lifetime.APPLICATION, + name = "boolean_metric", + sendInPings = listOf("store1") + ) ) booleanMetric.set(true) - assertTrue(booleanMetric.testGetValue()) + assertTrue(booleanMetric.testGetValue()!!) } } diff --git a/components/service/glean/src/test/java/mozilla/components/service/glean/net/ConceptFetchHttpUploaderTest.kt b/components/service/glean/src/test/java/mozilla/components/service/glean/net/ConceptFetchHttpUploaderTest.kt index 397b6efe2b8..388abcff528 100644 --- a/components/service/glean/src/test/java/mozilla/components/service/glean/net/ConceptFetchHttpUploaderTest.kt +++ b/components/service/glean/src/test/java/mozilla/components/service/glean/net/ConceptFetchHttpUploaderTest.kt @@ -13,7 +13,7 @@ import mozilla.components.support.test.any import mozilla.components.support.test.argumentCaptor import mozilla.components.support.test.mock import mozilla.telemetry.glean.config.Configuration -import mozilla.telemetry.glean.net.HttpResponse +import mozilla.telemetry.glean.net.HttpStatus import mozilla.telemetry.glean.net.RecoverableFailure import okhttp3.mockwebserver.Dispatcher import okhttp3.mockwebserver.MockResponse @@ -60,7 +60,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() })) - val request = uploader.buildRequest(testPath, testPing.toByteArray(), emptyList()) + val request = uploader.buildRequest(testPath, testPing.toByteArray(), emptyMap()) assertEquals( Pair(ConceptFetchHttpUploader.DEFAULT_READ_TIMEOUT, TimeUnit.MILLISECONDS), @@ -86,7 +86,7 @@ class ConceptFetchHttpUploaderTest { ) val uploader = ConceptFetchHttpUploader(lazy { mockClient }) - uploader.upload(testPath, testPing.toByteArray(), expectedHeaders.toList()) + uploader.upload(testPath, testPing.toByteArray(), expectedHeaders) val requestCaptor = argumentCaptor() verify(mockClient).fetch(requestCaptor.capture()) @@ -103,7 +103,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() })) - val request = uploader.buildRequest(testPath, testPing.toByteArray(), emptyList()) + val request = uploader.buildRequest(testPath, testPing.toByteArray(), emptyMap()) assertEquals(request.cookiePolicy, Request.CookiePolicy.OMIT) } @@ -119,7 +119,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { mockClient })) - assertEquals(HttpResponse(200), uploader.upload(testPath, testPing.toByteArray(), emptyList())) + assertEquals(HttpStatus(200), uploader.upload(testPath, testPing.toByteArray(), emptyMap())) } @Test fun `upload() returns false for server errors (5xx)`() { @@ -133,7 +133,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { mockClient })) - assertEquals(HttpResponse(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyList())) + assertEquals(HttpStatus(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyMap())) } } @@ -149,7 +149,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { mockClient })) - assertEquals(HttpResponse(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyList())) + assertEquals(HttpStatus(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyMap())) } } @@ -165,7 +165,7 @@ class ConceptFetchHttpUploaderTest { val uploader = spy(ConceptFetchHttpUploader(lazy { mockClient })) - assertEquals(HttpResponse(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyList())) + assertEquals(HttpStatus(responseCode), uploader.upload(testPath, testPing.toByteArray(), emptyMap())) } } @@ -176,7 +176,7 @@ class ConceptFetchHttpUploaderTest { val client = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() }) val submissionUrl = "http://" + server.hostName + ":" + server.port + testPath - assertEquals(HttpResponse(200), client.upload(submissionUrl, testPing.toByteArray(), listOf(Pair("test", "header")))) + assertEquals(HttpStatus(200), client.upload(submissionUrl, testPing.toByteArray(), mapOf("test" to "header"))) val request = server.takeRequest() assertEquals(testPath, request.path) @@ -194,7 +194,7 @@ class ConceptFetchHttpUploaderTest { val client = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() }) val submissionUrl = "http://" + server.hostName + ":" + server.port + testPath - assertEquals(HttpResponse(200), client.upload(submissionUrl, testPing.toByteArray(), listOf(Pair("test", "header")))) + assertEquals(HttpStatus(200), client.upload(submissionUrl, testPing.toByteArray(), mapOf("test" to "header"))) val request = server.takeRequest() assertEquals(testPath, request.path) @@ -213,7 +213,7 @@ class ConceptFetchHttpUploaderTest { val client = ConceptFetchHttpUploader(lazy { OkHttpClient() }) val submissionUrl = "http://" + server.hostName + ":" + server.port + testPath - assertEquals(HttpResponse(200), client.upload(submissionUrl, testPing.toByteArray(), listOf(Pair("test", "header")))) + assertEquals(HttpStatus(200), client.upload(submissionUrl, testPing.toByteArray(), mapOf("test" to "header"))) val request = server.takeRequest() assertEquals(testPath, request.path) @@ -262,7 +262,7 @@ class ConceptFetchHttpUploaderTest { // Trigger the connection. val client = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() }) val submissionUrl = testConfig.serverEndpoint + testPath - assertEquals(HttpResponse(200), client.upload(submissionUrl, testPing.toByteArray(), emptyList())) + assertEquals(HttpStatus(200), client.upload(submissionUrl, testPing.toByteArray(), emptyMap())) val request = server.takeRequest() assertEquals(testPath, request.path) @@ -286,7 +286,7 @@ class ConceptFetchHttpUploaderTest { // And IOException during upload is a failed upload that we should retry. The client should // return false in this case. - assertEquals(RecoverableFailure, uploader.upload("path", "ping".toByteArray(), emptyList())) + assertEquals(RecoverableFailure(0), uploader.upload("path", "ping".toByteArray(), emptyMap())) } @Test @@ -299,7 +299,7 @@ class ConceptFetchHttpUploaderTest { assertFalse(uploader.client.isInitialized()) // After calling upload, the client must get instantiated. - uploader.upload("path", "ping".toByteArray(), emptyList()) + uploader.upload("path", "ping".toByteArray(), emptyMap()) assertTrue(uploader.client.isInitialized()) } @@ -317,7 +317,7 @@ class ConceptFetchHttpUploaderTest { ) val uploader = ConceptFetchHttpUploader(lazy { mockClient }, true) - uploader.upload(testPath, testPing.toByteArray(), expectedHeaders.toList()) + uploader.upload(testPath, testPing.toByteArray(), expectedHeaders) val captor = argumentCaptor() diff --git a/components/support/migration/docs/metrics.md b/components/support/migration/docs/metrics.md index b0f9f7c31fb..57962c0c74c 100644 --- a/components/support/migration/docs/metrics.md +++ b/components/support/migration/docs/metrics.md @@ -1,4 +1,4 @@ - + # Metrics @@ -103,5 +103,5 @@ In addition to those built-in metrics, the following metrics are added to the pi Data categories are [defined here](https://wiki.mozilla.org/Firefox/Data_Collection). - + diff --git a/components/support/sync-telemetry/docs/metrics.md b/components/support/sync-telemetry/docs/metrics.md index 1aad4488996..7d1bb44f736 100644 --- a/components/support/sync-telemetry/docs/metrics.md +++ b/components/support/sync-telemetry/docs/metrics.md @@ -1,4 +1,4 @@ - + # Metrics @@ -208,5 +208,5 @@ In addition to those built-in metrics, the following metrics are added to the pi Data categories are [defined here](https://wiki.mozilla.org/Firefox/Data_Collection). - + diff --git a/components/support/sync-telemetry/src/test/java/mozilla/components/support/sync/telemetry/SyncTelemetryTest.kt b/components/support/sync-telemetry/src/test/java/mozilla/components/support/sync/telemetry/SyncTelemetryTest.kt index fcdf201c4bd..9cd4b104515 100644 --- a/components/support/sync-telemetry/src/test/java/mozilla/components/support/sync/telemetry/SyncTelemetryTest.kt +++ b/components/support/sync-telemetry/src/test/java/mozilla/components/support/sync/telemetry/SyncTelemetryTest.kt @@ -29,6 +29,7 @@ import org.json.JSONException import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.junit.Before @@ -126,22 +127,22 @@ class SyncTelemetryTest { 0 -> { HistorySync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now, startedAt.testGetValue().asSeconds()) - assertEquals(now + 5, finishedAt.testGetValue().asSeconds()) + assertEquals(now, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 5, finishedAt.testGetValue()!!.asSeconds()) assertEquals(5, incoming["applied"].testGetValue()) assertEquals(7, incoming["failed_to_apply"].testGetValue()) assertEquals(2, incoming["reconciled"].testGetValue()) assertEquals(14, outgoing["uploaded"].testGetValue()) assertEquals(7, outgoing["failed_to_upload"].testGetValue()) assertEquals(2, outgoingBatches.testGetValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } } 1 -> { HistorySync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now + 10, startedAt.testGetValue().asSeconds()) - assertEquals(now + 15, finishedAt.testGetValue().asSeconds()) + assertEquals(now + 10, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 15, finishedAt.testGetValue()!!.asSeconds()) assertTrue( listOf( incoming["applied"], @@ -150,9 +151,9 @@ class SyncTelemetryTest { outgoing["uploaded"], outgoing["failed_to_upload"], outgoingBatches - ).none { it.testHasValue() } + ).none { it.testGetValue() != null } ) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } } else -> fail() @@ -272,38 +273,38 @@ class SyncTelemetryTest { "other", "unexpected", "auth" - ).none { HistorySync.failureReason[it].testHasValue() } + ).none { HistorySync.failureReason[it].testGetValue() != null } ) } 1 -> HistorySync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } 2 -> HistorySync.apply { assertEquals("Unexpected error: 418", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } 3 -> HistorySync.apply { assertEquals("Splines not reticulated", failureReason["auth"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } 4 -> HistorySync.apply { assertEquals("Kaboom!", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } 5 -> HistorySync.apply { assertEquals("Qualia unsynchronized", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } else -> fail() } @@ -337,9 +338,9 @@ class SyncTelemetryTest { when (pingCount) { 0 -> HistorySync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("history-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("history-sync")) } else -> fail() } @@ -428,22 +429,22 @@ class SyncTelemetryTest { 0 -> { LoginsSync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now, startedAt.testGetValue().asSeconds()) - assertEquals(now + 5, finishedAt.testGetValue().asSeconds()) + assertEquals(now, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 5, finishedAt.testGetValue()!!.asSeconds()) assertEquals(5, incoming["applied"].testGetValue()) assertEquals(7, incoming["failed_to_apply"].testGetValue()) assertEquals(2, incoming["reconciled"].testGetValue()) assertEquals(14, outgoing["uploaded"].testGetValue()) assertEquals(7, outgoing["failed_to_upload"].testGetValue()) assertEquals(2, outgoingBatches.testGetValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } } 1 -> { LoginsSync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now + 10, startedAt.testGetValue().asSeconds()) - assertEquals(now + 15, finishedAt.testGetValue().asSeconds()) + assertEquals(now + 10, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 15, finishedAt.testGetValue()!!.asSeconds()) assertTrue( listOf( incoming["applied"], @@ -452,9 +453,9 @@ class SyncTelemetryTest { outgoing["uploaded"], outgoing["failed_to_upload"], outgoingBatches - ).none { it.testHasValue() } + ).none { it.testGetValue() != null } ) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } } else -> fail() @@ -574,38 +575,38 @@ class SyncTelemetryTest { "other", "unexpected", "auth" - ).none { LoginsSync.failureReason[it].testHasValue() } + ).none { LoginsSync.failureReason[it].testGetValue() != null } ) } 1 -> LoginsSync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } 2 -> LoginsSync.apply { assertEquals("Unexpected error: 418", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } 3 -> LoginsSync.apply { assertEquals("Splines not reticulated", failureReason["auth"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } 4 -> LoginsSync.apply { assertEquals("Kaboom!", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } 5 -> LoginsSync.apply { assertEquals("Qualia unsynchronized", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } else -> fail() } @@ -639,9 +640,9 @@ class SyncTelemetryTest { when (pingCount) { 0 -> LoginsSync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("logins-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("logins-sync")) } else -> fail() } @@ -704,15 +705,15 @@ class SyncTelemetryTest { 0 -> { BookmarksSync.apply { assertEquals("xyz789", uid.testGetValue()) - assertEquals(now + 25, startedAt.testGetValue().asSeconds()) - assertEquals(now + 31, finishedAt.testGetValue().asSeconds()) - assertFalse(incoming["applied"].testHasValue()) - assertFalse(incoming["failed_to_apply"].testHasValue()) - assertFalse(incoming["reconciled"].testHasValue()) + assertEquals(now + 25, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 31, finishedAt.testGetValue()!!.asSeconds()) + assertNull(incoming["applied"].testGetValue()) + assertNull(incoming["failed_to_apply"].testGetValue()) + assertNull(incoming["reconciled"].testGetValue()) assertEquals(10, outgoing["uploaded"].testGetValue()) assertEquals(5, outgoing["failed_to_upload"].testGetValue()) assertEquals(1, outgoingBatches.testGetValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } } else -> fail() @@ -821,38 +822,38 @@ class SyncTelemetryTest { "other", "unexpected", "auth" - ).none { BookmarksSync.failureReason[it].testHasValue() } + ).none { BookmarksSync.failureReason[it].testGetValue() != null } ) } 1 -> BookmarksSync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } 2 -> BookmarksSync.apply { assertEquals("Unexpected error: 418", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } 3 -> BookmarksSync.apply { assertEquals("Splines not reticulated", failureReason["auth"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } 4 -> BookmarksSync.apply { assertEquals("Kaboom!", failureReason["unexpected"].testGetValue()) - assertFalse(failureReason["other"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["other"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } 5 -> BookmarksSync.apply { assertEquals("Qualia unsynchronized", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } else -> fail() } @@ -886,9 +887,9 @@ class SyncTelemetryTest { when (pingCount) { 0 -> BookmarksSync.apply { assertEquals("Synergies not aligned", failureReason["other"].testGetValue()) - assertFalse(failureReason["unexpected"].testHasValue()) - assertFalse(failureReason["auth"].testHasValue()) - assertFalse(Sync.syncUuid.testHasValue("bookmarks-sync")) + assertNull(failureReason["unexpected"].testGetValue()) + assertNull(failureReason["auth"].testGetValue()) + assertNull(Sync.syncUuid.testGetValue("bookmarks-sync")) } else -> fail() } @@ -1021,7 +1022,7 @@ class SyncTelemetryTest { fun setOrAssertGlobalSyncUuid(currentPingIndex: Int, pingName: String) { if (globalSyncUuids.elementAtOrNull(currentPingIndex) == null) { - globalSyncUuids.add(Sync.syncUuid.testGetValue(pingName)) + globalSyncUuids.add(Sync.syncUuid.testGetValue(pingName)!!) } else { assertEquals(globalSyncUuids[currentPingIndex], Sync.syncUuid.testGetValue(pingName)) } @@ -1039,7 +1040,6 @@ class SyncTelemetryTest { syncTelemetry, submitGlobalPing = { assertNotNull(globalSyncUuids.elementAtOrNull(globalPingCount)) - assertTrue(Sync.syncUuid.testHasValue("sync")) assertEquals(globalSyncUuids[globalPingCount], Sync.syncUuid.testGetValue("sync")) // Assertions above already assert syncUuid; below, let's make sure that 'failureReason' is processed. @@ -1048,10 +1048,10 @@ class SyncTelemetryTest { assertEquals("Synergies not aligned", Sync.failureReason["other"].testGetValue()) } 1 -> { - assertFalse(Sync.failureReason["other"].testHasValue()) + assertNull(Sync.failureReason["other"].testGetValue()) } 2 -> { - assertFalse(Sync.failureReason["other"].testHasValue()) + assertNull(Sync.failureReason["other"].testGetValue()) } else -> fail() } @@ -1066,8 +1066,8 @@ class SyncTelemetryTest { setOrIncrementPingCount(currentPingIndex, "history") HistorySync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now, startedAt.testGetValue().asSeconds()) - assertEquals(now + 5, finishedAt.testGetValue().asSeconds()) + assertEquals(now, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 5, finishedAt.testGetValue()!!.asSeconds()) assertEquals(5, incoming["applied"].testGetValue()) assertEquals(7, incoming["failed_to_apply"].testGetValue()) assertEquals(2, incoming["reconciled"].testGetValue()) @@ -1082,8 +1082,8 @@ class SyncTelemetryTest { setOrIncrementPingCount(currentPingIndex, "history") HistorySync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now + 10, startedAt.testGetValue().asSeconds()) - assertEquals(now + 15, finishedAt.testGetValue().asSeconds()) + assertEquals(now + 10, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 15, finishedAt.testGetValue()!!.asSeconds()) assertTrue( listOf( incoming["applied"], @@ -1092,7 +1092,7 @@ class SyncTelemetryTest { outgoing["uploaded"], outgoing["failed_to_upload"], outgoingBatches - ).none { it.testHasValue() } + ).none { it.testGetValue() != null } ) } Pings.historySync.submit() @@ -1107,8 +1107,8 @@ class SyncTelemetryTest { setOrIncrementPingCount(currentPingIndex, "passwords") LoginsSync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now, startedAt.testGetValue().asSeconds()) - assertEquals(now + 5, finishedAt.testGetValue().asSeconds()) + assertEquals(now, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 5, finishedAt.testGetValue()!!.asSeconds()) assertEquals(5, incoming["applied"].testGetValue()) assertEquals(7, incoming["failed_to_apply"].testGetValue()) assertEquals(2, incoming["reconciled"].testGetValue()) @@ -1128,11 +1128,11 @@ class SyncTelemetryTest { setOrIncrementPingCount(currentPingIndex, "bookmarks") BookmarksSync.apply { assertEquals("abc123", uid.testGetValue()) - assertEquals(now + 25, startedAt.testGetValue().asSeconds()) - assertEquals(now + 31, finishedAt.testGetValue().asSeconds()) - assertFalse(incoming["applied"].testHasValue()) - assertFalse(incoming["failed_to_apply"].testHasValue()) - assertFalse(incoming["reconciled"].testHasValue()) + assertEquals(now + 25, startedAt.testGetValue()!!.asSeconds()) + assertEquals(now + 31, finishedAt.testGetValue()!!.asSeconds()) + assertNull(incoming["applied"].testGetValue()) + assertNull(incoming["failed_to_apply"].testGetValue()) + assertNull(incoming["reconciled"].testGetValue()) assertEquals(10, outgoing["uploaded"].testGetValue()) assertEquals(5, outgoing["failed_to_upload"].testGetValue()) assertEquals(1, outgoingBatches.testGetValue()) @@ -1165,13 +1165,12 @@ class SyncTelemetryTest { } """ SyncTelemetry.processFxaTelemetry(json) - assertTrue(FxaTab.sent.testHasValue()) - val events = FxaTab.sent.testGetValue() + val events = FxaTab.sent.testGetValue()!! assertEquals(1, events.size) assertEquals("test-flow-id", events.elementAt(0).extra!!["flow_id"]) assertEquals("test-stream-id", events.elementAt(0).extra!!["stream_id"]) - assertFalse(FxaTab.received.testHasValue()) + assertNull(FxaTab.received.testGetValue()) } @Test @@ -1186,14 +1185,13 @@ class SyncTelemetryTest { } """ SyncTelemetry.processFxaTelemetry(json) - assertTrue(FxaTab.received.testHasValue()) - val events = FxaTab.received.testGetValue() + val events = FxaTab.received.testGetValue()!! assertEquals(1, events.size) assertEquals("test-flow-id", events.elementAt(0).extra!!["flow_id"]) assertEquals("test-stream-id", events.elementAt(0).extra!!["stream_id"]) assertEquals("test-reason", events.elementAt(0).extra!!["reason"]) - assertFalse(FxaTab.sent.testHasValue()) + assertNull(FxaTab.sent.testGetValue()) } @Test @@ -1216,8 +1214,8 @@ class SyncTelemetryTest { verify(crashReporter, times(2)).submitCaughtException(any()) // completely invalid json SyncTelemetry.processFxaTelemetry(""" foo bar """, crashReporter) - assertFalse(FxaTab.sent.testHasValue()) - assertFalse(FxaTab.received.testHasValue()) + assertNull(FxaTab.sent.testGetValue()) + assertNull(FxaTab.received.testGetValue()) // One more exception, making it the 3rd time verify(crashReporter, times(3)).submitCaughtException(any()) } diff --git a/docs/changelog.md b/docs/changelog.md index f5954f84583..346c4e83703 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -11,6 +11,9 @@ permalink: /changelog/ * [Gecko](https://github.com/mozilla-mobile/android-components/blob/main/buildSrc/src/main/java/Gecko.kt) * [Configuration](https://github.com/mozilla-mobile/android-components/blob/main/.config.yml) +* **feature-media** + * App should not be locked in landscape when a tab or custom tab loads while in pip mode. [#12298] (https://github.com/mozilla-mobile/android-components/issues/12298) + * **browser-toolbar** * Expand toolbar when url changes. [#12215](https://github.com/mozilla-mobile/android-components/issues/12215) @@ -20,6 +23,22 @@ permalink: /changelog/ * **feature-prompts**: * Added optional `addressPickerView` and `onManageAddresses` parameters through `AddressDelegate` to `PromptFeature` for a new `AddressPicker` to display a view for selecting addresses to autofill into a site. [#12061](https://github.com/mozilla-mobile/android-components/issues/12061) +* **service-glean** + * 🆙 Updated Glean to version 50.0.1 ([changelog](https://github.com/mozilla/glean/releases/tag/v50.0.1)) + * **This is a breaking change**. See ) for full details. + Notable breakage: + * `testGetValue` on all metric types now returns `null` when no data is recorded instead of throwing an exception. + * `testGetValue` on metrics with more complex data now return new objects for inspection. + * `testHasValue` on all metric types is deprecated. + * On `TimingDistributionMetric`, `CustomDistributionMetric`, `MemoryDistributionMetric` the `accumulateSamples` method now takes a `List` instead of `LongArray`. + Use `listOf` instead of `longArrayOf` or call `.toList` + * `TimingDistributionMetricType.start` now always returns a valid `TimerId`, `TimingDistributionMetricType.stopAndAccumulate` always requires a `TimerId`. + +* **lib-auth** + * Added new `lib-auth` component for various forms of authentication. + * Adds a new `BiometricPromptAuth` for authenticating with biometrics or PIN. + [issue # 12289](https://github.com/mozilla-mobile/android-components/issues/12289) + # 102.0.0 * [Commits](https://github.com/mozilla-mobile/android-components/compare/v101.0.0...v102.0.1) * [Milestone](https://github.com/mozilla-mobile/android-components/milestone/149?closed=1) @@ -84,11 +103,6 @@ permalink: /changelog/ * **feature-syncedtabs** * ⚠️ **This is a breaking change**: When constructing a `SyncedTabsStorage`, the `tabsStorage: RemoteTabsStorage` parameter is no longer optional so must be supplied [#11799](https://github.com/mozilla-mobile/android-components/pull/11799). - -* **lib-auth** - * Add `lib-auth` for authentication using biometrics or PIN. - [issue # 12289](https://github.com/mozilla-mobile/android-components/issues/12289) - # 101.0.0 * [Commits](https://github.com/mozilla-mobile/android-components/compare/v100.0.0...v101.0.0) * [Milestone](https://github.com/mozilla-mobile/android-components/milestone/148?closed=1) diff --git a/samples/browser/src/main/java/org/mozilla/samples/browser/BrowserFragment.kt b/samples/browser/src/main/java/org/mozilla/samples/browser/BrowserFragment.kt index f2ee1683a8a..8148b14be0f 100644 --- a/samples/browser/src/main/java/org/mozilla/samples/browser/BrowserFragment.kt +++ b/samples/browser/src/main/java/org/mozilla/samples/browser/BrowserFragment.kt @@ -121,7 +121,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { mediaSessionFullscreenFeature.set( feature = MediaSessionFullscreenFeature( requireActivity(), - components.store + components.store, + sessionId ), owner = this, view = binding.root diff --git a/samples/glean/src/androidTest/java/org/mozilla/samples/glean/MainActivityTest.kt b/samples/glean/src/androidTest/java/org/mozilla/samples/glean/MainActivityTest.kt index 59c8a9ff552..1d36d0abe99 100644 --- a/samples/glean/src/androidTest/java/org/mozilla/samples/glean/MainActivityTest.kt +++ b/samples/glean/src/androidTest/java/org/mozilla/samples/glean/MainActivityTest.kt @@ -13,7 +13,7 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import mozilla.components.service.glean.testing.GleanTestLocalServer import org.junit.Assert.assertEquals -import org.junit.Assert.assertTrue +import org.junit.Assert.assertNotNull import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -35,8 +35,8 @@ class MainActivityTest { // We don't reset the storage in this test as the GleanTestRule does not // work nicely in instrumented test. Just check the current value, increment // by one and make it the expected value. - val expectedValue = if (GleanTestMetrics.counter.testHasValue()) { - GleanTestMetrics.counter.testGetValue() + 1 + val expectedValue = if (GleanTestMetrics.counter.testGetValue() != null) { + GleanTestMetrics.counter.testGetValue()!! + 1 } else { 1 } @@ -45,7 +45,7 @@ class MainActivityTest { onView(withId(R.id.buttonGenerateData)).perform(click()) // Use the Glean testing API to check if the expected data was recorded. - assertTrue(GleanTestMetrics.counter.testHasValue()) + assertNotNull(GleanTestMetrics.counter.testGetValue()) assertEquals(expectedValue, GleanTestMetrics.counter.testGetValue()) } }