From c3b680a158bcd66c355c3e409c1de89e7f8e97e9 Mon Sep 17 00:00:00 2001 From: indu Date: Tue, 7 Jun 2022 09:40:57 +0530 Subject: [PATCH 1/7] For #12298: App should not be locked in landscape when a tab or custom tab loads while in pip mode This allows a tab or custom tab to be loaded in device's current orientation while pip mode is active Co-Authored-By: Mugurell --- .../MediaSessionFullscreenFeature.kt | 6 +- .../MediaSessionFullscreenFeatureTest.kt | 78 +++++++++++++++++-- docs/changelog.md | 3 + .../samples/browser/BrowserFragment.kt | 3 +- 4 files changed, 81 insertions(+), 9 deletions(-) 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/docs/changelog.md b/docs/changelog.md index 5c95096e270..3ab6a82c743 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) 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 From f0043556d2de4a0df77eeb161d62c8d3b2435d86 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 8 Jun 2022 13:02:26 +0000 Subject: [PATCH 2/7] Update GeckoView (Nightly) to 103.0.20220609065921 --- buildSrc/src/main/java/Gecko.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 90d513d21c40039014d13f4e77936d830fc0b299 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 8 Jun 2022 13:02:27 +0000 Subject: [PATCH 3/7] Update Glean to 50.0.1. --- buildSrc/src/main/java/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index e01ce57da8e..8eb03dc192b 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -32,7 +32,7 @@ object Versions { const val mozilla_appservices = "93.2.2" - const val mozilla_glean = "44.1.1" + const val mozilla_glean = "50.0.1" const val material = "1.2.1" From b6589563d74638d0877c19b212236caf5013f85a Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Tue, 7 Dec 2021 16:52:21 +0100 Subject: [PATCH 4/7] Adopt APIs from Glean UniFFI --- .../engine/gecko/glean/GeckoAdapter.kt | 2 +- components/lib/crash/docs/metrics.md | 4 +- .../service/GleanCrashReporterServiceTest.kt | 68 ++---- .../mozilla/components/service/glean/Glean.kt | 14 +- .../glean/net/ConceptFetchHttpUploader.kt | 6 +- .../service/glean/private/MetricAliases.kt | 8 +- .../service/glean/testing/ErrorType.kt | 10 + .../components/service/glean/GleanTest.kt | 15 +- .../glean/net/ConceptFetchHttpUploaderTest.kt | 30 +-- components/support/migration/docs/metrics.md | 4 +- .../support/sync-telemetry/docs/metrics.md | 4 +- .../sync/telemetry/SyncTelemetryTest.kt | 200 +++++++++--------- docs/changelog.md | 11 + .../mozilla/samples/glean/MainActivityTest.kt | 8 +- 14 files changed, 186 insertions(+), 198 deletions(-) create mode 100644 components/service/glean/src/main/java/mozilla/components/service/glean/testing/ErrorType.kt 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/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..d4ef30f8f7f 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 @@ -28,6 +28,7 @@ import mozilla.components.support.test.robolectric.testContext import org.json.JSONException import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue import org.junit.Assert.fail @@ -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 3ab6a82c743..8183639bfc5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -23,6 +23,17 @@ 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`. + # 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) 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()) } } From 603bc899404f83858ced8499a2500e21386d1cb6 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 9 Jun 2022 16:58:00 +0200 Subject: [PATCH 5/7] Update A-S to 93.4.0 Supersedes #12293 --- buildSrc/src/main/java/Dependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 8eb03dc192b..2f3a52ab354 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -30,7 +30,7 @@ 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 = "50.0.1" From 90d8bc8862b68fd4b9b40366861334caf3ae27eb Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 9 Jun 2022 18:56:00 +0200 Subject: [PATCH 6/7] Fix order of imports --- .../components/support/sync/telemetry/SyncTelemetryTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d4ef30f8f7f..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 @@ -28,8 +28,8 @@ import mozilla.components.support.test.robolectric.testContext import org.json.JSONException import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse -import org.junit.Assert.assertNull import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Assert.fail import org.junit.Before From ab3cfe13fea8157e5ed33070fe58bf6be1a7de6c Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Fri, 10 Jun 2022 00:04:31 +0000 Subject: [PATCH 7/7] Import l10n. --- .../src/main/res/values-yo/strings.xml | 9 ++++++ .../src/main/res/values-yo/strings.xml | 31 +++++++++++++++++++ .../src/main/res/values-yo/strings.xml | 27 ++++++++++++++++ .../src/main/res/values-cy/strings.xml | 10 ++++++ .../src/main/res/values-fy-rNL/strings.xml | 10 ++++++ 5 files changed, 87 insertions(+) create mode 100644 components/feature/app-links/src/main/res/values-yo/strings.xml create mode 100644 components/feature/autofill/src/main/res/values-yo/strings.xml create mode 100644 components/feature/contextmenu/src/main/res/values-yo/strings.xml 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/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