From 84aae93af2ff3c70c0095b4c512368e16352ef22 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 26 Jan 2021 17:38:38 -0500 Subject: [PATCH 001/248] Update Android Components version to 73.0.20210126190058 --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 9b992ca96..a841c050a 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "72.0.20210125143126" + const val VERSION = "73.0.20210126190058" } From 171c466adac01a17fa4acc51af727297f81d6e42 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Wed, 14 Oct 2020 11:19:35 -0400 Subject: [PATCH 002/248] For #14302 - Skip one time pages visit from frecent top sites --- app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index e0a769f5a..6c3b2160d 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -69,6 +69,7 @@ import mozilla.components.browser.state.selector.privateTabs import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.concept.storage.FrecencyThresholdOption import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount @@ -274,7 +275,10 @@ class HomeFragment : Fragment() { */ private fun getTopSitesConfig(): TopSitesConfig { val settings = requireContext().settings() - return TopSitesConfig(settings.topSitesMaxLimit, settings.showTopFrecentSites) + return TopSitesConfig( + settings.topSitesMaxLimit, + FrecencyThresholdOption.SKIP_ONE_TIME_PAGES + ) } /** From ef8d07fadf7f98e15084f121578f27f964c053b9 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 26 Jan 2021 17:47:21 -0500 Subject: [PATCH 003/248] Fix breaking API change in FennecMigrator --- .../java/org/mozilla/fenix/MigratingFenixApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/migration/java/org/mozilla/fenix/MigratingFenixApplication.kt b/app/src/migration/java/org/mozilla/fenix/MigratingFenixApplication.kt index d64043f14..b7d50eccc 100644 --- a/app/src/migration/java/org/mozilla/fenix/MigratingFenixApplication.kt +++ b/app/src/migration/java/org/mozilla/fenix/MigratingFenixApplication.kt @@ -24,7 +24,7 @@ class MigratingFenixApplication : FenixApplication() { val migrator by lazy { FennecMigrator.Builder(this, this.components.analytics.crashReporter) - .migrateOpenTabs(this.components.core.sessionManager) + .migrateOpenTabs(this.components.useCases.tabsUseCases) .migrateHistory(this.components.core.lazyHistoryStorage) .migrateBookmarks( this.components.core.lazyBookmarksStorage, From 4877b7707362e1e7802e09c098a87c1c7cee8e9d Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Wed, 27 Jan 2021 00:02:04 +0000 Subject: [PATCH 004/248] Import l10n. --- app/src/main/res/values-hr/strings.xml | 5 +++-- app/src/main/res/values-pa-rIN/strings.xml | 22 +++++++++++++--------- app/src/main/res/values-tg/strings.xml | 6 +++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 595e1799b..2c36aef30 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -1094,6 +1094,8 @@ Prazni memoriju Dozvole web-stranice + + Preuzimanja Izbriši podatke pregledavanja @@ -1217,8 +1219,7 @@ - Dizajnirali smo %s tako, da ti vladaš onime što dijeliš -        na internetu i što dijeliš s nama. + %s smo stvorili za jednostavno upravljanje podacima koje dijeliš na mreži i koje dijeliš s nama. Pročitaj naša pravila privatnosti diff --git a/app/src/main/res/values-pa-rIN/strings.xml b/app/src/main/res/values-pa-rIN/strings.xml index d0c77e636..bcd118a1e 100644 --- a/app/src/main/res/values-pa-rIN/strings.xml +++ b/app/src/main/res/values-pa-rIN/strings.xml @@ -740,18 +740,22 @@ ਡਾਊਨਲੋਡ ਹਟਾਓ ਕੀ ਤੁਸੀਂ ਆਪਣੇ ਡਾਊਨਲੋਡਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ? - - ਡਾਊਨਲੋਡ ਹਟਾਏ ਗਏ + + ਡਾਊਨਲੋਡ ਹਟਾਏ ਗਏ + + %1$s ਹਟਾਏ - ਡਾਊਨਲੋਡ ਨਹੀਂ ਹੈ + ਕੋਈ ਡਾਊਨਲੋਡ ਕੀਤੀ ਫਾਇਲ ਨਹੀਂ ਹੈ %1$d ਚੁਣੇ ਖੋਲ੍ਹੋ - - ਹਟਾਓ + + + + ਹਟਾਓ @@ -875,6 +879,8 @@ ਸੂਚਨਾਵਾਂ ਪੱਕੀ ਸਟੋਰੇਜ਼ + + DRM-ਕੰਟਰੋਲ ਕੀਤੀ ਸਮੱਗਰੀ ਆਗਿਆ ਲਈ ਪੁੱਛੋ @@ -1102,6 +1108,8 @@ ਸਟੋਰੇਜ਼ ਥਾਂ ਖਾਲੀ ਕਰਦਾ ਹੈ ਸਾਈਟ ਇਜਾਜ਼ਤਾਂ + + ਡਾਊਨਲੋਡ ਬਰਾਊਜ਼ ਕਰਨ ਵਾਲਾ ਡਾਟਾ ਹਟਾਓ @@ -1223,10 +1231,6 @@ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ - - ਅਸੀਂ %s ਨੂੰ ਤੁਹਾਨੂੰ ਕੰਟਰੋਲ ਦੇਣ ਵਾਸਤੇ ਬਣਾਇਆ ਹੈ ਕਿ ਤੁਸੀਂ ਆਨਲਾਈਨ ਕੀ ਸਾਂਝਾ ਕਰਦੇ ਹੋ ਅਤੇ ਸਾਡੇ ਨਾਲ ਤੁਸੀਂ ਕੀ ਸਾਂਝਾ ਕਰਦੇ ਹੋ। - ਸਾਡੀ ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ ਨੂੰ ਪੜ੍ਹੋ diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index c7722a4d1..f380493ee 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -1089,6 +1089,8 @@ Фазои захирагоҳро озод намоед Иҷозатҳои сомона + + Боргириҳо Нест кардани маълумоти тамошокунӣ @@ -1214,9 +1216,7 @@ Махфияти шумо - Мо %s-ро ҳамин тавр тарҳрезӣ кардаем, ки шумо тавонед он чизҳоеро, ки дар онлайн - ва бо мо мубодила мекунед, идора намоед. - + Мо %s-ро ҳамин тавр тарҳрезӣ кардаем, ки шумо тавонед он чизҳоеро, ки дар онлайн ва бо мо мубодила мекунед, идора намоед. Огоҳиномаи махфияти моро хонед From 3abda6daec508a648e30e7fa1e60b14e4447ec1b Mon Sep 17 00:00:00 2001 From: Aki Sasaki Date: Tue, 26 Jan 2021 17:28:59 -0800 Subject: [PATCH 005/248] support staging release promotion projects (#17652) Let's make mozilla-releng/staging-fenix the official staging repository. By supporting it in the automation, we no longer need to maintain a staging patchset to test things properly. --- .taskcluster.yml | 2 +- taskcluster/ci/config.yml | 5 ++++- taskcluster/fenix_taskgraph/release_promotion.py | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.taskcluster.yml b/.taskcluster.yml index 4ee1f0b8c..e11debf8a 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -166,7 +166,7 @@ tasks: routes: $flattenDeep: - checks - - $if: 'level == "3"' + - $if: 'level == "3" || repoUrl == "https://github.com/mozilla-releng/staging-fenix"' then: - tc-treeherder.v2.${project}.${head_sha} # TODO Bug 1601928: Make this scope fork-friendly once ${project} is better defined. This will enable diff --git a/taskcluster/ci/config.yml b/taskcluster/ci/config.yml index 2f2caf9d8..4fb15565d 100644 --- a/taskcluster/ci/config.yml +++ b/taskcluster/ci/config.yml @@ -17,7 +17,10 @@ treeherder: 'Rap-P': 'Raptor power tests' 'TL': 'Toolchain builds for Linux 64-bits' -task-priority: highest +task-priority: + by-project: + "fenix": highest + "staging-fenix": low taskgraph: register: fenix_taskgraph:register diff --git a/taskcluster/fenix_taskgraph/release_promotion.py b/taskcluster/fenix_taskgraph/release_promotion.py index 414e19131..902e7371b 100644 --- a/taskcluster/fenix_taskgraph/release_promotion.py +++ b/taskcluster/fenix_taskgraph/release_promotion.py @@ -17,6 +17,7 @@ from taskgraph.util.taskgraph import find_decision_task, find_existing_tasks_fro RELEASE_PROMOTION_PROJECTS = ( "https://github.com/mozilla-mobile/fenix", + "https://github.com/mozilla-releng/staging-fenix", ) From 780e3362a5f3084d7d250fb2e985f8a71f39dbb9 Mon Sep 17 00:00:00 2001 From: mcarare Date: Wed, 27 Jan 2021 11:59:04 +0200 Subject: [PATCH 006/248] For #17464: Handle selected item background programmatically. --- .../quicksettings/WebsitePermissionsView.kt | 28 +++++++++++++++++-- .../drawable/etp_spinner_item_background.xml | 2 +- app/src/main/res/values/colors.xml | 3 ++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/WebsitePermissionsView.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/WebsitePermissionsView.kt index 8cc26d7fb..dc1735d33 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/WebsitePermissionsView.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/WebsitePermissionsView.kt @@ -12,6 +12,7 @@ import android.widget.ArrayAdapter import android.widget.TextView import androidx.annotation.VisibleForTesting import androidx.appcompat.widget.AppCompatSpinner +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.quicksettings_permissions.view.* @@ -151,11 +152,34 @@ class WebsitePermissionsView( } val selectedIndex = permissionState.options.indexOf(permissionState.autoplayValue) - val adapter = ArrayAdapter( + + val adapter = object : ArrayAdapter( context, R.layout.quicksettings_permission_spinner_item, permissionState.options - ) + ) { + override fun getDropDownView( + position: Int, + convertView: View?, + parent: ViewGroup + ): View { + val view = super.getDropDownView( + position, + convertView, + parent + ) + if (position == viewHolder.status.selectedItemPosition) { + view.setBackgroundColor( + ContextCompat.getColor( + context, + R.color.spinner_selected_item + ) + ) + } + return view + } + } + adapter.setDropDownViewResource(R.layout.quicksetting_permission_spinner_dropdown) viewHolder.status.adapter = adapter diff --git a/app/src/main/res/drawable/etp_spinner_item_background.xml b/app/src/main/res/drawable/etp_spinner_item_background.xml index 642b276e3..05f0f2eea 100644 --- a/app/src/main/res/drawable/etp_spinner_item_background.xml +++ b/app/src/main/res/drawable/etp_spinner_item_background.xml @@ -5,7 +5,7 @@ - + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 169b32455..5f2d1b1a9 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -419,4 +419,7 @@ @color/primary_text_light_theme @color/primary_text_light_theme + + + #1415141A From eaef276345d018d8de6c2eff3ac0b00ecf0cbca2 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Wed, 27 Jan 2021 10:51:03 -0500 Subject: [PATCH 007/248] Closes #17530: Update has open tabs metrics when tabs are opened or closed (#17557) --- .../org/mozilla/fenix/TelemetryMiddleware.kt | 5 +++++ .../mozilla/fenix/components/metrics/Event.kt | 2 ++ .../components/metrics/GleanMetricsService.kt | 6 ++++++ .../mozilla/fenix/TelemetryMiddlewareTest.kt | 21 ++++++++++++++++++- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt index c5c64df0a..c39b97e5f 100644 --- a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt @@ -104,6 +104,11 @@ class TelemetryMiddleware( is TabListAction.RestoreAction -> { // Update/Persist tabs count whenever it changes settings.openTabsCount = context.state.normalTabs.count() + if (context.state.normalTabs.count() > 0) { + metrics.track(Event.HaveOpenTabs) + } else { + metrics.track(Event.HaveNoOpenTabs) + } } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index f946077b2..3fa6b6589 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -197,6 +197,8 @@ sealed class Event { object SyncedTabOpened : Event() object RecentlyClosedTabsOpened : Event() + object HaveOpenTabs : Event() + object HaveNoOpenTabs : Event() object ContextMenuCopyTapped : Event() object ContextMenuSearchTapped : Event() diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 035605dc0..00fc6bc33 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -720,6 +720,12 @@ private val Event.wrapper: EventWrapper<*>? is Event.ContextMenuShareTapped -> EventWrapper( { ContextualMenu.shareTapped.record(it) } ) + Event.HaveOpenTabs -> EventWrapper( + { Metrics.hasOpenTabs.set(true) } + ) + Event.HaveNoOpenTabs -> EventWrapper( + { Metrics.hasOpenTabs.set(false) } + ) // Don't record other events in Glean: is Event.AddBookmark -> null diff --git a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt index 37fb3c1af..355c2bd10 100644 --- a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt +++ b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt @@ -6,6 +6,8 @@ package org.mozilla.fenix import io.mockk.mockk import io.mockk.verify +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineDispatcher import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.action.DownloadAction import mozilla.components.browser.state.action.TabListAction @@ -15,10 +17,12 @@ import mozilla.components.browser.state.store.BrowserStore import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext +import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.components.metrics.Event @@ -28,6 +32,7 @@ import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry import org.mozilla.fenix.utils.Settings @RunWith(FenixRobolectricTestRunner::class) +@ExperimentalCoroutinesApi class TelemetryMiddlewareTest { private lateinit var store: BrowserStore @@ -35,11 +40,15 @@ class TelemetryMiddlewareTest { private lateinit var telemetryMiddleware: TelemetryMiddleware private lateinit var metrics: MetricController private lateinit var adsTelemetry: AdsTelemetry + private val testDispatcher = TestCoroutineDispatcher() + + @get:Rule + val coroutinesTestRule = MainCoroutineRule(testDispatcher) @Before fun setUp() { settings = Settings(testContext) - metrics = mockk() + metrics = mockk(relaxed = true) adsTelemetry = mockk() telemetryMiddleware = TelemetryMiddleware( settings, @@ -55,6 +64,7 @@ class TelemetryMiddlewareTest { store.dispatch(TabListAction.AddTabAction(createTab("https://mozilla.org"))).joinBlocking() assertEquals(1, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } } @Test @@ -63,6 +73,7 @@ class TelemetryMiddlewareTest { store.dispatch(TabListAction.AddTabAction(createTab("https://mozilla.org", private = true))).joinBlocking() assertEquals(0, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveNoOpenTabs) } } @Test @@ -76,6 +87,7 @@ class TelemetryMiddlewareTest { ).joinBlocking() assertEquals(2, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } } @Test @@ -87,9 +99,11 @@ class TelemetryMiddlewareTest { ) ).joinBlocking() assertEquals(2, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } store.dispatch(TabListAction.RemoveTabAction("1")).joinBlocking() assertEquals(1, settings.openTabsCount) + verify(exactly = 2) { metrics.track(Event.HaveOpenTabs) } } @Test @@ -101,9 +115,11 @@ class TelemetryMiddlewareTest { ) ).joinBlocking() assertEquals(2, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } store.dispatch(TabListAction.RemoveAllTabsAction).joinBlocking() assertEquals(0, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveNoOpenTabs) } } @Test @@ -116,9 +132,11 @@ class TelemetryMiddlewareTest { ) ).joinBlocking() assertEquals(2, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } store.dispatch(TabListAction.RemoveAllNormalTabsAction).joinBlocking() assertEquals(0, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveNoOpenTabs) } } @Test @@ -131,6 +149,7 @@ class TelemetryMiddlewareTest { store.dispatch(TabListAction.RestoreAction(tabsToRestore)).joinBlocking() assertEquals(2, settings.openTabsCount) + verify(exactly = 1) { metrics.track(Event.HaveOpenTabs) } } @Test From 67ff4d460abbd7744603796c1c5fef79a2250bfc Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Wed, 27 Jan 2021 17:28:17 +0200 Subject: [PATCH 008/248] For #9188: wait for page load in Reader mode --- .../androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt | 5 +++++ app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt | 1 + 2 files changed, 6 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt index d7e0c50b8..c8ed91829 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -119,12 +119,14 @@ class ReaderViewTest { navigationToolbar { verifyReaderViewDetected(true) toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(true) }.closeBrowserMenuToBrowser { } navigationToolbar { toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(false) }.close { } @@ -150,6 +152,7 @@ class ReaderViewTest { navigationToolbar { verifyReaderViewDetected(true) toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { @@ -185,6 +188,7 @@ class ReaderViewTest { navigationToolbar { verifyReaderViewDetected(true) toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { @@ -226,6 +230,7 @@ class ReaderViewTest { navigationToolbar { verifyReaderViewDetected(true) toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 86fc7b286..a25b9421e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -1144,6 +1144,7 @@ class SmokeTest { navigationToolbar { verifyReaderViewDetected(true) toggleReaderView() + mDevice.waitForIdle() }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { From ac13f0dd468b37773c591485ceba88d997476dbe Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 27 Jan 2021 15:35:19 +0000 Subject: [PATCH 009/248] Update Android Components version to 73.0.20210127143126. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index a841c050a..580501ddc 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210126190058" + const val VERSION = "73.0.20210127143126" } From 124c2baf304704b807cbf5934ff2798b87a6845d Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Wed, 27 Jan 2021 12:46:16 -0500 Subject: [PATCH 010/248] Closes #17531: Use top sites count fact for top sites telemetry (#17664) --- .../mozilla/fenix/components/metrics/Event.kt | 3 + .../components/metrics/GleanMetricsService.kt | 6 ++ .../components/metrics/MetricController.kt | 25 ++++++++ .../metrics/MetricControllerTest.kt | 60 +++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index 3fa6b6589..a6e43ea03 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -205,6 +205,9 @@ sealed class Event { object ContextMenuSelectAllTapped : Event() object ContextMenuShareTapped : Event() + object HaveTopSites : Event() + object HaveNoTopSites : Event() + // Interaction events with extras data class TopSiteSwipeCarousel(val page: Int) : Event() { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 00fc6bc33..3b8da8e11 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -726,6 +726,12 @@ private val Event.wrapper: EventWrapper<*>? Event.HaveNoOpenTabs -> EventWrapper( { Metrics.hasOpenTabs.set(false) } ) + Event.HaveTopSites -> EventWrapper( + { Metrics.hasTopSites.set(true) } + ) + Event.HaveNoTopSites -> EventWrapper( + { Metrics.hasTopSites.set(false) } + ) // Don't record other events in Glean: is Event.AddBookmark -> null diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 3b31385c2..013fd2422 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -22,6 +22,7 @@ import mozilla.components.feature.findinpage.facts.FindInPageFacts import mozilla.components.feature.media.facts.MediaFacts import mozilla.components.feature.prompts.dialog.LoginDialogFacts import mozilla.components.feature.pwa.ProgressiveWebAppFacts +import mozilla.components.feature.top.sites.facts.TopSitesFacts import mozilla.components.support.base.Component import mozilla.components.support.base.facts.Action import mozilla.components.support.base.facts.Fact @@ -134,6 +135,13 @@ internal class ReleaseMetricController( } } + @VisibleForTesting + internal fun factToEvent( + fact: Fact + ): Event? { + return fact.toEvent() + } + private fun isInitialized(type: MetricServiceType): Boolean = initialized.contains(type) private fun isTelemetryEnabled(type: MetricServiceType): Boolean = when (type) { @@ -242,6 +250,23 @@ internal class ReleaseMetricController( Component.FEATURE_PWA to ProgressiveWebAppFacts.Items.INSTALL_SHORTCUT -> { Event.ProgressiveWebAppInstallAsShortcut } + Component.FEATURE_TOP_SITES to TopSitesFacts.Items.COUNT -> { + value?.let { + var count = 0 + try { + count = it.toInt() + } catch (e: NumberFormatException) { + // Do nothing + } + + return if (count > 0) { + Event.HaveTopSites + } else { + Event.HaveNoTopSites + } + } + null + } else -> null } diff --git a/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt index 97934c541..be97fd8a3 100644 --- a/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt @@ -10,7 +10,12 @@ import io.mockk.impl.annotations.MockK import io.mockk.mockk import io.mockk.verify import io.mockk.verifyAll +import mozilla.components.feature.top.sites.facts.TopSitesFacts +import mozilla.components.support.base.Component +import mozilla.components.support.base.facts.Action +import mozilla.components.support.base.facts.Fact import mozilla.components.support.base.log.logger.Logger +import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test @@ -167,4 +172,59 @@ class MetricControllerTest { controller.track(Event.TabMediaPause) verify { marketingService1.track(Event.TabMediaPause) } } + + @Test + fun `topsites fact should convert to the right events`() { + var enabled = true + val controller = ReleaseMetricController( + services = listOf(dataService1), + isDataTelemetryEnabled = { enabled }, + isMarketingDataTelemetryEnabled = { enabled } + ) + + var fact = Fact( + Component.FEATURE_TOP_SITES, + Action.INTERACTION, + TopSitesFacts.Items.COUNT, + "1" + ) + + assertEquals(controller.factToEvent(fact), Event.HaveTopSites) + + fact = Fact( + Component.FEATURE_TOP_SITES, + Action.INTERACTION, + TopSitesFacts.Items.COUNT, + "0" + ) + + assertEquals(controller.factToEvent(fact), Event.HaveNoTopSites) + + fact = Fact( + Component.FEATURE_TOP_SITES, + Action.INTERACTION, + TopSitesFacts.Items.COUNT, + "10" + ) + + assertEquals(controller.factToEvent(fact), Event.HaveTopSites) + + fact = Fact( + Component.FEATURE_TOP_SITES, + Action.INTERACTION, + TopSitesFacts.Items.COUNT, + "-4" + ) + + assertEquals(controller.factToEvent(fact), Event.HaveNoTopSites) + + fact = Fact( + Component.FEATURE_TOP_SITES, + Action.INTERACTION, + TopSitesFacts.Items.COUNT, + "test" + ) + + assertEquals(controller.factToEvent(fact), Event.HaveNoTopSites) + } } From 45c0ac85ec1da90b16962ac5e4750ae31171c48e Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Wed, 27 Jan 2021 12:26:04 -0500 Subject: [PATCH 011/248] Remove SessionManager from BrowserFragment/ToolbarGestureHandler --- .../mozilla/fenix/browser/BrowserFragment.kt | 2 +- .../fenix/browser/ToolbarGestureHandler.kt | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 042d33a3b..a2f3db7d9 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -69,7 +69,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { tabPreview = tabPreview, toolbarLayout = browserToolbarView.view, store = components.core.store, - sessionManager = components.core.sessionManager + selectTabUseCase = components.useCases.tabsUseCases.selectTab ) ) } diff --git a/app/src/main/java/org/mozilla/fenix/browser/ToolbarGestureHandler.kt b/app/src/main/java/org/mozilla/fenix/browser/ToolbarGestureHandler.kt index da19ec785..d6284bc4b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/ToolbarGestureHandler.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/ToolbarGestureHandler.kt @@ -17,16 +17,16 @@ import androidx.core.graphics.contains import androidx.core.graphics.toPoint import androidx.core.view.isVisible import androidx.interpolator.view.animation.LinearOutSlowInInterpolator -import mozilla.components.browser.session.Session -import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.state.selector.getNormalOrPrivateTabs import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.support.ktx.android.view.getRectWithViewLocation import org.mozilla.fenix.R import org.mozilla.fenix.ext.getRectWithScreenLocation import org.mozilla.fenix.ext.getWindowInsets import org.mozilla.fenix.ext.isKeyboardVisible -import org.mozilla.fenix.ext.sessionsOfType import org.mozilla.fenix.ext.settings import kotlin.math.abs import kotlin.math.max @@ -43,7 +43,7 @@ class ToolbarGestureHandler( private val tabPreview: TabPreview, private val toolbarLayout: View, private val store: BrowserStore, - private val sessionManager: SessionManager + private val selectTabUseCase: TabsUseCases.SelectTabUseCase ) : SwipeGestureListener { private enum class GestureDirection { @@ -51,7 +51,7 @@ class ToolbarGestureHandler( } private sealed class Destination { - data class Tab(val session: Session) : Destination() + data class Tab(val tab: TabSessionState) : Destination() object None : Destination() } @@ -140,7 +140,7 @@ class ToolbarGestureHandler( ) { val destination = getDestination() if (destination is Destination.Tab && isGestureComplete(velocityX)) { - animateToNextTab(destination.session) + animateToNextTab(destination.tab) } else { animateCanceledGesture(velocityX) } @@ -149,14 +149,14 @@ class ToolbarGestureHandler( private fun getDestination(): Destination { val isLtr = activity.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR val currentTab = store.state.selectedTab ?: return Destination.None - val currentIndex = sessionManager.sessionsOfType(currentTab.content.private).indexOfFirst { + val currentIndex = store.state.getNormalOrPrivateTabs(currentTab.content.private).indexOfFirst { it.id == currentTab.id } return if (currentIndex == -1) { Destination.None } else { - val sessions = sessionManager.sessionsOfType(currentTab.content.private) + val tabs = store.state.getNormalOrPrivateTabs(currentTab.content.private) val index = when (gestureDirection) { GestureDirection.RIGHT_TO_LEFT -> if (isLtr) { currentIndex + 1 @@ -170,8 +170,8 @@ class ToolbarGestureHandler( } } - if (index < sessions.count() && index >= 0) { - Destination.Tab(sessions.elementAt(index)) + if (index < tabs.count() && index >= 0) { + Destination.Tab(tabs.elementAt(index)) } else { Destination.None } @@ -180,7 +180,7 @@ class ToolbarGestureHandler( private fun preparePreview(destination: Destination) { val thumbnailId = when (destination) { - is Destination.Tab -> destination.session.id + is Destination.Tab -> destination.tab.id is Destination.None -> return } @@ -233,7 +233,7 @@ class ToolbarGestureHandler( } } - private fun animateToNextTab(session: Session) { + private fun animateToNextTab(tab: TabSessionState) { val browserFinalXCoordinate: Float = when (gestureDirection) { GestureDirection.RIGHT_TO_LEFT -> -windowWidth.toFloat() - previewOffset GestureDirection.LEFT_TO_RIGHT -> windowWidth.toFloat() + previewOffset @@ -243,7 +243,7 @@ class ToolbarGestureHandler( getAnimator(browserFinalXCoordinate, FINISHED_GESTURE_ANIMATION_DURATION).apply { doOnEnd { contentLayout.translationX = 0f - sessionManager.select(session) + selectTabUseCase(tab.id) // Fade out the tab preview to prevent flickering val shortAnimationDuration = From 4f770e9792f2b8073ca0f79347aa81aa956605df Mon Sep 17 00:00:00 2001 From: amedyne <68711330+amedyne@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:53:04 -0500 Subject: [PATCH 012/248] Update ---bug-report.md (#17660) Update Bug report template --- .github/ISSUE_TEMPLATE/---bug-report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/---bug-report.md b/.github/ISSUE_TEMPLATE/---bug-report.md index b9d0ec5da..e27d73793 100644 --- a/.github/ISSUE_TEMPLATE/---bug-report.md +++ b/.github/ISSUE_TEMPLATE/---bug-report.md @@ -18,6 +18,6 @@ assignees: '' ### Device information -* Android device: ? -* Fenix version: ? +* Device vendor / model and Android version: ? +* Firefox for Android version: ? (go to Settings -> About Firefox) From 8993a0acb28a03ee810fff42d6357ff2929417e5 Mon Sep 17 00:00:00 2001 From: Mihai Adrian Carare <48995920+mcarare@users.noreply.github.com> Date: Wed, 27 Jan 2021 23:54:48 +0200 Subject: [PATCH 013/248] For #17655: Do not pass threshold if showTopFrecentSites is false. (#17657) * For #17655: Do not pass threshold if showTopFrecentSites is false. * For #17655: Add unit tests for getTopSitesConfig. --- .../org/mozilla/fenix/home/HomeFragment.kt | 9 ++- .../mozilla/fenix/home/HomeFragmentTest.kt | 68 +++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 6c3b2160d..65ed19cfe 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -21,6 +21,7 @@ import android.view.accessibility.AccessibilityEvent import android.widget.Button import android.widget.LinearLayout import android.widget.PopupWindow +import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AlertDialog import androidx.appcompat.content.res.AppCompatResources import androidx.constraintlayout.widget.ConstraintLayout @@ -273,11 +274,12 @@ class HomeFragment : Fragment() { * Returns a [TopSitesConfig] which specifies how many top sites to display and whether or * not frequently visited sites should be displayed. */ - private fun getTopSitesConfig(): TopSitesConfig { + @VisibleForTesting + internal fun getTopSitesConfig(): TopSitesConfig { val settings = requireContext().settings() return TopSitesConfig( settings.topSitesMaxLimit, - FrecencyThresholdOption.SKIP_ONE_TIME_PAGES + if (settings.showTopFrecentSites) FrecencyThresholdOption.SKIP_ONE_TIME_PAGES else null ) } @@ -428,7 +430,8 @@ class HomeFragment : Fragment() { if (searchEngine != null) { val iconSize = requireContext().resources.getDimensionPixelSize(R.dimen.preference_icon_drawable_size) - val searchIcon = BitmapDrawable(requireContext().resources, searchEngine.icon) + val searchIcon = + BitmapDrawable(requireContext().resources, searchEngine.icon) searchIcon.setBounds(0, 0, iconSize, iconSize) search_engine_icon?.setImageDrawable(searchIcon) } else { diff --git a/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt new file mode 100644 index 000000000..8f24fa8e8 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt @@ -0,0 +1,68 @@ +/* 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 org.mozilla.fenix.home + +import android.content.Context +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.utils.Settings + +@ExperimentalCoroutinesApi +@RunWith(FenixRobolectricTestRunner::class) +class HomeFragmentTest { + + private lateinit var settings: Settings + private lateinit var context: Context + private lateinit var homeFragment: HomeFragment + + @Before + fun setup() { + context = mockk(relaxed = true) + settings = mockk(relaxed = true) + + homeFragment = spyk(HomeFragment()) + + every { homeFragment.context } returns context + every { context.settings() } returns settings + } + + @Test + fun `GIVEN showTopFrecentSites is false WHEN getTopSitesConfig is called THEN it returns TopSitesConfig with null frecencyConfig`() { + every { settings.showTopFrecentSites } returns false + every { settings.topSitesMaxLimit } returns 10 + + val topSitesConfig = homeFragment.getTopSitesConfig() + + Assert.assertNull(topSitesConfig.frecencyConfig) + } + + @Test + fun `GIVEN showTopFrecentSites is true WHEN getTopSitesConfig is called THEN it returns TopSitesConfig with non-null frecencyConfig`() { + every { context.settings().showTopFrecentSites } returns true + every { settings.topSitesMaxLimit } returns 10 + + val topSitesConfig = homeFragment.getTopSitesConfig() + + Assert.assertNotNull(topSitesConfig.frecencyConfig) + } + + @Test + fun `GIVEN a topSitesMaxLimit WHEN getTopSitesConfig is called THEN it returns TopSitesConfig with totalSites = topSitesMaxLimit`() { + val topSitesMaxLimit = 10 + every { settings.topSitesMaxLimit } returns topSitesMaxLimit + + val topSitesConfig = homeFragment.getTopSitesConfig() + + Assert.assertEquals(topSitesMaxLimit, topSitesConfig.totalSites) + } +} From f3d332dd8b62207296e3d4dfc4515959aac08d63 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Thu, 28 Jan 2021 00:04:39 +0000 Subject: [PATCH 014/248] Import l10n. --- app/src/main/res/values-sl/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index a03e3a9c5..7e06ccef1 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -735,6 +735,8 @@ Ste prepričani, da želite počistiti vaše prenose? Prenosi odstranjeni + + %1$s odstranjen Ni prenesenih datotek Dovoljenja strani + + Prenosi Izbriši podatke brskanja @@ -1220,8 +1224,7 @@ - %s smo zasnovali tako, da vam omogočimo nadzor nad tem, kaj delite - na spletu in kaj delite z nami. + %s smo zasnovali tako, da vam omogočimo nadzor nad tem, kaj delite na spletu in kaj delite z nami. Preberite naše obvestilo o zasebnosti From d7b8af78c95260db90c8d49497045d24d8b74040 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Thu, 28 Jan 2021 16:41:45 +0200 Subject: [PATCH 015/248] For #9188: wait for page content to appear in Reader mode tests --- .../org/mozilla/fenix/ui/ReaderViewTest.kt | 18 ++++++++++++++++++ .../java/org/mozilla/fenix/ui/SmokeTest.kt | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt index c8ed91829..d405215ab 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -17,6 +17,7 @@ import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource import org.mozilla.fenix.helpers.HomeActivityIntentTestRule import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.mDevice /** @@ -32,6 +33,7 @@ import org.mozilla.fenix.ui.robots.mDevice class ReaderViewTest { private lateinit var mockWebServer: MockWebServer private var readerViewNotification: ViewVisibilityIdlingResource? = null + private val estimatedReadingTime = "1 - 2 minutes" @get:Rule val activityIntentTestRule = HomeActivityIntentTestRule() @@ -120,6 +122,10 @@ class ReaderViewTest { verifyReaderViewDetected(true) toggleReaderView() mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.closeBrowserMenuToBrowser { } @@ -153,6 +159,10 @@ class ReaderViewTest { verifyReaderViewDetected(true) toggleReaderView() mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { @@ -189,6 +199,10 @@ class ReaderViewTest { verifyReaderViewDetected(true) toggleReaderView() mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { @@ -231,6 +245,10 @@ class ReaderViewTest { verifyReaderViewDetected(true) toggleReaderView() mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index a25b9421e..697255bfc 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -1128,6 +1128,7 @@ class SmokeTest { fun verifyReaderViewAppearanceUI() { val readerViewPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer) + val estimatedReadingTime = "1 - 2 minutes" navigationToolbar { }.enterURLAndEnterToBrowser(readerViewPage.url) { @@ -1145,6 +1146,10 @@ class SmokeTest { verifyReaderViewDetected(true) toggleReaderView() mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.openReaderViewAppearance { From c50dbb5bb91228ab58ca433b1b2c2ba102e8f756 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 28 Jan 2021 15:34:35 +0000 Subject: [PATCH 016/248] Update Android Components version to 73.0.20210128143151. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 580501ddc..de44861f4 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210127143126" + const val VERSION = "73.0.20210128143151" } From 43b0b27819133fbbfd761a9c2cdd299d2894eb8e Mon Sep 17 00:00:00 2001 From: Elise Richards Date: Thu, 28 Jan 2021 14:30:59 -0600 Subject: [PATCH 017/248] Update metrics when an addon is installed or enabled (#17669) --- .../java/org/mozilla/fenix/addons/AddonsManagementFragment.kt | 2 ++ .../org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index 5f6a6abfa..06a8555cc 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -29,6 +29,7 @@ import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment import mozilla.components.feature.addons.ui.AddonsManagerAdapter import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.translateName +import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.metrics.Event @@ -282,6 +283,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) adapter?.updateAddon(it) addonProgressOverlay?.visibility = View.GONE showInstallationDialog(it) + Addons.hasInstalledAddons.set(true) } }, onError = { _, e -> diff --git a/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt index c3fbcce10..c154aa4f9 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/InstalledAddonDetailsFragment.kt @@ -21,6 +21,7 @@ import kotlinx.coroutines.launch import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.ui.translateName +import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ext.components @@ -127,6 +128,7 @@ class InstalledAddonDetailsFragment : Fragment() { ) ) } + Addons.hasEnabledAddons.set(true) } }, onError = { From 41e6c7247e6d779804fd9e8e245092a50819e312 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Fri, 29 Jan 2021 00:04:27 +0000 Subject: [PATCH 018/248] Import l10n. --- app/src/main/res/values-be/strings.xml | 5 +++-- app/src/main/res/values-da/strings.xml | 5 +++-- app/src/main/res/values-gn/strings.xml | 5 +++-- app/src/main/res/values-in/strings.xml | 4 +++- app/src/main/res/values-kab/strings.xml | 6 +++--- app/src/main/res/values-oc/strings.xml | 10 ++++++++++ l10n.toml | 1 + 7 files changed, 26 insertions(+), 10 deletions(-) diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 91d67a267..38df7ab9c 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -1101,6 +1101,8 @@ Вызваліць месца Дазволы для сайтаў + + Сцягванні Выдаліць звесткі аглядання @@ -1223,8 +1225,7 @@ Ваша прыватнасць - Мы распрацавалі %s, каб даць вам кантроль над тым, чым дзяліцца - ў Інтэрнэце і тым, чым вы падзеліцеся з намі. + Мы распрацавалі %s, каб даць вам кантроль над тым, чым дзяліцца ў Інтэрнэце, і тым, чым вы падзеліцеся з намі. Паведамленне аб прыватнасці diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 0e01ba854..838fe1f53 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -1079,6 +1079,8 @@ Frigør lagerplads Websteds-indstillinger + + Filhentninger Slet browserdata @@ -1201,8 +1203,7 @@ Bedre beskyttelse af dit privatliv - Vi har designet %s til at give dig kontrol over, hvad du deler på - nettet - og hvad du deler med os. + Vi har designet %s til at give dig kontrol over, hvad du deler på nettet - og hvad du deler med os. Læs vores privatlivspolitik diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index d0da23ce6..9f8eb6a81 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -1107,6 +1107,8 @@ Emopotĩ pa’ũ ñembyatyha Tenda ñemoneĩ + + Ñemboguejy Emboguete kundahára mba’ekuaarã @@ -1230,8 +1232,7 @@ - Romoha’ãngáma %s eñangareko hag̃ua umi emoherakuãva rehe - ñandutípe ha emoherakuã orendive. + Rojapo %s eñangareko hag̃ua emoherakuãva ñandutípe rehe ha emoherakuãva orendive avei. Emoñe’ẽ ore marandu’i ñemigua diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 6e9623b70..95a0295e8 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -1105,6 +1105,8 @@ Membebaskan ruang penyimpanan Izin situs + + Unduhan Hapus data penjelajahan @@ -1229,7 +1231,7 @@ Privasi Anda - Kami merancang %s untuk memberi Anda kendali atas apa yang Anda bagikan secara daring dan apa yang Anda bagikan kepada kami. + Kami merancang %s agar Anda dapat mengendalikan apa saja yang Anda bagikan secara daring dan apa yang Anda bagikan kepada kami. Pelajari pemberitahuan privasi kami diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 2ae9c95b1..a81126fb4 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -1101,6 +1101,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Tisirag n usmel + + Isidar Kkes isefka n tunigin @@ -1223,9 +1225,7 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara - Nfeṣṣel %s akken ad nerr gar ifassen-ik ayen i tbeṭṭuḍ - srid daɣen ayen i beṭṭuḍ yid-neɣ. - + Nfeṣṣel %si w akken ad nerr gar ifassen-ik·im ayen i tbeṭṭuḍ srid aked wayen tbeṭṭuḍ yid-neɣ. Ɣer tasertit-nneɣ n tbaḍnit diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index f7a507e64..a6e822cc5 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -363,6 +363,12 @@ Colleccion de moduls complementaris modificada. Tampadura de l’aplicacion per aplicar las modificacions… + + + Lo modul complementari es pas pres en carga + + Lo modul complementari es ja installat + Sincronizar ara @@ -727,6 +733,8 @@ Telecargament suprimits %1$s suprimit + + Cap de fichièr pas telecargat %1$d seleccionats @@ -1091,6 +1099,8 @@ Libèra d’espaci d’emmagazinatge Permissions dels sites + + Telecargaments Suprimir las donadas de navegacion diff --git a/l10n.toml b/l10n.toml index 077ea1753..ef8242192 100644 --- a/l10n.toml +++ b/l10n.toml @@ -53,6 +53,7 @@ locales = [ "ka", "kab", "kk", + "kmr", "kn", "ko", "lij", From e754c1acc03b560374e691b8942d3aee9f910fd7 Mon Sep 17 00:00:00 2001 From: ekager Date: Thu, 28 Jan 2021 15:08:24 -0700 Subject: [PATCH 019/248] No issue - Update androidx dependencies newer stable versions --- buildSrc/src/main/java/Dependencies.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 27d9d713f..da3fe9a21 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -19,7 +19,7 @@ object Versions { const val jna = "5.6.0" const val androidx_appcompat = "1.2.0" - const val androidx_biometric = "1.1.0-rc01" + const val androidx_biometric = "1.1.0" const val androidx_coordinator_layout = "1.1.0" const val androidx_constraint_layout = "2.0.4" const val androidx_preference = "1.1.1" @@ -27,12 +27,12 @@ object Versions { const val androidx_annotation = "1.1.0" const val androidx_lifecycle = "2.2.0" const val androidx_fragment = "1.2.5" - const val androidx_navigation = "2.3.1" - const val androidx_recyclerview = "1.2.0-alpha06" + const val androidx_navigation = "2.3.3" + const val androidx_recyclerview = "1.2.0-beta01" const val androidx_core = "1.3.2" - const val androidx_paging = "2.1.0" - const val androidx_transition = "1.3.0" - const val androidx_work = "2.4.0" + const val androidx_paging = "2.1.2" + const val androidx_transition = "1.4.0" + const val androidx_work = "2.5.0" const val google_material = "1.2.1" const val mozilla_android_components = AndroidComponents.VERSION From 81e08b2e7ff90774442342891dbbb59c4e2b8852 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Thu, 28 Jan 2021 15:20:07 +0400 Subject: [PATCH 020/248] Close #15979: Add MOZILLA_OFFICIAL flag for release builds When we build release APKs on Mozilla infrastructure, we want a way to know this in code for features that would only work on them. --- app/build.gradle | 10 ++++++++++ taskcluster/fenix_taskgraph/transforms/build.py | 12 ++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cd7c44f2d..e0ff4c67d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -360,6 +360,16 @@ android.applicationVariants.all { variant -> buildConfigField 'String', 'NIMBUS_ENDPOINT', 'null' println("--") } + +// ------------------------------------------------------------------------------------------------- +// BuildConfig: Set flag for official builds; similar to MOZILLA_OFFICIAL in mozilla-central. +// ------------------------------------------------------------------------------------------------- + + if (project.hasProperty("official") || gradle.hasProperty("localProperties.official")) { + buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'true' + } else { + buildConfigField 'Boolean', 'MOZILLA_OFFICIAL', 'false' + } } androidExtensions { diff --git a/taskcluster/fenix_taskgraph/transforms/build.py b/taskcluster/fenix_taskgraph/transforms/build.py index a2ebdcf4f..032a746a6 100644 --- a/taskcluster/fenix_taskgraph/transforms/build.py +++ b/taskcluster/fenix_taskgraph/transforms/build.py @@ -104,7 +104,10 @@ def add_nightly_version(config, tasks): for task in tasks: if task.pop("include-nightly-version", False): - task["run"]["gradlew"].append('-PversionName={}'.format(formated_date_time)) + task["run"]["gradlew"].extend([ + '-PversionName={}'.format(formated_date_time), + '-Pofficial' + ]) yield task @@ -112,9 +115,10 @@ def add_nightly_version(config, tasks): def add_release_version(config, tasks): for task in tasks: if task.pop("include-release-version", False): - task["run"]["gradlew"].append( - '-PversionName={}'.format(config.params["version"]) - ) + task["run"]["gradlew"].extend([ + '-PversionName={}'.format(config.params["version"]), + '-Pofficial' + ]) yield task From e188185b15e48622ed1c804777df6f48e78d365d Mon Sep 17 00:00:00 2001 From: Codrut Topliceanu <60002907+codrut-topliceanu@users.noreply.github.com> Date: Fri, 29 Jan 2021 10:14:32 +0200 Subject: [PATCH 021/248] For #16828 - Adds telemetry for open in app banner (#17049) * For #16828 - Adds telemetry for open in app banner Specifically: Banner displayed, Dismiss action, Go to Settings action. --- app/metrics.yaml | 41 +++++++++++++++++++ .../browser/OpenInAppOnboardingObserver.kt | 12 +++++- .../mozilla/fenix/components/metrics/Event.kt | 4 ++ .../components/metrics/GleanMetricsService.kt | 11 +++++ .../OpenInAppOnboardingObserverTest.kt | 4 ++ docs/metrics.md | 3 ++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 61bcfead0..038fa418e 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -4291,6 +4291,47 @@ tabs: - fenix-core@mozilla.com expires: "2021-08-01" +banner_open_in_app: + displayed: + type: event + description: | + Open in App banner was shown. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/16828 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17049 + data_sensitivity: + - interaction + notification_emails: + - fenix-core@mozilla.com + expires: "2021-08-01" + dismissed: + type: event + description: | + User tapped 'dismiss' on Open in App banner. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/16828 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17049 + data_sensitivity: + - interaction + notification_emails: + - fenix-core@mozilla.com + expires: "2021-08-01" + go_to_settings: + type: event + description: | + User tapped 'go to settings' on Open in App banner. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/16828 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17049 + data_sensitivity: + - interaction + notification_emails: + - fenix-core@mozilla.com + expires: "2021-08-01" + contextual_menu: copy_tapped: type: event diff --git a/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt b/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt index 1d129a027..65cb98795 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt @@ -22,6 +22,9 @@ import mozilla.components.support.base.feature.LifecycleAwareFeature import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.metrics.Event.BannerOpenInAppGoToSettings +import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav import org.mozilla.fenix.utils.Settings @@ -85,6 +88,7 @@ class OpenInAppOnboardingObserver( infoBanner?.showBanner() sessionDomainForDisplayedBanner = url.tryGetHostFromUrl() settings.shouldShowOpenInAppBanner = false + context.components.analytics.metrics.track(Event.BannerOpenInAppDisplayed) } } @@ -95,12 +99,18 @@ class OpenInAppOnboardingObserver( message = context.getString(R.string.open_in_app_cfr_info_message), dismissText = context.getString(R.string.open_in_app_cfr_negative_button_text), actionText = context.getString(R.string.open_in_app_cfr_positive_button_text), - container = container + container = container, + dismissAction = ::dismissAction ) { val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment( preferenceToScrollTo = context.getString(R.string.pref_key_open_links_in_external_app) ) + context.components.analytics.metrics.track(BannerOpenInAppGoToSettings) navController.nav(R.id.browserFragment, directions) } } + + private fun dismissAction() { + context.components.analytics.metrics.track(Event.BannerOpenInAppDismissed) + } } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index a6e43ea03..983d228df 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -200,6 +200,10 @@ sealed class Event { object HaveOpenTabs : Event() object HaveNoOpenTabs : Event() + object BannerOpenInAppDisplayed : Event() + object BannerOpenInAppDismissed : Event() + object BannerOpenInAppGoToSettings : Event() + object ContextMenuCopyTapped : Event() object ContextMenuSearchTapped : Event() object ContextMenuSelectAllTapped : Event() diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 3b8da8e11..d1e653f09 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -17,6 +17,7 @@ import org.mozilla.fenix.GleanMetrics.AboutPage import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.GleanMetrics.AppTheme import org.mozilla.fenix.GleanMetrics.Autoplay +import org.mozilla.fenix.GleanMetrics.BannerOpenInApp import org.mozilla.fenix.GleanMetrics.BookmarksManagement import org.mozilla.fenix.GleanMetrics.BrowserSearch import org.mozilla.fenix.GleanMetrics.Collections @@ -733,6 +734,16 @@ private val Event.wrapper: EventWrapper<*>? { Metrics.hasTopSites.set(false) } ) + is Event.BannerOpenInAppDisplayed -> EventWrapper( + { BannerOpenInApp.displayed.record(it) } + ) + is Event.BannerOpenInAppDismissed -> EventWrapper( + { BannerOpenInApp.dismissed.record(it) } + ) + is Event.BannerOpenInAppGoToSettings -> EventWrapper( + { BannerOpenInApp.goToSettings.record(it) } + ) + // Don't record other events in Glean: is Event.AddBookmark -> null is Event.OpenedBookmark -> null diff --git a/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt b/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt index ce0cf7f01..ec8405f3f 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt @@ -11,7 +11,9 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleRegistry import androidx.navigation.NavController import io.mockk.every +import io.mockk.just import io.mockk.mockk +import io.mockk.runs import io.mockk.spyk import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -28,6 +30,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings @@ -138,6 +141,7 @@ class OpenInAppOnboardingObserverTest { every { settings.openLinksInExternalApp } returns false every { settings.shouldShowOpenInAppCfr } returns true every { appLinksUseCases.appLinkRedirect.invoke(any()).hasExternalApp() } returns true + every { context.components.analytics.metrics.track(any()) } just runs store.dispatch(ContentAction.UpdateLoadingStateAction("1", true)).joinBlocking() openInAppOnboardingObserver.start() diff --git a/docs/metrics.md b/docs/metrics.md index c301f0ec6..1ed8a6125 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -55,6 +55,9 @@ The following metrics are added to the ping: | app_theme.dark_theme_selected |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user selected Dark Theme |[1](https://github.com/mozilla-mobile/fenix/pull/7968), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)|
  • source: The source from where dark theme was selected. The source can be 'SETTINGS' or 'ONBOARDING'
|2021-04-01 |2 | | autoplay.setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their autoplay setting to either block_cellular, block_audio, or block_all. |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)|
  • autoplay_setting: The new setting for autoplay: block_cellular, block_audio, or block_all.
|2021-02-01 |2 | | autoplay.visited_setting |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user visited the autoplay settings screen |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)||2021-02-01 |2 | +| banner_open_in_app.dismissed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User tapped 'dismiss' on Open in App banner. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | +| banner_open_in_app.displayed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Open in App banner was shown. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | +| banner_open_in_app.go_to_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User tapped 'go to settings' on Open in App banner. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | | bookmarks_management.copied |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user copied a bookmark. |[1](https://github.com/mozilla-mobile/fenix/pull/1708), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | | bookmarks_management.edited |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user edited the title and/or URL of an existing bookmark. |[1](https://github.com/mozilla-mobile/fenix/pull/1708), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | | bookmarks_management.folder_add |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user added a new bookmark folder. |[1](https://github.com/mozilla-mobile/fenix/pull/1708), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | From be0382fca76eef12ae3d19a4e0dfe1689219d897 Mon Sep 17 00:00:00 2001 From: rxu Date: Fri, 30 Oct 2020 15:04:37 +0800 Subject: [PATCH 022/248] Pop out privacy notice in first launch in MozillaOnline builds Add privacy notice related strings Pop out privacy notice with onboarding Using embeded geckoview to display details about privacy Present or hide privacy pop window according to isMozillaOnline Add activity_privacy_content_display.xml into layoutNotToTest due to EngineView --- app/src/main/AndroidManifest.xml | 3 + .../org/mozilla/fenix/home/HomeFragment.kt | 8 ++ .../PrivacyContentDisplayActivity.kt | 84 +++++++++++++++++++ .../mozonline/PrivacyContentDisplayHelper.kt | 53 ++++++++++++ .../home/mozonline/PrivacyContentSpan.kt | 44 ++++++++++ .../java/org/mozilla/fenix/utils/Settings.kt | 5 ++ .../activity_privacy_content_display.xml | 43 ++++++++++ .../res/values-zh-rCN/mozonline_strings.xml | 22 +++++ app/src/main/res/values/mozonline_strings.xml | 22 +++++ app/src/main/res/values/preference_keys.xml | 3 + .../fenix/perf/PerformanceInflaterTest.kt | 3 +- 11 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentDisplayActivity.kt create mode 100644 app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentDisplayHelper.kt create mode 100644 app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentSpan.kt create mode 100644 app/src/main/res/layout/activity_privacy_content_display.xml create mode 100644 app/src/main/res/values-zh-rCN/mozonline_strings.xml create mode 100644 app/src/main/res/values/mozonline_strings.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index efb94c3c0..0f4ac90f1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -119,6 +119,9 @@ + + (R.id.privacyContentEngineView) as EngineView + closeButton = findViewById(R.id.privacyContentCloseButton) as ImageButton + engineSession = components.core.engine.createSession() + } + + override fun onCreateView( + parent: View?, + name: String, + context: Context, + attrs: AttributeSet + ): View? = when (name) { + EngineView::class.java.name -> components.core.engine.createView(context, attrs).apply { + selectionActionDelegate = DefaultSelectionActionDelegate( + BrowserStoreSearchAdapter( + components.core.store + ), + resources = context.resources, + shareTextClicked = { share(it) }, + emailTextClicked = { email(it) }, + callTextClicked = { call(it) } + ) + }.asView() + else -> super.onCreateView(parent, name, context, attrs) + } + + override fun onStart() { + super.onStart() + engineSession.register(this) + engineSession.let { engineSession -> + engineView.render(engineSession) + url?.let { engineSession.loadUrl(it) } + } + closeButton.setOnClickListener { finish() } + } + + override fun onStop() { + super.onStop() + engineSession.unregister(this) + } + + override fun onDestroy() { + super.onDestroy() + engineSession.close() + } +} diff --git a/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentDisplayHelper.kt b/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentDisplayHelper.kt new file mode 100644 index 000000000..d34371a00 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentDisplayHelper.kt @@ -0,0 +1,53 @@ +/* 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 org.mozilla.fenix.home.mozonline + +import android.app.Activity +import android.content.Context +import android.content.DialogInterface +import android.text.SpannableString +import android.text.Spanned +import android.text.method.LinkMovementMethod +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.settings +import kotlin.system.exitProcess + +fun showPrivacyPopWindow(context: Context, activity: Activity) { + val content = context.getString(R.string.privacy_notice_content) + + // Use hyperlinks to display details about privacy + val messageClickable1 = context.getString(R.string.privacy_notice_clickable1) + val messageClickable2 = context.getString(R.string.privacy_notice_clickable2) + val messageClickable3 = context.getString(R.string.privacy_notice_clickable3) + val messageSpannable = SpannableString(content) + + val clickableSpan1 = PrivacyContentSpan(Position.POS1, context) + val clickableSpan2 = PrivacyContentSpan(Position.POS2, context) + val clickableSpan3 = PrivacyContentSpan(Position.POS3, context) + + messageSpannable.setSpan(clickableSpan1, content.indexOf(messageClickable1), + content.indexOf(messageClickable1) + messageClickable1.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE) + messageSpannable.setSpan(clickableSpan2, content.indexOf(messageClickable2), + content.indexOf(messageClickable2) + messageClickable2.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE) + messageSpannable.setSpan(clickableSpan3, content.indexOf(messageClickable3), + content.indexOf(messageClickable3) + messageClickable3.length, Spanned.SPAN_INCLUSIVE_INCLUSIVE) + + // Users can only use fenix after they agree with the privacy notice + val builder = AlertDialog.Builder(activity) + .setPositiveButton(context.getString(R.string.privacy_notice_positive_button), + DialogInterface.OnClickListener { _, _ -> + context.settings().shouldShowPrivacyPopWindow = false + }) + .setNeutralButton(context.getString(R.string.privacy_notice_neutral_button), + DialogInterface.OnClickListener { _, _ -> exitProcess(0) }) + .setTitle(context.getString(R.string.privacy_notice_title)) + .setMessage(messageSpannable) + .setCancelable(false) + val alertDialog: AlertDialog = builder.create() + alertDialog.show() + alertDialog.findViewById(android.R.id.message)?.movementMethod = LinkMovementMethod.getInstance() +} diff --git a/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentSpan.kt b/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentSpan.kt new file mode 100644 index 000000000..c718a6654 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/home/mozonline/PrivacyContentSpan.kt @@ -0,0 +1,44 @@ +/* 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 org.mozilla.fenix.home.mozonline + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.text.style.ClickableSpan +import android.view.View + +object Position { + const val POS1 = 1 + const val POS2 = 2 + const val POS3 = 3 +} + +object ADDR { + const val URL1 = "https://www.mozilla.org/en-US/MPL/" + const val URL2 = "https://www.mozilla.org/en-US/foundation/trademarks/policy/" + const val URL3 = "https://www.mozilla.org/zh-CN/privacy/firefox/" +} + +class PrivacyContentSpan(var pos: Int, var context: Context) : + ClickableSpan() { + override fun onClick(widget: View) { + /** + * To avoid users directly using fenix by clicking these urls before + * they click positive button of privacy notice alert dialog, start + * PrivacyContentDisplayActivity to display them. + */ + val engineViewIntent = Intent(context, PrivacyContentDisplayActivity::class.java) + engineViewIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + val addr = Bundle() + when (pos) { + Position.POS1 -> addr.putString("url", ADDR.URL1) + Position.POS2 -> addr.putString("url", ADDR.URL2) + Position.POS3 -> addr.putString("url", ADDR.URL3) + } + engineViewIntent.putExtras(addr) + context.startActivity(engineViewIntent) + } +} diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index e12cc12f7..0ddb3c35e 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -252,6 +252,11 @@ class Settings(private val appContext: Context) : PreferencesHolder { val shouldShowSecurityPinWarning: Boolean get() = loginsSecureWarningCount.underMaxCount() + var shouldShowPrivacyPopWindow by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_privacy_pop_window), + default = true + ) + var shouldUseLightTheme by booleanPreference( appContext.getPreferenceKey(R.string.pref_key_light_theme), default = false diff --git a/app/src/main/res/layout/activity_privacy_content_display.xml b/app/src/main/res/layout/activity_privacy_content_display.xml new file mode 100644 index 000000000..c6ff55e47 --- /dev/null +++ b/app/src/main/res/layout/activity_privacy_content_display.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-zh-rCN/mozonline_strings.xml b/app/src/main/res/values-zh-rCN/mozonline_strings.xml new file mode 100644 index 000000000..d09a3e0b9 --- /dev/null +++ b/app/src/main/res/values-zh-rCN/mozonline_strings.xml @@ -0,0 +1,22 @@ + + + + + 关于您的权利 + + Mozilla Firefox 是一款自由开源软件,由来自世界各地成千上万的社区志愿者共同完成。以下几点您应该了解: + \n\n•Firefox 提供给您时依照的条款为 Mozilla 公共许可证(MPL)。这表示您可以使用、复制和向他人分发 Firefox。我们也非常欢迎您按自己的需要修改 Firefox 的源代码。Mozilla 公共许可证还授予您分发您自己修改过的软件版本的权利。 + \n•您没有获得 Mozilla 基金会或其他任何一方的商标权利或许可,这包括但不限于 Firefox 的名称或标志。有关商标的其他信息在:这里。 + \n•Firefox 的一些功能(例如崩溃报告器)使您可以向 Mozilla 提供反馈。提交反馈的同时,您授权 Mozilla 使用反馈信息改进产品、在其网站上发布反馈信息,以及分发反馈内容。 + \n•关于我们如何使用您通过 Firefox 提交给 Mozilla 的个人信息和反馈,请参见 Firefox 隐私权政策。 + + Mozilla 公共许可证(MPL) + + 这里 + + Firefox 隐私权政策 + + 同意并继续 + + 退出应用 + \ No newline at end of file diff --git a/app/src/main/res/values/mozonline_strings.xml b/app/src/main/res/values/mozonline_strings.xml new file mode 100644 index 000000000..89c9fbc4c --- /dev/null +++ b/app/src/main/res/values/mozonline_strings.xml @@ -0,0 +1,22 @@ + + + + + About your rights + + Mozilla Firefox is free and open source software, built by a community of thousands from all over the world. There are a few things you should know: + \n\n•Firefox is made available to you under the terms of the Mozilla Public License. This means you may use, copy and distribute Firefox to others. You are also welcome to modify the source code of Firefox as you want to meet your needs. The Mozilla Public License also gives you the right to distribute your modified versions. + \n•You are not granted any trademark rights or licenses to the trademarks of the Mozilla Foundation or any party, including without limitation the Firefox name or logo. Additional information on trademarks may be found here. + \n•Some features in Firefox, such as the Crash Reporter, give you the option to provide feedback to Mozilla. By choosing to submit feedback, you give Mozilla permission to use the feedback to improve its products, to publish the feedback on its websites, and to distribute the feedback. + \n•How we use your personal information and feedback submitted to Mozilla through Firefox is described in the Firefox Privacy Policy. + + Mozilla Public License + + found here + + Firefox Privacy Policy + + Agree and Continue + + Exit the App + \ No newline at end of file diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index aea6b7180..e0ad6b502 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -126,6 +126,9 @@ pref_key_toolbar_top pref_key_toolbar_bottom + + pref_key_privacy_pop_window + pref_key_light_theme pref_key_dark_theme diff --git a/app/src/test/java/org/mozilla/fenix/perf/PerformanceInflaterTest.kt b/app/src/test/java/org/mozilla/fenix/perf/PerformanceInflaterTest.kt index 59698c783..dc09d1fba 100644 --- a/app/src/test/java/org/mozilla/fenix/perf/PerformanceInflaterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/perf/PerformanceInflaterTest.kt @@ -26,7 +26,8 @@ class PerformanceInflaterTest { private val layoutsNotToTest = setOf( "fragment_browser", - "fragment_add_on_internal_settings" + "fragment_add_on_internal_settings", + "activity_privacy_content_display" ) @Before From a97ea9ac530b955841f0c6e30ec38e21143092b5 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Fri, 29 Jan 2021 18:06:01 +0400 Subject: [PATCH 023/248] Update Android Components version to 73.0.20210129102924 --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index de44861f4..5f110585a 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210128143151" + const val VERSION = "73.0.20210129102924" } From 66b94ced145b447140a4fa8bc573dd58d306a5e7 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Fri, 29 Jan 2021 18:17:54 +0400 Subject: [PATCH 024/248] Close #1340: Add support for WebAuthnFeature --- app/build.gradle | 1 + .../java/org/mozilla/fenix/FeatureFlags.kt | 2 +- .../fenix/browser/BaseBrowserFragment.kt | 5 +- .../mozilla/fenix/browser/WebAuthnFeature.kt | 62 ------------------- buildSrc/src/main/java/Dependencies.kt | 1 + 5 files changed, 7 insertions(+), 64 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/browser/WebAuthnFeature.kt diff --git a/app/build.gradle b/app/build.gradle index e0ff4c67d..9cded9b84 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -479,6 +479,7 @@ dependencies { implementation Deps.mozilla_feature_top_sites implementation Deps.mozilla_feature_share implementation Deps.mozilla_feature_accounts_push + implementation Deps.mozilla_feature_webauthn implementation Deps.mozilla_feature_webcompat implementation Deps.mozilla_feature_webnotifications implementation Deps.mozilla_feature_webcompat_reporter diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 02445794c..170520d85 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -48,7 +48,7 @@ object FeatureFlags { val newMediaSessionApi = true /** - * Enables experimental WebAuthn support. This implementation should never reach release! + * Enables WebAuthn support. */ val webAuthFeature = Config.channel.isNightlyOrDebug } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 60dfe78f3..7d5a95ea6 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -81,6 +81,7 @@ import mozilla.components.support.ktx.android.view.exitImmersiveModeIfNeeded import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged +import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.IntentReceiverActivity @@ -125,6 +126,7 @@ import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration import java.lang.ref.WeakReference import mozilla.components.feature.media.fullscreen.MediaFullscreenOrientationFeature +import mozilla.components.feature.webauthn.WebAuthnFeature import org.mozilla.fenix.FeatureFlags.newMediaSessionApi /** @@ -643,7 +645,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, view = view ) - if (FeatureFlags.webAuthFeature) { + // This component feature only works on Fenix when built on Mozilla infrastructure. + if (FeatureFlags.webAuthFeature && BuildConfig.MOZILLA_OFFICIAL) { webAuthnFeature.set( feature = WebAuthnFeature( engine = requireComponents.core.engine, diff --git a/app/src/main/java/org/mozilla/fenix/browser/WebAuthnFeature.kt b/app/src/main/java/org/mozilla/fenix/browser/WebAuthnFeature.kt deleted file mode 100644 index 24576f932..000000000 --- a/app/src/main/java/org/mozilla/fenix/browser/WebAuthnFeature.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 org.mozilla.fenix.browser - -import android.app.Activity -import android.content.Intent -import android.content.IntentSender -import mozilla.components.concept.engine.Engine -import mozilla.components.concept.engine.activity.ActivityDelegate -import mozilla.components.support.base.feature.ActivityResultHandler -import mozilla.components.support.base.feature.LifecycleAwareFeature -import mozilla.components.support.base.log.logger.Logger -import org.mozilla.fenix.FeatureFlags - -/** - * This implementation of the WebAuthnFeature is only for testing in a nightly signed build. - * - * ⚠️ This should always be behind the [FeatureFlags.webAuthFeature] nightly flag. - */ -class WebAuthnFeature( - private val engine: Engine, - private val activity: Activity -) : LifecycleAwareFeature, ActivityResultHandler { - val logger = Logger("WebAuthnFeature") - var requestCode = ACTIVITY_REQUEST_CODE - var resultCallback: ((Intent?) -> Unit)? = null - private val delegate = object : ActivityDelegate { - override fun startIntentSenderForResult(intent: IntentSender, onResult: (Intent?) -> Unit) { - val code = requestCode++ - logger.info("Received activity delegate request with code: $code intent: $intent") - activity.startIntentSenderForResult(intent, code, null, 0, 0, 0) - resultCallback = onResult - } - } - - override fun start() { - logger.info("Feature started.") - engine.registerActivityDelegate(delegate) - } - - override fun stop() { - logger.info("Feature stopped.") - engine.unregisterActivityDelegate() - } - - override fun onActivityResult(requestCode: Int, data: Intent?, resultCode: Int): Boolean { - logger.info("Received activity result with code: $requestCode\ndata: $data") - if (this.requestCode == requestCode) { - logger.info("Invoking callback!") - resultCallback?.invoke(data) - return true - } - - return false - } - - companion object { - const val ACTIVITY_REQUEST_CODE = 10 - } -} diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index da3fe9a21..b132351d4 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -124,6 +124,7 @@ object Deps { const val mozilla_feature_accounts_push = "org.mozilla.components:feature-accounts-push:${Versions.mozilla_android_components}" const val mozilla_feature_top_sites = "org.mozilla.components:feature-top-sites:${Versions.mozilla_android_components}" const val mozilla_feature_share = "org.mozilla.components:feature-share:${Versions.mozilla_android_components}" + const val mozilla_feature_webauthn = "org.mozilla.components:feature-webauthn:${Versions.mozilla_android_components}" const val mozilla_feature_webcompat = "org.mozilla.components:feature-webcompat:${Versions.mozilla_android_components}" const val mozilla_feature_webnotifications = "org.mozilla.components:feature-webnotifications:${Versions.mozilla_android_components}" const val mozilla_feature_webcompat_reporter = "org.mozilla.components:feature-webcompat-reporter:${Versions.mozilla_android_components}" From d434ff13a56aa7e97bc0137244752306366dff28 Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Fri, 29 Jan 2021 15:16:21 -0500 Subject: [PATCH 025/248] For #17092: Dismiss toolbar menu when configuration change occurs (#17682) --- .../org/mozilla/fenix/browser/BaseBrowserFragment.kt | 7 +++++++ .../fenix/components/toolbar/BrowserToolbarView.kt | 4 ++++ .../main/java/org/mozilla/fenix/home/HomeFragment.kt | 10 ++++++++++ .../org/mozilla/fenix/browser/BrowserFragmentTest.kt | 11 +++++++++++ .../java/org/mozilla/fenix/home/HomeFragmentTest.kt | 11 +++++++++++ 5 files changed, 43 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 7d5a95ea6..869be62a9 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix.browser import android.content.Context import android.content.Intent +import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.view.Gravity @@ -1317,6 +1318,12 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, } } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + + _browserToolbarView?.dismissMenu() + } + // This method is called in response to native web extension messages from // content scripts (e.g the reader view extension). By the time these // messages are processed the fragment/view may no longer be attached. diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index fdad11b3b..aff4b03d2 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -235,6 +235,10 @@ class BrowserToolbarView( } } + fun dismissMenu() { + view.dismissMenu() + } + /** * Dynamically sets scroll flags for the toolbar when the user does not have a screen reader enabled * Note that the toolbar will have the flags set and be able to be hidden diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 412d286ae..ca828cfac 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.home import android.animation.Animator import android.content.Context import android.content.DialogInterface +import android.content.res.Configuration import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.ColorDrawable import android.os.Bundle @@ -168,6 +169,9 @@ class HomeFragment : Fragment() { private val topSitesFeature = ViewBoundFeatureWrapper() + @VisibleForTesting + internal var getMenuButton: () -> MenuButton? = { menuButton } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -274,6 +278,12 @@ class HomeFragment : Fragment() { return view } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + + getMenuButton()?.dismissMenu() + } + private fun dismissTip(tip: Tip) { sessionControlInteractor.onCloseTip(tip) } diff --git a/app/src/test/java/org/mozilla/fenix/browser/BrowserFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/browser/BrowserFragmentTest.kt index adeb7b36b..cd32d5ee0 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/BrowserFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/BrowserFragmentTest.kt @@ -346,6 +346,17 @@ class BrowserFragmentTest { verify(exactly = 1) { toolbarIntegration.invalidateMenu() } } + @Test + fun `WHEN fragment configuration changed THEN menu is dismissed`() { + val browserToolbarView: BrowserToolbarView = mockk(relaxed = true) + every { browserFragment.context } returns null + browserFragment._browserToolbarView = browserToolbarView + + browserFragment.onConfigurationChanged(mockk(relaxed = true)) + + verify(exactly = 1) { browserToolbarView.dismissMenu() } + } + private fun addAndSelectTab(tab: TabSessionState) { store.dispatch(TabListAction.AddTabAction(tab)).joinBlocking() store.dispatch(TabListAction.SelectTabAction(tab.id)).joinBlocking() diff --git a/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt index 8f24fa8e8..b201fd2e5 100644 --- a/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/HomeFragmentTest.kt @@ -8,7 +8,9 @@ import android.content.Context import io.mockk.every import io.mockk.mockk import io.mockk.spyk +import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi +import mozilla.components.browser.menu.view.MenuButton import org.junit.Assert import org.junit.Before import org.junit.Test @@ -65,4 +67,13 @@ class HomeFragmentTest { Assert.assertEquals(topSitesMaxLimit, topSitesConfig.totalSites) } + + @Test + fun `WHEN configuration changed menu is dismissed`() { + val menuButton: MenuButton = mockk(relaxed = true) + homeFragment.getMenuButton = { menuButton } + homeFragment.onConfigurationChanged(mockk(relaxed = true)) + + verify(exactly = 1) { menuButton.dismissMenu() } + } } From 8586b689f0776f1e781ee17cb7501f46ed675b76 Mon Sep 17 00:00:00 2001 From: Mickey Moz <33347735+MickeyMoz@users.noreply.github.com> Date: Fri, 29 Jan 2021 23:25:21 +0100 Subject: [PATCH 026/248] Update Android Components version to 73.0.20210129143134. (#17695) Co-authored-by: Roger Yang Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 5f110585a..261dac0b0 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210129102924" + const val VERSION = "73.0.20210129143134" } From d48bb2a4ccb8dbb3409cca0280f21e7e0f8a756f Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Thu, 28 Jan 2021 16:07:26 -0800 Subject: [PATCH 027/248] Revert "For #17447: add intentional delay to cold start up in debug and nightly." This reverts commit 093470a8b347a56195cda0d368b8b9bda8119fe2. This intentional regression was only intended to be temporary so now we're removing it. --- app/src/main/java/org/mozilla/fenix/FeatureFlags.kt | 7 ------- app/src/main/java/org/mozilla/fenix/FenixApplication.kt | 7 ------- 2 files changed, 14 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 170520d85..2aedb9361 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -34,13 +34,6 @@ object FeatureFlags { // users are still experiencing crashes. const val nimbusExperiments = false - /** - * Enables an intentional regression to validate perftest alerting. See - * https://github.com/mozilla-mobile/fenix/issues/17447 for details. This - * is expected to be removed within several days. - */ - val intentionalRegressionToValidatePerfTestAlerting = Config.channel.isNightlyOrDebug - /** * Enables the new MediaSession API. */ diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 88d950629..fdcbad404 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -119,13 +119,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider { @CallSuper open fun setupInMainProcessOnly() { - // See feature flags kdoc for details. - if (FeatureFlags.intentionalRegressionToValidatePerfTestAlerting) { - logger.info("Intentional thread sleep. See #17447") - @Suppress("MagicNumber") // it's fine for a quick patch. - Thread.sleep(100) - } - run { // Attention: Do not invoke any code from a-s in this scope. val megazordSetup = setupMegazord() From 9afb78de3f26d92e0609d5dec022cffe634f36c3 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sat, 30 Jan 2021 00:04:09 +0000 Subject: [PATCH 028/248] Import l10n. --- app/src/main/res/values-ar/strings.xml | 21 ++++++++++++++++++++- app/src/main/res/values-zh-rCN/strings.xml | 8 ++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index f04e157ef..dce2059be 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -631,6 +631,8 @@ قائمة الألسنة المحددة أزِل اللسان من المجموعة + + اختر ألسنة أغلِق اللسان @@ -1012,6 +1014,8 @@ أُغلقت الألسنة! حُفظت العلامات! + + اعرض أُضيف إلى المواقع الشائعة! @@ -1088,6 +1092,8 @@ يحرّر مساحة التخزين تصاريح المواقع + + التنزيلات احذف بيانات التصفح @@ -1207,7 +1213,7 @@ خصوصيتك - صمّمنا لك %s لتقدر على التحكّم فيما تُشاركه عبر الشبكة، وما تُشاركه معنا. + صمّمنا لك %s لتقدر على التحكّم فيما تُشاركه عبر الشبكة، وما تُشاركه معنا. اقرأ تنويه الخصوصية @@ -1357,6 +1363,11 @@ The first parameter is the app name --> ‏%s | المكتبات مفتوحة المصدر + + متعقّبات التحويلات + + يمسح الكعكات التي ضبطتها التحويلات إلى مواقع تعقّب معروفة. + الدعم @@ -1612,6 +1623,12 @@ احذف خيارات الولوج + + حقل نصوص قابل للتعديل لعنوان وِب الولوج. + + حقل نصوص قابل للتعديل لاسم مستخدم الولوج. + + حقل نصوص قابل للتعديل لكلمة سر الولوج. احفظ التغييرات على الولوج. @@ -1657,6 +1674,8 @@ الاسم + + اسم الموقع الأكثر زيارة حسنا diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9b9f7cc5e..ff7cc6fce 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -531,7 +531,7 @@ 屏幕截图 - 下载项 + 下载 书签 @@ -738,11 +738,11 @@ - 删除下载项 + 清除下载记录 - 您确定要清除下载项吗? + 您确定要清除下载记录吗? - 下载项已移除 + 下载记录已清除 已移除 %1$s From 450756032561d6f7a2a239b54aa9446c287f6c91 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sun, 31 Jan 2021 00:03:55 +0000 Subject: [PATCH 029/248] Import l10n. --- app/src/main/res/values-es-rES/strings.xml | 5 +++-- app/src/main/res/values-pa-rIN/strings.xml | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 733006fb9..0285eea56 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1119,6 +1119,8 @@ Libera espacio de almacenamiento Permisos del sitio + + Descargas Eliminar datos de navegación @@ -1243,8 +1245,7 @@ Tu privacidad - Hemos diseñado %s para darte control sobre lo que compartes - en línea y lo que compartes con nosotros. + Hemos diseñado %s para darte el control sobre lo que compartes en línea y lo que compartes con nosotros. Lee nuestro aviso de privacidad diff --git a/app/src/main/res/values-pa-rIN/strings.xml b/app/src/main/res/values-pa-rIN/strings.xml index bcd118a1e..68bdccd77 100644 --- a/app/src/main/res/values-pa-rIN/strings.xml +++ b/app/src/main/res/values-pa-rIN/strings.xml @@ -1231,6 +1231,10 @@ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ ਤੁਹਾਡੀ ਪਰਦੇਦਾਰੀ + + ਅਸੀਂ %s ਨੂੰ ਇੰਝ ਬਣਾਇਆ ਹੈ ਕਿ ਤੁਹਾਡੇ ਕੋਲ ਪੂਰਾ ਕੰਟਰੋਲ ਹੋਵੇ ਕਿ ਤੁਸੀਂ +ਆਨਲਾਈਨ ਕੀ ਸਾਂਝਾ ਕਰਦੇ ਹੋ ਅਤੇ ਸਾਡੇ ਨਾਲ ਕੀ ਸਾਂਝਾ ਕਰਦੇ ਹੋ। ਸਾਡੀ ਪਰਦੇਦਾਰੀ ਸੂਚਨਾ ਨੂੰ ਪੜ੍ਹੋ From 4bc6b852374ddb340c71ebe07a121e42111d4feb Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sat, 30 Jan 2021 15:37:04 +0000 Subject: [PATCH 030/248] Update Android Components version to 73.0.20210129195412. --- app/src/main/java/org/mozilla/fenix/components/Analytics.kt | 1 + buildSrc/src/main/java/AndroidComponents.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt index 1ef9581fd..2feadad1b 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt @@ -133,6 +133,7 @@ class Analytics( // Nimbus should look after downloading experiment definitions from remote settings // on another thread, and making sure we don't hit the server each time we start. + @Suppress("Deprecation") updateExperiments() } } else { diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 261dac0b0..dd2adb25e 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210129143134" + const val VERSION = "73.0.20210129195412" } From 98737327907d74db1f57c9253abb7d631c0e745f Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 31 Jan 2021 15:35:01 +0000 Subject: [PATCH 031/248] Update Android Components version to 73.0.20210131143119. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index dd2adb25e..24daea91a 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210129195412" + const val VERSION = "73.0.20210131143119" } From 1df656cd0e89b00f619f18fa1e6646409081ebb4 Mon Sep 17 00:00:00 2001 From: mawen7 Date: Mon, 1 Feb 2021 09:17:49 +0100 Subject: [PATCH 032/248] Include selected session in session suggestions if opened from home fragment (#17127) --- .../java/org/mozilla/fenix/search/SearchDialogFragment.kt | 8 ++++++-- .../org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index 6e20a2972..394252af6 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -116,6 +116,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { } } + @SuppressWarnings("LongMethod") override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -172,10 +173,13 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { val awesomeBar = view.awesome_bar awesomeBar.customizeForBottomToolbar = requireContext().settings().shouldUseBottomToolbar + val fromHomeFragment = + findNavController().previousBackStackEntry?.destination?.id == R.id.homeFragment awesomeBarView = AwesomeBarView( activity, interactor, - awesomeBar + awesomeBar, + fromHomeFragment ) view.awesome_bar.setOnTouchListener { _, _ -> @@ -191,7 +195,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { requireComponents.core.engine.speculativeCreateSession(isPrivate) - if (findNavController().previousBackStackEntry?.destination?.id == R.id.homeFragment) { + if (fromHomeFragment) { // When displayed above home, dispatches the touch events to scrim area to the HomeFragment view.search_wrapper.background = ColorDrawable(Color.TRANSPARENT) dialog?.window?.decorView?.setOnTouchListener { _, event -> diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt index 7d97dea8f..2df4afa1d 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt @@ -42,7 +42,8 @@ import mozilla.components.browser.search.SearchEngine as LegacySearchEngine class AwesomeBarView( private val activity: HomeActivity, val interactor: AwesomeBarInteractor, - val view: BrowserAwesomeBar + val view: BrowserAwesomeBar, + private val fromHomeFragment: Boolean ) { private val sessionProvider: SessionSuggestionProvider private val historyStorageProvider: HistoryStorageSuggestionProvider @@ -111,7 +112,7 @@ class AwesomeBarView( selectTabUseCase, components.core.icons, getDrawable(activity, R.drawable.ic_search_results_tab), - excludeSelectedSession = true + excludeSelectedSession = !fromHomeFragment ) historyStorageProvider = From 89ad370eb27906f24b04ea198d9bc664f53fd8e3 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Fri, 29 Jan 2021 19:08:22 -0500 Subject: [PATCH 033/248] Remove SessionManager references from UI tests --- .../mozilla/fenix/helpers/SessionLoadedIdlingResource.kt | 8 ++++---- .../java/org/mozilla/fenix/ui/robots/BrowserRobot.kt | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/SessionLoadedIdlingResource.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/SessionLoadedIdlingResource.kt index a32fe743d..0d3537f65 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/SessionLoadedIdlingResource.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/SessionLoadedIdlingResource.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.helpers import androidx.test.core.app.ApplicationProvider import androidx.test.espresso.IdlingResource +import mozilla.components.browser.state.selector.selectedTab import org.mozilla.fenix.FenixApplication /** @@ -21,13 +22,12 @@ class SessionLoadedIdlingResource : IdlingResource { override fun isIdleNow(): Boolean { val context = ApplicationProvider.getApplicationContext() - val sessionManager = context.components.core.sessionManager - val session = sessionManager.selectedSession + val selectedTab = context.components.core.store.state.selectedTab - return if (session?.loading == true) { + return if (selectedTab?.content?.loading == true) { false } else { - if (session?.progress == 100) { + if (selectedTab?.content?.progress == 100) { invokeCallback() true } else { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index efce62eec..8446019b7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -32,6 +32,7 @@ import androidx.test.uiautomator.By.text import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until +import mozilla.components.browser.state.selector.selectedTab import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.containsString import org.hamcrest.Matchers.not @@ -49,8 +50,8 @@ class BrowserRobot { private lateinit var sessionLoadedIdlingResource: SessionLoadedIdlingResource fun verifyCurrentPrivateSession(context: Context) { - val session = context.components.core.sessionManager.selectedSession - assertTrue("Current session is private", session?.private!!) + val selectedTab = context.components.core.store.state.selectedTab + assertTrue("Current session is private", selectedTab?.content?.private ?: false) } fun verifyUrl(url: String) { From cdc008f6a3ef490482f26938431d4f1456b93c0e Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Fri, 29 Jan 2021 14:52:56 -0800 Subject: [PATCH 034/248] For #17553: renew storage.stats metrics. --- app/metrics.yaml | 12 ++++++++---- docs/metrics.md | 8 ++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 038fa418e..7e12f19bc 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -4105,6 +4105,7 @@ storage.stats: - https://github.com/mozilla-mobile/fenix/issues/12802 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732 + - https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127 data_sensitivity: - technical - interaction @@ -4112,7 +4113,7 @@ storage.stats: - fenix-core@mozilla.com - perf-android-fe@mozilla.com - mcomella@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" app_bytes: send_in_pings: - metrics @@ -4129,6 +4130,7 @@ storage.stats: - https://github.com/mozilla-mobile/fenix/issues/12802 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732 + - https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127 data_sensitivity: - technical - interaction @@ -4136,7 +4138,7 @@ storage.stats: - fenix-core@mozilla.com - perf-android-fe@mozilla.com - mcomella@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" cache_bytes: send_in_pings: - metrics @@ -4150,6 +4152,7 @@ storage.stats: - https://github.com/mozilla-mobile/fenix/issues/12802 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732 + - https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127 data_sensitivity: - technical - interaction @@ -4157,7 +4160,7 @@ storage.stats: - fenix-core@mozilla.com - perf-android-fe@mozilla.com - mcomella@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" data_dir_bytes: send_in_pings: - metrics @@ -4173,6 +4176,7 @@ storage.stats: - https://github.com/mozilla-mobile/fenix/issues/12802 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732 + - https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127 data_sensitivity: - technical - interaction @@ -4180,7 +4184,7 @@ storage.stats: - fenix-core@mozilla.com - perf-android-fe@mozilla.com - mcomella@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" progressive_web_app: homescreen_tap: diff --git a/docs/metrics.md b/docs/metrics.md index 1ed8a6125..2a80a4fff 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -330,10 +330,10 @@ The following metrics are added to the ping: | search.default_engine.code |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be the search engine identifier. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | | search.default_engine.name |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be the search engine name. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | | search.default_engine.submission_url |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be he base URL we use to build the search query for the search engine. For example: https://mysearchengine.com/?query=%s. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | -| storage.stats.app_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of the app's APK and related files as installed: this is expected to be larger than download size. This is the output of [StorageStats.getAppBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getAppBytes()) so see that for details. This value is only available on Android 8+. A similar value may be available on the Google Play dashboard: we can use this value to see if that value is reliable enough. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732)||2021-02-01 |1, 2 | -| storage.stats.cache_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of all cached data in the app. This is the output of [StorageStats.getCacheBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getCacheBytes()) so see that for details. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732)||2021-02-01 |1, 2 | -| storage.stats.data_dir_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of all data minus `cache_bytes`. This is the output of [StorageStats.getDataBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getDataBytes()) except we subtract the value of `cache_bytes` so the cache is not measured redundantly; see that method for details. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732)||2021-02-01 |1, 2 | -| storage.stats.query_stats_duration |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |How long it took to query the device for the StorageStats that contain the file size information. The docs say it may be expensive so we want to ensure it's not too expensive. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732)||2021-02-01 |1, 2 | +| storage.stats.app_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of the app's APK and related files as installed: this is expected to be larger than download size. This is the output of [StorageStats.getAppBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getAppBytes()) so see that for details. This value is only available on Android 8+. A similar value may be available on the Google Play dashboard: we can use this value to see if that value is reliable enough. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732), [2](https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127)||2021-08-01 |1, 2 | +| storage.stats.cache_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of all cached data in the app. This is the output of [StorageStats.getCacheBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getCacheBytes()) so see that for details. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732), [2](https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127)||2021-08-01 |1, 2 | +| storage.stats.data_dir_bytes |[memory_distribution](https://mozilla.github.io/glean/book/user/metrics/memory_distribution.html) |The size of all data minus `cache_bytes`. This is the output of [StorageStats.getDataBytes](https://developer.android.com/reference/android/app/usage/StorageStats#getDataBytes()) except we subtract the value of `cache_bytes` so the cache is not measured redundantly; see that method for details. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732), [2](https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127)||2021-08-01 |1, 2 | +| storage.stats.query_stats_duration |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |How long it took to query the device for the StorageStats that contain the file size information. The docs say it may be expensive so we want to ensure it's not too expensive. This value is only available on Android 8+. |[1](https://github.com/mozilla-mobile/fenix/pull/12876#issuecomment-666770732), [2](https://github.com/mozilla-mobile/fenix/pull/17704#issue-564299127)||2021-08-01 |1, 2 | ## startup-timeline From d8085480ad8b3715e03ea563ddc95809301d46ae Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Mon, 1 Feb 2021 14:28:14 -0500 Subject: [PATCH 035/248] Increase AMO collection cache timeout to 2 days --- .../main/java/org/mozilla/fenix/components/Components.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt index bd3981f72..457c7f638 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -31,7 +31,7 @@ import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.wifi.WifiConnectionMonitor import java.util.concurrent.TimeUnit -private const val DAY_IN_MINUTES = 24 * 60L +private const val AMO_COLLECTION_MAX_CACHE_AGE = 2 * 24 * 60L // Two days in minutes /** * Provides access to all components. This class is an implementation of the Service Locator @@ -102,12 +102,12 @@ class Components(private val context: Context) { serverURL = BuildConfig.AMO_SERVER_URL, collectionUser = BuildConfig.AMO_COLLECTION_USER, collectionName = BuildConfig.AMO_COLLECTION_NAME, - maxCacheAgeInMinutes = DAY_IN_MINUTES + maxCacheAgeInMinutes = AMO_COLLECTION_MAX_CACHE_AGE ) } // Fall back to defaults else { - AddonCollectionProvider(context, core.client, maxCacheAgeInMinutes = DAY_IN_MINUTES) + AddonCollectionProvider(context, core.client, maxCacheAgeInMinutes = AMO_COLLECTION_MAX_CACHE_AGE) } } From 72f977771d0eedb94ce4097ac621c0320c147862 Mon Sep 17 00:00:00 2001 From: jhugman Date: Mon, 1 Feb 2021 23:50:07 +0000 Subject: [PATCH 036/248] Re-enable Nimbus with Off the main thread I/O and non-blocking networking (#17684) * Moved Nimbus setup from Analytics to its own file * Change experiment identifiers to fit new run of the experiment * Re-enable nimbus for debug and nightly builds * ./gradlew ktlint && detekt --- .../java/org/mozilla/fenix/FeatureFlags.kt | 12 +--- .../org/mozilla/fenix/components/Analytics.kt | 33 +-------- .../mozilla/fenix/experiments/Experiments.kt | 6 +- .../mozilla/fenix/experiments/NimbusSetup.kt | 72 +++++++++++++++++++ 4 files changed, 79 insertions(+), 44 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/experiments/NimbusSetup.kt diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 2aedb9361..35e89de46 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -22,17 +22,9 @@ object FeatureFlags { val syncedTabsInTabsTray = Config.channel.isNightlyOrDebug /** - * Enables the Nimbus experiments library, especially the settings toggle to opt-out of - * all experiments. + * Enables the Nimbus experiments library. */ - // IMPORTANT: Only turn this back on once the following issues are resolved: - // - https://github.com/mozilla-mobile/fenix/issues/17086: Calls to - // getExperimentBranch seem to block on updateExperiments causing a - // large performance regression loading the home screen. - // - https://github.com/mozilla-mobile/fenix/issues/17143: Despite - // having wrapped getExperimentBranch/withExperiments in a catch-all - // users are still experiencing crashes. - const val nimbusExperiments = false + val nimbusExperiments = Config.channel.isNightlyOrDebug /** * Enables the new MediaSession API. diff --git a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt index 2feadad1b..00bfb6647 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt @@ -8,17 +8,13 @@ import android.app.Application import android.app.PendingIntent import android.content.Context import android.content.Intent -import android.net.Uri -import android.os.StrictMode import mozilla.components.lib.crash.CrashReporter import mozilla.components.lib.crash.service.CrashReporterService import mozilla.components.lib.crash.service.GleanCrashReporterService import mozilla.components.lib.crash.service.MozillaSocorroService import mozilla.components.lib.crash.service.SentryService import mozilla.components.service.nimbus.NimbusApi -import mozilla.components.service.nimbus.Nimbus as NimbusEnabled import mozilla.components.service.nimbus.NimbusDisabled -import mozilla.components.service.nimbus.NimbusServerSettings import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.Config import org.mozilla.fenix.FeatureFlags @@ -29,6 +25,7 @@ import org.mozilla.fenix.components.metrics.AdjustMetricsService import org.mozilla.fenix.components.metrics.GleanMetricsService import org.mozilla.fenix.components.metrics.LeanplumMetricsService import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.experiments.createNimbus import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.perf.lazyMonitored @@ -109,33 +106,7 @@ class Analytics( val experiments: NimbusApi by lazyMonitored { if (FeatureFlags.nimbusExperiments) { - // Eventually we'll want to use `NimbusDisabled` when we have no NIMBUS_ENDPOINT. - // but we keep this here to not mix feature flags and how we configure Nimbus. - val url: String? = BuildConfig.NIMBUS_ENDPOINT - val serverSettings = if (!url.isNullOrBlank()) { - NimbusServerSettings(url = Uri.parse(url)) - } else { - null - } - - NimbusEnabled(context, serverSettings).apply { - // Global opt out state is stored in Nimbus, and shouldn't be toggled to `true` - // from the app unless the user does so from a UI control. - // However, the user may have opt-ed out of mako experiments already, so - // we should respect that setting here. - val enabled = - context.components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { - context.settings().isExperimentationEnabled - } - if (!enabled) { - globalUserParticipation = enabled - } - - // Nimbus should look after downloading experiment definitions from remote settings - // on another thread, and making sure we don't hit the server each time we start. - @Suppress("Deprecation") - updateExperiments() - } + createNimbus(context, BuildConfig.NIMBUS_ENDPOINT) } else { NimbusDisabled() } diff --git a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt index 5b5f67b34..ab11ec8f4 100644 --- a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt +++ b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt @@ -6,7 +6,7 @@ package org.mozilla.fenix.experiments class Experiments { companion object { - const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation" + const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation-v2" const val BOOKMARK_ICON = "fenix-bookmark-list-icon" } } @@ -15,7 +15,7 @@ class ExperimentBranch { companion object { const val TREATMENT = "treatment" const val CONTROL = "control" - const val A1 = "A1" - const val A2 = "A2" + const val A1 = "a1" + const val A2 = "a2" } } diff --git a/app/src/main/java/org/mozilla/fenix/experiments/NimbusSetup.kt b/app/src/main/java/org/mozilla/fenix/experiments/NimbusSetup.kt new file mode 100644 index 000000000..1622e79da --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/experiments/NimbusSetup.kt @@ -0,0 +1,72 @@ +/* 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 org.mozilla.fenix.experiments + +import android.content.Context +import android.net.Uri +import android.os.StrictMode +import io.sentry.Sentry +import mozilla.components.service.nimbus.NimbusApi +import mozilla.components.service.nimbus.Nimbus +import mozilla.components.service.nimbus.NimbusDisabled +import mozilla.components.service.nimbus.NimbusServerSettings +import mozilla.components.support.base.log.logger.Logger +import org.mozilla.fenix.components.isSentryEnabled +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.settings + +@Suppress("TooGenericExceptionCaught") +fun createNimbus(context: Context, url: String?): NimbusApi = + try { + // Eventually we'll want to use `NimbusDisabled` when we have no NIMBUS_ENDPOINT. + // but we keep this here to not mix feature flags and how we configure Nimbus. + val serverSettings = if (!url.isNullOrBlank()) { + NimbusServerSettings(url = Uri.parse(url)) + } else { + null + } + + // Global opt out state is stored in Nimbus, and shouldn't be toggled to `true` + // from the app unless the user does so from a UI control. + // However, the user may have opt-ed out of mako experiments already, so + // we should respect that setting here. + val enabled = + context.components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { + context.settings().isExperimentationEnabled + } + + Nimbus(context, serverSettings).apply { + // This performs the minimal amount of work required to load branch and enrolment data + // into memory. If `getExperimentBranch` is called from another thread between here + // and the next nimbus disk write (setting `globalUserParticipation` or + // `applyPendingExperiments()`) then this has you covered. + // This call does its work on the db thread. + initialize() + + if (!enabled) { + // This opts out of nimbus experiments. It involves writing to disk, so does its + // work on the db thread. + globalUserParticipation = enabled + } + + // We may have downloaded experiments on a previous run, so let's start using them + // now. We didn't do this earlier, so as to make getExperimentBranch and friends returns + // the same thing throughout the session. This call does its work on the db thread. + applyPendingExperiments() + + // Now fetch the experiments from the server. These will be available for feature + // configuration on the next run of the app. This call launches on the fetch thread. + fetchExperiments() + } + } catch (e: Throwable) { + // Something went wrong. We'd like not to, but stability of the app is more important than + // failing fast here. + if (isSentryEnabled()) { + Sentry.capture(e) + } else { + Logger.error("Failed to initialize Nimbus", e) + } + NimbusDisabled() + } From 21c95f38ec6ef97f3eb8fbe6e88cd401de5fb2b2 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 1 Feb 2021 15:36:42 +0000 Subject: [PATCH 037/248] Update Android Components version to 73.0.20210201143120. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 24daea91a..65c1f1c54 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210131143119" + const val VERSION = "73.0.20210201143120" } From 4c2a4f4d2e3f4269220cb71309d0e072dcf65c10 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Tue, 2 Feb 2021 00:01:17 +0000 Subject: [PATCH 038/248] Import l10n. --- app/src/main/res/values-eu/strings.xml | 6 +-- app/src/main/res/values-hi-rIN/strings.xml | 50 +++++++++++++++------- app/src/main/res/values-ja/strings.xml | 5 +-- app/src/main/res/values-sk/strings.xml | 3 ++ 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 38d615fca..d0a3ea701 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -1101,6 +1101,8 @@ Biltegiratze tokia libratzen du Gunearen baimenak + + Deskargak Ezabatu nabigatze-datuak @@ -1224,9 +1226,7 @@ Zure pribatutasuna - Online partekatzen duzunaren eta gurekin partekatzen - duzunaren inguruko kontrola emateko diseinatu dugu %s. - + Online partekatzen duzunaren eta gurekin partekatzen duzunaren inguruko kontrola emateko diseinatu dugu %s. Irakurri gure pribatutasun-oharra diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index c3c0ba5f9..c6f044e44 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -20,6 +20,8 @@ आपके निजी टैब यहाँ दिखाए जाएंगे। + + JD 1 खुला टैब। टैब स्विच करने के लिए टैप करें। @@ -70,20 +72,15 @@ नहीं धन्यवाद - - - ओर तेज Firefox करने के लिए, अपने होम स्क्रीन पर एक विजेट जोड़ें। - - विजेट जोड़ें - - अभी नहीं - सेटिंग पर जाएं सेटिंग पर जाएं + + सेटिंग पर जाएं + नया टैब @@ -132,8 +129,6 @@ पृष्ठ में ढूँढें निजी टैब - - नया टैब संग्रहण में सहेजें @@ -200,6 +195,8 @@ अधिक जानें + + एक नया Firefox टैब खोलें खोजें @@ -273,6 +270,8 @@ टूलबार थीम + + मुख्य पृष्ठ अनुकूलित करें @@ -308,6 +307,8 @@ ब्राउज़िंग इतिहास खोजें बुकमार्क खोजें + + सिंक किए गए टैब खोजें खाता सेटिंग @@ -318,6 +319,12 @@ अधिसूचनाएं + + रद्द करें + + + ऐड-ऑन पहले से इंस्टॉल है + अब सिंक करें @@ -491,6 +498,8 @@ %d टैब + + टैब टैब बंद करें @@ -531,6 +540,10 @@ मुख्य पृष्ठ पर जाएं टैब मोड को टॉगल करें + + बुकमार्क + + बंद करें संग्रहण से टैब हटायें @@ -567,7 +580,7 @@ खुले टैब - हटाएं + हटाएं इतिहास से मिटाएं @@ -615,6 +628,7 @@ यहां कोई इतिहास नहीं + माफ़ कीजिए। %1$s उस पृष्ठ को लोड नहीं कर सकता हैं। @@ -878,6 +892,8 @@ टैब बंद हो गया टैब बंद हो गया + + बुकमार्क सहेजा गया! शीर्ष साइटों में जोड़ा गया! @@ -1070,10 +1086,6 @@ सेटिंग खोलें आपकी गोपनीयता - - आपने जो हमारे साथ साझा करते है या जो आप ऑनलाइन साझा करते हैं - उस पर नियंत्रण देने के लिए हमने %s डिज़ाइन किया हैं। हमारी गोपनीयता सूचना पढ़ें @@ -1535,10 +1547,18 @@ ठीक है, समझ गए + + नाम + + रद्द करें + %s का अधिकतम लाभ उठाएं। + + अधिक जानकारी के लिए क्लिक करें + जो चीजें आपके लिए मायने रखती हैं, उन्हें इकट्ठा करें diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index b3834ea38..9b8f339bd 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1107,6 +1107,8 @@ ストレージ領域を空けます サイトの許可設定 + + ダウンロード一覧 閲覧データを削除 @@ -1227,9 +1229,6 @@ 設定を開く あなたのプライバシー - - %s は、あなたがオンラインで共有するものと、私たちと共有するものをコントロールできるように設計されています。 個人情報保護方針を読む diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index ac5877ff9..9355c3540 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -1219,6 +1219,9 @@ Otvoriť nastavenia Vaše súkromie + + %s vám dáva kontrolu nad tým, čo zdieľate na internete a čo zdieľate s nami. Prečítajte si naše zásady ochrany súkromia From 23e6f7aa915c0c9df15d59e5b160c6cc41063e80 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Tue, 26 Jan 2021 15:39:44 +0200 Subject: [PATCH 039/248] For #16615: UI Smoke Tests for Tab Crash Reporter --- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 28 +++++++++++++++++++ .../mozilla/fenix/ui/robots/BrowserRobot.kt | 25 +++++++++++++++++ .../fenix/ui/robots/NavigationToolbarRobot.kt | 25 +++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 697255bfc..f194fddf7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -26,6 +26,7 @@ import org.mozilla.fenix.helpers.TestHelper import org.mozilla.fenix.helpers.TestHelper.deleteDownloadFromStorage import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource import org.mozilla.fenix.ui.robots.browserScreen +import org.mozilla.fenix.ui.robots.clickTabCrashedRestoreButton import org.mozilla.fenix.ui.robots.clickUrlbar import org.mozilla.fenix.ui.robots.downloadRobot import org.mozilla.fenix.ui.robots.enhancedTrackingProtection @@ -1164,4 +1165,31 @@ class SmokeTest { verifyAppearanceColorSepia(true) } } + + @Test + fun closeTabCrashedReporterTest() { + + homeScreen { + }.openNavigationToolbar { + }.openTabCrashReporter { + }.clickTabCrashedCloseButton { + }.openTabDrawer { + verifyNoTabsOpened() + } + } + + @Test + fun restoreTabCrashedReporterTest() { + val website = TestAssetHelper.getGenericAsset(mockWebServer, 1) + + homeScreen { + }.openNavigationToolbar { + }.enterURLAndEnterToBrowser(website.url) {} + + navigationToolbar { + }.openTabCrashReporter { + clickTabCrashedRestoreButton() + verifyPageContent(website.content) + } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt index 8446019b7..2e7343f36 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BrowserRobot.kt @@ -466,6 +466,20 @@ class BrowserRobot { HomeScreenRobot().interact() return HomeScreenRobot.Transition() } + + fun clickTabCrashedCloseButton(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { + + assertTrue( + mDevice.findObject(UiSelector().resourceId("$packageName:id/closeTabButton")) + .waitForExists(waitingTime) + ) + + val tabCrashedCloseButton = mDevice.findObject(text("Close tab")) + tabCrashedCloseButton.click() + + HomeScreenRobot().interact() + return HomeScreenRobot.Transition() + } } } @@ -526,3 +540,14 @@ private fun mediaPlayerPlayButton() = .className("android.widget.Button") .text("Play") ) + +fun clickTabCrashedRestoreButton() { + + assertTrue( + mDevice.findObject(UiSelector().resourceId("$packageName:id/restoreTabButton")) + .waitForExists(waitingTime) + ) + + val tabCrashRestoreButton = mDevice.findObject(UiSelector().resourceIdMatches("$packageName:id/restoreTabButton")) + tabCrashRestoreButton.click() +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt index 3c63c7eb9..1a0ad0075 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NavigationToolbarRobot.kt @@ -30,6 +30,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.anyOf @@ -121,6 +122,30 @@ class NavigationToolbarRobot { return BrowserRobot.Transition() } + fun openTabCrashReporter(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + val crashUrl = "about:crashcontent" + + sessionLoadedIdlingResource = SessionLoadedIdlingResource() + + mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/toolbar")), + waitingTime + ) + urlBar().click() + mDevice.waitNotNull( + Until.findObject(By.res("$packageName:id/mozac_browser_toolbar_edit_url_view")), + waitingTime + ) + + awesomeBar().perform(replaceText(crashUrl), pressImeActionButton()) + + runWithIdleRes(sessionLoadedIdlingResource) { + mDevice.findObject(UiSelector().resourceId("$packageName:id/crash_tab_image")) + } + + BrowserRobot().interact() + return BrowserRobot.Transition() + } + fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/mozac_browser_toolbar_menu")), waitingTime) threeDotButton().click() From 5eb1a3d2107aa197717ab8293018c3ada1114758 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 1 Feb 2021 15:11:05 +0200 Subject: [PATCH 040/248] For #17641 Fix Intermittent test addPredefinedSearchEngineTest --- .../java/org/mozilla/fenix/ui/robots/SearchRobot.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt index 5f565b257..6bf120a16 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SearchRobot.kt @@ -270,6 +270,9 @@ private fun assertSearchEngineList() { } private fun assertEngineListShortcutContains(searchEngineName: String) { + mDevice.findObject(UiSelector().resourceId("$packageName:id/awesome_bar")) + .waitForExists(waitingTime) + onView(withId(R.id.awesome_bar)) .perform(swipeDown()) .check(matches(hasDescendant(withText(searchEngineName)))) From c8c0131d00a83c943fd9db2d9634082428dfe710 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Fri, 29 Jan 2021 16:51:48 +0200 Subject: [PATCH 041/248] Go Forward Test Fix --- .../java/org/mozilla/fenix/ui/NavigationToolbarTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt index b29837983..ee42a73e6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/NavigationToolbarTest.kt @@ -66,7 +66,6 @@ class NavigationToolbarTest { } } - @Ignore("Flaky test: https://github.com/mozilla-mobile/fenix/issues/12894") @Test fun goForwardTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -79,7 +78,8 @@ class NavigationToolbarTest { }.enterURLAndEnterToBrowser(nextWebPage.url) { mDevice.waitForIdle() verifyUrl(nextWebPage.url.toString()) - mDevice.pressBack() + }.openThreeDotMenu { + }.goBack { mDevice.waitForIdle() verifyUrl(defaultWebPage.url.toString()) } From f180d932c83556a39b39e07214db5e804db4e502 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Mon, 1 Feb 2021 17:04:12 +0200 Subject: [PATCH 042/248] For #16959: verify page url not content in swipeToSwitchTabTest --- app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index f194fddf7..10b38c0ad 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -531,9 +531,9 @@ class SmokeTest { }.openNewTab { }.submitQuery(secondWebPage.url.toString()) { swipeNavBarRight(secondWebPage.url.toString()) - verifyPageContent(firstWebPage.content) + verifyUrl(firstWebPage.url.toString()) swipeNavBarLeft(firstWebPage.url.toString()) - verifyPageContent(secondWebPage.content) + verifyUrl(secondWebPage.url.toString()) } } From 06c1734aa5126de41035e12f02fd7a0b74efe1a7 Mon Sep 17 00:00:00 2001 From: isabelrios Date: Tue, 2 Feb 2021 14:39:07 +0100 Subject: [PATCH 043/248] Run UI tests nightly def (#17513) * run-ui-test-nightly * Run ui tests on nightly build * set correct number of shard according to tests running * fix typo * removing testing file Co-authored-by: isabel rios --- .../androidTest/flank-x86-start-test.yml | 4 +++- automation/taskcluster/androidTest/ui-test.sh | 2 +- taskcluster/ci/build/kind.yml | 18 +++++++++++++++--- taskcluster/ci/signing/kind.yml | 1 + taskcluster/ci/ui-test/kind.yml | 13 +++++++++++++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/automation/taskcluster/androidTest/flank-x86-start-test.yml b/automation/taskcluster/androidTest/flank-x86-start-test.yml index 16292c98e..ba3eddac4 100644 --- a/automation/taskcluster/androidTest/flank-x86-start-test.yml +++ b/automation/taskcluster/androidTest/flank-x86-start-test.yml @@ -42,7 +42,9 @@ gcloud: flank: project: GOOGLE_PROJECT + # test shards - the amount of groups to split the test suite into + # set to -1 to use one shard per test. + max-test-shards: 1 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x num-test-runs: 1 - diff --git a/automation/taskcluster/androidTest/ui-test.sh b/automation/taskcluster/androidTest/ui-test.sh index 8e02e4be0..ae11d9d96 100755 --- a/automation/taskcluster/androidTest/ui-test.sh +++ b/automation/taskcluster/androidTest/ui-test.sh @@ -76,7 +76,7 @@ set +e if [[ "${device_type}" =~ ^(arm64-v8a|armeabi-v7a|x86_64|x86)$ ]]; then flank_template="${PATH_TEST}/flank-${device_type}.yml" -elif [[ "${device_type}" == "x86-start-test" ]]; then +elif [[ "${device_type}" == "x86-start-nightly-test" ]]; then flank_template="${PATH_TEST}/flank-x86-start-test.yml" elif [[ "${device_type}" == "arm-start-test" ]]; then flank_template="${PATH_TEST}/flank-armeabi-v7a-start-test.yml" diff --git a/taskcluster/ci/build/kind.yml b/taskcluster/ci/build/kind.yml index 335abd497..2c3643f66 100644 --- a/taskcluster/ci/build/kind.yml +++ b/taskcluster/ci/build/kind.yml @@ -63,6 +63,15 @@ jobs: treeherder: symbol: beta(Bf) + nightly-firebase: + disable-optimization: true + run-on-tasks-for: [github-push] # We want this on push so that we detect problem before triggering a new beta + run: + gradle-build-type: nightly + test-build-type: nightly + treeherder: + symbol: nightly(Bf) + android-test-debug: attributes: code-review: true @@ -85,13 +94,16 @@ jobs: android-test-nightly: attributes: nightly: true - run: - gradle-build-type: androidTest apk-artifact-template: # 2 differences here: # * "androidTest/" is added # * "{gradle_build_type}" is forced to "debug" - path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/debug/{fileName}' + path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/nightly/app-nightly-androidTest.apk' + disable-optimization: true + run: + gradle-build-type: androidTest + test-build-type: nightly + run-on-tasks-for: [github-push] treeherder: symbol: nightly(Bat) diff --git a/taskcluster/ci/signing/kind.yml b/taskcluster/ci/signing/kind.yml index 87e55c0e7..c2817e496 100644 --- a/taskcluster/ci/signing/kind.yml +++ b/taskcluster/ci/signing/kind.yml @@ -56,6 +56,7 @@ job-template: by-build-type: android-test.+: Bats beta-firebase: Bfs + nightly-firebase: Bfs default: Bs kind: build platform: android-all/opt diff --git a/taskcluster/ci/ui-test/kind.yml b/taskcluster/ci/ui-test/kind.yml index f4c7ed80b..d942c92e2 100644 --- a/taskcluster/ci/ui-test/kind.yml +++ b/taskcluster/ci/ui-test/kind.yml @@ -80,3 +80,16 @@ jobs: - [automation/taskcluster/androidTest/ui-test.sh, x86-beta-tests, app.apk, android-test.apk, '50'] treeherder: symbol: beta(ui-test-x86-beta) + x86-nightly: + attributes: + build-type: nightly-firebase + description: Test Fenix + run-on-tasks-for: [github-push] + dependencies: + signing: signing-nightly-firebase + signing-android-test: signing-android-test-nightly + run: + commands: + - [automation/taskcluster/androidTest/ui-test.sh, x86-start-nightly-test, app.apk, android-test.apk, '-1'] + treeherder: + symbol: nightly(ui-test-x86-nightly) From 824f3fd82138b2e93dcfeddcf6310f7878e1de2d Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Mon, 1 Feb 2021 14:52:56 +0400 Subject: [PATCH 044/248] Issue #1340: Forward Activity results to the fragment --- app/src/main/java/org/mozilla/fenix/HomeActivity.kt | 10 ++++++++++ .../org/mozilla/fenix/browser/BaseBrowserFragment.kt | 9 +++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 64cfb7740..c39d42e6d 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -52,6 +52,7 @@ import mozilla.components.feature.privatemode.notification.PrivateNotificationFe import mozilla.components.feature.search.BrowserStoreSearchAdapter import mozilla.components.feature.search.ext.legacy import mozilla.components.service.fxa.sync.SyncReason +import mozilla.components.support.base.feature.ActivityResultHandler import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.ktx.android.arch.lifecycle.addObservers import mozilla.components.support.ktx.android.content.call @@ -536,6 +537,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { super.onBackPressed() } + final override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { + if (it is ActivityResultHandler && it.onActivityResult(requestCode, data, resultCode)) { + return + } + } + super.onActivityResult(requestCode, resultCode, data) + } + private fun shouldUseCustomBackLongPress(): Boolean { val isAndroidN = Build.VERSION.SDK_INT == Build.VERSION_CODES.N || Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1 diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 869be62a9..7aa83991e 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -128,6 +128,7 @@ import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration import java.lang.ref.WeakReference import mozilla.components.feature.media.fullscreen.MediaFullscreenOrientationFeature import mozilla.components.feature.webauthn.WebAuthnFeature +import mozilla.components.support.base.feature.ActivityResultHandler import org.mozilla.fenix.FeatureFlags.newMediaSessionApi /** @@ -137,7 +138,7 @@ import org.mozilla.fenix.FeatureFlags.newMediaSessionApi */ @ExperimentalCoroutinesApi @Suppress("TooManyFunctions", "LargeClass") -abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, +abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, ActivityResultHandler, OnBackLongPressedListener, AccessibilityManager.AccessibilityStateChangeListener { private lateinit var browserFragmentStore: BrowserFragmentStore @@ -1037,10 +1038,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, } /** - * Forwards activity results to the prompt feature. + * Forwards activity results to the [ActivityResultHandler] features. */ - final override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - listOf( + override fun onActivityResult(requestCode: Int, data: Intent?, resultCode: Int): Boolean { + return listOf( promptsFeature, webAuthnFeature ).any { it.onActivityResult(requestCode, data, resultCode) } From 47d7476f9c479b899c86b11a0905ab8bbef72e16 Mon Sep 17 00:00:00 2001 From: isabelrios Date: Tue, 2 Feb 2021 17:39:51 +0100 Subject: [PATCH 045/248] Revert "Run UI tests nightly def (#17513)" (#17761) This reverts commit 06c1734aa5126de41035e12f02fd7a0b74efe1a7. --- .../androidTest/flank-x86-start-test.yml | 4 +--- automation/taskcluster/androidTest/ui-test.sh | 2 +- taskcluster/ci/build/kind.yml | 18 +++--------------- taskcluster/ci/signing/kind.yml | 1 - taskcluster/ci/ui-test/kind.yml | 13 ------------- 5 files changed, 5 insertions(+), 33 deletions(-) diff --git a/automation/taskcluster/androidTest/flank-x86-start-test.yml b/automation/taskcluster/androidTest/flank-x86-start-test.yml index ba3eddac4..16292c98e 100644 --- a/automation/taskcluster/androidTest/flank-x86-start-test.yml +++ b/automation/taskcluster/androidTest/flank-x86-start-test.yml @@ -42,9 +42,7 @@ gcloud: flank: project: GOOGLE_PROJECT - # test shards - the amount of groups to split the test suite into - # set to -1 to use one shard per test. - max-test-shards: 1 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x num-test-runs: 1 + diff --git a/automation/taskcluster/androidTest/ui-test.sh b/automation/taskcluster/androidTest/ui-test.sh index ae11d9d96..8e02e4be0 100755 --- a/automation/taskcluster/androidTest/ui-test.sh +++ b/automation/taskcluster/androidTest/ui-test.sh @@ -76,7 +76,7 @@ set +e if [[ "${device_type}" =~ ^(arm64-v8a|armeabi-v7a|x86_64|x86)$ ]]; then flank_template="${PATH_TEST}/flank-${device_type}.yml" -elif [[ "${device_type}" == "x86-start-nightly-test" ]]; then +elif [[ "${device_type}" == "x86-start-test" ]]; then flank_template="${PATH_TEST}/flank-x86-start-test.yml" elif [[ "${device_type}" == "arm-start-test" ]]; then flank_template="${PATH_TEST}/flank-armeabi-v7a-start-test.yml" diff --git a/taskcluster/ci/build/kind.yml b/taskcluster/ci/build/kind.yml index 2c3643f66..335abd497 100644 --- a/taskcluster/ci/build/kind.yml +++ b/taskcluster/ci/build/kind.yml @@ -63,15 +63,6 @@ jobs: treeherder: symbol: beta(Bf) - nightly-firebase: - disable-optimization: true - run-on-tasks-for: [github-push] # We want this on push so that we detect problem before triggering a new beta - run: - gradle-build-type: nightly - test-build-type: nightly - treeherder: - symbol: nightly(Bf) - android-test-debug: attributes: code-review: true @@ -94,16 +85,13 @@ jobs: android-test-nightly: attributes: nightly: true + run: + gradle-build-type: androidTest apk-artifact-template: # 2 differences here: # * "androidTest/" is added # * "{gradle_build_type}" is forced to "debug" - path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/nightly/app-nightly-androidTest.apk' - disable-optimization: true - run: - gradle-build-type: androidTest - test-build-type: nightly - run-on-tasks-for: [github-push] + path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/debug/{fileName}' treeherder: symbol: nightly(Bat) diff --git a/taskcluster/ci/signing/kind.yml b/taskcluster/ci/signing/kind.yml index c2817e496..87e55c0e7 100644 --- a/taskcluster/ci/signing/kind.yml +++ b/taskcluster/ci/signing/kind.yml @@ -56,7 +56,6 @@ job-template: by-build-type: android-test.+: Bats beta-firebase: Bfs - nightly-firebase: Bfs default: Bs kind: build platform: android-all/opt diff --git a/taskcluster/ci/ui-test/kind.yml b/taskcluster/ci/ui-test/kind.yml index d942c92e2..f4c7ed80b 100644 --- a/taskcluster/ci/ui-test/kind.yml +++ b/taskcluster/ci/ui-test/kind.yml @@ -80,16 +80,3 @@ jobs: - [automation/taskcluster/androidTest/ui-test.sh, x86-beta-tests, app.apk, android-test.apk, '50'] treeherder: symbol: beta(ui-test-x86-beta) - x86-nightly: - attributes: - build-type: nightly-firebase - description: Test Fenix - run-on-tasks-for: [github-push] - dependencies: - signing: signing-nightly-firebase - signing-android-test: signing-android-test-nightly - run: - commands: - - [automation/taskcluster/androidTest/ui-test.sh, x86-start-nightly-test, app.apk, android-test.apk, '-1'] - treeherder: - symbol: nightly(ui-test-x86-nightly) From acae32095038ffef7569152aa43c5650bdac72fe Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 2 Feb 2021 15:35:15 +0000 Subject: [PATCH 046/248] Update Android Components version to 73.0.20210202143148. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 65c1f1c54..432fe7914 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210201143120" + const val VERSION = "73.0.20210202143148" } From e3b6f060aee03f0639ac63e1316b203ab0e4544b Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Fri, 29 Jan 2021 15:51:47 -0500 Subject: [PATCH 047/248] For #12822 - Opt-in of scoped storage --- app/build.gradle | 17 +++++++++++++---- app/src/main/AndroidManifest.xml | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9cded9b84..a0ad61917 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,7 +46,8 @@ android { def deepLinkSchemeValue = "fenix-dev" buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" manifestPlaceholders = [ - "deepLinkScheme": deepLinkSchemeValue + "deepLinkScheme": deepLinkSchemeValue, + "requestLegacyExternalStorage": true ] // Build flag for "Mozilla Online" variants. See `Config.isMozillaOnline`. @@ -81,13 +82,19 @@ android { applicationIdSuffix ".fenix.debug" resValue "bool", "IS_DEBUG", "true" pseudoLocalesEnabled true + def deepLinkSchemeValue = "fenix-dev" + buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" + manifestPlaceholders = [ + "deepLinkScheme": deepLinkSchemeValue, + "requestLegacyExternalStorage": false + ] } nightly releaseTemplate >> { applicationIdSuffix ".fenix" buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true" def deepLinkSchemeValue = "fenix-nightly" buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" - manifestPlaceholders = ["deepLinkScheme": deepLinkSchemeValue] + manifestPlaceholders = ["deepLinkScheme": deepLinkSchemeValue, "requestLegacyExternalStorage": false] } beta releaseTemplate >> { buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true" @@ -103,7 +110,8 @@ android { // - https://issuetracker.google.com/issues/36924841 // - https://issuetracker.google.com/issues/36905922 "sharedUserId": "org.mozilla.firefox.sharedID", - "deepLinkScheme": deepLinkSchemeValue + "deepLinkScheme": deepLinkSchemeValue, + "requestLegacyExternalStorage": true ] } release releaseTemplate >> { @@ -120,7 +128,8 @@ android { // - https://issuetracker.google.com/issues/36924841 // - https://issuetracker.google.com/issues/36905922 "sharedUserId": "org.mozilla.firefox.sharedID", - "deepLinkScheme": deepLinkSchemeValue + "deepLinkScheme": deepLinkSchemeValue, + "requestLegacyExternalStorage": true ] } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0f4ac90f1..660175dfc 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,7 +23,7 @@ android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" - android:requestLegacyExternalStorage="true" + android:requestLegacyExternalStorage="${requestLegacyExternalStorage}" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/NormalTheme" From 854a5e676f9a9c2802b63c65fa1e3491711b4af8 Mon Sep 17 00:00:00 2001 From: Elise Richards Date: Tue, 2 Feb 2021 12:27:10 -0600 Subject: [PATCH 048/248] Increase date on expired metrics (#17766) --- app/metrics.yaml | 12 ++++++------ docs/metrics.md | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 7e12f19bc..6148f67c2 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -623,7 +623,7 @@ login_dialog: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" cancelled: type: event description: | @@ -636,7 +636,7 @@ login_dialog: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" saved: type: event description: | @@ -649,7 +649,7 @@ login_dialog: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" never_save: type: event description: | @@ -662,7 +662,7 @@ login_dialog: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" find_in_page: opened: @@ -4070,7 +4070,7 @@ autoplay: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" setting_changed: type: event description: | @@ -4089,7 +4089,7 @@ autoplay: - interaction notification_emails: - fenix-core@mozilla.com - expires: "2021-02-01" + expires: "2021-08-01" storage.stats: query_stats_duration: diff --git a/docs/metrics.md b/docs/metrics.md index 2a80a4fff..8d0b6ea25 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -53,8 +53,8 @@ The following metrics are added to the ping: | addons.open_addon_in_toolbar_menu |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user interacted with an installed add-on in the toolbar menu |[1](https://github.com/mozilla-mobile/fenix/pull/8318), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)|
  • addon_id: The id of the add-on that was interacted with in the toolbar menu
|2021-04-01 |2 | | addons.open_addons_in_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user accessed "Add-ons" from the Settings |[1](https://github.com/mozilla-mobile/fenix/pull/8318), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | | app_theme.dark_theme_selected |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user selected Dark Theme |[1](https://github.com/mozilla-mobile/fenix/pull/7968), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)|
  • source: The source from where dark theme was selected. The source can be 'SETTINGS' or 'ONBOARDING'
|2021-04-01 |2 | -| autoplay.setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their autoplay setting to either block_cellular, block_audio, or block_all. |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)|
  • autoplay_setting: The new setting for autoplay: block_cellular, block_audio, or block_all.
|2021-02-01 |2 | -| autoplay.visited_setting |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user visited the autoplay settings screen |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)||2021-02-01 |2 | +| autoplay.setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their autoplay setting to either block_cellular, block_audio, or block_all. |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)|
  • autoplay_setting: The new setting for autoplay: block_cellular, block_audio, or block_all.
|2021-08-01 |2 | +| autoplay.visited_setting |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user visited the autoplay settings screen |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)||2021-08-01 |2 | | banner_open_in_app.dismissed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User tapped 'dismiss' on Open in App banner. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | | banner_open_in_app.displayed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Open in App banner was shown. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | | banner_open_in_app.go_to_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User tapped 'go to settings' on Open in App banner. |[1](https://github.com/mozilla-mobile/fenix/pull/17049)||2021-08-01 |2 | @@ -131,10 +131,10 @@ The following metrics are added to the ping: | history.removed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user removed a history item |[1](https://github.com/mozilla-mobile/fenix/pull/3940), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | history.removed_all |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user removed all history items |[1](https://github.com/mozilla-mobile/fenix/pull/3940), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | history.shared |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user shared a history item |[1](https://github.com/mozilla-mobile/fenix/pull/3940), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | -| login_dialog.cancelled |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt was cancelled |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-02-01 |2 | -| login_dialog.displayed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt was displayed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-02-01 |2 | -| login_dialog.never_save |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt "never save" button was pressed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-02-01 |2 | -| login_dialog.saved |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt "save" button was pressed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-02-01 |2 | +| login_dialog.cancelled |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt was cancelled |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-08-01 |2 | +| login_dialog.displayed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt was displayed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-08-01 |2 | +| login_dialog.never_save |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt "never save" button was pressed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-08-01 |2 | +| login_dialog.saved |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |The login dialog prompt "save" button was pressed |[1](https://github.com/mozilla-mobile/fenix/pull/13050)||2021-08-01 |2 | | logins.copy_login |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user copied a piece of a login in saved logins |[1](https://github.com/mozilla-mobile/fenix/pull/6352), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | logins.delete_saved_login |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user confirms delete of a saved login |[1](https://github.com/mozilla-mobile/fenix/issues/11208), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | logins.open_individual_login |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user accessed an individual login in saved logins |[1](https://github.com/mozilla-mobile/fenix/pull/6352), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | From 28c105dcb312254f015da3a2cc4f1e0f3df79c00 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Tue, 2 Feb 2021 17:36:09 +0100 Subject: [PATCH 049/248] Remove SessionManager dependency from CustomTabsIntegration. --- .../fenix/customtabs/CustomTabsIntegration.kt | 16 +++------------- .../customtabs/ExternalAppBrowserFragment.kt | 1 - 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt index 04e902d51..0d5a6fb0f 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabsIntegration.kt @@ -6,7 +6,6 @@ package org.mozilla.fenix.customtabs import android.app.Activity import androidx.appcompat.content.res.AppCompatResources.getDrawable -import mozilla.components.browser.session.SessionManager import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.browser.toolbar.display.DisplayToolbar @@ -19,7 +18,6 @@ import org.mozilla.fenix.components.toolbar.ToolbarMenu import org.mozilla.fenix.ext.settings class CustomTabsIntegration( - sessionManager: SessionManager, store: BrowserStore, useCases: CustomTabsUseCases, toolbar: BrowserToolbar, @@ -61,16 +59,6 @@ class CustomTabsIntegration( // If in private mode, override toolbar background to use private color // See #5334 if (isPrivate) { - sessionManager.findSessionById(sessionId)?.apply { - val config = customTabConfig - customTabConfig = config?.copy( - // Don't set toolbar background automatically - toolbarColor = null, - // Force tinting the action button - actionButtonConfig = config.actionButtonConfig?.copy(tint = true) - ) - } - toolbar.background = getDrawable(activity, R.drawable.toolbar_background) } } @@ -94,7 +82,9 @@ class CustomTabsIntegration( menuItemIndex = START_OF_MENU_ITEMS_INDEX, window = activity.window, shareListener = { onItemTapped.invoke(ToolbarMenu.Item.Share) }, - closeListener = { activity.finishAndRemoveTask() } + closeListener = { activity.finishAndRemoveTask() }, + updateToolbarBackground = !isPrivate, + forceActionButtonTinting = isPrivate ) override fun start() = feature.start() diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt index 016f220c0..c22e30482 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt @@ -61,7 +61,6 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler customTabsIntegration.set( feature = CustomTabsIntegration( - sessionManager = requireComponents.core.sessionManager, store = requireComponents.core.store, useCases = requireComponents.useCases.customTabsUseCases, toolbar = toolbar, From f4c0fe7643a3bef8ff8866cc10c63940544cd282 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 2 Feb 2021 20:23:58 +0000 Subject: [PATCH 050/248] Update Android Components version to 73.0.20210202194906. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 432fe7914..615dd3520 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210202143148" + const val VERSION = "73.0.20210202194906" } From 3dc638700f6f328a46caa92142aacdf4e73162d0 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 2 Feb 2021 16:14:34 -0500 Subject: [PATCH 051/248] Refactor tryReloadTabBy to use browser store --- .../settings/sitepermissions/Extensions.kt | 16 +++++-- .../sitepermissions/ExtensionsTest.kt | 45 +++++++++++++++++++ 2 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/components/settings/sitepermissions/ExtensionsTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/Extensions.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/Extensions.kt index 4c7daaed0..4f459f84e 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/Extensions.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/Extensions.kt @@ -13,12 +13,20 @@ import org.mozilla.fenix.components.Components import org.mozilla.fenix.settings.PhoneFeature /** - * Try to reload a session if a session with the given [origin] it is found. - * @param origin The origin the session to be reloaded. + * Reloads the last used tab matching the provided origin. For performance + * reasons we don't want to reload all matching tabs. Reloading the last used + * tab is a good compromise as it's likely the reason for a change in site + * permissions. + * + * @param origin The origin of the tab to reload. */ internal fun Components.tryReloadTabBy(origin: String) { - val session = core.sessionManager.all.find { it.url.toUri().host == origin } - useCases.sessionUseCases.reload(session) + core.store.state.tabs + .sortedByDescending { it.lastAccess } + .find { it.content.url.toUri().host == origin } + ?.let { + useCases.sessionUseCases.reload(it.id) + } } internal fun initBlockedByAndroidView(phoneFeature: PhoneFeature, blockedByAndroidView: View) { diff --git a/app/src/test/java/org/mozilla/fenix/components/settings/sitepermissions/ExtensionsTest.kt b/app/src/test/java/org/mozilla/fenix/components/settings/sitepermissions/ExtensionsTest.kt new file mode 100644 index 000000000..0c91f91d0 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/components/settings/sitepermissions/ExtensionsTest.kt @@ -0,0 +1,45 @@ +/* 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 org.mozilla.fenix.components.settings.sitepermissions + +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.createTab +import mozilla.components.browser.state.store.BrowserStore +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.components.Components +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.settings.sitepermissions.tryReloadTabBy + +@RunWith(FenixRobolectricTestRunner::class) +class ExtensionsTest { + + @Test + fun `tryReloadTabBy reloads latest tab matching origin`() { + val store = BrowserStore( + BrowserState(tabs = listOf( + createTab(id = "1", url = "https://www.mozilla.org/1", lastAccess = 1), + createTab(id = "2", url = "https://www.mozilla.org/2", lastAccess = 2), + createTab(id = "3", url = "https://www.firefox.com") + ) + ) + ) + + val components: Components = mockk(relaxed = true) + every { components.core.store } returns store + + components.tryReloadTabBy("www.getpocket.com") + verify(exactly = 0) { components.useCases.sessionUseCases.reload(any()) } + + components.tryReloadTabBy("www.mozilla.org") + verify { components.useCases.sessionUseCases.reload("2") } + + components.tryReloadTabBy("www.firefox.com") + verify { components.useCases.sessionUseCases.reload("3") } + } +} From dca0cb8c1061ca9b90161dd08a77d88d4c02bab9 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Wed, 3 Feb 2021 00:05:53 +0000 Subject: [PATCH 052/248] Import l10n. --- app/src/main/res/values-cs/strings.xml | 3 +-- app/src/main/res/values-hy-rAM/strings.xml | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 736a0b90e..530ab0a9c 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -1229,8 +1229,7 @@ Vaše soukromí - %s vám dává kontrolu nad tím, co sdílíte online a co sdílíte s námi. - + %s vám dává kontrolu nad tím, co sdílíte online a co sdílíte s námi. Přečíst zásady ochrany osobních údajů diff --git a/app/src/main/res/values-hy-rAM/strings.xml b/app/src/main/res/values-hy-rAM/strings.xml index bfb6ee09f..e955db150 100644 --- a/app/src/main/res/values-hy-rAM/strings.xml +++ b/app/src/main/res/values-hy-rAM/strings.xml @@ -1088,6 +1088,8 @@ Ազատում է պահեստային տարածք Կայքերի թույլտվություններ + + Ներբեռնումներ Ջնջել դիտարկման տվյալները @@ -1210,8 +1212,7 @@ - Մենք պատրաստել ենք %s-ը, որպեսզի Ձեզ տանք հսկողություն սահմանելը այն ամենի նկատմամբ, ինչ որ համօգտագործում եք - առցանց և մեզ հետ: + Մենք պատրաստել ենք %s-ը, որպեսզի դուք կառավարեք այն, ինչ համօգտագործում եք առցանց և թե ինչով եք կիսվում մեզ հետ: Կարդացեք մեր գաղտնիության ծանուցումը From e76445b299a56b56eaf0d66db5e93d4ba9efd8e6 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 2 Feb 2021 19:17:55 -0500 Subject: [PATCH 053/248] Refactor WebAppSiteControlsBuilder to use browser store --- .../fenix/customtabs/ExternalAppBrowserFragment.kt | 2 +- .../fenix/customtabs/WebAppSiteControlsBuilder.kt | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt index c22e30482..dd6eeda75 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/ExternalAppBrowserFragment.kt @@ -138,7 +138,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler customTabSessionId, manifest, WebAppSiteControlsBuilder( - requireComponents.core.sessionManager, + requireComponents.core.store, requireComponents.useCases.sessionUseCases.reload, customTabSessionId, manifest diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/WebAppSiteControlsBuilder.kt b/app/src/main/java/org/mozilla/fenix/customtabs/WebAppSiteControlsBuilder.kt index f592ea839..1244b7a11 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/WebAppSiteControlsBuilder.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/WebAppSiteControlsBuilder.kt @@ -7,15 +7,16 @@ package org.mozilla.fenix.customtabs import android.app.Notification import android.content.Context import android.content.Intent -import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.state.selector.findCustomTab import mozilla.components.browser.state.state.CustomTabSessionState +import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.manifest.WebAppManifest import mozilla.components.feature.pwa.feature.SiteControlsBuilder import mozilla.components.feature.session.SessionUseCases import org.mozilla.fenix.R class WebAppSiteControlsBuilder( - private val sessionManager: SessionManager, + private val store: BrowserStore, reloadUrlUseCase: SessionUseCases.ReloadUrlUseCase, private val sessionId: String, private val manifest: WebAppManifest @@ -26,9 +27,9 @@ class WebAppSiteControlsBuilder( override fun buildNotification(context: Context, builder: Notification.Builder) { inner.buildNotification(context, builder) - val isPrivateSession = sessionManager.findSessionById(sessionId)?.private ?: false - - if (!isPrivateSession) { return } + if (store.state.findCustomTab(sessionId)?.content?.private != true) { + return + } builder.setSmallIcon(R.drawable.ic_private_browsing) builder.setContentTitle(context.getString(R.string.pwa_site_controls_title_private, manifest.name)) From 542071a34407917ad787eafe78b48989defb84aa Mon Sep 17 00:00:00 2001 From: rxu Date: Tue, 2 Feb 2021 11:33:39 +0800 Subject: [PATCH 054/248] Add mozcn safebrowsing for release variant --- .../org/mozilla/fenix/engine/GeckoProvider.kt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt b/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt index ef75ce688..3c9cc3306 100644 --- a/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt +++ b/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt @@ -15,10 +15,15 @@ import org.mozilla.fenix.Config import org.mozilla.fenix.ext.components import org.mozilla.geckoview.GeckoRuntime import org.mozilla.geckoview.GeckoRuntimeSettings +import org.mozilla.geckoview.ContentBlocking.SafeBrowsingProvider object GeckoProvider { var testConfig: Bundle? = null private var runtime: GeckoRuntime? = null + const val CN_UPDATE_URL = + "https://sb.firefox.com.cn/downloads?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2" + const val CN_GET_HASH_URL = + "https://sb.firefox.com.cn/gethash?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2" @Synchronized fun getOrCreateRuntime( @@ -63,6 +68,28 @@ object GeckoProvider { runtimeSettings.fontSizeFactor = fontSize } + // Add safebrowsing providers for China + if (Config.channel.isMozillaOnline) { + val mozcn = SafeBrowsingProvider + .withName("mozcn") + .version("2.2") + .lists("m6eb-phish-shavar", "m6ib-phish-shavar") + .updateUrl(CN_UPDATE_URL) + .getHashUrl(CN_GET_HASH_URL) + .build() + + runtimeSettings.contentBlocking.setSafeBrowsingProviders(mozcn, + // Keep the existing configuration + ContentBlocking.GOOGLE_SAFE_BROWSING_PROVIDER, + ContentBlocking.GOOGLE_LEGACY_SAFE_BROWSING_PROVIDER) + + runtimeSettings.contentBlocking.setSafeBrowsingPhishingTable( + "m6eb-phish-shavar", + "m6ib-phish-shavar", + // Existing configuration + "goog-phish-proto") + } + val geckoRuntime = GeckoRuntime.create(context, runtimeSettings) val loginStorageDelegate = GeckoLoginStorageDelegate(storage) geckoRuntime.loginStorageDelegate = GeckoLoginDelegateWrapper(loginStorageDelegate) From d7ad20354434ac8d8ecd0a861586813ee90cda2a Mon Sep 17 00:00:00 2001 From: mcarare Date: Thu, 21 Jan 2021 14:51:29 +0200 Subject: [PATCH 055/248] For #17364: Do not show search suggestion hint before starting to type. --- .../java/org/mozilla/fenix/search/SearchDialogFragment.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index 394252af6..aa9db5b0b 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -487,7 +487,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { private fun updateSearchSuggestionsHintVisibility(state: SearchFragmentState) { view?.apply { - val showHint = state.showSearchSuggestionsHint && !state.showSearchShortcuts + val showHint = state.showSearchSuggestionsHint && + !state.showSearchShortcuts && + state.url != state.query + findViewById(R.id.search_suggestions_hint)?.isVisible = showHint search_suggestions_hint_divider?.isVisible = showHint } From 994ec4d55a5e16871eed1318b565424be5d13a58 Mon Sep 17 00:00:00 2001 From: mcarare Date: Thu, 21 Jan 2021 14:57:06 +0200 Subject: [PATCH 056/248] For #17364: Make hint scrollable and do not overlap other elements. --- .../fenix/search/SearchDialogFragment.kt | 7 + .../res/layout/fragment_search_dialog.xml | 62 +++---- .../res/layout/search_suggestions_hint.xml | 169 ++++++++++-------- 3 files changed, 130 insertions(+), 108 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt index aa9db5b0b..f1b5adcdb 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchDialogFragment.kt @@ -471,8 +471,15 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler { clear(pill_wrapper.id, BOTTOM) connect(pill_wrapper.id, BOTTOM, toolbar.id, TOP) + clear(awesome_bar.id, TOP) + clear(awesome_bar.id, BOTTOM) + connect(awesome_bar.id, TOP, search_suggestions_hint.id, BOTTOM) + connect(awesome_bar.id, BOTTOM, pill_wrapper.id, TOP) + clear(search_suggestions_hint.id, TOP) + clear(search_suggestions_hint.id, BOTTOM) connect(search_suggestions_hint.id, TOP, PARENT_ID, TOP) + connect(search_suggestions_hint.id, BOTTOM, search_hint_bottom_barrier.id, TOP) clear(fill_link_from_clipboard.id, TOP) connect(fill_link_from_clipboard.id, BOTTOM, pill_wrapper.id, TOP) diff --git a/app/src/main/res/layout/fragment_search_dialog.xml b/app/src/main/res/layout/fragment_search_dialog.xml index 14ff932e4..153723799 100644 --- a/app/src/main/res/layout/fragment_search_dialog.xml +++ b/app/src/main/res/layout/fragment_search_dialog.xml @@ -5,12 +5,12 @@ + android:background="?attr/scrimBackground"> - - - - + app:layout_constraintTop_toBottomOf="@id/toolbar" + app:layout_constraintHeight_default="wrap"/> + + + + - - - + android:layout_height="match_parent" + android:scrollbars="vertical" + android:fadeScrollbars="false" + app:layout_constraintBottom_toBottomOf="@id/search_divider" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/toolbar"> - + android:background="?attr/foundation" + android:paddingStart="20dp" + android:paddingTop="20dp" + android:paddingEnd="20dp" + android:paddingBottom="10dp"> - + - + - + + + + + - + - + + \ No newline at end of file From fedc2e1187862b79dbc06be1c4f864428e554e63 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 14 Jan 2021 11:20:34 -0500 Subject: [PATCH 057/248] Update bug numbers to URLs for activation ping Earlier versions of Glean supported bug numbers of the metadata, but this causes ambiguity, particularly for Fenix where issues exist in both Bugzilla and Github. This just updates the Bugzilla numbers to full URLs. We made the use of numbers an error sometime ago, but neglected to enforce this on "pings" in addition to "metrics". A future version of `glean_parser` [1] will make this an error and this will set Fenix up to be ready for that. [1] https://github.com/mozilla/glean_parser/pull/262 --- app/pings.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pings.yaml b/app/pings.yaml index ae1474c71..771cde2b7 100644 --- a/app/pings.yaml +++ b/app/pings.yaml @@ -12,8 +12,8 @@ activation: an hashed version of the Google Advertising ID. include_client_id: false bugs: - - 1538011 - - 1501822 + - https://bugzilla.mozilla.com/1538011/ + - https://bugzilla.mozilla.com/1501822/ data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1707#issuecomment-486972209 notification_emails: From 40fc9c108531add956f925550073f82bb0a49e47 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Fri, 15 Jan 2021 17:33:47 +0200 Subject: [PATCH 058/248] For #12414 - Support sharing images through ShareDownloadFeature Register a ViewBoundFeatureWrapper that will respond to "Share image" from the browser contextual menu --- .../mozilla/fenix/browser/BaseBrowserFragment.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 7aa83991e..392dc5458 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -58,6 +58,7 @@ import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.contextmenu.ContextMenuFeature import mozilla.components.feature.downloads.DownloadsFeature import mozilla.components.feature.downloads.manager.FetchDownloadManager +import mozilla.components.feature.downloads.share.ShareDownloadFeature import mozilla.components.feature.intent.ext.EXTRA_SESSION_ID import mozilla.components.feature.media.fullscreen.MediaSessionFullscreenFeature import mozilla.components.feature.privatemode.feature.SecureWindowFeature @@ -161,6 +162,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit private val sessionFeature = ViewBoundFeatureWrapper() private val contextMenuFeature = ViewBoundFeatureWrapper() private val downloadsFeature = ViewBoundFeatureWrapper() + private val shareDownloadsFeature = ViewBoundFeatureWrapper() private val appLinksFeature = ViewBoundFeatureWrapper() private val promptsFeature = ViewBoundFeatureWrapper() private val findInPageIntegration = ViewBoundFeatureWrapper() @@ -429,6 +431,13 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit ) } + val shareDownloadFeature = ShareDownloadFeature( + context = context.applicationContext, + httpClient = context.components.core.client, + store = store, + tabId = customTabSessionId + ) + val downloadFeature = DownloadsFeature( context.applicationContext, store = store, @@ -508,6 +517,12 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit store, view, context, toolbarHeight ) + shareDownloadsFeature.set( + shareDownloadFeature, + owner = this, + view = view + ) + downloadsFeature.set( downloadFeature, owner = this, From ebca575e261f7eeb84c984617c18af909e419e33 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Tue, 2 Feb 2021 13:24:30 -0800 Subject: [PATCH 059/248] Reuse helper functions in bookmark tests --- .../org/mozilla/fenix/ext/BookmarkNode.kt | 2 +- .../org/mozilla/fenix/ext/BookmarkNodeTest.kt | 35 +++--- .../fenix/library/bookmarks/UtilsKtTest.kt | 102 +++++------------- 3 files changed, 41 insertions(+), 98 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/ext/BookmarkNode.kt b/app/src/main/java/org/mozilla/fenix/ext/BookmarkNode.kt index 2152f3fb8..1d6f5388f 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/BookmarkNode.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/BookmarkNode.kt @@ -15,6 +15,6 @@ val Context.bookmarkStorage: PlacesBookmarksStorage * Removes [children] from [BookmarkNode.children] and returns the new modified [BookmarkNode]. */ operator fun BookmarkNode.minus(children: Set): BookmarkNode { - val removedChildrenGuids = children.map { it.guid }.toSet() + val removedChildrenGuids = children.map { it.guid } return this.copy(children = this.children?.filterNot { removedChildrenGuids.contains(it.guid) }) } diff --git a/app/src/test/java/org/mozilla/fenix/ext/BookmarkNodeTest.kt b/app/src/test/java/org/mozilla/fenix/ext/BookmarkNodeTest.kt index 5f291061a..0f15ea076 100644 --- a/app/src/test/java/org/mozilla/fenix/ext/BookmarkNodeTest.kt +++ b/app/src/test/java/org/mozilla/fenix/ext/BookmarkNodeTest.kt @@ -5,22 +5,21 @@ package org.mozilla.fenix.ext import mozilla.components.concept.storage.BookmarkNode -import mozilla.components.concept.storage.BookmarkNodeType import org.junit.Assert.assertEquals import org.junit.Test +import org.mozilla.fenix.library.bookmarks.testBookmarkItem +import org.mozilla.fenix.library.bookmarks.testFolder class BookmarkNodeTest { - private val bookmarkChild1 = newBookmarkNode("Child 1", 1, null) - private val bookmarkChild2 = newBookmarkNode("Child 2", 2, null) - private val bookmarkChild3 = newBookmarkNode("Child 3", 3, null) + private val bookmarkChild1 = testBookmarkItem("someFolder", "http://www.mockurl.com/1", "Child 1") + private val bookmarkChild2 = testBookmarkItem("someFolder", "http://www.mockurl.com/2", "Child 2") + private val bookmarkChild3 = testBookmarkItem("someFolder", "http://www.mockurl.com/3", "Child 3") private val allChildren = listOf(bookmarkChild1, bookmarkChild2) - private var uniqueId = 0 - @Test fun `GIVEN a bookmark node with children WHEN minusing a sub set of children THEN the children subset is removed and rest remains`() { - val bookmarkNode = newBookmarkNode("Parent 1", 0, allChildren) + val bookmarkNode = testFolder("parent1", "root", allChildren) val subsetToSubtract = setOf(bookmarkChild1) val expectedRemainingSubset = listOf(bookmarkChild2) val bookmarkNodeSubsetRemoved = bookmarkNode.minus(subsetToSubtract) @@ -29,7 +28,7 @@ class BookmarkNodeTest { @Test fun `GIVEN a bookmark node with children WHEN minusing a set of all children THEN all children are removed and empty list remains`() { - val bookmarkNode = newBookmarkNode("Parent 1", 0, allChildren) + val bookmarkNode = testFolder("parent1", "root", allChildren) val setofAllChildren = setOf(bookmarkChild1, bookmarkChild2) val bookmarkNodeAllChildrenRemoved = bookmarkNode.minus(setofAllChildren) assertEquals(emptyList(), bookmarkNodeAllChildrenRemoved.children) @@ -38,21 +37,21 @@ class BookmarkNodeTest { @Test fun `GIVEN a bookmark node with children WHEN minusing a set of non-children THEN no children are removed`() { val setofNonChildren = setOf(bookmarkChild3) - val bookmarkNode = newBookmarkNode("Parent 1", 0, allChildren) + val bookmarkNode = testFolder("parent1", "root", allChildren) val bookmarkNodeNonChildrenRemoved = bookmarkNode.minus(setofNonChildren) assertEquals(allChildren, bookmarkNodeNonChildrenRemoved.children) } @Test fun `GIVEN a bookmark node with children WHEN minusing an empty set THEN no children are removed`() { - val bookmarkNode = newBookmarkNode("Parent 1", 0, allChildren) + val bookmarkNode = testFolder("parent1", "root", allChildren) val bookmarkNodeEmptySetRemoved = bookmarkNode.minus(emptySet()) assertEquals(allChildren, bookmarkNodeEmptySetRemoved.children) } @Test fun `GIVEN a bookmark node with an empty list as children WHEN minusing a set of non-children from an empty parent THEN an empty list remains`() { - val parentWithEmptyList = newBookmarkNode("Parent 1", 0, emptyList()) + val parentWithEmptyList = testFolder("parent1", "root", emptyList()) val setofAllChildren = setOf(bookmarkChild1, bookmarkChild2) val parentWithEmptyListNonChildRemoved = parentWithEmptyList.minus(setofAllChildren) assertEquals(emptyList(), parentWithEmptyListNonChildRemoved.children) @@ -60,14 +59,14 @@ class BookmarkNodeTest { @Test fun `GIVEN a bookmark node with null as children WHEN minusing a set of non-children from a parent with null children THEN null remains`() { - val parentWithNullList = newBookmarkNode("Parent 1", 0, null) + val parentWithNullList = testFolder("parent1", "root", null) val parentWithNullListNonChildRemoved = parentWithNullList.minus(allChildren.toSet()) assertEquals(null, parentWithNullListNonChildRemoved.children) } @Test fun `GIVEN a bookmark node with children WHEN minusing a sub-set of children THEN the rest of the parents object should remain the same`() { - val bookmarkNode = newBookmarkNode("Parent 1", 0, allChildren) + val bookmarkNode = testFolder("parent1", "root", allChildren) val subsetToSubtract = setOf(bookmarkChild1) val expectedRemainingSubset = listOf(bookmarkChild2) val resultBookmarkNode = bookmarkNode.minus(subsetToSubtract) @@ -77,14 +76,4 @@ class BookmarkNodeTest { val restofOriginal = bookmarkNode.copy(children = expectedRemainingSubset) assertEquals(restOfResult, restofOriginal) } - - private fun newBookmarkNode(title: String, position: Int, children: List?) = BookmarkNode( - type = BookmarkNodeType.ITEM, - guid = uniqueId++.toString(), - parentGuid = "12", - position = position, - title = title, - url = "www.mockurl.com", - children = children - ) } diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt index 42f185f32..df0a2ec14 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt @@ -16,26 +16,10 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner class UtilsKtTest { @Test fun `friendly root titles`() { - val url = BookmarkNode( - BookmarkNodeType.ITEM, - "456", - "folder", - 0, - "Mozilla", - "http://mozilla.org", - null - ) + val url = testBookmarkItem("folder","http://mozilla.org", "Mozilla") assertEquals("Mozilla", friendlyRootTitle(testContext, url)) - val folder = BookmarkNode( - BookmarkNodeType.FOLDER, - "456", - "folder", - 0, - "Folder", - null, - null - ) + val folder = testFolder("456", "folder", null, "Folder") assertEquals("Folder", friendlyRootTitle(testContext, folder)) val root = folder.copy(guid = "root________", title = "root") @@ -65,67 +49,17 @@ class UtilsKtTest { @Test fun `flatNodeList various cases`() { - val url = BookmarkNode( - BookmarkNodeType.ITEM, - "456", - "folder", - 0, - "Mozilla", - "http://mozilla.org", - null - ) - val url2 = BookmarkNode( - BookmarkNodeType.ITEM, - "8674", - "folder2", - 0, - "Mozilla", - "http://mozilla.org", - null - ) + val url = testBookmarkItem("folder", "http://mozilla.org") + val url2 = testBookmarkItem( "folder2", "http://mozilla.org") assertEquals(emptyList(), url.flatNodeList(null)) - val root = BookmarkNode( - BookmarkNodeType.FOLDER, - "root", - null, - 0, - "root", - null, - null - ) + val root = testFolder("root", null, null) assertEquals(listOf(BookmarkNodeWithDepth(0, root, null)), root.flatNodeList(null)) assertEquals(emptyList(), root.flatNodeList("root")) - val folder = BookmarkNode( - BookmarkNodeType.FOLDER, - "folder", - root.guid, - 0, - "folder", - null, - listOf(url) - ) - - val folder3 = BookmarkNode( - BookmarkNodeType.FOLDER, - "folder3", - "folder2", - 0, - "folder3", - null, - null - ) - - val folder2 = BookmarkNode( - BookmarkNodeType.FOLDER, - "folder2", - root.guid, - 0, - "folder2", - null, - listOf(folder3, url2) - ) + val folder = testFolder("folder", root.guid, listOf(url)) + val folder3 = testFolder("folder3", "folder2", null) + val folder2 = testFolder("folder2", root.guid, listOf(folder3, url2)) val rootWithChildren = root.copy(children = listOf(folder, folder2)) assertEquals( @@ -145,3 +79,23 @@ class UtilsKtTest { ) } } + +internal fun testBookmarkItem(parentGuid: String, url: String, title: String = "Item for $url") = BookmarkNode( + BookmarkNodeType.ITEM, + "guid#${Math.random() * 1000}", + parentGuid, + 0, + title, + url, + null +) + +internal fun testFolder(guid: String, parentGuid: String?, children: List?, title: String = "Folder: $guid") = BookmarkNode( + BookmarkNodeType.FOLDER, + guid, + parentGuid, + 0, + title, + null, + children +) From 3ce9bf93bc4118f262b501f4c0c0cd1674802468 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Tue, 2 Feb 2021 16:22:20 -0800 Subject: [PATCH 060/248] Exclude separators from the bookmarks UI --- .../library/bookmarks/BookmarkAdapter.kt | 16 ++-- .../library/bookmarks/BookmarkAdapterTest.kt | 96 +++++++++++++------ .../fenix/library/bookmarks/UtilsKtTest.kt | 8 +- 3 files changed, 84 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt index f6f6a368d..e85ded68a 100644 --- a/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapter.kt @@ -21,23 +21,25 @@ import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkSeparatorViewHold class BookmarkAdapter(private val emptyView: View, private val interactor: BookmarkViewInteractor) : RecyclerView.Adapter() { - private var tree: List = listOf() + @VisibleForTesting var tree: List = listOf() private var mode: BookmarkFragmentState.Mode = BookmarkFragmentState.Mode.Normal() private var isFirstRun = true fun updateData(tree: BookmarkNode?, mode: BookmarkFragmentState.Mode) { - // Display folders above all other bookmarks. val allNodes = tree?.children.orEmpty() val folders: MutableList = mutableListOf() val notFolders: MutableList = mutableListOf() + val separators: MutableList = mutableListOf() allNodes.forEach { - if (it.type == BookmarkNodeType.FOLDER) { - folders.add(it) - } else { - notFolders.add(it) + when (it.type) { + BookmarkNodeType.SEPARATOR -> separators.add(it) + BookmarkNodeType.FOLDER -> folders.add(it) + else -> notFolders.add(it) } } - val newTree = folders + notFolders + // Display folders above all other bookmarks. Exclude separators. + // For separator removal, see discussion in https://github.com/mozilla-mobile/fenix/issues/15214 + val newTree = folders + notFolders - separators val diffUtil = DiffUtil.calculateDiff( BookmarkDiffUtil( diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapterTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapterTest.kt index b80e584a7..bc04b618b 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapterTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/BookmarkAdapterTest.kt @@ -8,29 +8,20 @@ import io.mockk.mockk import io.mockk.spyk import io.mockk.verifyOrder import mozilla.components.concept.storage.BookmarkNode -import mozilla.components.concept.storage.BookmarkNodeType -import org.junit.Assert.assertFalse +import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue +import org.junit.Assert.assertFalse import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkNodeViewHolder @RunWith(FenixRobolectricTestRunner::class) internal class BookmarkAdapterTest { private lateinit var bookmarkAdapter: BookmarkAdapter - private val item = BookmarkNode( - BookmarkNodeType.ITEM, - "456", - "123", - 0, - "Mozilla", - "http://mozilla.org", - null - ) - @Before fun setup() { bookmarkAdapter = spyk( @@ -40,33 +31,83 @@ internal class BookmarkAdapterTest { @Test fun `update adapter from tree of bookmark nodes, null tree returns empty list`() { - val tree = BookmarkNode( - BookmarkNodeType.FOLDER, "123", null, 0, "Mobile", null, listOf( - item, - BookmarkNode(BookmarkNodeType.SEPARATOR, "789", "123", 1, null, null, null), - BookmarkNode( - BookmarkNodeType.ITEM, - "987", - "123", - 2, - "Firefox", - "https://www.mozilla.org/en-US/firefox/", - null - ) + val tree = testFolder("123", "root", listOf( + testBookmarkItem("someFolder", "http://mozilla.org"), + testSeparator("123"), + testBookmarkItem("123", "https://www.mozilla.org/en-US/firefox/") ) ) bookmarkAdapter.updateData(tree, BookmarkFragmentState.Mode.Normal()) bookmarkAdapter.updateData(null, BookmarkFragmentState.Mode.Normal()) verifyOrder { bookmarkAdapter.updateData(tree, BookmarkFragmentState.Mode.Normal()) - bookmarkAdapter.notifyItemRangeInserted(0, 3) + bookmarkAdapter.notifyItemRangeInserted(0, 2) bookmarkAdapter.updateData(null, BookmarkFragmentState.Mode.Normal()) - bookmarkAdapter.notifyItemRangeRemoved(0, 3) + bookmarkAdapter.notifyItemRangeRemoved(0, 2) } } + @Test + fun `update adapter from tree of bookmark nodes, separators are excluded`() { + val sep1 = testSeparator("123") + val sep2 = testSeparator("123") + val item1 = testBookmarkItem("123", "http://mozilla.org") + val item2 = testBookmarkItem("123", "https://www.mozilla.org/en-US/firefox/") + val folder = testFolder("123", "root", title = "Mobile", children = listOf(item1, sep1, item2, sep2)) + bookmarkAdapter.updateData(folder, BookmarkFragmentState.Mode.Normal()) + verifyOrder { + bookmarkAdapter.updateData(folder, BookmarkFragmentState.Mode.Normal()) + bookmarkAdapter.notifyItemRangeInserted(0, 2) + } + + assertEquals(2, bookmarkAdapter.itemCount) + assertEquals(listOf(item1, item2), bookmarkAdapter.tree) + } + + @Test + fun `update adapter from tree of bookmark nodes, folders are moved to the top`() { + val sep1 = testSeparator("123") + val item1 = testBookmarkItem("123", "http://mozilla.org") + val item2 = testBookmarkItem("123", "https://www.mozilla.org/en-US/firefox/") + val item3 = testBookmarkItem("123", "https://www.mozilla.org/en-US/firefox/2") + val item4 = testBookmarkItem("125", "https://www.mozilla.org/en-US/firefox/3") + val folder2 = testFolder("124", "123", title = "Mobile 2", children = emptyList()) + val folder3 = testFolder("125", "123", title = "Mobile 3", children = listOf(item4)) + val folder4 = testFolder("126", "123", title = "Mobile 3", children = emptyList()) + val folder = testFolder("123", "root", title = "Mobile", children = listOf( + folder4, item1, sep1, item2, folder2, folder3, item3 + )) + bookmarkAdapter.updateData(folder, BookmarkFragmentState.Mode.Normal()) + verifyOrder { + bookmarkAdapter.updateData(folder, BookmarkFragmentState.Mode.Normal()) + bookmarkAdapter.notifyItemRangeInserted(0, 6) + } + + assertEquals(6, bookmarkAdapter.itemCount) + assertEquals(listOf(folder4, folder2, folder3, item1, item2, item3), bookmarkAdapter.tree) + } + + @Test + fun `get item view type for different types of nodes`() { + val sep1 = testSeparator("123") + val item1 = testBookmarkItem("123", "https://www.mozilla.org/en-US/firefox/") + val folder1 = testFolder("124", "123", title = "Mobile 2", children = emptyList()) + bookmarkAdapter.updateData( + testFolder("123", "root", listOf(sep1, item1, folder1)), + BookmarkFragmentState.Mode.Normal() + ) + + assertEquals(2, bookmarkAdapter.itemCount) + // item1 + assertEquals(BookmarkNodeViewHolder.LAYOUT_ID, bookmarkAdapter.getItemViewType(0)) + // folder1 + assertEquals(BookmarkNodeViewHolder.LAYOUT_ID, bookmarkAdapter.getItemViewType(1)) + // sep is dropped during update + } + @Test fun `items are the same if they have the same guids`() { + val item = testBookmarkItem("someFolder", "http://mozilla.org") assertTrue(createSingleItemDiffUtil(item, item).areItemsTheSame(0, 0)) assertTrue( createSingleItemDiffUtil( @@ -84,6 +125,7 @@ internal class BookmarkAdapterTest { @Test fun `equal items have same contents unless their selected state changes`() { + val item = testBookmarkItem("someFolder", "http://mozilla.org") assertTrue(createSingleItemDiffUtil(item, item).areContentsTheSame(0, 0)) assertFalse( createSingleItemDiffUtil(item, item.copy(position = 1)).areContentsTheSame(0, 0) diff --git a/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt b/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt index df0a2ec14..3ea5539dc 100644 --- a/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/bookmarks/UtilsKtTest.kt @@ -16,7 +16,7 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner class UtilsKtTest { @Test fun `friendly root titles`() { - val url = testBookmarkItem("folder","http://mozilla.org", "Mozilla") + val url = testBookmarkItem("folder", "http://mozilla.org", "Mozilla") assertEquals("Mozilla", friendlyRootTitle(testContext, url)) val folder = testFolder("456", "folder", null, "Folder") @@ -50,7 +50,7 @@ class UtilsKtTest { @Test fun `flatNodeList various cases`() { val url = testBookmarkItem("folder", "http://mozilla.org") - val url2 = testBookmarkItem( "folder2", "http://mozilla.org") + val url2 = testBookmarkItem("folder2", "http://mozilla.org") assertEquals(emptyList(), url.flatNodeList(null)) val root = testFolder("root", null, null) @@ -99,3 +99,7 @@ internal fun testFolder(guid: String, parentGuid: String?, children: List Date: Wed, 3 Feb 2021 11:31:01 +0100 Subject: [PATCH 061/248] Remove TabsUseCases methods that take a Session object. --- .../java/org/mozilla/fenix/engine/GeckoProvider.kt | 1 + .../mozilla/fenix/browser/BaseBrowserFragment.kt | 2 +- .../fenix/search/awesomebar/AwesomeBarView.kt | 5 ----- .../mozilla/fenix/tabtray/TabTrayDialogFragment.kt | 13 ------------- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 5 files changed, 3 insertions(+), 20 deletions(-) diff --git a/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt b/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt index 3c9cc3306..16ad137f4 100644 --- a/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt +++ b/app/src/geckoRelease/java/org/mozilla/fenix/engine/GeckoProvider.kt @@ -13,6 +13,7 @@ import mozilla.components.lib.crash.handler.CrashHandlerService import mozilla.components.service.sync.logins.GeckoLoginStorageDelegate import org.mozilla.fenix.Config import org.mozilla.fenix.ext.components +import org.mozilla.geckoview.ContentBlocking import org.mozilla.geckoview.GeckoRuntime import org.mozilla.geckoview.GeckoRuntimeSettings import org.mozilla.geckoview.ContentBlocking.SafeBrowsingProvider diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 392dc5458..817a5ba2b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -1070,7 +1070,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit getSessionById()?.let { session -> return if (session.source == SessionState.Source.ACTION_VIEW) { activity?.finish() - requireComponents.useCases.tabsUseCases.removeTab(session) + requireComponents.useCases.tabsUseCases.removeTab(session.id) true } else { if (session.hasParentSession) { diff --git a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt index 2df4afa1d..cd9fa8c8b 100644 --- a/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt +++ b/app/src/main/java/org/mozilla/fenix/search/awesomebar/AwesomeBarView.kt @@ -10,7 +10,6 @@ import androidx.core.graphics.BlendModeCompat.SRC_IN import androidx.core.graphics.drawable.toBitmap import mozilla.components.browser.awesomebar.BrowserAwesomeBar import mozilla.components.browser.search.DefaultSearchEngineProvider -import mozilla.components.browser.session.Session import mozilla.components.browser.state.search.SearchEngine import mozilla.components.concept.awesomebar.AwesomeBar import mozilla.components.concept.engine.EngineSession @@ -86,10 +85,6 @@ class AwesomeBarView( } private val selectTabUseCase = object : TabsUseCases.SelectTabUseCase { - override fun invoke(session: Session) { - interactor.onExistingSessionSelected(session.id) - } - override fun invoke(tabId: String) { interactor.onExistingSessionSelected(tabId) } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index fbf222d8a..a06f4a08a 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -32,7 +32,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import kotlinx.coroutines.plus import mozilla.appservices.places.BookmarkRoot -import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.selector.getNormalOrPrivateTabs import mozilla.components.browser.state.selector.normalTabs @@ -105,12 +104,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler requireComponents.useCases.tabsUseCases.selectTab(tabId) navigateToBrowser() } - - override fun invoke(session: Session) { - requireContext().components.analytics.metrics.track(Event.OpenedExistingTab) - requireComponents.useCases.tabsUseCases.selectTab(session) - navigateToBrowser() - } } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -127,12 +120,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler showUndoSnackbarForTab(sessionId) removeIfNotLastTab(sessionId) } - - override fun invoke(session: Session) { - requireContext().components.analytics.metrics.track(Event.ClosedExistingTab) - showUndoSnackbarForTab(session.id) - removeIfNotLastTab(session.id) - } } private fun removeIfNotLastTab(sessionId: String) { diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 615dd3520..f0cdce4dc 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210202194906" + const val VERSION = "73.0.20210203143122" } From c488bb0e110450297495d931dbd9eab6e51afcec Mon Sep 17 00:00:00 2001 From: hwinnemo Date: Mon, 1 Feb 2021 21:10:58 +0100 Subject: [PATCH 062/248] For #17724: Wait for tab to be fully created before showing ETP Onboarding if ETP is active --- .../TrackingProtectionOverlay.kt | 14 +++++++++----- .../TrackingProtectionOverlayTest.kt | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt index 6e098fa12..167c78d18 100644 --- a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlay.kt @@ -62,9 +62,9 @@ class TrackingProtectionOverlay( }.ifChanged { tab -> tab.content.loading } - .collect { tab -> - onLoadingStateChanged(tab) - } + .collect { tab -> + onLoadingStateChanged(tab) + } } } @@ -77,7 +77,10 @@ class TrackingProtectionOverlay( @VisibleForTesting internal fun onLoadingStateChanged(tab: SessionState) { - if (!tab.content.loading && shouldShowTrackingProtectionOnboarding(tab)) { + if (shouldShowTrackingProtectionOnboarding(tab) && + tab.content.progress == FULL_PROGRESS && + settings.shouldUseTrackingProtection + ) { showTrackingProtectionOnboarding() } } @@ -85,7 +88,7 @@ class TrackingProtectionOverlay( private fun shouldShowTrackingProtectionOnboarding(tab: SessionState) = tab.trackingProtection.enabled && tab.trackingProtection.blockedTrackers.isNotEmpty() && - settings.shouldShowTrackingProtectionCfr + settings.shouldShowTrackingProtectionCfr @Suppress("MagicNumber", "InflateParams") private fun showTrackingProtectionOnboarding() { @@ -184,6 +187,7 @@ class TrackingProtectionOverlay( } private companion object { + private const val FULL_PROGRESS = 100 private const val BUTTON_INCREASE_DPS = 12 } } diff --git a/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlayTest.kt b/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlayTest.kt index 59f5753c7..98da76499 100644 --- a/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlayTest.kt +++ b/app/src/test/java/org/mozilla/fenix/trackingprotection/TrackingProtectionOverlayTest.kt @@ -156,7 +156,9 @@ class TrackingProtectionOverlayTest { fun `show onboarding when trackers are blocked`() { every { toolbar.hasWindowFocus() } returns true every { settings.shouldShowTrackingProtectionCfr } returns true + every { session.content.progress } returns 100 every { session.content.loading } returns false + every { settings.shouldUseTrackingProtection } returns true every { session.trackingProtection } returns TrackingProtectionState( enabled = true, blockedTrackers = listOf(mockk()) @@ -165,6 +167,20 @@ class TrackingProtectionOverlayTest { verify { settings.incrementTrackingProtectionOnboardingCount() } } + @Test + fun `no-op when trackers are blocked but not finished loading`() { + every { toolbar.hasWindowFocus() } returns true + every { settings.shouldShowTrackingProtectionCfr } returns true + every { session.content.progress } returns 50 + every { session.content.loading } returns false + every { session.trackingProtection } returns TrackingProtectionState( + enabled = true, + blockedTrackers = listOf(mockk()) + ) + overlay.onLoadingStateChanged(session) + verify(exactly = 0) { settings.incrementTrackingProtectionOnboardingCount() } + } + @Test fun `no-op when toolbar doesn't have focus`() { every { toolbar.hasWindowFocus() } returns false From a4a2a59b7d5049d973d508718383ea99e8a56d7d Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Wed, 3 Feb 2021 12:20:59 +0200 Subject: [PATCH 063/248] For #12895 Fix Intermittent test navigateBookmarksFoldersTest --- .../java/org/mozilla/fenix/ui/BookmarksTest.kt | 4 ++++ .../org/mozilla/fenix/ui/robots/BookmarksRobot.kt | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt index dcf5a6c4f..3b50a489f 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/BookmarksTest.kt @@ -494,12 +494,16 @@ class BookmarksTest { }.openBookmarks { createFolder("1") getInstrumentation().waitForIdleSync() + waitForBookmarksFolderContentToExist("Bookmarks", "1") selectFolder("1") + verifyCurrentFolderTitle("1") createFolder("2") getInstrumentation().waitForIdleSync() + waitForBookmarksFolderContentToExist("1", "2") selectFolder("2") verifyCurrentFolderTitle("2") navigateUp() + waitForBookmarksFolderContentToExist("1", "2") verifyCurrentFolderTitle("1") mDevice.pressBack() verifyBookmarksMenuView() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt index 8eddc0384..3f15b840e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/BookmarksRobot.kt @@ -105,6 +105,10 @@ class BookmarksRobot { fun verifySelectDefaultFolderSnackBarText() = assertSnackBarText("Can’t edit default folders") fun verifyCurrentFolderTitle(title: String) { + mDevice.findObject(UiSelector().resourceId("$packageName:id/navigationToolbar") + .textContains(title)) + .waitForExists(waitingTime) + onView( allOf( withText(title), @@ -114,6 +118,14 @@ class BookmarksRobot { .check(matches(isDisplayed())) } + fun waitForBookmarksFolderContentToExist(parentFolderName: String, childFolderName: String) { + mDevice.findObject(UiSelector().resourceId("$packageName:id/navigationToolbar") + .textContains(parentFolderName)) + .waitForExists(waitingTime) + + mDevice.waitNotNull(Until.findObject(By.text(childFolderName)), waitingTime) + } + fun verifySignInToSyncButton() = signInToSyncButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) From 9783930ac543347df12749f10c95aa7a2e310609 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Wed, 3 Feb 2021 17:32:45 +0200 Subject: [PATCH 064/248] For #16615: UI smoke test customTrackingProtectionSettingsTest --- .../assets/pages/trackingPage.html | 66 +++++++++++++++++++ .../java/org/mozilla/fenix/ui/SmokeTest.kt | 31 ++++++++- .../StrictEnhancedTrackingProtectionTest.kt | 4 +- .../robots/EnhancedTrackingProtectionRobot.kt | 57 ++++++++++++++++ ...sSubMenuEnhancedTrackingProtectionRobot.kt | 39 +++++++++-- 5 files changed, 189 insertions(+), 8 deletions(-) diff --git a/app/src/androidTest/assets/pages/trackingPage.html b/app/src/androidTest/assets/pages/trackingPage.html index 1a0d735a6..a0a53c954 100644 --- a/app/src/androidTest/assets/pages/trackingPage.html +++ b/app/src/androidTest/assets/pages/trackingPage.html @@ -9,5 +9,71 @@ + +

Level 1 (Basic) List

+

social-track-digest256:

+ +
+

ads-track-digest256:

+ +
+

analytics-track-digest256:

+ +
+

Fingerprinting: +

test not run
+ +

+
+

Cryptomining: + not blocked +

+ +

Cookie blocking +

+ + + +

+ * Facebook-cookies


+    * LinkedIn-cookies 

+    * Twitter-cookies 

+    

+ + diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 10b38c0ad..20f34e422 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -28,6 +28,7 @@ import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.clickTabCrashedRestoreButton import org.mozilla.fenix.ui.robots.clickUrlbar +import org.mozilla.fenix.ui.robots.dismissTrackingOnboarding import org.mozilla.fenix.ui.robots.downloadRobot import org.mozilla.fenix.ui.robots.enhancedTrackingProtection import org.mozilla.fenix.ui.robots.homeScreen @@ -372,7 +373,7 @@ class SmokeTest { }.openThreeDotMenu { }.openSettings { }.openEnhancedTrackingProtectionSubMenu { - clickEnhancedTrackingProtectionDefaults() + switchEnhancedTrackingProtectionToggle() verifyEnhancedTrackingProtectionOptionsGrayedOut() }.goBackToHomeScreen { navigationToolbar { @@ -381,7 +382,7 @@ class SmokeTest { }.openThreeDotMenu { }.openSettings { }.openEnhancedTrackingProtectionSubMenu { - clickEnhancedTrackingProtectionDefaults() + switchEnhancedTrackingProtectionToggle() }.goBack { }.goBackToBrowser { clickEnhancedTrackingProtectionPanel() @@ -391,6 +392,32 @@ class SmokeTest { } } + @Test + fun customTrackingProtectionSettingsTest() { + val trackingPage = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer) + + homeScreen { + }.openThreeDotMenu { + }.openSettings { + }.openEnhancedTrackingProtectionSubMenu { + verifyEnhancedTrackingProtectionOptions() + selectTrackingProtectionOption("Custom") + verifyCustomTrackingProtectionSettings() + }.goBackToHomeScreen {} + + navigationToolbar { + }.enterURLAndEnterToBrowser(trackingPage.url) {} + + enhancedTrackingProtection { + dismissTrackingOnboarding() + }.openEnhancedTrackingProtectionSheet { + verifyTrackingCookiesBlocked() + verifyCryptominersBlocked() + verifyFingerprintersBlocked() + verifyBasicLevelTrackingContentBlocked() + } + } + @Test // Verifies changing the default engine from the Search Shortcut menu fun verifySearchEngineCanBeChangedTemporarilyUsingShortcuts() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt index 659f7547e..2107f9d10 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt @@ -70,7 +70,7 @@ class StrictEnhancedTrackingProtectionTest { }.openEnhancedTrackingProtectionSubMenu { verifyEnhancedTrackingProtectionHeader() verifyEnhancedTrackingProtectionOptions() - verifyEnhancedTrackingProtectionDefaults() + verifyTrackingProtectionSwitchEnabled() }.openExceptions { verifyDefault() } @@ -177,7 +177,7 @@ class StrictEnhancedTrackingProtectionTest { }.openProtectionSettings { verifyEnhancedTrackingProtectionHeader() verifyEnhancedTrackingProtectionOptions() - verifyEnhancedTrackingProtectionDefaults() + verifyTrackingProtectionSwitchEnabled() } settingsSubMenuEnhancedTrackingProtection { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt index aa6adc18a..5fb906ad7 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/EnhancedTrackingProtectionRobot.kt @@ -8,13 +8,20 @@ package org.mozilla.fenix.ui.robots import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until +import org.hamcrest.Matchers.containsString import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper +import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull @@ -37,6 +44,14 @@ class EnhancedTrackingProtectionRobot { fun verifyEnhancedTrackingProtectionDetailsStatus(status: String) = assertEnhancedTrackingProtectionDetailsStatus(status) + fun verifyTrackingCookiesBlocked() = assertTrackingCookiesBlocked() + + fun verifyFingerprintersBlocked() = assertFingerprintersBlocked() + + fun verifyCryptominersBlocked() = assertCryptominersBlocked() + + fun verifyBasicLevelTrackingContentBlocked() = assertBasicLevelTrackingContentBlocked() + class Transition { fun openEnhancedTrackingProtectionSheet(interact: EnhancedTrackingProtectionRobot.() -> Unit): Transition { openEnhancedTrackingProtectionSheet().click() @@ -129,3 +144,45 @@ private fun openEnhancedTrackingProtectionSettings() = private fun openEnhancedTrackingProtectionDetails() = onView(ViewMatchers.withId(R.id.tracking_content)) + +private fun assertTrackingCookiesBlocked() { + mDevice.findObject(UiSelector().resourceId("$packageName:id/cross_site_tracking")) + .waitForExists(waitingTime) + onView(withId(R.id.blocking_header)).check(matches(isDisplayed())) + onView(withId(R.id.cross_site_tracking)).check(matches(isDisplayed())) +} + +private fun assertFingerprintersBlocked() { + mDevice.findObject(UiSelector().resourceId("$packageName:id/fingerprinters")) + .waitForExists(waitingTime) + onView(withId(R.id.blocking_header)).check(matches(isDisplayed())) + onView(withId(R.id.fingerprinters)).check(matches(isDisplayed())) +} + +private fun assertCryptominersBlocked() { + mDevice.findObject(UiSelector().resourceId("$packageName:id/cryptominers")) + .waitForExists(waitingTime) + onView(withId(R.id.blocking_header)).check(matches(isDisplayed())) + onView(withId(R.id.cryptominers)).check(matches(isDisplayed())) +} + +private fun assertBasicLevelTrackingContentBlocked() { + mDevice.findObject(UiSelector().resourceId("$packageName:id/tracking_content")) + .waitForExists(waitingTime) + + onView(withId(R.id.tracking_content)) + .check(matches(isDisplayed())) + .click() + onView(withId(R.id.blocking_text_list)) + .check( + matches( + withText( + containsString( + "social-track-digest256.dummytracker.org\n" + + "ads-track-digest256.dummytracker.org\n" + + "analytics-track-digest256.dummytracker.org" + ) + ) + ) + ) +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt index 340699e58..14e7b0a8e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuEnhancedTrackingProtectionRobot.kt @@ -13,6 +13,7 @@ import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.hasSibling import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withChild import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility @@ -25,6 +26,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.not +import org.mozilla.fenix.helpers.TestHelper.scrollToElementByText import org.mozilla.fenix.helpers.assertIsChecked import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.isChecked @@ -49,9 +51,9 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { fun verifyEnhancedTrackingProtectionOptionsGrayedOut() = assertEnhancedTrackingProtectionOptionsGrayedOut() - fun verifyEnhancedTrackingProtectionDefaults() = assertEnhancedTrackingProtectionDefaults() + fun verifyTrackingProtectionSwitchEnabled() = assertTrackingProtectionSwitchEnabled() - fun clickEnhancedTrackingProtectionDefaults() = onView(withResourceName("switch_widget")).click() + fun switchEnhancedTrackingProtectionToggle() = onView(withResourceName("switch_widget")).click() fun verifyRadioButtonDefaults() = assertRadioButtonDefaults() @@ -60,11 +62,15 @@ class SettingsSubMenuEnhancedTrackingProtectionRobot { verifyEnhancedTrackingProtectionHeaderDescription() verifyLearnMoreText() verifyEnhancedTrackingProtectionTextWithSwitchWidget() - verifyEnhancedTrackingProtectionDefaults() + verifyTrackingProtectionSwitchEnabled() verifyRadioButtonDefaults() verifyEnhancedTrackingProtectionOptions() } + fun verifyCustomTrackingProtectionSettings() = assertCustomTrackingProtectionSettings() + + fun selectTrackingProtectionOption(option: String) = onView(withText(option)).click() + class Transition { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! @@ -183,7 +189,7 @@ private fun assertEnhancedTrackingProtectionOptionsGrayedOut() { .check(matches(not(isEnabled(true)))) } -private fun assertEnhancedTrackingProtectionDefaults() { +private fun assertTrackingProtectionSwitchEnabled() { onView(withResourceName("switch_widget")).check( matches( isChecked( @@ -218,3 +224,28 @@ private fun goBackButton() = private fun openExceptions() = onView(allOf(withText("Exceptions"))) + +private fun assertCustomTrackingProtectionSettings() { + scrollToElementByText("Redirect Trackers") + cookiesCheckbox().check(matches(isDisplayed())) + cookiesDropDownMenuDefault().check(matches(isDisplayed())) + trackingContentCheckbox().check(matches(isDisplayed())) + trackingcontentDropDownDefault().check(matches(isDisplayed())) + cryptominersCheckbox().check(matches(isDisplayed())) + fingerprintersCheckbox().check(matches(isDisplayed())) + redirectTrackersCheckbox().check(matches(isDisplayed())) +} + +private fun cookiesCheckbox() = onView(withText("Cookies")) + +private fun cookiesDropDownMenuDefault() = onView(withText("All cookies (will cause websites to break)")) + +private fun trackingContentCheckbox() = onView(withText("Tracking content")) + +private fun trackingcontentDropDownDefault() = onView(withText("In all tabs")) + +private fun cryptominersCheckbox() = onView(withText("Cryptominers")) + +private fun fingerprintersCheckbox() = onView(withText("Fingerprinters")) + +private fun redirectTrackersCheckbox() = onView(withText("Redirect Trackers")) From e1d6fa527cfcb6735f3073259d606de1df9c6b79 Mon Sep 17 00:00:00 2001 From: amedyne <68711330+amedyne@users.noreply.github.com> Date: Thu, 4 Feb 2021 09:53:58 -0500 Subject: [PATCH 065/248] Add configuration file for probot-stale - https://github.com/probot/stale (#17801) * Create stale.yml * Update stale.yml * Update stale.yml --- .github/stale.yml | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..64e7e858f --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,62 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 180 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 7 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - pin + - "feature request 🌟" + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: wontfix + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + See: https://github.com/mozilla-mobile/fenix/issues/17373 + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +# closeComment: > +# Your comment here. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: issues + +# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +# pulls: +# daysUntilStale: 30 +# markComment: > +# This pull request has been automatically marked as stale because it has not had +# recent activity. It will be closed if no further activity occurs. Thank you +# for your contributions. + +issues: + exemptLabels: + - pin + - "feature request 🌟" From 936966596a8b714f94d26d265af4042307ac4fb9 Mon Sep 17 00:00:00 2001 From: Andrei Joltan <51314259+AndiAJ@users.noreply.github.com> Date: Thu, 4 Feb 2021 18:42:58 +0200 Subject: [PATCH 066/248] For #16020 Fix Intermittent tests caused by the Menu Button (#17829) --- .../java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt | 10 ++++++---- .../org/mozilla/fenix/ui/robots/HomeScreenRobot.kt | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt index ca48ce5b6..088136fcd 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt @@ -68,14 +68,16 @@ class ThreeDotMenuMainTest { }.openHelp { verifyHelpUrl() }.openTabDrawer { - }.openNewTab { - }.dismissSearchBar { + closeTab() + } + + homeScreen { }.openThreeDotMenu { }.openWhatsNew { verifyWhatsNewURL() }.openTabDrawer { - }.openNewTab { - }.dismissSearchBar { } + closeTab() + } homeScreen { }.openThreeDotMenu { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 7c156b5b2..4c42f3276 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -309,6 +309,7 @@ class HomeScreenRobot { } fun openThreeDotMenu(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { + mDevice.waitNotNull(Until.findObject(By.res("$packageName:id/menuButton")), waitingTime) threeDotButton().perform(click()) ThreeDotMenuMainRobot().interact() From 378e68f3a63b644416635f09dfd185f7816c948c Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 4 Feb 2021 15:37:37 +0000 Subject: [PATCH 067/248] Update Android Components version to 73.0.20210204143136. --- app/src/main/java/org/mozilla/fenix/components/Core.kt | 4 +++- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt index 96b6b504a..1d29decb8 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -18,7 +18,6 @@ import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.engine.EngineMiddleware import mozilla.components.browser.session.storage.SessionStorage -import mozilla.components.browser.session.undo.UndoMiddleware import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.storage.sync.PlacesBookmarksStorage @@ -44,6 +43,8 @@ import mozilla.components.feature.recentlyclosed.RecentlyClosedMiddleware import mozilla.components.feature.search.middleware.SearchMiddleware import mozilla.components.feature.search.region.RegionMiddleware import mozilla.components.feature.session.HistoryDelegate +import mozilla.components.feature.session.middleware.LastAccessMiddleware +import mozilla.components.feature.session.middleware.undo.UndoMiddleware import mozilla.components.feature.top.sites.DefaultTopSitesStorage import mozilla.components.feature.top.sites.PinnedSiteStorage import mozilla.components.feature.webcompat.WebCompatFeature @@ -178,6 +179,7 @@ class Core( val store by lazyMonitored { val middlewareList = mutableListOf( + LastAccessMiddleware(), RecentlyClosedMiddleware(context, RECENTLY_CLOSED_MAX, engine), DownloadMiddleware(context, DownloadService::class.java), ReaderViewMiddleware(), diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index f0cdce4dc..c49a8862a 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210203143122" + const val VERSION = "73.0.20210204143136" } From f0b7b3b987202339a5affbe76c5b857405f004a6 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Fri, 5 Feb 2021 10:38:54 +0200 Subject: [PATCH 068/248] For #17847: disables editCustomSearchEngineTest --- app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 20f34e422..b056de1bb 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -14,6 +14,7 @@ import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -521,6 +522,7 @@ class SmokeTest { } } + @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/17847") @Test // Verifies setting as default a customized search engine name and URL fun editCustomSearchEngineTest() { From 50e66b469dbd3c21902737a3203faff46bf0aeb0 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Thu, 4 Feb 2021 16:31:06 -0500 Subject: [PATCH 069/248] Remove SessionManager reference from FenixApplication --- .../java/org/mozilla/fenix/FenixApplication.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index fdcbad404..93386ce04 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.launch import mozilla.appservices.Megazord -import mozilla.components.browser.session.Session import mozilla.components.browser.state.action.SystemAction import mozilla.components.browser.state.selector.selectedTab import mozilla.components.concept.base.crash.Breadcrumb @@ -402,9 +401,19 @@ open class FenixApplication : LocaleAwareApplication(), Provider { components.core.store.state.selectedTab?.content?.private ?: components.settings.openLinksInAPrivateTab - val session = Session(url, shouldCreatePrivateSession) - components.core.sessionManager.add(session, true, engineSession) - session.id + if (shouldCreatePrivateSession) { + components.useCases.tabsUseCases.addPrivateTab( + url = url, + selectTab = true, + engineSession = engineSession + ) + } else { + components.useCases.tabsUseCases.addTab( + url = url, + selectTab = true, + engineSession = engineSession + ) + } }, onCloseTabOverride = { _, sessionId -> components.useCases.tabsUseCases.removeTab(sessionId) From 0b764fd3e4eb40b3fc3bf569a9de70a75804a3f1 Mon Sep 17 00:00:00 2001 From: jhugman Date: Fri, 5 Feb 2021 16:41:46 +0000 Subject: [PATCH 070/248] Fixes #17833 - increment A/A experiment id (#17835) r=christian --- app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt index ab11ec8f4..baa800910 100644 --- a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt +++ b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt @@ -6,7 +6,7 @@ package org.mozilla.fenix.experiments class Experiments { companion object { - const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation-v2" + const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation-v3" const val BOOKMARK_ICON = "fenix-bookmark-list-icon" } } From a3d401a3b79ace94232c71c5ce12e49bf186ca65 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Fri, 5 Feb 2021 12:06:32 -0500 Subject: [PATCH 071/248] For #17418 - Add event ping telemetry for the Google Top Site click (#17862) Co-authored-by: codrut.topliceanu Co-authored-by: Gabriel Luong --- app/metrics.yaml | 13 +++++++++++++ .../org/mozilla/fenix/components/metrics/Event.kt | 1 + .../fenix/components/metrics/GleanMetricsService.kt | 3 +++ .../home/sessioncontrol/SessionControlController.kt | 4 ++++ .../home/DefaultSessionControlControllerTest.kt | 6 ++++++ docs/metrics.md | 5 +++-- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 6148f67c2..4c9a2bd0e 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -3415,6 +3415,19 @@ top_sites: notification_emails: - fenix-core@mozilla.com expires: "2021-08-01" + open_google_search_attribution: + type: event + description: | + A user opened the google top site + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17418 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17637 + data_sensitivity: + - interaction + notification_emails: + - fenix-core@mozilla.com + expires: "2021-08-01" open_frecency: type: event description: | diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index 983d228df..a5b94eec2 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -122,6 +122,7 @@ sealed class Event { object NotificationMediaPlay : Event() object NotificationMediaPause : Event() object TopSiteOpenDefault : Event() + object TopSiteOpenGoogle : Event() object TopSiteOpenFrecent : Event() object TopSiteOpenPinned : Event() object TopSiteOpenInNewTab : Event() diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index d1e653f09..404ae9aff 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -516,6 +516,9 @@ private val Event.wrapper: EventWrapper<*>? is Event.TopSiteOpenDefault -> EventWrapper( { TopSites.openDefault.record(it) } ) + is Event.TopSiteOpenGoogle -> EventWrapper( + { TopSites.openGoogleSearchAttribution.record(it) } + ) is Event.TopSiteOpenFrecent -> EventWrapper( { TopSites.openFrecency.record(it) } ) diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index 264480f74..88f46fdac 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -372,6 +372,10 @@ class DefaultSessionControlController( TopSite.Type.PINNED -> metrics.track(Event.TopSiteOpenPinned) } + if (url == SupportUtils.GOOGLE_URL) { + metrics.track(Event.TopSiteOpenGoogle) + } + if (url == SupportUtils.POCKET_TRENDING_URL) { metrics.track(Event.PocketTopSiteClicked) } diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 9039f7f44..8b45154f6 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -369,6 +369,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.DEFAULT) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenDefault) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( url = SupportUtils.GOOGLE_US_URL, @@ -388,6 +389,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.DEFAULT) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenDefault) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( SupportUtils.GOOGLE_XX_URL, @@ -407,6 +409,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.PINNED) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenPinned) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( SupportUtils.GOOGLE_US_URL, @@ -426,6 +429,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.PINNED) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenPinned) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( SupportUtils.GOOGLE_XX_URL, @@ -445,6 +449,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.FRECENT) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenFrecent) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( SupportUtils.GOOGLE_US_URL, @@ -464,6 +469,7 @@ class DefaultSessionControlControllerTest { controller.handleSelectTopSite(topSiteUrl, TopSite.Type.FRECENT) verify { metrics.track(Event.TopSiteOpenInNewTab) } verify { metrics.track(Event.TopSiteOpenFrecent) } + verify { metrics.track(Event.TopSiteOpenGoogle) } verify { tabsUseCases.addTab.invoke( SupportUtils.GOOGLE_XX_URL, diff --git a/docs/metrics.md b/docs/metrics.md index 8d0b6ea25..d06c57488 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -28,8 +28,8 @@ an hashed version of the Google Advertising ID. **Bugs related to this ping:** -- 1538011 -- 1501822 +- +- The following metrics are added to the ping: @@ -221,6 +221,7 @@ The following metrics are added to the ping: | top_sites.long_press |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user long pressed on a top site |[1](https://github.com/mozilla-mobile/fenix/pull/15136), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)|
  • type: The type of top site. Options are: "FRECENCY," "DEFAULT," or "PINNED."
|2021-08-01 |2 | | top_sites.open_default |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened a default top site |[1](https://github.com/mozilla-mobile/fenix/pull/10752), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | top_sites.open_frecency |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened a frecency top site |[1](https://github.com/mozilla-mobile/fenix/pull/15136), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | +| top_sites.open_google_search_attribution |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened the google top site |[1](https://github.com/mozilla-mobile/fenix/pull/17637)||2021-08-01 |2 | | top_sites.open_in_new_tab |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opens a new tab based on a top site item |[1](https://github.com/mozilla-mobile/fenix/pull/7523), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | top_sites.open_in_private_tab |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opens a new private tab based on a top site item |[1](https://github.com/mozilla-mobile/fenix/pull/7523), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | top_sites.open_pinned |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened a pinned top site |[1](https://github.com/mozilla-mobile/fenix/pull/15136), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | From 8bf1cae2cae7bb72fc406b89538914bd24e12d83 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Wed, 27 Jan 2021 17:56:48 +0200 Subject: [PATCH 072/248] For #10686 - Use the AC custom behavior for both the top and bottom toolbars This comes to unify the experience (with improvements but also specific issues) for the url toolbar irrespective of it being placed at the bottom or at the top Going further this will ease development and ensure the best UX for users. --- .../fenix/browser/BaseBrowserFragment.kt | 65 ++++-- .../components/toolbar/BrowserToolbarView.kt | 99 ++++----- .../SwipeRefreshScrollingViewBehavior.kt | 50 ----- .../layout/component_browser_top_toolbar.xml | 10 +- app/src/main/res/layout/fragment_browser.xml | 3 +- .../fenix/browser/BaseBrowserFragmentTest.kt | 133 ++++++++++++ .../toolbar/BrowserToolbarViewTest.kt | 196 ++++++++++++++++++ 7 files changed, 421 insertions(+), 135 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/components/toolbar/SwipeRefreshScrollingViewBehavior.kt create mode 100644 app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt create mode 100644 app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 817a5ba2b..c90ca97f4 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -70,7 +70,6 @@ import mozilla.components.feature.session.FullScreenFeature import mozilla.components.feature.session.PictureInPictureFeature import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SwipeRefreshFeature -import mozilla.components.feature.session.behavior.EngineViewBottomBehavior import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissionsFeature import mozilla.components.lib.state.ext.consumeFlow @@ -103,9 +102,7 @@ import org.mozilla.fenix.components.toolbar.BrowserToolbarView import org.mozilla.fenix.components.toolbar.BrowserToolbarViewInteractor import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarController import org.mozilla.fenix.components.toolbar.DefaultBrowserToolbarMenuController -import org.mozilla.fenix.components.toolbar.SwipeRefreshScrollingViewBehavior import org.mozilla.fenix.components.toolbar.ToolbarIntegration -import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.downloads.DownloadService import org.mozilla.fenix.downloads.DynamicDownloadDialog import org.mozilla.fenix.ext.accessibilityManager @@ -128,9 +125,11 @@ import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration import java.lang.ref.WeakReference import mozilla.components.feature.media.fullscreen.MediaFullscreenOrientationFeature +import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.support.base.feature.ActivityResultHandler import org.mozilla.fenix.FeatureFlags.newMediaSessionApi +import mozilla.components.feature.session.behavior.ToolbarPosition as MozacToolbarPosition /** * Base fragment extended by [BrowserFragment]. @@ -838,34 +837,42 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit !inFullScreen } - private fun initializeEngineView(toolbarHeight: Int) { + @VisibleForTesting + internal fun initializeEngineView(toolbarHeight: Int) { val context = requireContext() - if (context.settings().isDynamicToolbarEnabled) { - engineView.setDynamicToolbarMaxHeight(toolbarHeight) + // If there is an a11y service enabled and the user hasn't explicitly set bottom toolbar + val isTopToolbarForced = + !context.settings().shouldUseBottomToolbar && + context.settings().shouldUseFixedTopToolbar + + if (!isTopToolbarForced && context.settings().isDynamicToolbarEnabled) { + getEngineView().setDynamicToolbarMaxHeight(toolbarHeight) - val behavior = when (context.settings().toolbarPosition) { - // Set engineView dynamic vertical clipping depending on the toolbar position. - ToolbarPosition.BOTTOM -> EngineViewBottomBehavior(context, null) - // Set scroll flags depending on if if the browser or the website is doing the scroll. - ToolbarPosition.TOP -> SwipeRefreshScrollingViewBehavior( + val toolbarPosition = if (context.settings().shouldUseBottomToolbar) { + MozacToolbarPosition.BOTTOM + } else { + MozacToolbarPosition.TOP + } + (getSwipeRefreshLayout().layoutParams as CoordinatorLayout.LayoutParams).behavior = + EngineViewBrowserToolbarBehavior( context, null, - engineView, - browserToolbarView + getSwipeRefreshLayout(), + toolbarHeight, + toolbarPosition ) - } - - (swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams).behavior = behavior } else { // Ensure webpage's bottom elements are aligned to the very bottom of the engineView. - engineView.setDynamicToolbarMaxHeight(0) + getEngineView().setDynamicToolbarMaxHeight(0) - // Effectively place the engineView on top of the toolbar if that is not dynamic. + // Effectively place the engineView on top/below of the toolbar if that is not dynamic. + val swipeRefreshParams = + getSwipeRefreshLayout().layoutParams as CoordinatorLayout.LayoutParams if (context.settings().shouldUseBottomToolbar) { - val browserEngine = swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams - browserEngine.bottomMargin = - requireContext().resources.getDimensionPixelSize(R.dimen.browser_toolbar_height) + swipeRefreshParams.bottomMargin = toolbarHeight + } else { + swipeRefreshParams.topMargin = toolbarHeight } } } @@ -1251,6 +1258,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit browserToolbarView.view.isVisible = false val browserEngine = swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams browserEngine.bottomMargin = 0 + browserEngine.topMargin = 0 + swipeRefresh.translationY = 0f engineView.setDynamicToolbarMaxHeight(0) browserToolbarView.expand() @@ -1330,7 +1339,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit override fun onAccessibilityStateChanged(enabled: Boolean) { if (_browserToolbarView != null) { - browserToolbarView.setScrollFlags(enabled) + browserToolbarView.setToolbarBehavior(enabled) } } @@ -1352,4 +1361,16 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit } } } + + /** + * Convenience method for replacing EngineView (id/engineView) in unit tests. + */ + @VisibleForTesting + internal fun getEngineView() = engineView + + /** + * Convenience method for replacing SwipeRefreshLayout (id/swipeRefresh) in unit tests. + */ + @VisibleForTesting + internal fun getSwipeRefreshLayout() = swipeRefresh } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index aff4b03d2..af57953a5 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -9,25 +9,18 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.annotation.LayoutRes +import androidx.annotation.VisibleForTesting import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat -import androidx.core.view.updateLayoutParams import androidx.lifecycle.LifecycleOwner -import com.google.android.material.appbar.AppBarLayout -import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS -import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED -import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL -import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP import kotlinx.android.extensions.LayoutContainer -import kotlinx.android.synthetic.main.component_browser_top_toolbar.* -import kotlinx.android.synthetic.main.component_browser_top_toolbar.view.* import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.selectedTab import mozilla.components.browser.state.state.ExternalAppType import mozilla.components.browser.toolbar.BrowserToolbar -import mozilla.components.browser.toolbar.behavior.BrowserToolbarBottomBehavior +import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.support.utils.URLStringUtils import mozilla.components.ui.tabcounter.TabCounterMenu @@ -40,6 +33,7 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.utils.ToolbarPopupWindow import java.lang.ref.WeakReference +import mozilla.components.browser.toolbar.behavior.ToolbarPosition as MozacToolbarPosition interface BrowserToolbarViewInteractor { fun onBrowserToolbarPaste(text: String) @@ -76,12 +70,14 @@ class BrowserToolbarView( private val layout = LayoutInflater.from(container.context) .inflate(toolbarLayout, container, true) - val view: BrowserToolbar = layout + @VisibleForTesting + internal var view: BrowserToolbar = layout .findViewById(R.id.toolbar) val toolbarIntegration: ToolbarIntegration - private val isPwaTabOrTwaTab: Boolean + @VisibleForTesting + internal val isPwaTabOrTwaTab: Boolean get() = customTabSession?.customTabConfig?.externalAppType == ExternalAppType.PROGRESSIVE_WEB_APP || customTabSession?.customTabConfig?.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY @@ -101,17 +97,8 @@ class BrowserToolbarView( with(container.context) { val isPinningSupported = components.useCases.webAppUseCases.isPinningSupported() - if (toolbarPosition == ToolbarPosition.TOP) { - val offsetChangedListener = - AppBarLayout.OnOffsetChangedListener { _: AppBarLayout?, verticalOffset: Int -> - interactor.onScrolled(verticalOffset) - } - - app_bar.addOnOffsetChangedListener(offsetChangedListener) - } - view.apply { - setScrollFlags() + setToolbarBehavior() elevation = resources.getDimension(R.dimen.browser_fragment_toolbar_elevation) @@ -222,16 +209,9 @@ class BrowserToolbarView( if (isPwaTabOrTwaTab) { return } - when (settings.toolbarPosition) { - ToolbarPosition.BOTTOM -> { - (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - // behavior can be null if the "Scroll to hide toolbar" setting is toggled off. - (behavior as? BrowserToolbarBottomBehavior)?.forceExpand(view) - } - } - ToolbarPosition.TOP -> { - layout.app_bar?.setExpanded(true) - } + + (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { + (behavior as? BrowserToolbarBehavior)?.forceExpand(view) } } @@ -240,41 +220,54 @@ class BrowserToolbarView( } /** - * Dynamically sets scroll flags for the toolbar when the user does not have a screen reader enabled - * Note that the toolbar will have the flags set and be able to be hidden - * only if the user didn't disabled this behavior in app's settings. + * Sets whether the toolbar will have a dynamic behavior (to be scrolled) or not. + * + * This will intrinsically check and disable the dynamic behavior if + * - this is disabled in app settings + * - toolbar is placed at the bottom and tab shows a PWA or TWA + * + * Also if the user has not explicitly set a toolbar position and has a screen reader enabled + * the toolbar will be placed at the top and in a fixed position. + * + * @param shouldDisableScroll force disable of the dynamic behavior irrespective of the intrinsic checks. */ - fun setScrollFlags(shouldDisableScroll: Boolean = false) { + fun setToolbarBehavior(shouldDisableScroll: Boolean = false) { when (settings.toolbarPosition) { ToolbarPosition.BOTTOM -> { if (settings.isDynamicToolbarEnabled && !isPwaTabOrTwaTab) { - (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { - behavior = BrowserToolbarBottomBehavior(view.context, null) - } + setDynamicToolbarBehavior(MozacToolbarPosition.BOTTOM) } else { - expand() + expandToolbarAndMakeItFixed() } } ToolbarPosition.TOP -> { - view.updateLayoutParams { - scrollFlags = - if (settings.shouldUseFixedTopToolbar || - !settings.isDynamicToolbarEnabled || - shouldDisableScroll) { - // Force expand the toolbar so the user is not stuck with a hidden toolbar - expand() - 0 - } else { - SCROLL_FLAG_SCROLL or - SCROLL_FLAG_ENTER_ALWAYS or - SCROLL_FLAG_SNAP or - SCROLL_FLAG_EXIT_UNTIL_COLLAPSED - } + if (settings.shouldUseFixedTopToolbar || + !settings.isDynamicToolbarEnabled || + shouldDisableScroll + ) { + expandToolbarAndMakeItFixed() + } else { + setDynamicToolbarBehavior(MozacToolbarPosition.TOP) } } } } + @VisibleForTesting + internal fun expandToolbarAndMakeItFixed() { + expand() + (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { + behavior = null + } + } + + @VisibleForTesting + internal fun setDynamicToolbarBehavior(toolbarPosition: MozacToolbarPosition) { + (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { + behavior = BrowserToolbarBehavior(view.context, null, toolbarPosition) + } + } + @Suppress("ComplexCondition") private fun ToolbarMenu.Item.performHapticIfNeeded(view: View) { if (this is ToolbarMenu.Item.Reload && this.bypassCache || diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/SwipeRefreshScrollingViewBehavior.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/SwipeRefreshScrollingViewBehavior.kt deleted file mode 100644 index b69bc0f94..000000000 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/SwipeRefreshScrollingViewBehavior.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* 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 org.mozilla.fenix.components.toolbar - -import android.content.Context -import android.util.AttributeSet -import android.view.View -import androidx.coordinatorlayout.widget.CoordinatorLayout -import com.google.android.material.appbar.AppBarLayout -import kotlinx.coroutines.ExperimentalCoroutinesApi -import mozilla.components.concept.engine.EngineView -import mozilla.components.concept.engine.EngineView.InputResult.INPUT_RESULT_UNHANDLED -import org.mozilla.fenix.ext.settings - -/** - * ScrollingViewBehavior that will setScrollFlags on BrowserToolbar based on EngineView touch handling - */ -@ExperimentalCoroutinesApi -class SwipeRefreshScrollingViewBehavior( - context: Context, - attrs: AttributeSet?, - private val engineView: EngineView, - private val browserToolbarView: BrowserToolbarView -) : AppBarLayout.ScrollingViewBehavior(context, attrs) { - override fun onStartNestedScroll( - coordinatorLayout: CoordinatorLayout, - child: View, - directTargetChild: View, - target: View, - axes: Int, - type: Int - ): Boolean { - - if (!browserToolbarView.view.context.settings().shouldUseBottomToolbar) { - val shouldDisable = engineView.getInputResult() == INPUT_RESULT_UNHANDLED - browserToolbarView.setScrollFlags(shouldDisable) - } - - return super.onStartNestedScroll( - coordinatorLayout, - child, - directTargetChild, - target, - axes, - type - ) - } -} diff --git a/app/src/main/res/layout/component_browser_top_toolbar.xml b/app/src/main/res/layout/component_browser_top_toolbar.xml index 479bc9dd9..77f460296 100644 --- a/app/src/main/res/layout/component_browser_top_toolbar.xml +++ b/app/src/main/res/layout/component_browser_top_toolbar.xml @@ -2,12 +2,9 @@ - + - - diff --git a/app/src/main/res/layout/fragment_browser.xml b/app/src/main/res/layout/fragment_browser.xml index 63150e569..32d2bd4c4 100644 --- a/app/src/main/res/layout/fragment_browser.xml +++ b/app/src/main/res/layout/fragment_browser.xml @@ -25,8 +25,7 @@ + android:layout_height="match_parent"> (relaxed = true) + } + + @Test + fun `initializeEngineView should setDynamicToolbarMaxHeight to 0 if top toolbar is forced for a11y`() { + every { testContext.settings().shouldUseBottomToolbar } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns true + + fragment.initializeEngineView(13) + + verify { engineView.setDynamicToolbarMaxHeight(0) } + } + + @Test + fun `initializeEngineView should setDynamicToolbarMaxHeight to toolbar height if dynamic toolbar is enabled`() { + every { testContext.settings().shouldUseFixedTopToolbar } returns false + every { testContext.settings().isDynamicToolbarEnabled } returns true + + fragment.initializeEngineView(13) + + verify { engineView.setDynamicToolbarMaxHeight(13) } + } + + @Test + fun `initializeEngineView should setDynamicToolbarMaxHeight to 0 if dynamic toolbar is disabled`() { + every { testContext.settings().shouldUseFixedTopToolbar } returns false + every { testContext.settings().isDynamicToolbarEnabled } returns false + + fragment.initializeEngineView(13) + + verify { engineView.setDynamicToolbarMaxHeight(0) } + } + + @Test + fun `initializeEngineView should set EngineViewBrowserToolbarBehavior when dynamic toolbar is enabled`() { + every { testContext.settings().shouldUseFixedTopToolbar } returns false + every { testContext.settings().isDynamicToolbarEnabled } returns true + val params: CoordinatorLayout.LayoutParams = mockk(relaxed = true) + every { params.behavior } returns mockk(relaxed = true) + every { swipeRefreshLayout.layoutParams } returns params + val behavior = slot() + + fragment.initializeEngineView(13) + + // EngineViewBrowserToolbarBehavior constructor parameters are not properties, we cannot check them. + // Ensure just that the right behavior is set. + verify { params.behavior = capture(behavior) } + } + + @Test + fun `initializeEngineView should set toolbar height as EngineView parent's bottom margin when using bottom toolbar`() { + every { testContext.settings().isDynamicToolbarEnabled } returns false + every { testContext.settings().shouldUseBottomToolbar } returns true + + fragment.initializeEngineView(13) + + verify { (swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 13 } + } + + @Test + fun `initializeEngineView should set toolbar height as EngineView parent's bottom margin if top toolbar is forced for a11y`() { + every { testContext.settings().shouldUseBottomToolbar } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns true + + fragment.initializeEngineView(13) + + verify { (swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 13 } + } +} + +@ExperimentalCoroutinesApi +private class TestBaseBrowserFragment : BaseBrowserFragment() { + override fun getContextMenuCandidates( + context: Context, + view: View + ): List { + // no-op + return emptyList() + } + + override fun navToQuickSettingsSheet(tab: SessionState, sitePermissions: SitePermissions?) { + // no-op + } + + override fun navToTrackingProtectionPanel(tab: SessionState) { + // no-op + } +} diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt new file mode 100644 index 000000000..f75b1d448 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt @@ -0,0 +1,196 @@ +/* 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 org.mozilla.fenix.components.toolbar + +import androidx.coordinatorlayout.widget.CoordinatorLayout + +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import kotlinx.coroutines.ExperimentalCoroutinesApi +import mozilla.components.support.test.robolectric.testContext +import org.junit.Test +import org.junit.runner.RunWith +import mozilla.components.browser.toolbar.BrowserToolbar +import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertNull +import org.junit.Before +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import mozilla.components.browser.toolbar.behavior.ToolbarPosition as MozacToolbarPosition + +@ExperimentalCoroutinesApi +@RunWith(FenixRobolectricTestRunner::class) +class BrowserToolbarViewTest { + private lateinit var toolbarView: BrowserToolbarView + private lateinit var toolbar: BrowserToolbar + private lateinit var behavior: BrowserToolbarBehavior + + @Before + fun `setup`() { + toolbar = BrowserToolbar(testContext) + toolbar.layoutParams = CoordinatorLayout.LayoutParams(100, 100) + behavior = spyk(BrowserToolbarBehavior(testContext, null, MozacToolbarPosition.BOTTOM)) + (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = behavior + + toolbarView = BrowserToolbarView( + container = CoordinatorLayout(testContext), + toolbarPosition = ToolbarPosition.BOTTOM, + interactor = mockk(), + customTabSession = mockk(relaxed = true), + lifecycleOwner = mockk() + ) + + toolbarView.view = toolbar + } + + @Test + fun `setToolbarBehavior(false) should setDynamicToolbarBehavior if bottom toolbar is dynamic and the tab is not for a PWA or TWA`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.setDynamicToolbarBehavior(MozacToolbarPosition.BOTTOM) } + } + + @Test + fun `setToolbarBehavior(false) should expandToolbarAndMakeItFixed if bottom toolbar is not set as dynamic`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(false) should expandToolbarAndMakeItFixed if bottom toolbar is dynamic but the tab is for a PWA or TWA`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should setDynamicToolbarBehavior if bottom toolbar is dynamic and the tab is not for a PWA or TWA`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.setDynamicToolbarBehavior(MozacToolbarPosition.BOTTOM) } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed if bottom toolbar is not set as dynamic`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed if bottom toolbar is dynamic but the tab is for a PWA or TWA`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed for top toolbar if shouldUseFixedTopToolbar`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.TOP + every { testContext.settings().shouldUseFixedTopToolbar } returns true + + toolbarViewSpy.setToolbarBehavior(true) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed for top toolbar if it is not dynamic`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.TOP + every { testContext.settings().isDynamicToolbarEnabled } returns false + + toolbarViewSpy.setToolbarBehavior(true) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed for top toolbar if shouldDisableScroll`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.TOP + + toolbarViewSpy.setToolbarBehavior(true) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(false) should setDynamicToolbarBehavior for top toolbar`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.TOP + every { testContext.settings().shouldUseFixedTopToolbar } returns true + every { testContext.settings().isDynamicToolbarEnabled } returns true + + toolbarViewSpy.setToolbarBehavior(true) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `expandToolbarAndMakeItFixed should expand the toolbar and and disable the dynamic behavior`() { + val toolbarViewSpy = spyk(toolbarView) + + assertNotNull((toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior) + + toolbarViewSpy.expandToolbarAndMakeItFixed() + + verify { toolbarViewSpy.expand() } + assertNull((toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior) + } + + @Test + fun `setDynamicToolbarBehavior should set a BrowserToolbarBehavior for the bottom toolbar`() { + val toolbarViewSpy = spyk(toolbarView) + (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = null + + toolbarViewSpy.setDynamicToolbarBehavior(MozacToolbarPosition.BOTTOM) + + assertNotNull((toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior) + } + + @Test + fun `setDynamicToolbarBehavior should set a BrowserToolbarBehavior for the top toolbar`() { + val toolbarViewSpy = spyk(toolbarView) + (toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior = null + + toolbarViewSpy.setDynamicToolbarBehavior(MozacToolbarPosition.TOP) + + assertNotNull((toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior) + } +} From d61857c0e3f6ece1573a830fb3dc520ce8540945 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Fri, 5 Feb 2021 18:20:37 +0200 Subject: [PATCH 073/248] Update Android Components version --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index c49a8862a..488871a43 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210204143136" + const val VERSION = "73.0.20210205154357" } From 1ef4102e1319591d087aeee9b77a72d2cf89635d Mon Sep 17 00:00:00 2001 From: jhugman Date: Fri, 5 Feb 2021 18:54:47 +0000 Subject: [PATCH 074/248] Fixes #17738 - Early initialization of Nimbus (#17834) r=christian --- app/src/main/java/org/mozilla/fenix/FenixApplication.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 93386ce04..7e40e24aa 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -306,6 +306,10 @@ open class FenixApplication : LocaleAwareApplication(), Provider { // ... but RustHttpConfig.setClient() and RustLog.enable() can be called later. RustHttpConfig.setClient(lazy { components.core.client }) RustLog.enable(components.analytics.crashReporter) + // We want to ensure Nimbus is initialized as early as possible so we can + // experiment on features close to startup. + // But we need viaduct (the RustHttp client) to be ready before we do. + components.analytics.experiments.initialize() } } From f5b068a4534ccdfc9ddf8e5f5e016052ce378cfd Mon Sep 17 00:00:00 2001 From: ekager Date: Thu, 4 Feb 2021 16:42:05 -0700 Subject: [PATCH 075/248] For #17785 - Use screenshots setting when adding secure flag --- .../java/org/mozilla/fenix/HomeActivity.kt | 22 +++++++++++++++++-- .../java/org/mozilla/fenix/ext/Fragment.kt | 2 ++ .../org/mozilla/fenix/home/HomeFragment.kt | 14 +++--------- .../fenix/settings/PrivateBrowsingFragment.kt | 15 ++++++++++++- .../logins/fragment/LoginDetailFragment.kt | 9 ++++++++ .../fenix/tabtray/TabTrayDialogFragment.kt | 2 +- 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index c39d42e6d..44ef9352c 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -17,7 +17,7 @@ import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewConfiguration -import android.view.WindowManager +import android.view.WindowManager.LayoutParams.FLAG_SECURE import androidx.annotation.CallSuper import androidx.annotation.IdRes import androidx.annotation.VisibleForTesting @@ -278,6 +278,11 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { override fun onResume() { super.onResume() + // Even if screenshots are allowed, we hide private content in the recents screen in onPause + // so onResume we should go back to setting these flags with the user screenshot setting + // See https://github.com/mozilla-mobile/fenix/issues/11153 + updateSecureWindowFlags(settings().lastKnownMode) + // Diagnostic breadcrumb for "Display already aquired" crash: // https://github.com/mozilla-mobile/android-components/issues/7960 breadcrumb( @@ -341,8 +346,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { settings().shouldReturnToBrowser = components.core.store.state.getNormalOrPrivateTabs(private = false).isNotEmpty() + // Even if screenshots are allowed, we want to hide private content in the recents screen + // See https://github.com/mozilla-mobile/fenix/issues/11153 if (settings().lastKnownMode.isPrivate) { - window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + window.addFlags(FLAG_SECURE) } // We will remove this when AC code lands to emit a fact on getTopSites in DefaultTopSitesStorage @@ -850,7 +857,18 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { protected open fun createBrowsingModeManager(initialMode: BrowsingMode): BrowsingModeManager { return DefaultBrowsingModeManager(initialMode, components.settings) { newMode -> + updateSecureWindowFlags(newMode) themeManager.currentTheme = newMode + }.also { + updateSecureWindowFlags(initialMode) + } + } + + fun updateSecureWindowFlags(mode: BrowsingMode = browsingModeManager.mode) { + if (mode == BrowsingMode.Private && !settings().allowScreenshotsInPrivateMode) { + window.addFlags(FLAG_SECURE) + } else { + window.clearFlags(FLAG_SECURE) } } diff --git a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt index 1eb2cb27b..4275dd801 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -13,6 +13,7 @@ import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment.findNavController import androidx.navigation.fragment.findNavController import mozilla.components.concept.base.crash.Breadcrumb +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.Components @@ -65,6 +66,7 @@ fun Fragment.hideToolbar() { * */ fun Fragment.redirectToReAuth(destinations: List, currentDestination: Int?) { + (activity as? HomeActivity)?.updateSecureWindowFlags() if (currentDestination !in destinations) { findNavController().popBackStack(R.id.savedLoginsAuthFragment, false) } diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index ca828cfac..1ea437124 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -12,7 +12,6 @@ import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.os.StrictMode -import android.view.Display.FLAG_SECURE import android.view.Gravity import android.view.LayoutInflater import android.view.View @@ -85,6 +84,7 @@ import mozilla.components.support.ktx.android.content.res.resolveAttribute import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged import mozilla.components.ui.tabcounter.TabCounterMenu import org.mozilla.fenix.BrowserDirection +import org.mozilla.fenix.Config import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.BrowserAnimator.Companion.getToolbarNavOptions @@ -104,8 +104,9 @@ import org.mozilla.fenix.ext.hideToolbar import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.requireComponents -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.runIfFragmentIsAttached +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor import org.mozilla.fenix.home.sessioncontrol.SessionControlView @@ -121,8 +122,6 @@ import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.whatsnew.WhatsNew import java.lang.ref.WeakReference import kotlin.math.min -import org.mozilla.fenix.Config -import org.mozilla.fenix.home.mozonline.showPrivacyPopWindow @ExperimentalCoroutinesApi @Suppress("TooManyFunctions", "LargeClass") @@ -407,12 +406,6 @@ class HomeFragment : Fragment() { } } - if (browsingModeManager.mode.isPrivate) { - requireActivity().window.addFlags(FLAG_SECURE) - } else { - requireActivity().window.clearFlags(FLAG_SECURE) - } - consumeFrom(requireComponents.core.store) { updateTabCounter(it) } @@ -551,7 +544,6 @@ class HomeFragment : Fragment() { sessionControlView = null appBarLayout = null bundleArgs.clear() - requireActivity().window.clearFlags(FLAG_SECURE) } override fun onStart() { diff --git a/app/src/main/java/org/mozilla/fenix/settings/PrivateBrowsingFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/PrivateBrowsingFragment.kt index ff0515af0..2a9812054 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/PrivateBrowsingFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/PrivateBrowsingFragment.kt @@ -5,9 +5,11 @@ package org.mozilla.fenix.settings import android.os.Bundle +import android.view.WindowManager import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.PrivateShortcutCreateManager import org.mozilla.fenix.components.metrics.Event @@ -44,7 +46,18 @@ class PrivateBrowsingFragment : PreferenceFragmentCompat() { } requirePreference(R.string.pref_key_allow_screenshots_in_private_mode).apply { - onPreferenceChangeListener = SharedPreferenceUpdater() + onPreferenceChangeListener = object : SharedPreferenceUpdater() { + override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { + if ((activity as? HomeActivity)?.browsingModeManager?.mode?.isPrivate == true && + newValue == false + ) { + activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + } else { + activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + } + return super.onPreferenceChange(preference, newValue) + } + } } } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt index 63fe12c87..10b031877 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/LoginDetailFragment.kt @@ -13,6 +13,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import android.view.WindowManager import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment @@ -111,6 +112,14 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) { setHasOptionsMenu(true) } + override fun onResume() { + super.onResume() + activity?.window?.setFlags( + WindowManager.LayoutParams.FLAG_SECURE, + WindowManager.LayoutParams.FLAG_SECURE + ) + } + /** * As described in #10727, the User should re-auth if the fragment is paused and the user is not * navigating to SavedLoginsFragment or EditLoginFragment diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index a06f4a08a..05b34235a 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -268,7 +268,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler private fun setSecureFlagsIfNeeded(private: Boolean) { if (private && context?.settings()?.allowScreenshotsInPrivateMode == false) { dialog?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE) - } else if (!(activity as HomeActivity).browsingModeManager.mode.isPrivate) { + } else { dialog?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) } } From 0defc5444929663bef0e124dcc585b03bb19a637 Mon Sep 17 00:00:00 2001 From: ekager Date: Thu, 4 Feb 2021 15:22:43 -0700 Subject: [PATCH 076/248] Closes #13089 - Adds correct animations for account settings --- app/src/main/res/navigation/nav_graph.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml index 07666ee3c..d3a9c5efb 100644 --- a/app/src/main/res/navigation/nav_graph.xml +++ b/app/src/main/res/navigation/nav_graph.xml @@ -102,7 +102,11 @@ app:destination="@id/trackingProtectionExceptionsFragment" /> + app:destination="@id/accountSettingsFragment" + app:enterAnim="@anim/slide_in_right" + app:exitAnim="@anim/slide_out_left" + app:popEnterAnim="@anim/slide_in_left" + app:popExitAnim="@anim/slide_out_right" /> From 993cf74e729974903525b05482834aac0ed5cbdf Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Fri, 5 Feb 2021 18:54:37 -0500 Subject: [PATCH 077/248] Closes #17174: Remove the New Media Session API Feature Flag (#17863) --- .../java/org/mozilla/fenix/FeatureFlags.kt | 6 - .../fenix/browser/BaseBrowserFragment.kt | 28 ++--- .../java/org/mozilla/fenix/components/Core.kt | 11 +- .../intent/OpenSpecificTabIntentProcessor.kt | 14 +-- .../fenix/tabtray/TabTrayViewHolder.kt | 110 +++++------------- .../OpenSpecificTabIntentProcessorTest.kt | 10 +- .../fenix/tabtray/TabTrayViewHolderTest.kt | 68 ++++------- 7 files changed, 63 insertions(+), 184 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 35e89de46..1092fff0e 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -26,12 +26,6 @@ object FeatureFlags { */ val nimbusExperiments = Config.channel.isNightlyOrDebug - /** - * Enables the new MediaSession API. - */ - @Suppress("MayBeConst") - val newMediaSessionApi = true - /** * Enables WebAuthn support. */ diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index c90ca97f4..6a4bcc9ff 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -128,7 +128,6 @@ import mozilla.components.feature.media.fullscreen.MediaFullscreenOrientationFea import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.support.base.feature.ActivityResultHandler -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi import mozilla.components.feature.session.behavior.ToolbarPosition as MozacToolbarPosition /** @@ -410,25 +409,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit view = view ) - if (newMediaSessionApi) { - fullScreenMediaSessionFeature.set( - feature = MediaSessionFullscreenFeature( - requireActivity(), - context.components.core.store - ), - owner = this, - view = view - ) - } else { - fullScreenMediaFeature.set( - feature = MediaFullscreenOrientationFeature( - requireActivity(), - context.components.core.store - ), - owner = this, - view = view - ) - } + fullScreenMediaSessionFeature.set( + feature = MediaSessionFullscreenFeature( + requireActivity(), + context.components.core.store + ), + owner = this, + view = view + ) val shareDownloadFeature = ShareDownloadFeature( context = context.applicationContext, diff --git a/app/src/main/java/org/mozilla/fenix/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt index 1d29decb8..9a4889eff 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -34,7 +34,6 @@ import mozilla.components.feature.customtabs.store.CustomTabsServiceStore import mozilla.components.feature.downloads.DownloadMiddleware import mozilla.components.feature.logins.exceptions.LoginExceptionStorage import mozilla.components.feature.media.MediaSessionFeature -import mozilla.components.feature.media.middleware.MediaMiddleware import mozilla.components.feature.media.middleware.RecordingDevicesMiddleware import mozilla.components.feature.pwa.ManifestStorage import mozilla.components.feature.pwa.WebAppShortcutManager @@ -62,7 +61,6 @@ import mozilla.components.support.locale.LocaleManager import org.mozilla.fenix.AppRequestInterceptor import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.Config -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.TelemetryMiddleware @@ -70,7 +68,6 @@ import org.mozilla.fenix.components.search.SearchMigration import org.mozilla.fenix.downloads.DownloadService import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings -import org.mozilla.fenix.media.MediaService import org.mozilla.fenix.media.MediaSessionService import org.mozilla.fenix.perf.StrictModeManager import org.mozilla.fenix.perf.lazyMonitored @@ -199,10 +196,6 @@ class Core( RecordingDevicesMiddleware(context) ) - if (!newMediaSessionApi) { - middlewareList.add(MediaMiddleware(context, MediaService::class.java)) - } - BrowserStore( middleware = middlewareList + EngineMiddleware.create(engine, ::findSessionById) ) @@ -250,9 +243,7 @@ class Core( permissionStorage.permissionsStorage, HomeActivity::class.java ) - if (newMediaSessionApi) { - MediaSessionFeature(context, MediaSessionService::class.java, store).start() - } + MediaSessionFeature(context, MediaSessionService::class.java, store).start() } } diff --git a/app/src/main/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessor.kt b/app/src/main/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessor.kt index dec4cac01..5d59643ae 100644 --- a/app/src/main/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessor.kt @@ -7,10 +7,8 @@ package org.mozilla.fenix.home.intent import android.content.Intent import androidx.navigation.NavController import mozilla.components.browser.state.selector.findTab -import mozilla.components.feature.media.service.AbstractMediaService import mozilla.components.feature.media.service.AbstractMediaSessionService import org.mozilla.fenix.BrowserDirection -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.ext.components @@ -44,17 +42,9 @@ class OpenSpecificTabIntentProcessor( } private fun getAction(): String { - return if (newMediaSessionApi) { - AbstractMediaSessionService.Companion.ACTION_SWITCH_TAB - } else { - AbstractMediaService.Companion.ACTION_SWITCH_TAB - } + return AbstractMediaSessionService.Companion.ACTION_SWITCH_TAB } private fun getTabId(): String { - return if (newMediaSessionApi) { - AbstractMediaSessionService.Companion.EXTRA_TAB_ID - } else { - AbstractMediaService.Companion.EXTRA_TAB_ID - } + return AbstractMediaSessionService.Companion.EXTRA_TAB_ID } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt index 1965f32b1..5d0832433 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt @@ -36,12 +36,6 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showAndEnable import org.mozilla.fenix.ext.toShortUrl import kotlin.math.max -import mozilla.components.browser.state.state.MediaState -import mozilla.components.feature.media.ext.pauseIfPlaying -import mozilla.components.feature.media.ext.playIfPaused -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi -import org.mozilla.fenix.ext.getMediaStateForSession -import org.mozilla.fenix.utils.Do /** * A RecyclerView ViewHolder implementation for "tab" items. @@ -99,94 +93,46 @@ class TabTrayViewHolder( // Media state playPauseButtonView.increaseTapArea(PLAY_PAUSE_BUTTON_EXTRA_DPS) - if (newMediaSessionApi) { - with(playPauseButtonView) { - invalidate() - val sessionState = store.state.findTabOrCustomTab(tab.id) - when (sessionState?.mediaSessionState?.playbackState) { - MediaSession.PlaybackState.PAUSED -> { - showAndEnable() - contentDescription = - context.getString(R.string.mozac_feature_media_notification_action_play) - setImageDrawable( - AppCompatResources.getDrawable(context, R.drawable.media_state_play) - ) - } - - MediaSession.PlaybackState.PLAYING -> { - showAndEnable() - contentDescription = - context.getString(R.string.mozac_feature_media_notification_action_pause) - setImageDrawable( - AppCompatResources.getDrawable(context, R.drawable.media_state_pause) - ) - } - - else -> { - removeTouchDelegate() - removeAndDisable() - } + with(playPauseButtonView) { + invalidate() + val sessionState = store.state.findTabOrCustomTab(tab.id) + when (sessionState?.mediaSessionState?.playbackState) { + MediaSession.PlaybackState.PAUSED -> { + showAndEnable() + contentDescription = + context.getString(R.string.mozac_feature_media_notification_action_play) + setImageDrawable( + AppCompatResources.getDrawable(context, R.drawable.media_state_play) + ) } - setOnClickListener { - when (sessionState?.mediaSessionState?.playbackState) { - MediaSession.PlaybackState.PLAYING -> { - metrics.track(Event.TabMediaPause) - sessionState.mediaSessionState?.controller?.pause() - } - - MediaSession.PlaybackState.PAUSED -> { - metrics.track(Event.TabMediaPlay) - sessionState.mediaSessionState?.controller?.play() - } - else -> throw AssertionError( - "Play/Pause button clicked without play/pause state." - ) - } + MediaSession.PlaybackState.PLAYING -> { + showAndEnable() + contentDescription = + context.getString(R.string.mozac_feature_media_notification_action_pause) + setImageDrawable( + AppCompatResources.getDrawable(context, R.drawable.media_state_pause) + ) } - } - } else { - with(playPauseButtonView) { - invalidate() - Do exhaustive when (store.state.getMediaStateForSession(tab.id)) { - MediaState.State.PAUSED -> { - showAndEnable() - contentDescription = - context.getString(R.string.mozac_feature_media_notification_action_play) - setImageDrawable( - AppCompatResources.getDrawable(context, R.drawable.media_state_play) - ) - } - - MediaState.State.PLAYING -> { - showAndEnable() - contentDescription = - context.getString(R.string.mozac_feature_media_notification_action_pause) - setImageDrawable( - AppCompatResources.getDrawable(context, R.drawable.media_state_pause) - ) - } - MediaState.State.NONE -> { - removeTouchDelegate() - removeAndDisable() - } + else -> { + removeTouchDelegate() + removeAndDisable() } } - playPauseButtonView.setOnClickListener { - Do exhaustive when (store.state.getMediaStateForSession(tab.id)) { - MediaState.State.PLAYING -> { + setOnClickListener { + when (sessionState?.mediaSessionState?.playbackState) { + MediaSession.PlaybackState.PLAYING -> { metrics.track(Event.TabMediaPause) - store.state.media.pauseIfPlaying() + sessionState.mediaSessionState?.controller?.pause() } - MediaState.State.PAUSED -> { + MediaSession.PlaybackState.PAUSED -> { metrics.track(Event.TabMediaPlay) - store.state.media.playIfPaused() + sessionState.mediaSessionState?.controller?.play() } - - MediaState.State.NONE -> throw AssertionError( + else -> throw AssertionError( "Play/Pause button clicked without play/pause state." ) } diff --git a/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt b/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt index ea155c2fc..c925bbc38 100644 --- a/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt @@ -23,7 +23,6 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.BrowserDirection -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @@ -81,13 +80,8 @@ class OpenSpecificTabIntentProcessorTest { @Test fun `GIVEN an intent with correct action and extra string WHEN it is processed THEN session should be selected and openToBrowser should be called`() { val intent = Intent().apply { - if (newMediaSessionApi) { - action = AbstractMediaSessionService.Companion.ACTION_SWITCH_TAB - putExtra(AbstractMediaSessionService.Companion.EXTRA_TAB_ID, TEST_SESSION_ID) - } else { - action = AbstractMediaService.Companion.ACTION_SWITCH_TAB - putExtra(AbstractMediaService.Companion.EXTRA_TAB_ID, TEST_SESSION_ID) - } + action = AbstractMediaSessionService.Companion.ACTION_SWITCH_TAB + putExtra(AbstractMediaSessionService.Companion.EXTRA_TAB_ID, TEST_SESSION_ID) } val store = BrowserStore(BrowserState(tabs = listOf(createTab(id = TEST_SESSION_ID, url = "https:mozilla.org")))) val tabUseCases: TabsUseCases = mockk(relaxed = true) diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayViewHolderTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayViewHolderTest.kt index f55d4d6cc..144abb980 100644 --- a/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayViewHolderTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayViewHolderTest.kt @@ -17,7 +17,6 @@ import io.mockk.verify import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.ContentState import mozilla.components.browser.state.state.MediaSessionState -import mozilla.components.browser.state.state.MediaState import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.store.BrowserStore @@ -31,7 +30,6 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mozilla.fenix.FeatureFlags.newMediaSessionApi import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @@ -83,31 +81,20 @@ class TabTrayViewHolderTest { url = "https://example.com" ) - if (newMediaSessionApi) { - state = state.copy( - tabs = listOf( - TabSessionState( - id = "123", - content = ContentState( - url = "https://example.com", - searchTerms = "search terms" - ), - mediaSessionState = mediaSessionState - ) + state = state.copy( + tabs = listOf( + TabSessionState( + id = "123", + content = ContentState( + url = "https://example.com", + searchTerms = "search terms" + ), + mediaSessionState = mediaSessionState ) ) + ) - every { mediaSessionState.playbackState } answers { MediaSession.PlaybackState.PAUSED } - } else { - state = state.copy( - media = MediaState( - aggregate = MediaState.Aggregate( - activeTabId = "123", - state = MediaState.State.PAUSED - ) - ) - ) - } + every { mediaSessionState.playbackState } answers { MediaSession.PlaybackState.PAUSED } tabViewHolder.bind(tab, false, mockk(), mockk()) @@ -124,31 +111,20 @@ class TabTrayViewHolderTest { url = "https://example.com" ) - if (newMediaSessionApi) { - state = state.copy( - tabs = listOf( - TabSessionState( - id = "123", - content = ContentState( - url = "https://example.com", - searchTerms = "search terms" - ), - mediaSessionState = mediaSessionState - ) + state = state.copy( + tabs = listOf( + TabSessionState( + id = "123", + content = ContentState( + url = "https://example.com", + searchTerms = "search terms" + ), + mediaSessionState = mediaSessionState ) ) + ) - every { mediaSessionState.playbackState } answers { MediaSession.PlaybackState.PLAYING } - } else { - state = state.copy( - media = MediaState( - aggregate = MediaState.Aggregate( - activeTabId = "123", - state = MediaState.State.PLAYING - ) - ) - ) - } + every { mediaSessionState.playbackState } answers { MediaSession.PlaybackState.PLAYING } tabViewHolder.bind(tab, false, mockk(), mockk()) From dc8c88fa50c82439a1b9385dd2a0e4561d36aa37 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sat, 6 Feb 2021 00:01:31 +0000 Subject: [PATCH 078/248] Import l10n. --- app/src/main/res/values-en-rCA/strings.xml | 98 +- app/src/main/res/values-es/strings.xml | 6 +- app/src/main/res/values-fa/strings.xml | 31 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-kmr/strings.xml | 1152 ++++++++++++++++++++ app/src/main/res/values-nl/strings.xml | 5 +- app/src/main/res/values-nn-rNO/strings.xml | 5 +- app/src/main/res/values-sq/strings.xml | 6 +- app/src/main/res/values-te/strings.xml | 5 + 9 files changed, 1274 insertions(+), 36 deletions(-) create mode 100644 app/src/main/res/values-kmr/strings.xml diff --git a/app/src/main/res/values-en-rCA/strings.xml b/app/src/main/res/values-en-rCA/strings.xml index 7c6c578bc..f9baeb8e9 100644 --- a/app/src/main/res/values-en-rCA/strings.xml +++ b/app/src/main/res/values-en-rCA/strings.xml @@ -20,6 +20,10 @@ Your private tabs will be shown here. + + Baidu + + JD 1 open tab. Tap to switch tabs. @@ -71,14 +75,6 @@ No thanks - - - Get to Firefox faster. Add a widget to your Home screen. - - Add widget - - Not now - You can set Firefox to automatically open links in apps. @@ -101,6 +97,13 @@ Dismiss + + Change the layout of open tabs. Go to settings and select grid under tab view. + + Go to settings + + Dismiss + New tab @@ -151,8 +154,6 @@ Find in page Private tab - - New tab Save to collection @@ -359,6 +360,12 @@ Add-on collection modified. Quitting the application to apply changes… + + + Add-on is not supported + + Add-on is already installed + Sync now @@ -437,6 +444,10 @@ Marketing data Shares data about what features you use in %1$s with Leanplum, our mobile marketing vendor. + + Studies + + Allows Mozilla to install and run studies Experiments @@ -559,6 +570,15 @@ After one month + + Close manually + + Close after one day + + Close after one week + + Close after one month + Open tabs @@ -576,6 +596,8 @@ Open Tabs Save to collection + + Select Share all tabs @@ -590,8 +612,18 @@ Go home Toggle tab mode + + Bookmark + + Close + + Share selected tabs + + Selected tabs menu Remove tab from collection + + Select tabs Close tab @@ -627,8 +659,10 @@ Collection name - - Remove + + Rename + + Remove Delete from history @@ -681,12 +715,27 @@ No history here + + Delete downloads + + Are you sure you want to clear your downloads? + + Downloads Removed + + Removed %1$s - No downloads here + No downloaded files %1$d selected + + + Open + + Remove + + Sorry. %1$s can’t load that page. @@ -808,6 +857,8 @@ Notification Persistent Storage + + DRM-controlled content Ask to allow @@ -947,6 +998,12 @@ Tab closed Tabs closed + + Tabs closed! + + Bookmarks saved! + + View Added to top sites! @@ -1022,6 +1079,8 @@ Frees up storage space Site permissions + + Downloads Delete browsing data @@ -1143,9 +1202,7 @@ Your privacy - We’ve designed %s to give you control over what you share - online and what you share with us. - + We’ve designed %s to give you control over what you share online and what you share with us. Read our privacy notice @@ -1603,6 +1660,15 @@ Show most visited sites + + Name + + Top site name + + OK + + Cancel + Remove diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 21a0f87f1..ad65854cf 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1119,6 +1119,8 @@ Libera espacio de almacenamiento Permisos de los sitios + + Descargas Eliminar datos de navegación @@ -1243,9 +1245,7 @@ Tu privacidad - Hemos diseñado %s para darte control sobre lo que compartes - en línea y lo que compartes con nosotros. - + Hemos diseñado %s para darte el control sobre lo que compartes en línea y lo que compartes con nosotros. Lee nuestro aviso de privacidad diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index ca33925c9..b0fb3425e 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -8,9 +8,9 @@ گزینه‌های بیشتر - فعال شده در حالت مرور خصوصی + فعال کردن حالت خصوصی - غیر فعال شده در حالت مرور خصوصی + غیرفعال کردن حالت مرور خصوصی جست‌وجو یا ورود آدرس @@ -24,7 +24,7 @@ JD - 1 زبانه باز. برای تغییر زبانه ها ضربه بزنید. + 1 زبانه‌ي باز. برای تغییر زبانه ها ضربه بزنید. %1$s زبانه‌های باز. برای تغییر زبانه‌ها ضربه بزنید. @@ -68,9 +68,9 @@ برای باز کردن زبانه های خصوصی از صفحه اصلی ، میانبر اضافه کنید. - میانبر را اضافه کنید + افزودن میانبر - نه، ممنون! + نه، ممنون @@ -192,13 +192,13 @@ - اسکن + بررسی موتور جست‌وجو تنظیمات موتور جستجو - این بار، جست‌وجو با: + این بار بگرد با: پیوند را از کلیپ بورد پر کنید @@ -493,6 +493,11 @@ موضوع دستگاه را دنبال کنید + + + برای تازه‌ سازی صفحه بکشید + + برای پنهان‌ کردن نوار ابزار پیمایش کنید برای جابجایی بین زبانه‌ها، نوار ابزار را به طرفین بکشید @@ -1078,6 +1083,8 @@ فضای ذخیره سازی را آزاد می کند مجوزهای سایت + + دریافت‌ها داده مرور را حذف کنید @@ -1148,6 +1155,10 @@ شروع به همگام سازی نشانک‌ها،‌ گذرواژه ها و چیزهای بیشتر با حساب Firefox شما. اطلاعات بیشتر + + شما به عنوان%s در یک مرورگر دیگر Firefox در این تلفن وارد شده اید. آیا می خواهید با این حساب وارد شوید؟ بله،‌ من را وارد کن @@ -1195,8 +1206,7 @@ حریم‌ خصوصی شما - ما%s طراحی کرده ایم تا بتوانیم بر آنچه به اشتراک می گذارید کنترل کنید -        آنلاین و آنچه را با ما به اشتراک می گذارید. + ما%s طراحی کرده ایم تا بتوانیم بر آنچه به صورت انلاین یا با ما اشتراک می گذارید کنترل داشته باشید. اعلامیه حریم خصوصی ما را بخوانید @@ -1397,6 +1407,9 @@ نام میانبر + + شما به راحتی می‌توانید این پایگاه اینترنتی را به صفحه خانگی تلفن خود اضافه کنید تا دسترسی مستقیم به آن داشته باشید و مرور سریعتی را مانند تجربه کردن یک برنامه داشته باشید. + ورودها و گذرواژه‌ها diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 79cea5f88..60f385327 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -205,7 +205,7 @@ Adesso cerca con: - Copia il link dagli appunti + Incolla il link dagli appunti Consenti diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml new file mode 100644 index 000000000..d6a2ef5da --- /dev/null +++ b/app/src/main/res/values-kmr/strings.xml @@ -0,0 +1,1152 @@ + + + + Taybet %s + + %s (Taybet) + + + + + Vebijarkên zêdetir + + Gerîna taybet veke + + Gerîna taybet bigire + + Lê bigere an jî navnîşanê bikevê + + Hilpekînên te yên vekirî ew ê li vir bên nîşandan. + + Hilpekînên te yên taybet ew ê li vir bên nîşandan. + + Baidu + + JD + + 1 hilpekîna vekirî. Ji bo hilpekînê biguherînî, bitikîne. + + %1$s hilpekînên vekirî. Ji bo hilpekînê biguherînî, bitikîne. + + %1$d hilpekîn hatin bijartin + + Koleksiyona nû tevlî bike + + Nav + + Koleksiyonê hilbijêre + + Ji moda pir-bijartinê derkeve + + Hilpekînên bijartî li koleksiyonê qeyd bike + + %1$s hat bijartin + + + Bıjartina %1$s hate rakirin + + Ji moda pir-bijartinê hate derketin + + + Tu ket moda pir-bijartinê, ji bo tomarkirina li koleksiyonê hilpekînan hilbijêre + + Hate bijartin + + + %1$s berhemeke Mozillayê ye. + + + + Tu di rûniştina taybet de yî. + + + %1$s, dema ku te hilpekînên taybet girtin an jî tu ji sepanê derket ew ê raboriya te ya gerîn û lêgerînê ji hilpekînên taybet bên paqijkirin. Ev, rê li ber şopandina/nedîtina te ji aliyê malper û peydakerên servîsê ve nagirê lê heke hin kesên din ên vê cîhazê bi kar tînin hebin ew ê bihêle ku tu raboriya xwe ji wan veşêrî. + + Efsaneyên berbelav ên derbarê gerîna taybet de + + + Rûniştinê jê bibe + + + + Ji bo ku tu ji ekrana xwe ya Destpêkê hilpekîneke taybet vekî, kurterêyekê tevlî bike. + + Kurterêyê tevlî bike + + Na, spas + + + + Tu dikarî Firefoxê saz bike ku girêdanan bi otomatîkî di sepanan de veke. + + Here sazkariyan + + Bigire + + + Gihîna kamerayê hewce ye. Here sazkariyên Androidê ji beşa destûran, destûrê bide. + + Here sazkariyan + + Bigire + + + Hilpekînên vekirî yên ku di ser wan re roj, hefte an jî meh derbas bûne tu dikarî wan bixweber bidî girtin. + + Vebijarkan bibîne + + Bigire + + + Tu dikarî raxistina hilpekînên vekirî biguherînî. Here sazkariyan û ji bin "xuyabûna hilpekînê" gridê hilbijêre. + + Here sazkariyan + + Bigire + + + + + Hilpekîna nû + + Hilpekîna taybet a nû + + Malperên favorî + + + + Hilpekînên vekirî + + Paşve + + Pêşve + + Nû bike + + Rawestîne + + Pêvek + + Ti pêvek li vir tune + + Alîkarî + + Çi tiştên nû hene? + + Sazkarî + + Pirtûkxane + + Malpera sermaseyê + + Tevlî ekrana destpêkê bike + + Saz bike + + Hilpekînên senkronîzekirî + + Dîsa senkronîze bike + + Di rûpelê de bibîne + + Hilpekîna taybet + + Li koleksiyonê tomar bike + + Parve bike + + Parve bike bi… + + Di %1$s de veke + + Bihêzkirin ji aliyê %1$s + + Bihêzkirin ji aliyê %1$s + + Moda xwînerê + + Moda xwînerê bigire + + Di sepanê de veke + + Xuyang + + Nayê girêdan. Şemaya URLyê nayê nasîn. + + + + Zimanê hilbijartî + + + + Lêgerîn + + Zimanê cîhazê + + Li zimanan bigere + + + Motora lêgerînê + + Sazkariyên motora lêgerînê + + Îja ka bi vê bigere: + + Girêdanê ji panoyê bîne + + Destûrê bide + + Destûrê nede + + Di rûniştina taybet de bila pêşniyarên lêgerînê were pêş te? + + Zêdetir bizane + + + + Hilpekîna nû ya Firefoxê veke + + Lêgerîn + + Di web’ê de bigere + + Lêgerîna dengî + + + + Sazkarî + + Bingeh + + Giştî + + Derbar + + Motora lêgerînê ya jixweber + + Lêgerîn + + Alîkarî + + Li ser Google Playê puan bide + + Paşragihandinê bişîne + + Derbarê %1$s + + + + Mafên te + + Pêborîn + + Kartên krediyê û navnîşan + + Bike geroka sereke + + Pêşketî + + Nihênî + + Nihênî û ewlehî + + Destûrên malperê + + Gerîna taybet + + Girêdanan di hilpekîna taybet de veke + + Gihînbarî + + Servera taybet a hesabê Firefoxê + + Hesab + + Têkeve + + Rûkar + + Serrûpel + + Taybet bike + + Hesabê Firefoxê + + Ziman + + Vebijarkên daneyê + + Berhevkirina daneyan + + Agahdariya nihêniyê + + Amûrên pêşvebirinê + + Lêgerîna dengî nîşan bide + + Sazkariyên hesêb + + Navnîşanan bixweber dagire + + Girêdanan di sepanan de veke + + Pêvek + + Danezan + + + + Koleksiyona pêvekên taybet + + Baş e + + Betal bike + + Navê koleksiyonê + + Xwediyê koleksiyonê (nasnameya bikarhêner) + + + + Pêvek nayê piştgirîkirin + + + Pêvek jixwe sazkirî ye + + + + + Aniha senkronîze bike + + Bila çi bên senkronîzekirin, hilbijêre + + Raborî + + Hesab + + Hilpekînên vekirî + + Derkeve + + Navê cîhazê + + Navê cîhazê nabe vala bimîne. + + + Tê sekronîzekirin… + + + Senkronîzekirin têk çû, Senkronîzeya dawî: %s + + Senkronîzekirin têk çû, Senkronîzeya dawî: tune + + Senkronîzekirina dawî: %s + + Senkronîzekirina dawî: tune + + + %1$s - %2$s %3$s + + + + Hilpekînên hatine wergirtin + + Hilpekîn hate wergirtin + + Hilpekîn hatin wergirtin + + Hilpekîna ji %s ve hat + + + + Parastina ji Şopandinê + + Parastina ji Şopandinê + + + Zêdetir bizane + + + Telemetrî + + Daneyên bazarkirinê + + Lêkolîn + + + Raporkera têkçûnan + + + Xizmeta cîgehê ya Mozillayê + + Rapora tenduristiyê ya %s’ê + + + + Sync’ê veke + + Têkeve + + Hesêb rake + + + Kamerayê veke + + Betal + + + + Li jorê + + Li jêrê + + + + Ronî + + Tarî + + + Rûkara cîhazê bi kar bîne + + + + Rûniştin + + Wêneyên ekranê + + Daxistinên te + + Raborî + + Lîsteya xwendinê + + Lêgerîn + + Sazkarî + + Bigire + + + %d hilpekîn + + %d hilpekîn + + + + Hilpekîn + + Xuyabûna hilpekînê + + Lîste + + Grid + + + Hilpekînan bigire + + Manûel + + Piştî rojekê + + Piştî hefteyekê + + Piştî mehekê + + + Manûelê bigire + + Piştî rojekê bigire + + Piştî hefteyekê bigire + + Piştî mehekê bigire + + + + Hilpekînên vekirî + + Rûniştina taybet + + Hilpekînên taybet + + Hilpekînê tevlî bike + + Hilpekîna taybet tevlî bike + + Taybet + + Hilpekînên vekirî + + Li koleksiyonê tomar bike + + Hilbijêre + + Hemû hilpekînan parve bike + + Sazkariyên hilpekînê + + Hemû hilpekînan bigire + + Hilpekîna nû + + Here serrûpelê + + Bigire + + Hilpekînan hilbijêre + + Hilpekînê bigire + + Hemû hilpekînan bigire + + Hilpekînan parve bike + + Hilpekînan li koleksiyonê tomar bike + + Menûya hilpekînan + + Hilpekînê parve bike + + Jê bibe + + Tomar bike + + Parve bike + + Wêneyê rûniştina niha + + Li koleksiyonê tomar bike + + Koleksiyonê jê bibe + + Koleksiyonê bi nav bike + + Hilpekînan veke + + Navê koleksiyonê + + Nav biguherîne + + Rake + + Ji raboriyê rake + + %1$s (Moda Taybet) + + Tomar bike + + + + Raboriyê jê bibe + + Tu bi rastî jî dixwazî raboriya xwe paqij bikî? + + Raborî hate jêbirin + + + + %1$s hate jêbirin + + Paqij bike + + Kopî + + Parve bike + + Di hilpekîna nû de veke + + Di hilpekîna taybet de veke + + Jê bibe + + %1$d hate bijartin + + %1$d hêmanan jê bibe + + Îro + + Doh + + 24 saetên dawî + + 7 rojên dawî + + 30 rojên dawî + + Kevntir + + Raborî tune + + + + Daxistinan jê bibe + + Tu bi rastî jî dixwazî daxistinên xwe paqij bikî? + + Daxistin hatin rakirin + + %1$s hate rakirin + + Ti tişt nehatiye daxistin + + Veke + + Rake + + + + Hilpekînê bigire + + + Peldankê tevlî bike + + SERERAST BIKE + + Sererast bike + + Hilbijêre + + Kopî bike + + Parve bike + + Jê bibe + + Tomar bike + + + Peldankê sererast bike + + NAVNÎŞAN + + PELDANK + + NAV + + Peldankê tevlî bike + + Peldankê hilbijêre + + Sernav hewce ye + + + VEGERÎNE + + + + Destûr + + Here sazkariyan + + Kamera + + Mîkrofon + + Cîgeh + + Danezan + + Ji hêla Androidê ve hate astengkirin + + Istisna + + Vekirî + + Girtî + + Destûrê bide deng û vîdyoyê + + Deng û vîdyoyê tenê di daneya hucreyî de asteng bike + + Deng û vîdyo ew ê tenê di Wi-Fi de bên vekirin + + Tenê dengan asteng bike + + Deng û vîdyoyê asteng bike + + Vekirî + + Girtî + + + + Koleksiyon + + Menûya koleksiyonê + + Hilpekînan hilbijêre + + Koleksiyonê hilbijêre + + Koleksiyonê bi nav bike + + Koleksiyona nû tevlî bike + + Gişî hilbijêre + + Ji bo tomarkirinê, hilpekînan hilbijêre + + %d hilpekîn hatin bijartin + + %d hilpekîn hate bijartin + + Hilpekîn hatin tomarkirin! + + Koleksiyon hate tomarkirin! + + Hilpekîn hate tomarkirin! + + Bigire + + Tomar bike + + Bibîne + + + Koleksiyona %d + + + + Bişîne û parve bike + + Parve bike + + Parve bike + + Girêdanê parve bike + + Bişîne cîhazê + + Hemû çalakî + + Têkeve Sync’ê + + Ji hemû cîhazan re bişîne + + Dîsa li Sync’ê girê bide + + Derhêl + + Cîhazeke din girê bide + + Min fêm kir + + Bişîne cîhazê + + + Veke + + Jê bibe û veke + + Bihêzkirin ji aliyê + + Koleksiyon hate jêbirin + + Hilpekîn hate jêbirin + + Hilpekîn hatin jêbirin + + Hilpekîn hate girtin + + Hilpekîn hatin girtin + + Hilpekîn hatin girtin! + + Bibîne + + Tevlî malperên favorî bû! + + Hilpekîna taybet hate girtin + + Hilpekînên taybet hatin girtin + + Hilpekînên taybet hatin jêbirin + + VEGERÎNE + + Malper hate rakirin + + Vegerîne + + Bipejirîne + + BIHÊLE + + NEHÊLE + + Tu bi rastî jî dixwazî koleksiyana %1$s’ê were jêbirin? + + %1$s’ê jê bibe? + + Jê bibe + + Betal bike + + URL hate kopîkirin + + Mezinahiya fontê + + + Daneyên gerînê jê bibe + + Hilpekînên vekirî + + %d hilpekîn + + Raboriya gerînê û daneyên malperê + + %d navnîşan + + Raborî + + %d rûpel + + Kûkî + + Daxistinên te + + Daneyên gerînê jê bibe + + Derkeve + + + Betal bike + + Jê bibe + + + Daneyên gerînê hate jêbirin + + Daneyên gerînê tên jêbirin… + + + + Firefox Preview niha bûye Firefox Nightly + + + + Tu bi xêr hatî %s’ê! + + Jixwe hesabekî te heye? + + %s’ê nas bike + + Tiştên nû bibîne + + Bersiv li vir in + + Zêdetir bizane + + Erê, têkeve + + Dikevê… + + Têkeve Firefox’ê + + Têketinê neke + + Sync vekirî ye + + Têketin bi ser neket + + Nihêniya otomatîk + + Standard (jixweber) + + Tund (tê pêşniyarkirin) + + Tund + + Sazkariyan veke + + Nihêniya te + + Agahdariya me ya nihêniyê bixwîne + + Bigire + + + Dest bi gerînê bike + + + + Rûkara xwe hilbijêre + + Otomatîk + + Rûkara tarî + + Rûkara ronî + + + Hilpekîn hatin şandin! + + Hilpekîn hate şandin! + + Nehate şandin + + DÎSA BICERIBÎNE + + Girêdanê qut bike + + Betal bike + + + Paşve here + + Mafên te + + Di %s çi tiştên nû hene? + + %s | Pirtûkxaneyên OSS’ê + + + Piştgirî + + Agahdariya nihêniyê + + + 1 hilpekîn + + %d hilpekîn + + + + Kopî bike + + Bizeliqîne û here + + Bizeliqîne + + URL li panoyê hate kopîkirin + + + Tevlî ekrana destpêkê bike + + Betal bike + + Tevlî bike + + Li malperê berdewam bike + + Navê kurterêyê + + + Hesab û pêborîn + + Hesab û pêborînan tomar bike + + Ji bo tomarkirinê, bipirse + + Qet tomar neke + + Bixweber dagire + + Hesaban senkronîze bike + + Vekirî + + Girtî + + Dîsa girê bide + + Têkeve Sync’ê + + Hesabên tomarkirî + + Derbarê Sync’ê de agahî bistîne. + + Istisna + + Hemû istisnayan jê bibe + + Li hesaban bigere + + Alfabetîkî + + Malper + + Navê bikarhêner + + Pêborîn + + PIN’a xwe dîsa bikevê + + Zêdetir bizane + + Bila %s, vî hesabî tomar bike? + + Tomar bike + + Tomar neke + + Pêborîn li panoyê hate kopîkirin + + Navê bikarhêner li panoyê hate kopîkirin + + Malper li panoyê hate kopîkirin + + Pêborînê kopî bike + + Pêborînê paqij bike + + Navê bikarhêner kopî bike + + Navê bikarhêner paqij bike + + Malperê kopî bike + + Malperê di gerokê de veke + + Pêborînê nîşan bide + + Pêborînê veşêre + + ji bo hesabên xwe yên tomarkirî bibînî, kilîdê veke + + Hesab û pêborînên xwe biparêze + + Piştre + + Aniha saz bike + + Kilîda cîhaza xwe rake + + Hemû malperan nêzîk bike + + Nav (A-Z) + + Bikaranîna dawî + + + Motora lêgerînê tevlî bike + + Motora lêgerînê sererast bike + + + Tevlî bike + + Tomar bike + + Sererast bike + + Jê bibe + + + Yên din + + Nav + + Zêdetir Bizane + + + %s tê nûvekirin… + + Pêborîn + + + Ji bo destûrdayînê: + + 1. Here sazkariyên Androidê + + Destûrê bitikîne]]> + + %1$sê bike VEKIRÎ]]> + + + Girêdana ewle + + Girêdana neewle + + Istisnayên malperê tune + + Gotarên Serekî + + Tevlî malperên favorî bike + + Piştrastkirin ji aliyê: %1$s + + Jê bibe + + Sererast bike + + + Tu bi rastî jî dixwazî vî hesabî jê bibî? + + Jê bibe + + Vebijarkên hesêb + + Guhertinan li hesêb tomar bike. + + Guhertinan betal bike + + Sererast bike + + Pêborîn hewce ye + + Lêgerîna dengî + + Aniha bipeyive + + Jixwe hesabek bi vî navê bikarhêneriyê heye + + + + Cîhazeke din girê bide. + + Ji kerema xwe, ji nû ve têkeve. + + Ji kerema xwe, senkronîzekirina hilpekînê veke. + + Têkeve Sync’ê + + Hilpekînên vekirî tune + + + + Gihîşte sînorê malperên favorî + + + Baş e + + Nav + + Navê malpera favorî + + Baş e + + Betal bike + + + Rake + + + Ji bo agahiyên zêdetir, bitikîne + + + Tiştên ku ji te re girîng in berhev bike + diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 06b20c412..3695b01ae 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -1129,8 +1129,9 @@ Firefox Preview is nu Firefox Nightly - Firefox Nightly wordt elke nacht bijgewerkt en heeft experimentele nieuwe functies. - Het is echter mogelijk minder stabiel. Download onze bètabrowser voor een meer stabiele ervaring. + + Firefox Nightly wordt elke nacht bijgewerkt en heeft experimentele nieuwe functies. + Het is echter mogelijk minder stabiel. Download onze betabrowser voor een meer stabiele ervaring. Download Firefox voor Android Beta diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index 58d1377c7..a3a44291e 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -1101,6 +1101,8 @@ Frigjer lagringsplass Nettstadløyve + + Nedlastingar Slett nettlesardata @@ -1225,8 +1227,7 @@ Ditt personvern - Vi har utvikla %s for å gi deg kontroll over det du deler -        på nettet og kva du deler med oss. + Vi har utvikla %s for å gi deg kontroll over det du deler på nettet og kva du deler med oss. Les personvernmerknaden vår diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index f2410d8eb..a4f867572 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -1084,6 +1084,8 @@ Liron hapësirë depozitimi Leje sajti + + Shkarkime Fshi të dhëna shfletimi @@ -1207,9 +1209,7 @@ Privatësia juaj - E kemi hartuar %s për t’ju dhënë kontroll mbi ç’ndani me - të tjerë në internet dhe ç’ndani me ne. - + E kemi hartuar %s për t’ju dhënë kontroll mbi ç’ndani me të tjerë në internet dhe ç’ndani me ne. Lexoni shënimin tonë mbi privatësinë diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index a19cf0da0..25e6030c3 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -537,6 +537,8 @@ ట్యాబులు + + ట్యాబు వీక్షణ జాబితా @@ -1348,6 +1350,9 @@ దారిమళ్ళింపు ట్రాకర్లు + + తెలిసిన ట్రాకింగు వెబ్‌సైట్లు దారిమార్పుల ద్వారా అమర్చే కుకీలను తుడిచివేస్తుంది. + తోడ్పాటు From f6455b014830bd36b0d001cbc750a6b9e5de6bbf Mon Sep 17 00:00:00 2001 From: ekager Date: Fri, 5 Feb 2021 17:47:25 -0700 Subject: [PATCH 079/248] Closes #17871 - use viewLifecycleOwner for TopSitesFeature owner on HomeFragment (#17873) --- app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 1ea437124..3cd9a2989 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -234,7 +234,7 @@ class HomeFragment : Fragment() { storage = components.core.topSitesStorage, config = ::getTopSitesConfig ), - owner = this, + owner = viewLifecycleOwner, view = view ) From 13f5df33a162e3bd00fe75437ce3ed008badc600 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Tue, 2 Feb 2021 23:31:30 -0800 Subject: [PATCH 080/248] Hiding the usernameview if the data item.username is blank. --- .../mozilla/fenix/settings/logins/view/LoginsListViewHolder.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/view/LoginsListViewHolder.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/view/LoginsListViewHolder.kt index 223139995..f6c89acbb 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/view/LoginsListViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/view/LoginsListViewHolder.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.settings.logins.view import android.view.View +import androidx.core.view.isVisible import kotlinx.android.synthetic.main.logins_item.* import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.loadIntoView @@ -28,6 +29,7 @@ class LoginsListViewHolder( timeLastUsed = item.timeLastUsed ) webAddressView.text = item.origin + usernameView.isVisible = item.username.isNotEmpty() usernameView.text = item.username updateFavIcon(item.origin) From b057dead450cacaf9e360bce24f790ad7053108f Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sun, 7 Feb 2021 00:05:29 +0000 Subject: [PATCH 081/248] Import l10n. --- app/src/main/res/values-ca/strings.xml | 21 ++-- app/src/main/res/values-kmr/strings.xml | 130 +++++++++++++++++++----- 2 files changed, 121 insertions(+), 30 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index da6be1f05..4ea32843a 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -726,10 +726,12 @@ Suprimeix les baixades Segur que voleu esborrar les baixades? - - S’han suprimit les baixades + + S’han eliminat les baixades + + S’ha eliminat %1$s - No hi ha cap baixada + No hi ha cap fitxer baixat %1$d seleccionades @@ -737,8 +739,10 @@ Obre - - Suprimeix + + + + Elimina @@ -862,6 +866,8 @@ Notificació Emmagatzematge persistent + + Contingut controlat per DRM Demana-m’ho @@ -1086,6 +1092,8 @@ Permisos dels llocs + + Baixades Suprimeix les dades de navegació @@ -1208,8 +1216,7 @@ La vostra privadesa - Hem dissenyat el %s per donar-vos el control sobre tot allò que compartiu en línia i que compartiu amb nosaltres. - + Hem dissenyat el %s per donar-vos el control sobre tot allò que compartiu en línia i que compartiu amb nosaltres. Mostra l’avís de privadesa diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index d6a2ef5da..5160a024c 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -1,24 +1,24 @@ - Taybet %s + %s’a veşartî - %s (Taybet) + %s (Veşartî) Vebijarkên zêdetir - Gerîna taybet veke + Gerîna veşartî veke - Gerîna taybet bigire + Gerîna veşartî bigire Lê bigere an jî navnîşanê bikevê Hilpekînên te yên vekirî ew ê li vir bên nîşandan. - Hilpekînên te yên taybet ew ê li vir bên nîşandan. + Hilpekînên te yên veşartî ew ê li vir bên nîşandan. Baidu @@ -57,20 +57,20 @@ - Tu di rûniştina taybet de yî. + Tu di rûniştina veşartî de yî - %1$s, dema ku te hilpekînên taybet girtin an jî tu ji sepanê derket ew ê raboriya te ya gerîn û lêgerînê ji hilpekînên taybet bên paqijkirin. Ev, rê li ber şopandina/nedîtina te ji aliyê malper û peydakerên servîsê ve nagirê lê heke hin kesên din ên vê cîhazê bi kar tînin hebin ew ê bihêle ku tu raboriya xwe ji wan veşêrî. + %1$s, dema ku te hilpekînên veşartî girtin an jî tu ji sepanê derket ew ê raboriya te ya gerîn û lêgerînê ji hilpekînên veşartî bên paqijkirin. Ev, rê li ber şopandina/nedîtina te ya ji aliyê malper û peydakerên servîsê ve nagirê lê heke hin kesên din ên vê cîhazê bi kar tînin hebin ew ê bihêle ku tu raboriya xwe ji wan veşêrî.
- Efsaneyên berbelav ên derbarê gerîna taybet de + Efsaneyên berbelav ên derbarê gerîna veşartî de Rûniştinê jê bibe - Ji bo ku tu ji ekrana xwe ya Destpêkê hilpekîneke taybet vekî, kurterêyekê tevlî bike. + Ji bo ku tu ji ekrana xwe ya Destpêkê hilpekîneke veşartî vekî, kurterêyekê tevlî bike. Kurterêyê tevlî bike @@ -110,7 +110,7 @@ Hilpekîna nû - Hilpekîna taybet a nû + Hilpekîna veşartî ya nû Malperên favorî @@ -150,7 +150,7 @@ Di rûpelê de bibîne - Hilpekîna taybet + Hilpekîna veşartî Li koleksiyonê tomar bike @@ -203,7 +203,7 @@ Destûrê nede - Di rûniştina taybet de bila pêşniyarên lêgerînê were pêş te? + Di rûniştina veşartî de bila pêşniyarên lêgerînê werin pêş te? Zêdetir bizane @@ -258,13 +258,15 @@ Destûrên malperê - Gerîna taybet + Gerîna veşartî - Girêdanan di hilpekîna taybet de veke + Girêdanan di hilpekîna veşartî de veke Gihînbarî Servera taybet a hesabê Firefoxê + + Servera taybet a Sync`ê Hesab @@ -287,8 +289,18 @@ Agahdariya nihêniyê Amûrên pêşvebirinê + + Motorên lêgerînê nîşan bide + + Pêşniyarên lêgerînê nîşan bide Lêgerîna dengî nîşan bide + + Di rûniştinên veşartî de nîşan bide + + Pêşniyarên panoyê nîşan bide + + Di raboriya gerînê de lê bigere Sazkariyên hesêb @@ -432,6 +444,8 @@ Lêgerîn Sazkarî + + Menûya hêmana raboriyê Bigire @@ -476,15 +490,15 @@ Hilpekînên vekirî - Rûniştina taybet + Rûniştina veşartî - Hilpekînên taybet + Hilpekînên veşartî Hilpekînê tevlî bike - Hilpekîna taybet tevlî bike + Hilpekîna veşartî tevlî bike - Taybet + Veşartî Hilpekînên vekirî @@ -507,6 +521,10 @@ Hilpekînan hilbijêre Hilpekînê bigire + + Hilpekîna %s’ê bigire + + Menûya hilpekînên vekirî, veke Hemû hilpekînan bigire @@ -542,7 +560,7 @@ Ji raboriyê rake - %1$s (Moda Taybet) + %1$s (Moda Veşartî) Tomar bike @@ -566,7 +584,7 @@ Di hilpekîna nû de veke - Di hilpekîna taybet de veke + Di hilpekîna veşartî de veke Jê bibe Ti tişt nehatiye daxistin + + %1$d hatin bijartin Veke Rake + + + Bibore. %1$s, nikare vê rûpelê bar bike. + + Rapora têkçûnê ji Mozillayê re bişîne Hilpekînê bigire + + Hilpekînê vegerîne + + + Vebijarkên rûniştinê + + + Rûniştinê parve bike + + + Peldankê hilbijêre + + Tu bi rastî jî dixwazî vê peldankê jê bibî? + + %s ew ê hêmanên bijartî jê bibe. + + %1$s hate jêbirin Peldankê tevlî bike @@ -622,11 +665,18 @@ Kopî bike Parve bike + + Di hilpekîna nû de veke + + Di hilpekîna veşartî de veke Jê bibe Tomar bike + + %1$d hatin bijartin Peldankê sererast bike @@ -642,6 +692,11 @@ Sernav hewce ye + + URL’ya nederbasdar + + %1$s hate jêbirin VEGERÎNE @@ -650,6 +705,14 @@ Destûr Here sazkariyan + + Tê pêşniyarkirin + + Destûrên malperê birêve bibe + + Destûran paqij bike + + Destûrê paqij bike Kamera @@ -658,6 +721,12 @@ Cîgeh Danezan + + Bîrgeha mayinde + + Destûrê bixwaze + + Hate astengkirin Ji hêla Androidê ve hate astengkirin @@ -772,11 +841,11 @@ Tevlî malperên favorî bû! - Hilpekîna taybet hate girtin + Hilpekîna veşartî hate girtin - Hilpekînên taybet hatin girtin + Hilpekînên veşartî hatin girtin - Hilpekînên taybet hatin jêbirin + Hilpekînên veşartî hatin jêbirin VEGERÎNE @@ -911,6 +980,21 @@ Betal bike + + Zêdetir bizane + + Tund + + Taybet + + + Kûkî + + Di hemû hilpekînan de + + Tenê di hilpekînên veşartî de + + Tenê di hilpekînên taybet de Paşve here From 3a1d56d7c81f3af0e38735ef8fabe990e3f743ab Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Fri, 5 Feb 2021 16:47:01 -0500 Subject: [PATCH 082/248] For #17817 Change the feature prompt references from fragment to activity. --- .../main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 6a4bcc9ff..5f3de347c 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -538,7 +538,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit promptsFeature.set( feature = PromptFeature( - fragment = this, + activity = activity, store = store, customTabId = customTabSessionId, fragmentManager = parentFragmentManager, From e24580f0b7a4ef2e02f4f1549eeeee1d41d8371e Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Mon, 8 Feb 2021 00:09:00 +0000 Subject: [PATCH 083/248] Import l10n. --- app/src/main/res/values-ja/strings.xml | 3 + app/src/main/res/values-kmr/strings.xml | 347 +++++++++++++++++++++++- app/src/main/res/values-sat/strings.xml | 29 +- app/src/main/res/values-th/strings.xml | 5 +- 4 files changed, 363 insertions(+), 21 deletions(-) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 9b8f339bd..0cb6e8306 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1229,6 +1229,9 @@ 設定を開く あなたのプライバシー + + %s は、あなたがオンラインで共有するものと、私たちと共有するものをコントロールできるように設計されています。 個人情報保護方針を読む diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 5160a024c..a60f1b66d 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -14,7 +14,7 @@ Gerîna veşartî bigire - Lê bigere an jî navnîşanê bikevê + Lêgerîn yan navnîşanek Hilpekînên te yên vekirî ew ê li vir bên nîşandan. @@ -125,6 +125,10 @@ Nû bike Rawestîne + + Favorî + + Favoriyan serast bike Pêvek @@ -190,6 +194,9 @@ Li zimanan bigere + + + Sken Motora lêgerînê @@ -204,6 +211,8 @@ Destûrê nede Di rûniştina veşartî de bila pêşniyarên lêgerînê werin pêş te? + + %s dê hemû tiştên tu li darikê navnîşanan binivîsî bi motora te ya lêgerînê ya derbasdar re parve bike. Zêdetir bizane @@ -230,6 +239,8 @@ Motora lêgerînê ya jixweber Lêgerîn + + Dariikê navnîşanan Alîkarî @@ -261,24 +272,40 @@ Gerîna veşartî Girêdanan di hilpekîna veşartî de veke + + Destûrê bide girtina wêneyê ekranê di gera nepen de + + Heke destûrê bidî, gava gelek bernamok vekirî bin hilpekînên nepen dê xuya bibin + + Kurteriya gera nepen lê zêde bike Gihînbarî Servera taybet a hesabê Firefoxê Servera taybet a Sync`ê + + Hesabê Firefoxê/PÊşkêşkara Sync hat guhertin. Ji bo sepandina guhertinan ji bernameyê derdikeve… Hesab Têkeve + + Darikê amûran Rûkar Serrûpel + + Îşaretên tiliyan Taybet bike + + Bi hesabê xwe yê Firefoxê favorî, mêjû û zêdetir tiştên xwe hevseng bike Hesabê Firefoxê + + Ji bo dewamkirina hevsengkirinê dîsgirêdanê çêke Ziman @@ -289,6 +316,8 @@ Agahdariya nihêniyê Amûrên pêşvebirinê + + Bi riya USBê ji dûr ve neqandina çewtiyan Motorên lêgerînê nîşan bide @@ -301,12 +330,18 @@ Pêşniyarên panoyê nîşan bide Di raboriya gerînê de lê bigere + + Di favoriyan de bigere + + Di hilpekînên hevsengkirî de bigere Sazkariyên hesêb Navnîşanan bixweber dagire Girêdanan di sepanan de veke + + Rêvebera jêbarkirinê ya derveyî Pêvek @@ -324,6 +359,9 @@ Xwediyê koleksiyonê (nasnameya bikarhêner) + + Koleksiyona pêvekan hat guhertin. Ji bo sepandina guhertinan ji bernamokê derdikeve… + Pêvek nayê piştgirîkirin @@ -339,6 +377,8 @@ Bila çi bên senkronîzekirin, hilbijêre Raborî + + Favorî Hesab @@ -370,6 +410,8 @@ Hilpekînên hatine wergirtin + + Danezanên ji bo hilpekînên ji amûrên din yên Firefoxê hatî Hilpekîn hate wergirtin @@ -383,16 +425,37 @@ Parastina ji Şopandinê + + Naverok û skrîptên li ser înternetê te dişopînin asteng bike + + Istisna + + Ji bo van malperan Parastina ji Şopandinê hat girtin + + Ji bo hemû malperan veke + + Istisna dihêle ku tu dikaribî ji bo malperên hilbijartî parastina şopandinê bigirî. Zêdetir bizane + + Bi temamî hat girtin, ji bo vekirinê here Eyaran. + Telemetrî + + Daneyên bikaranînê û teknîkî Daneyên bazarkirinê Lêkolîn + + Destûrê bide Mozillayê ku lêkolînan saz bike û bimeşîne + + Ceribandin + + Destûrê dide Mozillayê ku ji bo taybetiyên ceribandinê daneyan saz bike û berhev bike Raporkera têkçûnan @@ -404,11 +467,18 @@ Sync’ê veke + + Koda hevsengkirinê ya di Firefoxa Sermaseyê de sken bike Têkeve + + Ji bo dîsberibandinê têkevinê Hesêb rake + + + firefox.com/pair de xuya dibe sken bike]]> Kamerayê veke @@ -426,9 +496,21 @@ Tarî + + Li gorî teserufa akuyê Rûkara cîhazê bi kar bîne + + + Ji bo nûkirinê bikişîne + + Ji bo veşartina derikê amûran bişemitîne + + Ji bo guhertina hilpekînê darikê amûran bi kêlekê ve kaş bike + + Ji bo vekirina hilpekînan darikê amûran bi jorê ve bikişîne + Rûniştin @@ -436,8 +518,20 @@ Wêneyên ekranê Daxistinên te + + Favorî + + Favoriyên Sermaseyê + + Menuya Favoriyan + + Darikê Amûran yê Favoriyan + + Favoriyên din Raborî + + Hilpekînên hevsengkirî Lîsteya xwendinê @@ -449,6 +543,10 @@ Bigire + + Hilpekînên dawiyê hatî girtin + + Mêjûyê hemû nîşan bide %d hilpekîn @@ -456,6 +554,9 @@ %d is a placeholder for the number of tabs selected. --> %d hilpekîn + + Hilpekîna di nêzîk de hatî girtin nîn in + Hilpekîn @@ -507,6 +608,8 @@ Hilbijêre Hemû hilpekînan parve bike + + Hilpekînên dawiyê hatî girtin Sazkariyên hilpekînê @@ -515,8 +618,18 @@ Hilpekîna nû Here serrûpelê + + Moda hilpekînan biguherîne + + Favorî Bigire + + Hilpekînên hilbijartî parve bike + + Menuya hilpekînên hilbijartî + + Hilpekînê ji koleksiyê rake Hilpekînan hilbijêre @@ -631,6 +744,8 @@ Bibore. %1$s, nikare vê rûpelê bar bike. + + Tu dikarî biceribînî ku vê hilpekînê bifilitînî yan jî bigirî. Rapora têkçûnê ji Mozillayê re bişîne @@ -645,6 +760,11 @@ Rûniştinê parve bike + + + Menuya Favoriyan + + Favoriyan serast bike Peldankê hilbijêre @@ -655,6 +775,10 @@ %1$s hate jêbirin Peldankê tevlî bike + + Favorî hat afirandin. + + Favorî hat hilanîn! SERERAST BIKE @@ -677,8 +801,12 @@ %1$d hatin bijartin + + Favoriyan serast bike Peldankê sererast bike + + Ji bo favoriyan hevsengirî bibînî têkevê NAVNÎŞAN @@ -694,9 +822,15 @@ URL’ya nederbasdar + + Hîç favorî nîn in %1$s hate jêbirin + + Favorî hat jêbirin + + Peldankên hilbijartî tên jêbirin VEGERÎNE @@ -705,6 +839,10 @@ Destûr Here sazkariyan + + Rûpela sazkariyên zû Tê pêşniyarkirin @@ -713,6 +851,10 @@ Destûran paqij bike Destûrê paqij bike + + Destûran ji hemû malperan paqij bike + + Lêdera xweber Kamera @@ -723,10 +865,14 @@ Danezan Bîrgeha mayinde + + Naveroka DRM kontrolkirî Destûrê bixwaze Hate astengkirin + + Destûrgirtî Ji hêla Androidê ve hate astengkirin @@ -755,6 +901,8 @@ Koleksiyon Menûya koleksiyonê + + Tiştên ji te re girîng berhev bike.\nLêgerîn, malper û hilpekînên dixwazî xwe zû bigihînî wan bîne cem hev. Hilpekînan hilbijêre @@ -765,6 +913,8 @@ Koleksiyona nû tevlî bike Gişî hilbijêre + + Hemû hilbijartinan rake Ji bo tomarkirinê, hilpekînan hilbijêre Hemû çalakî + + Dawiyê hatî bikaranîn Têkeve Sync’ê @@ -813,11 +965,30 @@ Derhêl Cîhazeke din girê bide + + Ji bo şandina hilpekînekê herî kêm ji amûreke din têkeve Firefoxê. Min fêm kir + + Bi vê amûrê re nayê parvekirin Bişîne cîhazê + + Amûra girêdayî nîn e + + + Derbarê Şandina Hilpekînan de agahiyan bistîne… + + Bi amûreke din ve girê bide… + + + + Danişîna gera nepen + + Hilpekînên nepen jê bibe + + Hilpekînên nepen bigire Veke @@ -826,6 +997,8 @@ Bihêzkirin ji aliyê Koleksiyon hate jêbirin + + Navê koleksiyê hat guhertin Hilpekîn hate jêbirin @@ -836,6 +1009,8 @@ Hilpekîn hatin girtin Hilpekîn hatin girtin! + + Favorî hatin tomarkirin! Bibîne @@ -854,23 +1029,39 @@ Vegerîne Bipejirîne + + Destûrê bide %1$sê ku %2$sê veke BIHÊLE NEHÊLE Tu bi rastî jî dixwazî koleksiyana %1$s’ê were jêbirin? + + Jêbirina vê hilpekînê dê hemû koleksiyê jê bibe. Kengê bixwazî dikarî koleksiyoneke nû biafirînî. %1$s’ê jê bibe? Jê bibe Betal bike + + Têketina moda ekrana dagirtî URL hate kopîkirin + + Ev nivîseke nimûneyî ye. Li virê xuya dibe ka gava tu bi vê sazkariyê mezinahiyê biguherînî dê çawa be. + + Nivîsên li ser malperan mezintir yan biçûktir bike Mezinahiya fontê + + Lêaîna mezinahiya nivîsan ya xweber + + Mezinahiya nivîsan dê li gorî sazkariyên Androîda te be. Ji bo mezinahiyê nivîsê li virê biguherînî vê wê betal bike. + Daneyên gerînê jê bibe @@ -889,13 +1080,31 @@ %d rûpel Kûkî + + Danişînên li ser gelek malperan dê bên girtin + + Wêne û pelên di pêşbîrê de + + Ciyê depokirinê vala dike + + Destûrên malperan Daxistinên te Daneyên gerînê jê bibe + + Daneyên gerê di dema derketinê de jê bibe + + Gava tu ji menuya giştî "Derkeve"yê hilbijêrî daneyên gerê xweber paqij dike + + Gava tu ji menuya giştî \"Derkeve\"yê hilbijêrî daneyên gerê xweber paqij dike Derkeve + + Ev ê hemû daneyên te yên gerê jê bibe + + %s dê daneyên gerê yên hilbijartî jê bibe. Betal bike @@ -910,6 +1119,31 @@ Firefox Preview niha bûye Firefox Nightly + + + Firefox Nightly her şev tê nûkirin û tê de taybetiyên nû yên ceribandinê hene. + Lê belê, dibe ku hindiktir stabîl be. Ji bo ceribandineke stabîltir geroka me ya beta jêbar bike. + + Firefox Betaya ji bo Andoîdê jêbar bikin + + + Firefox Nightlyê bar kir + + + Ev sepan dê venûkirinên ewlekariyê êdî wernegire. Êdî vê sepanê bi kar neyne û derbasî Nightlya nû bibe. + \ n \ nJi bo transferkirina favorî, têketin û mêjûya xwe bo sepaneke din, hesabekî Firefoxê biafirîne. + + Derbasî Nightlya nû bibe + + + Firefox Nightlyê bar kir + + + Ev sepan dê venûkirinên ewlekariyê êdî wernegire. Êdî vê sepanê bi kar neyne û derbasî Nightlya nû bibe. + \ n \ nJi bo transferkirina favorî, têketin û mêjûya xwe bo sepaneke din, hesabekî Firefoxê biafirîne. + + Nightlya nû jêbar bike + @@ -921,10 +1155,19 @@ %s’ê nas bike Tiştên nû bibîne + + Pirsên te derbarê %sa nû de hene? Dixwazî bizanî ka çi guheriye? Bersiv li vir in + + Bi hesabê xwe yê Firefoxê dest bi hevsengkirina favoriyan, şîfreyan û zêdetir tiştên xwe bike. Zêdetir bizane + + Te li ser vê amûrê wekî %s li ser gerokeke din a Firefoxê têketin pêk anî. Tu dixwazî bi vî hesabî têkeviyê? Erê, têkeve @@ -939,16 +1182,39 @@ Têketin bi ser neket Nihêniya otomatîk + + Sazkariyên nepeniyê û ewlekariyê şopîneran û sepanên niyetxirab û şirketên dixwazin te bişopînin asteng dike. Standard (jixweber) + + Hindiktir şopîneran asteng dike. Rûpel dê bi awayê asayî bên barkirin. Tund (tê pêşniyarkirin) Tund + + Zêdetir şopîneran, reklaman û popupan asteng dike. Rûpel zûtir vedibin, lê dibe ku hin taybetî nexebitin. + + Aliyê xwe hilbijêre + + Bi darikê amûran yê li xwarê gera bi destekî biceribîne yan jî wê bibe jorê. + + Bi nepenî bigere + + Carekê hilpekîneke nepen veke: Pêl îkona %sê bike. + + Her car hilpekînên nepen veke: Sazkariyên xwe yên gera nepen venû bike. Sazkariyan veke Nihêniya te + + Me %s ji bo hindê çêkiriye ku derbarê tiştên tu li ser înternetê û tiştên bi me re parve dikî de kontrol di destê te de be. Agahdariya me ya nihêniyê bixwîne @@ -960,8 +1226,12 @@ Rûkara xwe hilbijêre + + Bi çalakkirina moda tarî him ji bataryayê teseruf bike him çavên xwe vehesîne. Otomatîk + + Xwe li sazkariyên amûra te tîne Rûkara tarî @@ -975,26 +1245,99 @@ Nehate şandin DÎSA BICERIBÎNE + + Kodê sken bike + + https://firefox.com/pair]]> + + Ji bo skenkirinê amade me + + Bi kameraya xwe têkevê + + Bi e-peyamê têkevê + + Yekê biafirîne ku Firefoxê di navbera amûran de hevseng bikî.]]> + + Firefox dê hevsengkirina bi hesabê te re asteng bike, lê dê daneyên te yên gerê yên li ser vê amûrê jê nebe. + + %s dê hevsengkirina bi hesabê te re asteng bike, lê dê daneyên te yên gerê yên li ser vê amûrê jê nebe. Girêdanê qut bike Betal bike + + Peldankên standard nayên serastkirin + + + + Sazkariyên parastinê + + Parastina şopandinê ya pêşketî + + Bêyî ku bêtî şopandin bigere + + Bila daneyên te ji te re bimînin. %s te ji piraniya şopîneran diparêze ku tiştên tu li ser înternetê dikî dişopînin. Zêdetir bizane + + Standard (heyî) + + Hindiktir şopîneran asteng bike. Rûpel dê asayî vebin. + + Bi parastina şopandinê ya standard çi tên astengkirin? Tund + + Zêdetir şopîneran, reklaman û popupan asteng dike. Rûpel zûtir tên barkirin, lê dibe ku hin taybetî nexebitin. + + Bi parastina şopandinê ya tund çi tên astengkirin? Taybet + + Hilbijêre ka kîjan şopîner û skrîpt bên astengkirin. + + Bi parastina şopandina taybet çi tên astengkirin? Kûkî + + Şopînerên nav-malperî û şopînerên medyaya civakî + + Çerezên malperên nehatine bikaranîn + + Hemû çerezên partiya sêyemîn (dibe ku hin malper xira bibin) + + Hemû çerezan (dibe ku hin malper xira bibin) + + Naverokên şopandinê Di hemû hilpekînan de Tenê di hilpekînên veşartî de Tenê di hilpekînên taybet de + + Kankerên krîpto + + Berhevkarên şoptiliyan + Astengker + + Destûrgirtî + + Şopînerên medyaya civakî + + Taybetiya şopandina çalakiyên te yên gera li ser torên civakî bisînor dike. + + Çerezên şopandinê yên nav-malperî + + Çerezên ku torên reklamê û şirketên analîtîkê ji bo şopandina gera di navbera malperên cuda de bi kar tînin asteng dike. + + Kankerên krîpto + + Skrîptên xirab yên ji bo ku kankerên krîpto ji bo çêkirina pereyên krîpto xwe bigihînin amûra te asteng dike. + + Şoptilî Paşve here @@ -1076,7 +1419,7 @@ Pêborîn - PIN’a xwe dîsa bikevê + PIN’a xwe dîsa binivîse Zêdetir bizane diff --git a/app/src/main/res/values-sat/strings.xml b/app/src/main/res/values-sat/strings.xml index 0262c80be..7aef50afb 100644 --- a/app/src/main/res/values-sat/strings.xml +++ b/app/src/main/res/values-sat/strings.xml @@ -40,11 +40,11 @@ ᱵᱟᱪᱷᱟᱣᱮᱱᱟ %1$s - ᱵᱟᱝ ᱪᱚᱭᱚᱱᱟᱜ%1$s + ᱵᱟᱝ ᱵᱟᱪᱷᱟᱣᱟᱜ%1$s ᱵᱟᱹᱰ ᱟᱠᱟᱱᱟ ᱢᱟᱹᱴᱤᱥᱤᱞᱮᱼᱴ ᱢᱳᱰ - ᱢᱟᱹᱞᱴᱤᱥᱤᱞᱮᱠᱼᱴ ᱢᱳᱰ ᱵᱚᱞᱚ ᱮᱱᱟᱢ, ᱛᱩᱢᱟᱹᱞ ᱥᱟᱸᱪᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱨᱮᱵ ᱠᱚ ᱪᱚᱭᱚᱱ ᱢᱮ + ᱢᱟᱹᱞᱴᱤᱥᱤᱞᱮᱠᱼᱴ ᱢᱳᱰ ᱵᱚᱞᱚ ᱮᱱᱟᱢ, ᱛᱩᱢᱟᱹᱞ ᱥᱟᱸᱪᱟᱣ ᱞᱟᱹᱜᱤᱫ ᱨᱮᱵ ᱠᱚ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱵᱟᱪᱷᱟᱣᱮᱱᱟ @@ -95,7 +95,7 @@ ᱵᱟᱹᱰ - ᱠᱷᱩᱞᱟᱹ ᱴᱮᱵ ᱞᱮᱭᱟᱩᱴ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾ ᱥᱟᱡᱟᱣ ᱴᱷᱮᱱ ᱪᱟᱞᱟᱣ ᱠᱟᱛᱮᱫᱽ ᱴᱮᱵ ᱣᱤᱣ ᱞᱟᱛᱟᱨ ᱨᱮ ᱜᱨᱤᱰ ᱪᱚᱭᱚᱱ ᱢᱮ ᱾ + ᱠᱷᱩᱞᱟᱹ ᱴᱮᱵ ᱞᱮᱭᱟᱩᱴ ᱠᱚ ᱵᱚᱫᱚᱞ ᱢᱮ ᱾ ᱥᱟᱡᱟᱣ ᱴᱷᱮᱱ ᱪᱟᱞᱟᱣ ᱠᱟᱛᱮᱫᱽ ᱴᱮᱵ ᱣᱤᱣ ᱞᱟᱛᱟᱨ ᱨᱮ ᱜᱨᱤᱰ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱾ ᱥᱟᱡᱟᱣ ᱛᱮ ᱪᱟᱞᱟᱜᱽ ᱢᱮ @@ -361,7 +361,7 @@ ᱱᱤᱛᱚᱜ ᱥᱭᱸᱠ ᱢᱮ - ᱚᱠᱟ ᱥᱭᱸᱠ ᱨᱮᱭᱟᱜ ᱛᱟᱦᱮᱸᱱᱟ ᱪᱚᱭᱚᱱ ᱢᱮ + ᱚᱠᱟ ᱥᱭᱸᱠ ᱨᱮᱭᱟᱜ ᱛᱟᱦᱮᱸᱱᱟ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱦᱤᱛᱟᱹᱞ @@ -419,7 +419,7 @@ ᱡᱷᱚᱛᱚ ᱠᱚ ᱥᱟᱭᱤᱴ ᱞᱟᱹᱜᱤᱛ ᱛᱮ ᱚᱱ ᱢᱮ - ᱪᱚᱭᱚᱱᱟᱠᱟᱱ ᱫᱟᱭᱤᱴ ᱠᱚᱨᱮ ᱟᱢ ᱤᱪᱷᱟᱹ ᱚᱱᱩᱥᱟᱨ ᱜᱷᱮᱨ ᱮᱥᱮᱫ ᱵᱚᱸᱫᱚ ᱫᱟᱲᱮᱭᱟᱜᱼᱟᱢ ᱾ + ᱵᱟᱪᱷᱟᱣᱟᱠᱟᱱ ᱫᱟᱭᱤᱴ ᱠᱚᱨᱮ ᱟᱢ ᱤᱪᱷᱟᱹ ᱚᱱᱩᱥᱟᱨ ᱜᱷᱮᱨ ᱮᱥᱮᱫ ᱵᱚᱸᱫᱚ ᱫᱟᱲᱮᱭᱟᱜᱼᱟᱢ ᱾ ᱰᱷᱮᱨ ᱥᱮᱬᱟᱭ ᱢᱮ @@ -595,7 +595,7 @@ ᱛᱩᱢᱟᱹᱞ ᱨᱮ ᱥᱟᱸᱪᱟᱣ ᱢᱮ - ᱪᱚᱭᱚᱱ + ᱵᱟᱪᱷᱟᱣ ᱡᱷᱚᱛᱚ ᱴᱮᱵ ᱠᱚ ᱦᱟᱹᱴᱧ ᱢᱮ @@ -615,13 +615,13 @@ ᱵᱚᱸᱫᱽ - ᱪᱚᱭᱚᱱ ᱟᱠᱟᱱ ᱴᱮᱵᱽ ᱠᱚ ᱦᱟᱹᱴᱤᱧ ᱢᱮ + ᱵᱟᱪᱷᱟᱣ ᱟᱠᱟᱱ ᱴᱮᱵᱽ ᱠᱚ ᱦᱟᱹᱴᱤᱧ ᱢᱮ - ᱪᱚᱭᱚᱱ ᱟᱠᱟᱱ ᱴᱮᱵ ᱢᱮᱱᱭᱩ ᱠᱚ + ᱵᱟᱪᱷᱟᱣ ᱟᱠᱟᱱ ᱴᱮᱵ ᱢᱮᱱᱭᱩ ᱠᱚ ᱴᱮᱵ ᱛᱩᱢᱟᱹᱞ ᱠᱷᱚᱱ ᱚᱪᱚᱜ ᱢᱮ - ᱴᱮᱵ ᱠᱚ ᱪᱚᱭᱚᱱ ᱢᱮ + ᱴᱮᱵ ᱠᱚ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱴᱮᱵ ᱵᱚᱸᱫᱚᱭ ᱢᱮ @@ -1203,11 +1203,6 @@ ᱟᱢᱟᱜ ᱱᱤᱥᱚᱱ - - ᱟᱞᱮ %s ᱞᱮ ᱰᱤᱡᱟᱭᱤᱱ ᱟᱠᱟᱫᱼᱟ ᱚᱠᱟ ᱫᱚ ᱡᱟᱦᱟᱱᱟᱜ ᱠᱚ ᱚᱱᱞᱟᱭᱤᱱ ᱦᱟᱹᱴᱤᱧ ᱨᱮ - ᱟᱨ ᱚᱠᱟ ᱠᱚ ᱟᱞᱮ ᱦᱟᱹᱤᱧ ᱟᱞᱮᱭᱟᱢ, ᱜᱚᱲᱚ ᱮᱢᱟᱭ ᱾ - ᱟᱞᱮᱭᱟᱜ ᱱᱤᱥᱚᱱ ᱱᱚᱴᱤᱥ ᱯᱟᱲᱦᱟᱣ ᱯᱮ @@ -1218,7 +1213,7 @@ - ᱩᱭᱦᱟᱹᱨ ᱪᱚᱭᱚᱱ ᱛᱟᱢ + ᱩᱭᱦᱟᱹᱨ ᱵᱟᱪᱷᱟᱣ ᱛᱟᱢ ᱛᱤᱱᱟᱹᱜ ᱜᱟᱱ ᱵᱮᱴᱨᱭ ᱵᱚᱪᱚᱛ ᱢᱮ ᱟᱨ ᱟᱢᱟᱜ ᱢᱮᱫ ᱵᱟᱸᱪᱟᱣ ᱛᱟᱢ ᱧᱩᱛ ᱩᱭᱦᱟᱹᱨ ᱪᱟᱹᱞᱩ ᱠᱟᱛᱮ ᱾ @@ -1287,7 +1282,7 @@ ᱠᱩᱥᱤᱭᱟᱜ - ᱪᱚᱭᱚᱱ ᱢᱮ ᱚᱠᱟ ᱯᱟᱧᱡᱟ ᱫᱟᱱᱟᱲ ᱠᱚ ᱟᱨ ᱥᱠᱨᱤᱯᱴ ᱞᱚ ᱵᱞᱚᱠ ᱠᱚᱣᱟ ᱾ + ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱚᱠᱟ ᱯᱟᱧᱡᱟ ᱫᱟᱱᱟᱲ ᱠᱚ ᱟᱨ ᱥᱠᱨᱤᱯᱴ ᱞᱚ ᱵᱞᱚᱠ ᱠᱚᱣᱟ ᱾ ᱠᱚᱥᱴᱚᱢ ᱜᱷᱮᱨ ᱮᱥᱮᱫ ᱯᱨᱚᱴᱮᱠᱥᱚᱱ ᱛᱮ ᱪᱮᱫ ᱵᱞᱚᱠ ᱟᱹᱠᱟᱱᱟ @@ -1658,7 +1653,7 @@ ᱴᱚᱯ ᱥᱟᱭᱤᱴ ᱞᱤᱢᱤᱴ ᱥᱮᱴᱮᱨᱮᱱᱟ - ᱱᱟᱶᱟ ᱴᱟᱹᱯ ᱥᱟᱭᱤᱴ ᱥᱮᱞᱮᱫᱽ ᱞᱟᱹᱜᱤᱫ, ᱢᱤᱫᱴᱟᱹᱝ ᱚᱰᱚᱠ ᱢᱮ ᱾ ᱥᱟᱭᱤᱴ ᱴᱤᱯᱟᱹᱣ ᱟᱨ ᱚᱛᱟ ᱛᱷᱤᱨ ᱠᱟᱛᱮ ᱪᱚᱭᱚᱱ ᱢᱮ ᱟᱨ ᱚᱰᱚᱠ ᱢᱮ ᱾ + ᱱᱟᱶᱟ ᱴᱟᱹᱯ ᱥᱟᱭᱤᱴ ᱥᱮᱞᱮᱫᱽ ᱞᱟᱹᱜᱤᱫ, ᱢᱤᱫᱴᱟᱹᱝ ᱚᱰᱚᱠ ᱢᱮ ᱾ ᱥᱟᱭᱤᱴ ᱴᱤᱯᱟᱹᱣ ᱟᱨ ᱚᱛᱟ ᱛᱷᱤᱨ ᱠᱟᱛᱮ ᱵᱟᱪᱷᱟᱣ ᱢᱮ ᱟᱨ ᱚᱰᱚᱠ ᱢᱮ ᱾ ᱴᱷᱤᱠ, ᱵᱟᱰᱟᱭ ᱠᱮᱜᱼᱟᱹᱧ diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 796c45851..db8d6885d 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -1085,6 +1085,8 @@ เพิ่มเนื้อที่เก็บข้อมูล สิทธิอนุญาตไซต์ + + ดาวน์โหลด ลบข้อมูลการเรียกดู @@ -1206,8 +1208,7 @@ ความเป็นส่วนตัวของคุณ - เราได้ออกแบบ %s เพื่อให้คุณสามารถควบคุมสิ่งที่คุณต้องการแบ่งปัน - ออนไลน์และสิ่งที่คุณต้องการแบ่งปันกับเราได้ + เราได้ออกแบบ %s เพื่อให้คุณสามารถควบคุมสิ่งที่คุณต้องการแบ่งปันออนไลน์และสิ่งที่คุณต้องการแบ่งปันกับเราได้ อ่านประกาศความเป็นส่วนตัวของเรา From c6bf949a036d906e5ea7555eba793c726d3c4fc4 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Mon, 8 Feb 2021 15:10:59 +0200 Subject: [PATCH 084/248] For #17847: Removes editCustomSearchEngineTest UI test --- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 31 -------------- .../ui/robots/SettingsSubMenuSearchRobot.kt | 42 +------------------ 2 files changed, 1 insertion(+), 72 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index b056de1bb..a97a7d4c4 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -14,7 +14,6 @@ import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -50,10 +49,6 @@ class SmokeTest { private var recentlyClosedTabsListIdlingResource: RecyclerViewIdlingResource? = null private var readerViewNotification: ViewVisibilityIdlingResource? = null private val downloadFileName = "Globe.svg" - private val searchEngine = object { - var title = "Ecosia" - var url = "https://www.ecosia.org/search?q=%s" - } val collectionName = "First Collection" private var bookmarksListIdlingResource: RecyclerViewIdlingResource? = null @@ -522,32 +517,6 @@ class SmokeTest { } } - @Ignore("Failing, see: https://github.com/mozilla-mobile/fenix/issues/17847") - @Test - // Verifies setting as default a customized search engine name and URL - fun editCustomSearchEngineTest() { - homeScreen { - }.openThreeDotMenu { - }.openSettings { - }.openSearchSubMenu { - openAddSearchEngineMenu() - selectAddCustomSearchEngine() - typeCustomEngineDetails(searchEngine.title, searchEngine.url) - saveNewSearchEngine() - openEngineOverflowMenu("Ecosia") - clickEdit() - typeCustomEngineDetails("Test", searchEngine.url) - saveEditSearchEngine() - changeDefaultSearchEngine("Test") - }.goBack { - }.goBack { - }.openSearch { - verifyDefaultSearchEngine("Test") - clickSearchEngineShortcutButton() - verifyEnginesListShortcutContains("Test") - } - } - @Test // Swipes the nav bar left/right to switch between tabs fun swipeToSwitchTabTest() { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt index da518f563..92c29ce00 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSearchRobot.kt @@ -8,25 +8,20 @@ package org.mozilla.fenix.ui.robots import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions.clearText import androidx.test.espresso.action.ViewActions.click -import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.ViewMatchers.Visibility import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.isDisplayed -import androidx.test.espresso.matcher.ViewMatchers.withChild +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.espresso.matcher.ViewMatchers.withContentDescription -import androidx.test.espresso.matcher.ViewMatchers.withParent import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiSelector import org.hamcrest.CoreMatchers -import org.hamcrest.CoreMatchers.allOf import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.click @@ -67,33 +62,6 @@ class SettingsSubMenuSearchRobot { saveNewSearchEngine() } - fun selectAddCustomSearchEngine() = onView(withText("Other")).click() - - fun typeCustomEngineDetails(engineName: String, engineURL: String) { - onView(withId(R.id.edit_engine_name)) - .perform(clearText()) - .perform(typeText(engineName)) - onView(withId(R.id.edit_search_string)) - .perform(clearText()) - .perform(typeText(engineURL)) - } - - fun openEngineOverflowMenu(searchEngineName: String) { - mDevice.findObject( - UiSelector().resourceId("org.mozilla.fenix.debug:id/overflow_menu") - ).waitForExists(waitingTime) - threeDotMenu(searchEngineName).click() - } - - fun clickEdit() = onView(withText("Edit")).click() - - fun saveEditSearchEngine() { - onView(withId(R.id.save_button)).click() - mDevice.findObject( - UiSelector().resourceId("org.mozilla.fenix.debug:id/recycler_view") - ).waitForExists(waitingTime) - } - class Transition { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) @@ -220,11 +188,3 @@ private fun addSearchEngineSaveButton() = onView(withId(R.id.add_search_engine)) private fun assertEngineListContains(searchEngineName: String) { onView(withId(R.id.search_engine_group)).check(matches(hasDescendant(withText(searchEngineName)))) } - -private fun threeDotMenu(searchEngineName: String) = - onView( - allOf( - withId(R.id.overflow_menu), - withParent(withChild(withText(searchEngineName))) - ) - ) From 46888cc70f46df28c286b95a6151927a32547338 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 8 Feb 2021 12:11:58 +0200 Subject: [PATCH 085/248] For #14523 Fix Intermittent tests verifyContextOpenLinkNewTab & verifyContextOpenLinkPrivateTab --- .../java/org/mozilla/fenix/ui/ContextMenusTest.kt | 1 + .../java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt index c877171ec..258a2a803 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ContextMenusTest.kt @@ -69,6 +69,7 @@ class ContextMenusTest { snackBarButtonClick("Switch") verifyUrl(genericURL.url.toString()) }.openTabDrawer { + verifyNormalModeSelected() verifyExistingOpenTabs("Test_Page_1") verifyExistingOpenTabs("Test_Page_4") } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index 16dddca95..f0fd1cd8c 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -42,6 +42,7 @@ import org.hamcrest.Matcher import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime +import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.idlingresource.BottomSheetBehaviorStateIdlingResource @@ -326,6 +327,11 @@ private fun threeDotMenu() = onView(withId(R.id.tab_tray_overflow)) private fun assertExistingOpenTabs(title: String) { try { + mDevice.findObject(UiSelector() + .resourceId("$packageName:id/mozac_browser_tabstray_title") + .textContains(title)) + .waitForExists(waitingTime) + tab(title).check(matches(isDisplayed())) } catch (e: NoMatchingViewException) { onView(withId(R.id.tabsTray)).perform( From 5e9fb855f56030a5a8a5356dff63861b0f39b5d4 Mon Sep 17 00:00:00 2001 From: ekager Date: Mon, 8 Feb 2021 09:17:19 -0700 Subject: [PATCH 086/248] For #17915 - Do not launch system settings on Role Request Intent cancel --- .../fenix/settings/SettingsFragment.kt | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 2bf9ad3a0..677f4863d 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -434,8 +434,14 @@ class SettingsFragment : PreferenceFragmentCompat() { Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { Preference.OnPreferenceClickListener { requireContext().getSystemService(RoleManager::class.java).also { - if (!it.isRoleHeld(RoleManager.ROLE_BROWSER)) { - startActivityForResult(it.createRequestRoleIntent(RoleManager.ROLE_BROWSER), 0) + if (it.isRoleAvailable(RoleManager.ROLE_BROWSER) && !it.isRoleHeld( + RoleManager.ROLE_BROWSER + ) + ) { + startActivityForResult( + it.createRequestRoleIntent(RoleManager.ROLE_BROWSER), + REQUEST_CODE_BROWSER_ROLE + ) } else { navigateUserToDefaultAppsSettings() } @@ -452,12 +458,12 @@ class SettingsFragment : PreferenceFragmentCompat() { else -> { Preference.OnPreferenceClickListener { (activity as HomeActivity).openToBrowserAndLoad( - searchTermOrURL = SupportUtils.getSumoURLForTopic( - requireContext(), - SupportUtils.SumoTopic.SET_AS_DEFAULT_BROWSER - ), - newTab = true, - from = BrowserDirection.FromSettings + searchTermOrURL = SupportUtils.getSumoURLForTopic( + requireContext(), + SupportUtils.SumoTopic.SET_AS_DEFAULT_BROWSER + ), + newTab = true, + from = BrowserDirection.FromSettings ) true } @@ -468,12 +474,9 @@ class SettingsFragment : PreferenceFragmentCompat() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - /* - If role manager doesn't show in-app browser changing dialog for a reason, navigate user to - Default Apps Settings. - */ - if (resultCode == Activity.RESULT_CANCELED && requestCode == 0) { - navigateUserToDefaultAppsSettings() + // If the user made us the default browser, update the switch + if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_BROWSER_ROLE) { + updateMakeDefaultBrowserPreference() } } @@ -547,6 +550,7 @@ class SettingsFragment : PreferenceFragmentCompat() { } companion object { + private const val REQUEST_CODE_BROWSER_ROLE = 1 private const val SCROLL_INDICATOR_DELAY = 10L private const val FXA_SYNC_OVERRIDE_EXIT_DELAY = 2000L private const val AMO_COLLECTION_OVERRIDE_EXIT_DELAY = 3000L From 4084664d303977cd59fdb8b5df59a4686731635e Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Tue, 9 Feb 2021 00:05:00 +0000 Subject: [PATCH 087/248] Import l10n. --- app/src/main/res/values-kmr/strings.xml | 119 +++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index a60f1b66d..7a4a2dce5 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -112,7 +112,7 @@ Hilpekîna veşartî ya nû - Malperên favorî + Malperên sereke @@ -1338,22 +1338,55 @@ Skrîptên xirab yên ji bo ku kankerên krîpto ji bo çêkirina pereyên krîpto xwe bigihînin amûra te asteng dike. Şoptilî + + Naverokên şopandinê + + Barkirina reklam, vidyo û naverokên din yên tê de koda şopandin heye asteng dike. Dibe ku bandorê li taybetiyên hin malperan bike. + + Gava mertal bû rengê mor, nexwe %sê şopîner asteng kirine. Ji bo agahiyên zêdetir bipelîne. + + Parastin ji bo v malperê VEKIRÎ ne. + + Parastin ji bo vê malperê GIRTÎ ne + + Parastina şopandinê ya pêşketî ji bo van malperan hat girtin Paşve here Mafên te + + Pirtûkxaneyên çavkaniya azad yên em bi kar tînin Di %s çi tiştên nû hene? %s | Pirtûkxaneyên OSS’ê + + Şoînerên beralîkirinê + + Çerezên aîdî beralîkirinên ji bo malperên şopandinê yên naskirî asteng dike. + Piştgirî + + Têkçûn Agahdariya nihêniyê + + Mafên xwe bizane + + Agahiyên lîsanskirinê + + Pirtûkxaneyên em bikar tînin + + Menuya neqandina çewtiyan: Ji bo çalakkirinê %1$d tikandin man + + Menuya neqandina çewtiyan hat çalakkirin + 1 hilpekîn @@ -1380,6 +1413,9 @@ Navê kurterêyê + + Tu dikarî vê malperê bi hêsanî li ekrana Serûpela amûra xwe zêde bikî ku zû bigihiyê û wê wekî sepanekê bi kar bînî. + Hesab û pêborîn @@ -1402,16 +1438,24 @@ Têkeve Sync’ê Hesabên tomarkirî + + Têketinên te tomar kirine yan hevsengkirinên bi %sê re dê li virê bên nîşandan. Derbarê Sync’ê de agahî bistîne. Istisna + + Têketin û şîfreyên nehatine tomarkirin dê li virê bên nîşandan. + + Têketin û şîfre dê ji bo van malperan neyên tomarkirin. Hemû istisnayan jê bibe Li hesaban bigere Alfabetîkî + + Dawiyê hatî bikaranîn Malper @@ -1420,6 +1464,10 @@ Pêborîn PIN’a xwe dîsa binivîse + + Ji bo têketinên xwe yên tomarkirî bibînî kilîdê veke + + Ev girêdan ne ewle ye. Îhtîmal heye têketinên li virê bên bidestxistin. Zêdetir bizane @@ -1467,6 +1515,9 @@ Bikaranîna dawî + + Menuya rêzkirina têketinan + Motora lêgerînê tevlî bike @@ -1485,11 +1536,45 @@ Yên din Nav + + Rêzeya lêgerînê ya ji bo bikaranînê + + Daxwazê bi “%s”. Mînak:\nhttps://www.google.com/search?q=%sê biguherîne Zêdetir Bizane + + Hûrgiliyên motora lêgerînê ya taybet + + Lînka agahiyên zêdetir + + + Navê motora lêgerînê binivîse + + Motora lêgerînê ya bi navê “%s” jixwe heye. + + Rêzikeek lêgerînê binivîse + + Kontrol bike ka rêzika lêgerînê û formata Mînak li hev dikin yan na + + Êewtiya girêdana bi “%s”ê ve + + %s hat afirandin + + %s hat tomarkirin + + %s hat jêbirin + + + Bi xêr hatî geroka %sê ya nipînû + + Me geroka te bi performans û taybetiyên pêşxistî ji serî heta binî nû kir ku tu dikarî li ser înternetê tiştên zêdetir bikî.\n\nTika ye heta %sê van venû bike li bendê bin... %s tê nûvekirin… + + %sê bide destpêkirin + + Veguhestin qediya Pêborîn @@ -1506,10 +1591,18 @@ Girêdana ewle Girêdana neewle + + Tu ji dil dizanî hemû destûrên li ser hemû malperan jê bibî? + + Tu ji dil dizanî hemû destûran ji bo hemû malperan jê bibî? + + Tu ji dil dixwazî vê destûrê ji bo vê malperê jê bibî? Istisnayên malperê tune Gotarên Serekî + + Tu ji dil dixwazî vê favoriyê jê bibî? Tevlî malperên favorî bike Vebijarkên hesêb + + Qada nivîsê ya ji bo navnîşana webê ya têketinê + + Qada nivîsê ya ji bo navê bikarhêneriyê ya têketinê. + + Qada nivîsê ya ji bo şîfreya têketinê. Guhertinan li hesêb tomar bike. @@ -1548,6 +1647,10 @@ Ji kerema xwe, ji nû ve têkeve. Ji kerema xwe, senkronîzekirina hilpekînê veke. + + Li ser amûrên din ti hilpekîneke di Firefoxê de vekirî tune ye. + + Lîsteyeke hilpekînan ya ji amûrên xwe yên din bibîne. Têkeve Sync’ê @@ -1557,9 +1660,13 @@ Gihîşte sînorê malperên favorî + + Ji bo malpereke din ya sereke lê zêde bikî, yekê jê bibe.Malperê bipelîne û li ser bigire û rakirinê hilbijêre. Baş e - + + Malperên herî zêde hatine vekirin nîşan bide + Nav Navê malpera favorî @@ -1571,9 +1678,17 @@ Rake + + Ji %sa xwe fêdeya herî zêde bibînin. + Ji bo agahiyên zêdetir, bitikîne Tiştên ku ji te re girîng in berhev bike + + Lêgerîn, malper û hilpekînên wekî hev bi hev re bike kom da ku paşê xwe zû bigihîniyê. + + Tu li ser vê telefonê di gerokeke din ya Firefoxê de wekî %s têketiyê. Tu dixwazî bi vî hesabî têkeviyê? From 4de49c758589b21ff26637bf87a0e9003bde7a9f Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Mon, 1 Feb 2021 17:51:09 -0800 Subject: [PATCH 088/248] For #17816: add profiler marker for 2x Activity.onCreate. The IntentReceiverActivity one is particularly useful to quickly determine when we can begin executing code in the WARM VIEW case (i.e. "Set selection begin here"). The HomeActivity one is useful for COLD start up analysis in similar ways and to see the Activity transitions in WARM VIEW. --- app/src/main/java/org/mozilla/fenix/HomeActivity.kt | 3 +++ app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 44ef9352c..ce79e1ac3 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -163,6 +163,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { private lateinit var navigationToolbar: Toolbar final override fun onCreate(savedInstanceState: Bundle?) { + // DO NOT MOVE ANYTHING ABOVE THIS addMarker CALL. + components.core.engine.profiler?.addMarker("Activity.onCreate", "HomeActivity") + components.strictMode.attachListenerToDisablePenaltyDeath(supportFragmentManager) // There is disk read violations on some devices such as samsung and pixel for android 9/10 components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index 3e84fa22a..0c995371e 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -26,6 +26,9 @@ class IntentReceiverActivity : Activity() { @VisibleForTesting override fun onCreate(savedInstanceState: Bundle?) { + // DO NOT MOVE ANYTHING ABOVE THIS addMarker CALL. + components.core.engine.profiler?.addMarker("Activity.onCreate", "IntentReceiverActivity") + // StrictMode violation on certain devices such as Samsung components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) { super.onCreate(savedInstanceState) From b3ef8a11e843b7550617b07f37038d63f31e1943 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Mon, 1 Feb 2021 17:58:46 -0800 Subject: [PATCH 089/248] For #17816: add profiler marker for onPreDraw via HomeActivity.onStart. This may be useful for MAIN start up to determine when the user begins seeing content. --- .../java/org/mozilla/fenix/HomeActivity.kt | 3 +++ .../org/mozilla/fenix/perf/ProfilerMarkers.kt | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkers.kt diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index ce79e1ac3..e07844bd9 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -92,6 +92,7 @@ import org.mozilla.fenix.library.history.HistoryFragmentDirections import org.mozilla.fenix.library.recentlyclosed.RecentlyClosedFragmentDirections import org.mozilla.fenix.perf.Performance import org.mozilla.fenix.perf.PerformanceInflater +import org.mozilla.fenix.perf.ProfilerMarkers import org.mozilla.fenix.perf.StartupTimeline import org.mozilla.fenix.search.SearchDialogFragmentDirections import org.mozilla.fenix.session.PrivateNotificationService @@ -327,6 +328,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { breadcrumb( message = "onStart()" ) + + ProfilerMarkers.homeActivityOnStart(rootContainer, components.core.engine.profiler) } override fun onStop() { diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkers.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkers.kt new file mode 100644 index 000000000..783992303 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkers.kt @@ -0,0 +1,22 @@ +/* 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 org.mozilla.fenix.perf + +import android.view.View +import androidx.core.view.doOnPreDraw +import mozilla.components.concept.base.profiler.Profiler + +/** + * A container for functions for when adding a profiler marker is less readable + * (e.g. multiple lines, more advanced logic). + */ +object ProfilerMarkers { + + fun homeActivityOnStart(rootContainer: View, profiler: Profiler?) { + rootContainer.doOnPreDraw { + profiler?.addMarker("onPreDraw", "expected first frame via HomeActivity.onStart") + } + } +} From 71d908b3ef4da869f704211eccb32868bc70d0bc Mon Sep 17 00:00:00 2001 From: Florin Strugariu Date: Thu, 21 Jan 2021 12:52:20 +0200 Subject: [PATCH 090/248] Update taskcluster settings to use short names instead of indexes --- taskcluster/ci/browsertime/kind.yml | 179 ++++-------------- .../fenix_taskgraph/transforms/browsertime.py | 61 ++++-- 2 files changed, 81 insertions(+), 159 deletions(-) diff --git a/taskcluster/ci/browsertime/kind.yml b/taskcluster/ci/browsertime/kind.yml index ea014660d..2c2f7d6a1 100644 --- a/taskcluster/ci/browsertime/kind.yml +++ b/taskcluster/ci/browsertime/kind.yml @@ -83,7 +83,6 @@ job-defaults: - '--cfg=mozharness/configs/raptor/android_hw_config.py' - '--app=fenix' - '--browsertime' - - '--cold' - '--no-conditioned-profile' - '--binary=org.mozilla.fenix' - '--activity=org.mozilla.fenix.IntentReceiverActivity' @@ -101,168 +100,54 @@ job-defaults: - linux64-node jobs: - tp6m-1-cold: - test-name: amazon - treeherder: - symbol: 'Btime(tp6m-1-c)' - - tp6m-2-cold: - test-name: google - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-2-c)' - - tp6m-3-cold: - test-name: instagram - treeherder: - symbol: 'Btime(tp6m-3-c)' - - tp6m-4-cold: - test-name: bing-search-restaurants - treeherder: - symbol: 'Btime(tp6m-4-c)' - - tp6m-5-cold: - test-name: ebay-kleinanzeigen-search - treeherder: - symbol: 'Btime(tp6m-5-c)' - - tp6m-6-cold: - test-name: amazon-search - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-6-c)' - - tp6m-7-cold: - test-name: wikipedia - treeherder: - symbol: 'Btime(tp6m-7-c)' - - tp6m-8-cold: - test-name: booking - treeherder: - symbol: 'Btime(tp6m-8-c)' - - tp6m-9-cold: - test-name: cnn-ampstories - treeherder: - symbol: 'Btime(tp6m-9-c)' - - tp6m-10-cold: - test-name: bbc - treeherder: - symbol: 'Btime(tp6m-10-c)' - - tp6m-11-cold: - test-name: microsoft-support - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-11-c)' - - tp6m-12-cold: - test-name: imdb - treeherder: - symbol: 'Btime(tp6m-12-c)' - - tp6m-13-cold: - test-name: espn - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-13-c)' - - tp6m-14-cold: - test-name: facebook-cristiano - treeherder: - symbol: 'Btime(tp6m-14-c)' - - tp6m-15-cold: - test-name: facebook - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-15-c)' - - tp6m-16-cold: - test-name: youtube - treeherder: - symbol: 'Btime(tp6m-16-c)' - - tp6m-17-cold: - test-name: bing - treeherder: - symbol: 'Btime(tp6m-17-c)' - - tp6m-18-cold: - test-name: ebay-kleinanzeigen - treeherder: - symbol: 'Btime(tp6m-18-c)' - - tp6m-19-cold: - test-name: google-maps - treeherder: - symbol: 'Btime(tp6m-19-c)' - - tp6m-20-cold: - test-name: youtube-watch + tp6m: + page-load-tests: + - amazon + - instagram + - [bing-search-restaurants, bing-s-r] + - [ebay-kleinanzeigen-search, ebay-k-s] + - wikipedia + - booking + - [cnn-ampstories, cnn-amp] + - bbc + - imdb + - [facebook-cristiano, fb-cris] + - youtube + - bing + - [ebay-kleinanzeigen, ebay-k] + - [google-maps, gmaps] + - reddit + - [stackoverflow, stacko] + - jianshu + - web-de + - cnn + - [google-search-restaurants, gsearch-r] + + tp6m-hv: web-render-only: False - treeherder: - symbol: 'Btime(tp6m-20-c)' - - tp6m-21-cold: - test-name: reddit - treeherder: - symbol: 'Btime(tp6m-21-c)' - - tp6m-22-cold: - test-name: stackoverflow - treeherder: - symbol: 'Btime(tp6m-22-c)' - - tp6m-23-cold: - test-name: jianshu - treeherder: - symbol: 'Btime(tp6m-23-c)' - - tp6m-24-cold: - test-name: allrecipes - web-render-only: False - treeherder: - symbol: 'Btime(tp6m-24-c)' - - tp6m-25-cold: - test-name: web-de - treeherder: - symbol: 'Btime(tp6m-25-c)' - - tp6m-27-cold: - test-name: cnn - treeherder: - symbol: 'Btime(tp6m-27-c)' - - tp6m-28-cold: - test-name: google-search-restaurants - treeherder: - symbol: 'Btime(tp6m-28-c)' + page-load-tests: + - google + - [amazon-search, amazon-s] + - [microsoft-support, micros-sup] + - espn + - facebook + - [youtube-watch, youtube-w] + - allrecipes youtube-playback-av1-sfr: description: "Raptor YouTube Playback AV1 SFR on Fenix" test-name: youtube-playback-av1-sfr run-visual-metrics: False chimera: False - treeherder: - symbol: 'Btime(ytp-av1-sfr)' youtube-playback-h264-sfr: description: "Raptor YouTube Playback H264 SFR on Fenix" test-name: youtube-playback-h264-sfr run-visual-metrics: False chimera: False - treeherder: - symbol: Btime(ytp-h264-sfr) youtube-playback-vp9-sfr: description: "Raptor YouTube Playback VP9 SFR on Fenix" run-visual-metrics: False chimera: False test-name: youtube-playback-vp9-sfr - treeherder: - symbol: Btime(ytp-vp9-sfr) diff --git a/taskcluster/fenix_taskgraph/transforms/browsertime.py b/taskcluster/fenix_taskgraph/transforms/browsertime.py index 9f5e91572..544d06860 100644 --- a/taskcluster/fenix_taskgraph/transforms/browsertime.py +++ b/taskcluster/fenix_taskgraph/transforms/browsertime.py @@ -11,6 +11,7 @@ from __future__ import absolute_import, print_function, unicode_literals import copy import json +from copy import deepcopy from taskgraph.transforms.base import TransformSequence from taskgraph.util.treeherder import inherit_treeherder_from_dep from taskgraph.util.schema import resolve_keyed_by @@ -18,6 +19,28 @@ from taskgraph.util.schema import resolve_keyed_by transforms = TransformSequence() +@transforms.add +def split_raptor_subtests(config, tests): + for test in tests: + # For tests that have 'page-load-tests' listed, we want to create a separate + # test job for every subtest (i.e. split out each page-load URL into its own job) + subtests = test.pop("page-load-tests", None) + if not subtests: + yield test + continue + + for subtest in subtests: + pageload_test = deepcopy(test) + + if isinstance(subtest, list): + pageload_test["test-name"] = subtest[0] + pageload_test["subtest-symbol"] = subtest[1] + else: + pageload_test["test-name"] = subtest + pageload_test["subtest-symbol"] = subtest + yield pageload_test + + @transforms.add def add_variants(config, tasks): only_types = config.config["only-for-build-types"] @@ -26,7 +49,7 @@ def add_variants(config, tasks): tests = list(tasks) for dep_task in config.kind_dependencies_tasks: - build_type = dep_task.attributes.get("build-type", '') + build_type = dep_task.attributes.get("build-type", "") if build_type not in only_types: continue @@ -91,6 +114,22 @@ def build_browsertime_task(config, tasks): task["run"]["command"].append("--test={}".format(test_name)) task["run"]["command"].extend(task.pop("args", [])) + # Setup treherder symbol + symbol = task.pop("subtest-symbol", None) + + # taskcluster is merging task attributes with the default ones + # resulting the --cold extra option in the ytp warm tasks + if "youtube-playback" in task["name"]: + symbol = test_name.replace("youtube-playback-", "ytp-") + + # Setup chimera for combined warm+cold testing + if task.pop("chimera", False): + task["run"]["command"].append("--chimera") + + # Add '-c' to taskcluster symbol when running cold tests + elif "--cold" in task["run"]["command"]: + symbol += "-c" + # Setup visual metrics run_visual_metrics = task.pop("run-visual-metrics", False) if run_visual_metrics: @@ -98,15 +137,11 @@ def build_browsertime_task(config, tasks): task["run"]["command"].append("--browsertime-no-ffwindowrecorder") task["attributes"]["run-visual-metrics"] = True - # Setup chimera for combined warm+cold testing - if task.pop("chimera", False): - task["run"]["command"].append("--chimera") - - # taskcluster is merging task attributes with the default ones - # resulting the --cold extra option in the ytp warm tasks - if 'youtube-playback' in task["name"]: - task["run"]["command"].remove("--cold") - + # Build taskcluster group and symol + task["treeherder"]["symbol"] = "Btime(%s)" % symbol + task["name"] = ( + task["name"].replace("tp6m-", "tp6m-{}-".format(symbol)).replace("-hv", "") + ) yield task @@ -129,7 +164,7 @@ def enable_webrender(config, tasks): @transforms.add def fill_email_data(config, tasks): - product_name = config.graph_config['taskgraph']['repositories']['mobile']['name'] + product_name = config.graph_config["taskgraph"]["repositories"]["mobile"]["name"] format_kwargs = { "product_name": product_name.lower(), "head_rev": config.params["head_rev"], @@ -138,7 +173,9 @@ def fill_email_data(config, tasks): for task in tasks: format_kwargs["task_name"] = task["name"] - resolve_keyed_by(task, 'notify', item_name=task["name"], level=config.params["level"]) + resolve_keyed_by( + task, "notify", item_name=task["name"], level=config.params["level"] + ) email = task["notify"].get("email") if email: email["link"]["href"] = email["link"]["href"].format(**format_kwargs) From e0c70582b82e71703001b5f096eae4b59a54cde8 Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 8 Feb 2021 17:23:12 +0200 Subject: [PATCH 091/248] For #17852 Change and Fix Intermittent UI test openNewTabTest --- .../mozilla/fenix/ui/TabbedBrowsingTest.kt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index 24d78cc61..80453dd49 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -72,8 +72,6 @@ class TabbedBrowsingTest { @Test fun openNewTabTest() { - homeScreen { }.dismissOnboarding() - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -81,11 +79,18 @@ class TabbedBrowsingTest { mDevice.waitForIdle() verifyTabCounter("1") }.openTabDrawer { - verifyExistingTabList() - }.openTabsListThreeDotMenu { - verifyCloseAllTabsButton() - verifyShareTabButton() - verifySelectTabs() + verifyNormalModeSelected() + verifyExistingOpenTabs("Test_Page_1") + closeTab() + }.openTabDrawer { + verifyNoTabsOpened() + }.openNewTab { + }.submitQuery(defaultWebPage.url.toString()) { + mDevice.waitForIdle() + verifyTabCounter("1") + }.openTabDrawer { + verifyNormalModeSelected() + verifyExistingOpenTabs("Test_Page_1") } } From e31b4f49e93389c5ad1f45dd9e2f87491d7d6b6e Mon Sep 17 00:00:00 2001 From: AndiAJ Date: Mon, 8 Feb 2021 17:45:42 +0200 Subject: [PATCH 092/248] For #17195 Fix Intermittent UI test verifyTabTrayNotShowingStateHalfExpanded --- .../androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index 80453dd49..de8380e1b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -262,7 +262,6 @@ class TabbedBrowsingTest { @Test fun verifyTabTrayNotShowingStateHalfExpanded() { - homeScreen { }.dismissOnboarding() navigationToolbar { }.openTabTray { From a98b40896d83a00a2a6173279658c9f633f96cf8 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Tue, 9 Feb 2021 14:47:52 +0200 Subject: [PATCH 093/248] For #15259 UI test: waits for home screen to be visible --- .../org/mozilla/fenix/helpers/TestHelper.kt | 21 ------------------- .../mozilla/fenix/ui/TabbedBrowsingTest.kt | 3 --- .../fenix/ui/robots/HomeScreenRobot.kt | 5 ++++- .../fenix/ui/robots/NotificationRobot.kt | 2 +- 4 files changed, 5 insertions(+), 26 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt index ad339c592..9dffa1728 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/TestHelper.kt @@ -12,11 +12,6 @@ import android.os.Build import android.os.Environment import androidx.preference.PreferenceManager import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.ViewAction -import androidx.test.espresso.action.CoordinatesProvider -import androidx.test.espresso.action.GeneralClickAction -import androidx.test.espresso.action.Press -import androidx.test.espresso.action.Tap import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.assertion.ViewAssertions import androidx.test.espresso.matcher.ViewMatchers.withId @@ -108,22 +103,6 @@ object TestHelper { } } - fun sendSingleTapToScreen(x: Int, y: Int): ViewAction? { - return GeneralClickAction( - Tap.SINGLE, - CoordinatesProvider { view -> - val screenPos = IntArray(2) - view.getLocationOnScreen(screenPos) - val screenX = screenPos[0] + x.toFloat() - val screenY = screenPos[1] + y.toFloat() - floatArrayOf(screenX, screenY) - }, - Press.FINGER, - 0, - 0 - ) - } - // Remove test file from the device Downloads folder @Suppress("Deprecation") fun deleteDownloadFromStorage(fileName: String) { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index de8380e1b..54b59f22a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -16,7 +16,6 @@ import org.junit.Test import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.helpers.TestAssetHelper -import org.mozilla.fenix.helpers.TestHelper.sendSingleTapToScreen import org.mozilla.fenix.ui.robots.browserScreen import org.mozilla.fenix.ui.robots.homeScreen import org.mozilla.fenix.ui.robots.navigationToolbar @@ -254,8 +253,6 @@ class TabbedBrowsingTest { notificationShade { verifyPrivateTabsNotification() }.clickClosePrivateTabsNotification { - // Tap an empty spot on the app homescreen to make sure it's into focus - sendSingleTapToScreen(20, 20) verifyHomeScreen() } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt index 4c42f3276..0d29f036e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/HomeScreenRobot.kt @@ -486,8 +486,11 @@ private fun assertFocusedNavigationToolbar() = onView(allOf(withHint("Search or enter address"))) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) -private fun assertHomeScreen() = onView(ViewMatchers.withResourceName("homeLayout")) +private fun assertHomeScreen() { + mDevice.findObject(UiSelector().resourceId("$packageName:id/homeLayout")).waitForExists(waitingTime) + onView(ViewMatchers.withResourceName("homeLayout")) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) +} private fun assertHomeMenu() = onView(ViewMatchers.withResourceName("menuButton")) .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt index aea828072..2c7ffe6ac 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/NotificationRobot.kt @@ -67,7 +67,7 @@ class NotificationRobot { fun clickClosePrivateTabsNotification(interact: HomeScreenRobot.() -> Unit): HomeScreenRobot.Transition { NotificationRobot().verifySystemNotificationExists("Close private tabs") - closePrivateTabsNotification().clickAndWaitForNewWindow() + closePrivateTabsNotification().click() HomeScreenRobot().interact() return HomeScreenRobot.Transition() From 08a1e0f72870be30d52ab23892edcbde7def572b Mon Sep 17 00:00:00 2001 From: ekager Date: Mon, 8 Feb 2021 08:55:51 -0700 Subject: [PATCH 094/248] For #17906 - Allow screenshots for private home screenshot test --- .../org/mozilla/fenix/screenshots/DefaultHomeScreenTest.kt | 6 +++++- .../fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/screenshots/DefaultHomeScreenTest.kt b/app/src/androidTest/java/org/mozilla/fenix/screenshots/DefaultHomeScreenTest.kt index 0fa99cc35..d0f32270d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/screenshots/DefaultHomeScreenTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/screenshots/DefaultHomeScreenTest.kt @@ -44,10 +44,14 @@ class DefaultHomeScreenTest : ScreenshotTest() { SystemClock.sleep(TestAssetHelper.waitingTimeShort) Screengrab.screenshot("HomeScreenRobot_home-screen") }.openThreeDotMenu { - }.openSettings { } + }.openSettings { + }.openPrivateBrowsingSubMenu { + clickPrivateModeScreenshotsSwitch() + } // To get private screenshot, // dismiss onboarding going to settings and back mDevice.pressBack() + mDevice.pressBack() homeScreen { togglePrivateBrowsingModeOnOff() Screengrab.screenshot("HomeScreenRobot_private-browsing-menu") diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt index 5ce0944af..c8ef29dd0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuPrivateBrowsingRobot.kt @@ -46,6 +46,8 @@ class SettingsSubMenuPrivateBrowsingRobot { fun verifyPrivateBrowsingShortcutIcon() = assertPrivateBrowsingShortcutIcon() + fun clickPrivateModeScreenshotsSwitch() = screenshotsInPrivateModeSwitch().click() + fun clickOpenLinksInPrivateTabSwitch() = openLinksInPrivateTabSwitch().click() fun addPrivateShortcutToHomescreen() { @@ -92,6 +94,9 @@ private fun assertNavigationToolBarHeader() { private fun openLinksInPrivateTabSwitch() = onView(withText("Open links in a private tab")) +private fun screenshotsInPrivateModeSwitch() = + onView(withText("Allow screenshots in private browsing")) + private fun addPrivateBrowsingShortcutButton() = onView(withText("Add private browsing shortcut")) private fun goBackButton() = onView(withContentDescription("Navigate up")) From 672d9b272207c29735ad508b3ea2c866564dcf15 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 9 Feb 2021 21:09:40 +0000 Subject: [PATCH 095/248] Update Android Components version to 73.0.20210209203620. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 488871a43..02650c1a6 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210205154357" + const val VERSION = "73.0.20210209203620" } From ca57a132c7125a08be2608e99864496990efb4c3 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Wed, 10 Feb 2021 00:05:17 +0000 Subject: [PATCH 096/248] Import l10n. --- app/src/main/res/values-bg/strings.xml | 160 ++++++++++++++++++++---- app/src/main/res/values-kmr/strings.xml | 8 +- 2 files changed, 143 insertions(+), 25 deletions(-) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 66808702e..ed2e3f428 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -72,14 +72,6 @@ Не, благодаря - - - Стигнете по-бързо до Firefox. Добавете джаджа към началния си екран. - - Добавяне на джаджа - - Не сега - Може да настроите Firefox автоматично да отваря препратки в приложения @@ -88,6 +80,8 @@ Прекратяване + + Необходим е достъп до камерата. Отворете настройките на Android, докоснете разрешения и изберете разрешаване. Към настройки @@ -100,6 +94,13 @@ Прекратяване + + Променете изгледа на отворените раздели. Отворете настройки и изберете „мрежа“ в „преглед на раздел“. + + Към настройки + + Отхвърляне + Нов раздел @@ -143,12 +144,12 @@ Инсталиране Синхронизирани раздели + + Повторно синхронизиране Търсене в страницата Поверителен раздел - - Нов раздел Добавяне към списък @@ -213,6 +214,8 @@ Научете повече + + Отваряне на раздел във Firefox Търсене @@ -262,7 +265,7 @@ Поверителност и сигурност - Права на страницата + Права на страници Поверително разглеждане @@ -279,6 +282,8 @@ Личен сървър за Firefox Account Личен сървър за Sync + + Сървърът на Firefox Account/Sync е променен. Излизане от приложението за прилагане на промените… Сметка @@ -341,6 +346,20 @@ Известия + + + Персонализиран списък от добавки + + Добре + + Отказ + + Наименование на списък + + Собственик на списък (User ID) + + Списъкът с добавки е променен. Излизане от приложението за прилагане на промените… + Синхронизиране @@ -418,6 +437,10 @@ Маркетингови данни Споделя данни за използваните от вас възможности на %1$s чрез Leanplum, нашият партньор за мобилен маркетинг. + + Проучвания + + Позволява на Mozilla да инсталира и изпълнява проучвания Експерименти @@ -466,11 +489,19 @@ Зададена от приложение за пестене на батерия - Следва темата на устройството + Като темата на устройството - Издърпайте за презареждане + Издърпване за презареждане + + + Плъзване скрива лентата с инструменти + + Плъзване на лентата с инструменти настрани сменя раздели + + + Плъзване нагоре на лентата с инструменти отваря раздели @@ -519,6 +550,14 @@ Няма затворени раздели + + Раздели + + Изглед на раздели + + Списък + + Решетка Затваряне на раздели @@ -530,6 +569,15 @@ След един месец + + Ръчно затваряне + + Затваряне след един ден + + Затваряне след една седмица + + Затваряне след един месец + Отворени раздели @@ -547,6 +595,8 @@ Отворени раздели Добавяне към списък + + Избиране Споделяне на всички раздели @@ -561,6 +611,12 @@ Начален екран Превключване режима на раздела + + Отметка + + Затваряне + + Споделяне на избраните раздели Премахване на раздела от спъсъка @@ -596,8 +652,10 @@ Преименуване на списък Отваряне на раздели - - Премахване + + Преименуване + + Премахване Премахване от историята @@ -633,6 +691,10 @@ is a digit showing the number of items you have selected --> Изтриване на %1$d записа + + Днес + + Вчера Последните 24 часа @@ -646,12 +708,19 @@ Липсва история - - Няма изтегляния + + Изтриване на изтеглени файлове + + Сигурни ли сте, че желаете да изтриете изтеглените файлове? %1$d избрани + + + Отваряне + + Извинете. %1$s не можа да зареди страницата. @@ -774,6 +843,8 @@ Местоположение Известие + + Постоянно хранилище Винаги да пита @@ -905,6 +976,11 @@ Адресът е копиран + + Направи текста в уебсайтовете по-голям или по-малък + + Размер на шрифт + Отворени раздели @@ -919,6 +995,14 @@ %d страници Бисквитки + + Буферирани изображения и файлове + + Освобождава място за съхранение + + Права на страницата + + Изтриване на история на разглеждане и изход Изход @@ -987,10 +1071,6 @@ Отваряне на настройки Поверителност - - Проектирали сме %s така, че да ви предоставя контрол върху това, което споделяте както онлайн, така и с нас. - Бележка за поверителността @@ -1254,9 +1334,33 @@ Добре дошли в един чисто нов %s + + Обновяване на %s… + + Стартиране на %s + + Миграцията е завършена + + Пароли + + + Редактиране + + Паролата е задължителна + + Гласово търсене + + Говорете сега + + Регистрация с това потребителско име вече съществува + Добавете друго на устройство. + + Моля, удостоверете се отново. + + Моля, включете синхронизиране на раздели. Няма отворени раздели във Firefox на други ваши устройства. @@ -1270,6 +1374,13 @@ Добре, разбрах + + Наименование + + Добре + + Отказ + Премахване @@ -1277,4 +1388,11 @@ The first parameter is the name of the app (e.g. Firefox Preview) --> Извлечете максимума от %s + + Натиснете за подробности + + + Съберете нещата, които са важни за вас + + Групирайте заедно подобни търсения, сайтове и раздели за бърз достъп по-късно. diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 7a4a2dce5..a883ba0e3 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -1014,7 +1014,7 @@ Bibîne - Tevlî malperên favorî bû! + Tevlî malperên sereke bû! Hilpekîna veşartî hate girtin @@ -1604,7 +1604,7 @@ Tu ji dil dixwazî vê favoriyê jê bibî? - Tevlî malperên favorî bike + Tevlî malperên sereke bike Piştrastkirin ji aliyê: %1$s @@ -1658,10 +1658,10 @@ - Gihîşte sînorê malperên favorî + Gihîşte sînorê malperên sereke - Ji bo malpereke din ya sereke lê zêde bikî, yekê jê bibe.Malperê bipelîne û li ser bigire û rakirinê hilbijêre. + Ji bo malpereke din a sereke lê zêde bikî, yekê jê bibe. Li malperê bitikîne û li ser bihêle piştre rakirinê hilbijêre. Baş e From 88facc4608b0960efd9e3678f34f0ebc66af21a6 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 9 Feb 2021 17:53:17 -0500 Subject: [PATCH 097/248] Closes #17889: Wrong tab selected/reloaded when restored from collection --- .../SessionControlController.kt | 6 +-- .../DefaultSessionControlControllerTest.kt | 43 ++++++++++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index 88f46fdac..a181d1f69 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -215,10 +215,8 @@ class DefaultSessionControlController( tab, onTabRestored = { activity.openToBrowser(BrowserDirection.FromHome) - store.state.selectedTabId?.let { - selectTabUseCase.invoke(it) - reloadUrlUseCase.invoke(it) - } + selectTabUseCase.invoke(it) + reloadUrlUseCase.invoke(it) }, onFailure = { activity.openToBrowserAndLoad( diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 8b45154f6..16275ed79 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -182,8 +182,8 @@ class DefaultSessionControlControllerTest { } @Test - fun `handleCollectionOpenTabClicked onTabRestored`() { - val restoredTab = RecoverableTab( + fun `handleCollectionOpenTabClicked with existing selected tab`() { + val recoverableTab = RecoverableTab( id = "test", parentId = null, url = "https://www.mozilla.org", @@ -196,13 +196,42 @@ class DefaultSessionControlControllerTest { ) val tab = mockk { - every { restore(activity, engine, restoreSessionId = false) } returns restoredTab + every { restore(activity, engine, restoreSessionId = false) } returns recoverableTab } - store.dispatch(TabListAction.AddTabAction( - createTab(id = restoredTab.id, url = restoredTab.url)) - ).joinBlocking() - store.dispatch(TabListAction.SelectTabAction(restoredTab.id)).joinBlocking() + val restoredTab = createTab(id = recoverableTab.id, url = recoverableTab.url) + val otherTab = createTab(id = "otherTab", url = "https://mozilla.org") + store.dispatch(TabListAction.AddTabAction(otherTab)).joinBlocking() + store.dispatch(TabListAction.SelectTabAction(otherTab.id)).joinBlocking() + store.dispatch(TabListAction.AddTabAction(restoredTab)).joinBlocking() + + controller.handleCollectionOpenTabClicked(tab) + verify { metrics.track(Event.CollectionTabRestored) } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + verify { selectTabUseCase.selectTab.invoke(restoredTab.id) } + verify { reloadUrlUseCase.reload.invoke(restoredTab.id) } + } + + @Test + fun `handleCollectionOpenTabClicked without existing selected tab`() { + val recoverableTab = RecoverableTab( + id = "test", + parentId = null, + url = "https://www.mozilla.org", + title = "Mozilla", + state = null, + contextId = null, + readerState = ReaderState(), + lastAccess = 0, + private = false + ) + + val tab = mockk { + every { restore(activity, engine, restoreSessionId = false) } returns recoverableTab + } + + val restoredTab = createTab(id = recoverableTab.id, url = recoverableTab.url) + store.dispatch(TabListAction.AddTabAction(restoredTab)).joinBlocking() controller.handleCollectionOpenTabClicked(tab) verify { metrics.track(Event.CollectionTabRestored) } From 886850483c59d88cbd98c698ab1fb5a64828f049 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Tue, 9 Feb 2021 17:06:03 +0100 Subject: [PATCH 098/248] Issue #17819: Add Maven Central repository. --- build.gradle | 41 +++++++++++++++++++ .../toolchain/android-gradle-dependencies.sh | 2 +- .../android-gradle-dependencies/after.sh | 1 + 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e1399e459..91ab24ac0 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ buildscript { includeGroupByRegex RepoMatching.mozilla } } + maven { name "Mozilla" url "https://maven.mozilla.org/maven2" @@ -21,6 +22,7 @@ buildscript { includeGroupByRegex RepoMatching.mozilla } } + if (project.hasProperty("googleRepo")) { maven { name "Google" @@ -38,6 +40,24 @@ buildscript { } } + if (project.hasProperty("centralRepo")) { + maven { + name "MavenCentral" + url project.property("centralRepo") + } + } else { + mavenCentral() { + content { + // Improve security: don't search deps with known repos. + excludeGroupByRegex RepoMatching.mozilla + excludeGroupByRegex RepoMatching.androidx + excludeGroupByRegex RepoMatching.comGoogleAndroid + excludeGroupByRegex RepoMatching.comGoogleFirebase + excludeGroupByRegex RepoMatching.comAndroid + } + } + } + if (project.hasProperty("jcenterRepo")) { maven { name "BintrayJCenter" @@ -86,6 +106,7 @@ allprojects { includeGroupByRegex RepoMatching.mozilla } } + maven { name "Mozilla" url "https://maven.mozilla.org/maven2" @@ -94,6 +115,7 @@ allprojects { includeGroupByRegex RepoMatching.mozilla } } + if (project.hasProperty("googleRepo")) { maven { name "Google" @@ -110,6 +132,25 @@ allprojects { } } } + + if (project.hasProperty("centralRepo")) { + maven { + name "MavenCentral" + url project.property("centralRepo") + } + } else { + mavenCentral() { + content { + // Improve security: don't search deps with known repos. + excludeGroupByRegex RepoMatching.mozilla + excludeGroupByRegex RepoMatching.androidx + excludeGroupByRegex RepoMatching.comGoogleAndroid + excludeGroupByRegex RepoMatching.comGoogleFirebase + excludeGroupByRegex RepoMatching.comAndroid + } + } + } + if (project.hasProperty("jcenterRepo")) { maven { name "BintrayJCenter" diff --git a/taskcluster/scripts/toolchain/android-gradle-dependencies.sh b/taskcluster/scripts/toolchain/android-gradle-dependencies.sh index 06c23c34a..7117fe288 100755 --- a/taskcluster/scripts/toolchain/android-gradle-dependencies.sh +++ b/taskcluster/scripts/toolchain/android-gradle-dependencies.sh @@ -19,7 +19,7 @@ pushd $PROJECT_DIR . taskcluster/scripts/toolchain/android-gradle-dependencies/before.sh NEXUS_PREFIX='http://localhost:8081/nexus/content/repositories' -GRADLE_ARGS="--parallel -PgoogleRepo=$NEXUS_PREFIX/google/ -PjcenterRepo=$NEXUS_PREFIX/jcenter/" +GRADLE_ARGS="--parallel -PgoogleRepo=$NEXUS_PREFIX/google/ -PjcenterRepo=$NEXUS_PREFIX/jcenter/ -PcentralRepo=$NEXUS_PREFIX/central/" # We build everything to be sure to fetch all dependencies ./gradlew $GRADLE_ARGS assemble assembleAndroidTest testClasses ktlint detekt # Some tests may be flaky, although they still download dependencies. So we let the following diff --git a/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh b/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh index a62ab02a2..eed8d01fb 100644 --- a/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh +++ b/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh @@ -22,6 +22,7 @@ mkdir -p android-gradle-dependencies /builds/worker/artifacts cp -R ${NEXUS_WORK}/storage/jcenter android-gradle-dependencies cp -R ${NEXUS_WORK}/storage/google android-gradle-dependencies +cp -R ${NEXUS_WORK}/storage/central android-gradle-dependencies tar cf - android-gradle-dependencies | xz > /builds/worker/artifacts/android-gradle-dependencies.tar.xz From 7609f919d6f04216a7c68bdc70a69c65ba9e0046 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Tue, 9 Feb 2021 16:10:21 +0100 Subject: [PATCH 099/248] Issue #17819: Remove JCenter from buildscript repositories. --- build.gradle | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/build.gradle b/build.gradle index 91ab24ac0..2e45b98ad 100644 --- a/build.gradle +++ b/build.gradle @@ -57,24 +57,6 @@ buildscript { } } } - - if (project.hasProperty("jcenterRepo")) { - maven { - name "BintrayJCenter" - url project.property("jcenterRepo") - } - } else { - jcenter() { - content { - // Improve security: don't search deps with known repos. - excludeGroupByRegex RepoMatching.mozilla - excludeGroupByRegex RepoMatching.androidx - excludeGroupByRegex RepoMatching.comGoogleAndroid - excludeGroupByRegex RepoMatching.comGoogleFirebase - excludeGroupByRegex RepoMatching.comAndroid - } - } - } } dependencies { From ffc89c539a3a73682c7667b6ea7e9cbc171f100b Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Tue, 9 Feb 2021 18:15:18 +0100 Subject: [PATCH 100/248] Issue #17819: Only use JCenter for specific dependencies. --- build.gradle | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 2e45b98ad..356605f2a 100644 --- a/build.gradle +++ b/build.gradle @@ -141,12 +141,36 @@ allprojects { } else { jcenter() { content { - // Improve security: don't search deps with known repos. - excludeGroupByRegex RepoMatching.mozilla - excludeGroupByRegex RepoMatching.androidx - excludeGroupByRegex RepoMatching.comGoogleAndroid - excludeGroupByRegex RepoMatching.comGoogleFirebase - excludeGroupByRegex RepoMatching.comAndroid + //////////////////////////////////////////////////////////////////////////////// + // JCenter is going away. Please do not add any new dependencies here. + // https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ + //////////////////////////////////////////////////////////////////////////////// + + // Leanplum + // The docs mention a custom repository (repo.leanplum.com) that we may be able + // to switch to. + includeVersion("com.leanplum", "leanplum-core", "5.4.0") + includeVersion("com.leanplum", "leanplum-push", "5.4.0") + includeVersion("com.leanplum", "leanplum-fcm", "5.4.0") + + // Used by Android Gradle Plugin + // Issue for publishing to maven central: https://youtrack.jetbrains.com/issue/IDEA-261387 + // Related plugin issue: https://issuetracker.google.com/issues/179291081 + // Other option: Update to Android Gradle Plugin 7+ (still in Alpha currently) + includeVersion("org.jetbrains.trove4j", "trove4j", "20160824") + + // Used by detekt + // Issue for publishing to maven central: https://github.com/Kotlin/kotlinx.html/issues/173 + // Related detekt issue: https://github.com/detekt/detekt/issues/3461 + includeVersion("org.jetbrains.kotlinx", "kotlinx-html-jvm", "0.7.1") + includeVersion("org.jetbrains.kotlinx", "kotlinx-html-common", "0.7.1") + + // Fastlane + // Doesn't seem to be available on Maven Central yet, and I couldn't find an issue for it + // https://github.com/fastlane/fastlane + includeVersion("tools.fastlane", "screengrab", "2.0.0") + // https://github.com/jraska/Falcon/issues/52 + includeVersion("com.jraska", "falcon", "2.1.1") } } } From f4f5e4b663ab005dff7e4722d6c17bd0a7a0caca Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Wed, 10 Feb 2021 15:31:54 +0100 Subject: [PATCH 101/248] Issue #17174: Remove usage of old media APIs. --- app/src/main/AndroidManifest.xml | 3 -- .../fenix/browser/BaseBrowserFragment.kt | 3 -- .../collections/CollectionCreationStore.kt | 7 +--- .../collections/CollectionCreationView.kt | 4 +- .../org/mozilla/fenix/ext/BrowserState.kt | 16 -------- .../mozilla/fenix/home/HomeFragmentStore.kt | 4 +- .../org/mozilla/fenix/media/MediaService.kt | 16 -------- ...DefaultCollectionCreationControllerTest.kt | 7 ++-- .../org/mozilla/fenix/ext/BrowserStateTest.kt | 37 ------------------- 9 files changed, 7 insertions(+), 90 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/ext/BrowserState.kt delete mode 100644 app/src/main/java/org/mozilla/fenix/media/MediaService.kt delete mode 100644 app/src/test/java/org/mozilla/fenix/ext/BrowserStateTest.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 660175dfc..b1b84e842 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -232,9 +232,6 @@ - - diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 5f3de347c..7530c2ceb 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -124,7 +124,6 @@ import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration import java.lang.ref.WeakReference -import mozilla.components.feature.media.fullscreen.MediaFullscreenOrientationFeature import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.support.base.feature.ActivityResultHandler @@ -172,8 +171,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit private val sitePermissionWifiIntegration = ViewBoundFeatureWrapper() private val secureWindowFeature = ViewBoundFeatureWrapper() - private var fullScreenMediaFeature = - ViewBoundFeatureWrapper() private var fullScreenMediaSessionFeature = ViewBoundFeatureWrapper() private val searchFeature = ViewBoundFeatureWrapper() diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationStore.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationStore.kt index c9fffedb8..8e45a1d72 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationStore.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationStore.kt @@ -15,7 +15,6 @@ import mozilla.components.lib.state.State import mozilla.components.lib.state.Store import org.mozilla.fenix.collections.CollectionCreationAction.StepChanged import org.mozilla.fenix.components.TabCollectionStorage -import org.mozilla.fenix.ext.getMediaStateForSession import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.home.Tab @@ -87,12 +86,11 @@ internal fun BrowserState.getTabs( ): List { return tabIds ?.mapNotNull { id -> findTab(id) } - ?.map { it.toTab(this, publicSuffixList) } + ?.map { it.toTab(publicSuffixList) } .orEmpty() } private fun TabSessionState.toTab( - state: BrowserState, publicSuffixList: PublicSuffixList ): Tab { val url = readerState.activeUrl ?: content.url @@ -102,8 +100,7 @@ private fun TabSessionState.toTab( hostname = url.toShortUrl(publicSuffixList), title = content.title, selected = null, - icon = content.icon, - mediaState = state.getMediaStateForSession(this.id) + icon = content.icon ) } diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt index 0edcb6c29..63abf3c19 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt @@ -19,7 +19,6 @@ import androidx.transition.Transition import androidx.transition.TransitionManager import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.component_collection_creation.* -import mozilla.components.browser.state.state.MediaState import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.android.view.showKeyboard @@ -197,8 +196,7 @@ class CollectionCreationView( sessionId = tab.id.toString(), url = tab.url, hostname = tab.url.toShortUrl(publicSuffixList), - title = tab.title, - mediaState = MediaState.State.NONE + title = tab.title ) }.let { tabs -> collectionCreationTabListAdapter.updateData(tabs, tabs.toSet(), true) diff --git a/app/src/main/java/org/mozilla/fenix/ext/BrowserState.kt b/app/src/main/java/org/mozilla/fenix/ext/BrowserState.kt deleted file mode 100644 index 3339b01b1..000000000 --- a/app/src/main/java/org/mozilla/fenix/ext/BrowserState.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* 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 org.mozilla.fenix.ext - -import mozilla.components.browser.state.state.BrowserState -import mozilla.components.browser.state.state.MediaState - -fun BrowserState.getMediaStateForSession(sessionId: String): MediaState.State { - return if (media.aggregate.activeTabId == sessionId) { - media.aggregate.state - } else { - MediaState.State.NONE - } -} diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragmentStore.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragmentStore.kt index dc6b78d7d..f1284ee6a 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragmentStore.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragmentStore.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.home import android.graphics.Bitmap -import mozilla.components.browser.state.state.MediaState import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.top.sites.TopSite import mozilla.components.lib.state.Action @@ -28,8 +27,7 @@ data class Tab( val hostname: String, val title: String, val selected: Boolean? = null, - val icon: Bitmap? = null, - val mediaState: MediaState.State + val icon: Bitmap? = null ) /** diff --git a/app/src/main/java/org/mozilla/fenix/media/MediaService.kt b/app/src/main/java/org/mozilla/fenix/media/MediaService.kt deleted file mode 100644 index 32a1ce2da..000000000 --- a/app/src/main/java/org/mozilla/fenix/media/MediaService.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* 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 org.mozilla.fenix.media - -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.feature.media.service.AbstractMediaService -import org.mozilla.fenix.ext.components - -/** - * [AbstractMediaService] implementation for injecting [BrowserStore] singleton. - */ -class MediaService : AbstractMediaService() { - override val store: BrowserStore by lazy { components.core.store } -} diff --git a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt index 5af2f79a6..5d04f96b6 100644 --- a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt @@ -15,7 +15,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runBlockingTest import mozilla.components.browser.state.action.TabListAction -import mozilla.components.browser.state.state.MediaState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.feature.tab.collections.TabCollection @@ -80,8 +79,8 @@ class DefaultCollectionCreationControllerTest { ).joinBlocking() val tabs = listOf( - Tab("session-1", "", "", "", mediaState = MediaState.State.NONE), - Tab("null-session", "", "", "", mediaState = MediaState.State.NONE) + Tab("session-1", "", "", ""), + Tab("null-session", "", "", "") ) controller.saveCollectionName(tabs, "name") @@ -173,7 +172,7 @@ class DefaultCollectionCreationControllerTest { ).joinBlocking() val tabs = listOf( - Tab("session-1", "", "", "", mediaState = MediaState.State.NONE) + Tab("session-1", "", "", "") ) val collection = mockk() diff --git a/app/src/test/java/org/mozilla/fenix/ext/BrowserStateTest.kt b/app/src/test/java/org/mozilla/fenix/ext/BrowserStateTest.kt deleted file mode 100644 index 7c2c0a1d1..000000000 --- a/app/src/test/java/org/mozilla/fenix/ext/BrowserStateTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* 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 org.mozilla.fenix.ext - -import mozilla.components.browser.state.state.BrowserState -import mozilla.components.browser.state.state.MediaState -import mozilla.components.browser.state.state.createTab -import org.junit.Assert.assertEquals -import org.junit.Test - -private const val SESSION_ID_MOZILLA = "0" -private const val SESSION_ID_BCC = "1" -private const val SESSION_ID_BAD = "not a real session id" - -class BrowserStateTest { - - private val sessionMozilla = createTab(url = "www.mozilla.org", id = SESSION_ID_MOZILLA) - private val sessionBcc = createTab(url = "www.bcc.co.uk", id = SESSION_ID_BCC) - - @Test - fun `return media state if it matches tab id`() { - val state = BrowserState( - tabs = listOf(sessionBcc, sessionMozilla), - media = MediaState( - MediaState.Aggregate( - state = MediaState.State.PLAYING, - activeTabId = SESSION_ID_MOZILLA - )) - ) - - assertEquals(MediaState.State.PLAYING, state.getMediaStateForSession(SESSION_ID_MOZILLA)) - assertEquals(MediaState.State.NONE, state.getMediaStateForSession(SESSION_ID_BCC)) - assertEquals(MediaState.State.NONE, state.getMediaStateForSession(SESSION_ID_BAD)) - } -} From 8dfa4525ca8a3bbe0a35aaa1748093d221a7ac2a Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Wed, 10 Feb 2021 13:33:39 -0500 Subject: [PATCH 102/248] Fix OpenSpecificTabIntentProcessorTest to remove AbstractMediaService (#17955) --- .../home/intent/OpenSpecificTabIntentProcessorTest.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt b/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt index c925bbc38..045f5d680 100644 --- a/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/intent/OpenSpecificTabIntentProcessorTest.kt @@ -14,7 +14,6 @@ import io.mockk.verifyOrder import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.feature.media.service.AbstractMediaService import mozilla.components.feature.media.service.AbstractMediaSessionService import mozilla.components.feature.tabs.TabsUseCases import org.junit.Assert.assertFalse @@ -67,9 +66,14 @@ class OpenSpecificTabIntentProcessorTest { @Test fun `GIVEN an intent with null extra string WHEN it is processed THEN openToBrowser should not be called`() { val intent = Intent().apply { - action = AbstractMediaService.Companion.ACTION_SWITCH_TAB + action = AbstractMediaSessionService.Companion.ACTION_SWITCH_TAB } + val store = BrowserStore(BrowserState(tabs = listOf(createTab(id = TEST_SESSION_ID, url = "https:mozilla.org")))) + val tabUseCases: TabsUseCases = mockk(relaxed = true) + every { activity.components.core.store } returns store + every { activity.components.useCases.tabsUseCases } returns tabUseCases + assertFalse(processor.process(intent, navController, out)) verify(exactly = 0) { activity.openToBrowser(BrowserDirection.FromGlobal) } From 9f911e2e4c4193e9c91d71cd651cf5d141594721 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 10 Feb 2021 19:17:00 +0000 Subject: [PATCH 103/248] Update Android Components version to 73.0.20210210190047. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 02650c1a6..668ad1604 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210209203620" + const val VERSION = "73.0.20210210190047" } From a3b556aa35d10360cdfbbf42bf37276316107da7 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Wed, 10 Feb 2021 18:54:55 +0100 Subject: [PATCH 104/248] ToolbarIntegration: Use global public suffix list instance. --- .../org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt index 018bf6efb..fca3accc6 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt @@ -21,7 +21,6 @@ import mozilla.components.feature.tabs.toolbar.TabCounterToolbarButton import mozilla.components.feature.toolbar.ToolbarAutocompleteFeature import mozilla.components.feature.toolbar.ToolbarFeature import mozilla.components.feature.toolbar.ToolbarPresenter -import mozilla.components.lib.publicsuffixlist.PublicSuffixList import mozilla.components.support.base.feature.LifecycleAwareFeature import mozilla.components.support.ktx.android.view.hideKeyboard import org.mozilla.fenix.R @@ -45,7 +44,7 @@ abstract class ToolbarIntegration( store, sessionId, ToolbarFeature.UrlRenderConfiguration( - PublicSuffixList(context), + context.components.publicSuffixList, ThemeManager.resolveAttribute(R.attr.primaryText, context), renderStyle = renderStyle ) From 032879991e2ec5541fd9cddc223775d481457850 Mon Sep 17 00:00:00 2001 From: isabelrios Date: Thu, 11 Feb 2021 09:58:41 +0100 Subject: [PATCH 105/248] Add UI tests nightly build (#17948) * Try adding UI Tests to Nightly build * adding try_config file * remove try_task_config --- .../androidTest/flank-x86-start-test.yml | 3 +++ taskcluster/ci/build/kind.yml | 18 +++++++++++++++--- taskcluster/ci/signing/kind.yml | 3 ++- taskcluster/ci/ui-test/kind.yml | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/automation/taskcluster/androidTest/flank-x86-start-test.yml b/automation/taskcluster/androidTest/flank-x86-start-test.yml index 16292c98e..5d9c8d49c 100644 --- a/automation/taskcluster/androidTest/flank-x86-start-test.yml +++ b/automation/taskcluster/androidTest/flank-x86-start-test.yml @@ -42,6 +42,9 @@ gcloud: flank: project: GOOGLE_PROJECT + # test shards - the amount of groups to split the test suite into + # set to -1 to use one shard per test. + max-test-shards: 1 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x num-test-runs: 1 diff --git a/taskcluster/ci/build/kind.yml b/taskcluster/ci/build/kind.yml index 335abd497..2d647cb8f 100644 --- a/taskcluster/ci/build/kind.yml +++ b/taskcluster/ci/build/kind.yml @@ -63,6 +63,15 @@ jobs: treeherder: symbol: beta(Bf) + nightly-firebase: + disable-optimization: true + run-on-tasks-for: [github-push] # We want this on push so that we detect problem before triggering a new nightly + run: + gradle-build-type: nightly + test-build-type: nightly + treeherder: + symbol: nightly(Bf) + android-test-debug: attributes: code-review: true @@ -85,13 +94,16 @@ jobs: android-test-nightly: attributes: nightly: true - run: - gradle-build-type: androidTest apk-artifact-template: # 2 differences here: # * "androidTest/" is added # * "{gradle_build_type}" is forced to "debug" - path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/debug/{fileName}' + path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/nightly/app-nightly-androidTest.apk' + disable-optimization: true + run: + gradle-build-type: androidTest + test-build-type: nightly + run-on-tasks-for: [github-push] treeherder: symbol: nightly(Bat) diff --git a/taskcluster/ci/signing/kind.yml b/taskcluster/ci/signing/kind.yml index 87e55c0e7..c1880f856 100644 --- a/taskcluster/ci/signing/kind.yml +++ b/taskcluster/ci/signing/kind.yml @@ -49,13 +49,14 @@ job-template: # No test job runs on push against this build type. Although we do want nightly-simulation # signed to use it in the gecko trees. # We want beta on push so that we detect problem before shipping it - (nightly-simulation|beta-firebase|android-test-beta): [github-push] + (nightly-simulation|beta-firebase|android-test-beta|nightly-firebase|android-test-nightly): [github-push] default: [] treeherder: job-symbol: by-build-type: android-test.+: Bats beta-firebase: Bfs + nightly-firebase: Bfs default: Bs kind: build platform: android-all/opt diff --git a/taskcluster/ci/ui-test/kind.yml b/taskcluster/ci/ui-test/kind.yml index f4c7ed80b..164a8ed5e 100644 --- a/taskcluster/ci/ui-test/kind.yml +++ b/taskcluster/ci/ui-test/kind.yml @@ -80,3 +80,17 @@ jobs: - [automation/taskcluster/androidTest/ui-test.sh, x86-beta-tests, app.apk, android-test.apk, '50'] treeherder: symbol: beta(ui-test-x86-beta) + x86-nightly: + attributes: + build-type: nightly-firebase + description: Test Fenix + run-on-tasks-for: [github-push] + dependencies: + signing: signing-nightly-firebase + signing-android-test: signing-android-test-nightly + run: + commands: + - [automation/taskcluster/androidTest/ui-test.sh, x86-start-test, app.apk, android-test.apk, '-1'] + treeherder: + symbol: nightly(ui-test-x86-nightly) + From 243080ab7c2ca7bf5ce2c102010293ae3c769aa7 Mon Sep 17 00:00:00 2001 From: isabelrios Date: Thu, 11 Feb 2021 10:24:41 +0100 Subject: [PATCH 106/248] Revert "Add UI tests nightly build (#17948)" (#17960) This reverts commit 032879991e2ec5541fd9cddc223775d481457850. --- .../androidTest/flank-x86-start-test.yml | 3 --- taskcluster/ci/build/kind.yml | 18 +++--------------- taskcluster/ci/signing/kind.yml | 3 +-- taskcluster/ci/ui-test/kind.yml | 14 -------------- 4 files changed, 4 insertions(+), 34 deletions(-) diff --git a/automation/taskcluster/androidTest/flank-x86-start-test.yml b/automation/taskcluster/androidTest/flank-x86-start-test.yml index 5d9c8d49c..16292c98e 100644 --- a/automation/taskcluster/androidTest/flank-x86-start-test.yml +++ b/automation/taskcluster/androidTest/flank-x86-start-test.yml @@ -42,9 +42,6 @@ gcloud: flank: project: GOOGLE_PROJECT - # test shards - the amount of groups to split the test suite into - # set to -1 to use one shard per test. - max-test-shards: 1 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x num-test-runs: 1 diff --git a/taskcluster/ci/build/kind.yml b/taskcluster/ci/build/kind.yml index 2d647cb8f..335abd497 100644 --- a/taskcluster/ci/build/kind.yml +++ b/taskcluster/ci/build/kind.yml @@ -63,15 +63,6 @@ jobs: treeherder: symbol: beta(Bf) - nightly-firebase: - disable-optimization: true - run-on-tasks-for: [github-push] # We want this on push so that we detect problem before triggering a new nightly - run: - gradle-build-type: nightly - test-build-type: nightly - treeherder: - symbol: nightly(Bf) - android-test-debug: attributes: code-review: true @@ -94,16 +85,13 @@ jobs: android-test-nightly: attributes: nightly: true + run: + gradle-build-type: androidTest apk-artifact-template: # 2 differences here: # * "androidTest/" is added # * "{gradle_build_type}" is forced to "debug" - path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/nightly/app-nightly-androidTest.apk' - disable-optimization: true - run: - gradle-build-type: androidTest - test-build-type: nightly - run-on-tasks-for: [github-push] + path: '/builds/worker/checkouts/src/app/build/outputs/apk/androidTest/debug/{fileName}' treeherder: symbol: nightly(Bat) diff --git a/taskcluster/ci/signing/kind.yml b/taskcluster/ci/signing/kind.yml index c1880f856..87e55c0e7 100644 --- a/taskcluster/ci/signing/kind.yml +++ b/taskcluster/ci/signing/kind.yml @@ -49,14 +49,13 @@ job-template: # No test job runs on push against this build type. Although we do want nightly-simulation # signed to use it in the gecko trees. # We want beta on push so that we detect problem before shipping it - (nightly-simulation|beta-firebase|android-test-beta|nightly-firebase|android-test-nightly): [github-push] + (nightly-simulation|beta-firebase|android-test-beta): [github-push] default: [] treeherder: job-symbol: by-build-type: android-test.+: Bats beta-firebase: Bfs - nightly-firebase: Bfs default: Bs kind: build platform: android-all/opt diff --git a/taskcluster/ci/ui-test/kind.yml b/taskcluster/ci/ui-test/kind.yml index 164a8ed5e..f4c7ed80b 100644 --- a/taskcluster/ci/ui-test/kind.yml +++ b/taskcluster/ci/ui-test/kind.yml @@ -80,17 +80,3 @@ jobs: - [automation/taskcluster/androidTest/ui-test.sh, x86-beta-tests, app.apk, android-test.apk, '50'] treeherder: symbol: beta(ui-test-x86-beta) - x86-nightly: - attributes: - build-type: nightly-firebase - description: Test Fenix - run-on-tasks-for: [github-push] - dependencies: - signing: signing-nightly-firebase - signing-android-test: signing-android-test-nightly - run: - commands: - - [automation/taskcluster/androidTest/ui-test.sh, x86-start-test, app.apk, android-test.apk, '-1'] - treeherder: - symbol: nightly(ui-test-x86-nightly) - From 9d07b7ae03bc73a61fb780aa06852b60fe891b04 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Thu, 11 Feb 2021 00:03:55 +0000 Subject: [PATCH 107/248] Import l10n. --- app/src/main/res/values-tl/strings.xml | 386 ++++++++++++++++++++++++- 1 file changed, 383 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index d59696360..93f5ed5e4 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -9,10 +9,22 @@ Iba pang pagpipilian Paganahin ang private browsing + + I-disable ang private browsing + + Maghanap o ilagay ang address + + Ipapakita rito ang iyong nakabukas na mga tab. + + Ipapakita rito ang iyong mga pribadong tab. Baidu JD + + 1 nakabukas na tab. I-tap para lumipat ng tab. + + %1$s nakabukas na tab. I-tap para lumipat ng tab. %1$d ang napili @@ -22,10 +34,18 @@ Pumili ng koleksyon + + Umalis sa multiselect mode + + I-save ang mga napiling tab sa collection Napiling %1$s Hindi napiling %1$s + + Umalis na sa multiselect mode + + Pumasok na sa multiselect mode, pumili ng mga tab para mai-save sa isang collection Napili @@ -43,11 +63,16 @@ Salamat na lang + + + Maaari mong itakda sa Firefox na kusang buksan ang mga link sa mga app. Magpunta sa Settings Alisin + + Kailangan ng camera access. Pumunta sa Android settings, i-tap ang permiso, at i-tap ang payagan. Magpunta sa settings @@ -88,6 +113,8 @@ i-Edit ang Bookmark Mga Add-on + + Walang mga add-on dito Tulong @@ -128,30 +155,50 @@ Powered by %1$s Reader view + + Isara ang reader view Buksan sa app Itsura + + Hindi makakonekta. Hindi kilalang URL scheme. + Mamili ng wika Hanapin + + Sundin ang wika sa device + i-Scan Search engine + + Mga search engine setting + + Ngayon naman, maghanap gamit ang: + + Punan ang link mula sa clipboard Payagan Huwag Payagan + + Payagan ang mga mungkahi sa paghahanap sa mga pribadong session? Alamin + + + Magbukas ng bagong Firefox tab Maghanap @@ -175,6 +222,10 @@ Address bar Tulong + + I-rate sa Google Play + + Magbigay ng puna Tungkol sa %1$s @@ -182,10 +233,24 @@ Your Rights Mga Password + + Mga credit card at tirahan + + Itakda bilang default browser Pribasiya Pribasiya at Seguridad + + Mga site permission + + Private browsing + + Buksan ang mga link sa pribadong tab + + Payagan ang mga screenshot sa private browsing + + Magdagdag ng private browsing shortcut Accessibility @@ -202,27 +267,77 @@ Gestures Customize + + Mag-sync ng mga bookmark, kasaysayan, at iba pa gamit ang iyong Firefox Account Firefox Account + + Muling kumonekta para maipagpatuloy ang pag-sync Wika + + Mga pamimilian sa data + + Pagkolekta ng data Developer tools + + Remote debugging via USB + + Ipakita ang mga search engine + + Ipakita ang mga mungkahi sa paghanap + + Ipakita ang voice search + + Ipakita sa mga pribadong session + + Ipakita ang mga mungkahi mula sa clipboard + + Ipakita ang kasaysayan ng pag-browse + + Hanapin sa mga bookmark + + Hanapin sa mga naka-sync na tab + + Mga account setting + + Autocomplete URLs + + Buksan ang mga link sa mga app + + Hiwalay na download manager Add-ons + + Mga abiso + OK Kanselahin + + Pangalan ng collection + + May-ari ng collection (User ID) + + + + Hindi suportado ang add-on + + Naka-install na ang add-on + Sync now + + Piliin alin ang isi-sync Kasaysayan @@ -236,15 +351,55 @@ Ngalan ng device + + Hindi maaaring blangko ang pangalan ng device. Syncing… + + Bigong pag-sync. Huling matagumpay na pag-sync: %s + + Bigong pag-sync. Huling pag-sync: hindi pa ni minsan + + Huling na-sync: %s + + Huling na-sync: hindi pa ni minsan %1$s ng %2$s %3$s + + + Mga natanggap na tab + + May natanggap na tab + + May natanggap na mga tab + + Tab mula sa %s + + + + Tracking Protection + + Tracking Protection + + Harangin ang content at mga script na sumusubaybay sa iyo online + + Mga exception + + Nakasara ang Tracking Protection sa mga website na ito + + Buksan sa lahat ng mga site + + Nakakapag-disable ka ng tracking protection sa mga piling site gamit ang mga exception. + + Alamin + Telemetry + + Usage at technical data Marketing data @@ -292,12 +447,42 @@ Madilim + + Sundin ang tema ng device + + + + Hilahin pababa para mag-refresh + + Mag-scroll para maitago ang toolbar + + Mag-swipe patagilid sa toolbar para makalipat ng tab + + Mag-swipe pataas sa toolbar para maipakita ang mga tab + + + + Mga session Mga Screenshot Mga Download Mga Bookmark + + Mga Desktop Bookmark + + Menu ng mga Bookmark + + Bookmarks Toolbar + + Iba pang mga Bookmark + + Kasaysayan + + Mga naka-sync na tab + + Reading List Hanapin @@ -305,6 +490,10 @@ Isara + + Mga isinarang tab kamakailan + + Ipakita ang kumpletong kasaysayan %d mga tab @@ -312,6 +501,9 @@ %d is a placeholder for the number of tabs selected. --> %d tab + + Walang mga isinarang tab kamakailan + Mga Tab @@ -323,25 +515,75 @@ Isara ang mga tab + + Manu-mano + + Pagkatapos ng isang araw + + Pagkatapos ng isang linggo + + Pagkatapos ng isang buwan + + + Manu-manong isara + + Isara pagkatapos ng isang araw + + Isara pagkatapos ng isang linggo + + Isara pagkatapos ng isang buwan + Buksan ang mga tab + + Pribadong session + + Mga pribadong tab Magdagdag ng Tab + + Idagdag sa pribadong tab Pribado Buksan ang mga Tab + + I-save sa collection Pumili + + Ibahagi lahat ng mga tab + + Mga isinarang tab kamakailan + + Mga tab setting + + Isara lahat ng mga tab Bagong Tab Bookmark Isara + + Ibahagi ang mga piniling mga tab + + Piliin ang mga tab + + Isara ang tab + + Isara ang tab na %s + + Buksan ang menu ng mga tab + + Isara lahat ng mga tab Ibahagi ang mga tab + + I-save ang mga tab sa collection + + Menu ng tab Ibahagi ang tab @@ -352,31 +594,131 @@ i-Save Ibahagi - + + Kasalukuyang session image + + I-save sa collection + + Burahin ang collection + + Baguhin ang pangalan ng collection + + Buksan ang mga tab + + Pangalan ng collection + + Palitan ng pangalan + Alisin + + Burahin sa kasaysayan + + %1$s (Pribadong Mode) i-Save + + + Burahin ang kasaysayan + + Sigurado ka bang gusto mong burahin ang iyong kasaysayan? + + Nabura na ang Kasaysayan + + Binura na ang %1$s + + Alisin Kopyahin Ibahagi + + Buksan sa bagong tab + + Buksan sa pribadong tab + + Burahin + + Napili na ang %1$d + + Burahin ang %1$d item Ngayon Kahapon + + Nakaraang 24 oras + + Huling 7 araw + + Huling 30 araw Mas luma + + Walang kasaysayan dito + + + + Burahin ang mga download + + Sigurado ka bang gusto mong burahin lahat ng iyong mga download? + + Natanggal na ang mga Download + + Natanggal na ang %1$s + + Walang mga naka-download na file + + Napili na ang %1$d Buksan - - Burahin + + Tanggalin + + + + + Pasensya na. Hindi kayang ma-load ng %1$s ang pahina. + + Maaari mong subukang i-restore o isara ang tab na ito sa baba. + + Ipadala ang crash report sa Mozilla + + Isara ang tab + + I-restore ang tab + + + Mga pagpipilian sa session + + + Ibahagi ang session + + + Pumili ng folder + + Sigurado ka bang gusto mong burahin ang folder na ito? + + Buburahin ng %s ang mga napiling item. + + Nabura na ang %1$s + + Magdagdag ng folder + + Nalikha na ang bookmark. + + Nai-save na ang bookmark! + + I-EDIT i-Edit @@ -386,10 +728,23 @@ Ibahagi + + Buksan sa bagong tab + + Buksan sa pribadong tab Burahin i-Save + + Napili na ang %1$d + + i-Edit ang bookmark + + i-Edit ang folder + + Mag-sign in para makita ang mga naka-sync na bookmark URL @@ -397,6 +752,31 @@ PANGALAN + + Magdagdag ng folder + + Pumili ng folder + + Kailangang may pamagat + + Di-wastong URL + + Walang mga bookmark dito + + Binura na ang %1$s + + Nabura na ang mga bookmark + + Binubura ang mga napiling folder + + I-UNDO + + + + Mga permiso + + Pumunta sa mga Setting Camera From d56b4a2b9222d6a90202c306e4601e667266ed93 Mon Sep 17 00:00:00 2001 From: Codrut Topliceanu <60002907+codrut-topliceanu@users.noreply.github.com> Date: Thu, 11 Feb 2021 18:31:01 +0200 Subject: [PATCH 108/248] For #17418 - Added telemetry for Google Default Top Site (#17637) * For #17418 - Adds channel "ts" to TrackKey This is used to track if the `InContentTelemetry` is a result of the user using the Google Top Site. It looks for `&channel=ts` within the uri. * For #17418 - Adds TopSite PerformedSearch back in * For #17418 - Check now looks for equality with GOOGLE_URL * For #17418 - Adds test for topSite changes --- app/metrics.yaml | 2 +- .../mozilla/fenix/components/metrics/Event.kt | 4 +- .../fenix/components/metrics/MetricsUtils.kt | 6 ++- .../SessionControlController.kt | 25 +++++++++ .../telemetry/incontent/InContentTelemetry.kt | 5 +- .../telemetry/incontent/TrackKeyInfo.kt | 8 ++- .../DefaultSessionControlControllerTest.kt | 51 ++++++++++++++++++- .../incontent/InContentTelemetryTest.kt | 9 ++++ docs/metrics.md | 2 +- 9 files changed, 103 insertions(+), 9 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 4c9a2bd0e..3eced0a56 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -910,7 +910,7 @@ metrics: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be `custom`. - `source` will be: `action`, `suggestion`, `widget` or `shortcut` + `source` will be: `action`, `suggestion`, `widget`, `shortcut`, `topsite` (depending on the source from which the search started). Also added the `other` option for the source but it should never enter on this case. send_in_pings: diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index a5b94eec2..974e6b83a 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -456,6 +456,7 @@ sealed class Event { data class Action(override val engineSource: EngineSource) : EventSource(engineSource) data class Widget(override val engineSource: EngineSource) : EventSource(engineSource) data class Shortcut(override val engineSource: EngineSource) : EventSource(engineSource) + data class TopSite(override val engineSource: EngineSource) : EventSource(engineSource) data class Other(override val engineSource: EngineSource) : EventSource(engineSource) private val label: String @@ -464,6 +465,7 @@ sealed class Event { is Action -> "action" is Widget -> "widget" is Shortcut -> "shortcut" + is TopSite -> "topsite" is Other -> "other" } @@ -475,7 +477,7 @@ sealed class Event { } enum class SearchAccessPoint { - SUGGESTION, ACTION, WIDGET, SHORTCUT, NONE + SUGGESTION, ACTION, WIDGET, SHORTCUT, TOPSITE, NONE } override val extras: Map? diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsUtils.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsUtils.kt index 18b53961a..8857290c3 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricsUtils.kt @@ -17,7 +17,6 @@ import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.store.BrowserStore import mozilla.components.support.base.log.logger.Logger import org.mozilla.fenix.components.metrics.Event.PerformedSearch.SearchAccessPoint -import org.mozilla.fenix.ext.components import java.io.IOException import java.security.NoSuchAlgorithmException import java.security.spec.InvalidKeySpecException @@ -58,6 +57,11 @@ object MetricsUtils { engineSource ) ) + SearchAccessPoint.TOPSITE -> Event.PerformedSearch( + Event.PerformedSearch.EventSource.TopSite( + engineSource + ) + ) SearchAccessPoint.NONE -> Event.PerformedSearch( Event.PerformedSearch.EventSource.Other( engineSource diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index a181d1f69..1fa618487 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -6,12 +6,14 @@ package org.mozilla.fenix.home.sessioncontrol import android.view.LayoutInflater import android.widget.EditText +import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AlertDialog import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.browser.state.selector.getNormalOrPrivateTabs +import mozilla.components.browser.state.state.searchEngines import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine @@ -378,6 +380,20 @@ class DefaultSessionControlController( metrics.track(Event.PocketTopSiteClicked) } + if (SupportUtils.GOOGLE_URL.equals(url, true)) { + val availableEngines = getAvailableSearchEngines() + + val searchAccessPoint = Event.PerformedSearch.SearchAccessPoint.TOPSITE + val event = + availableEngines.firstOrNull { engine -> engine.suggestUrl?.contains(url) == true } + ?.let { searchEngine -> + searchAccessPoint.let { sap -> + MetricsUtils.createSearchEvent(searchEngine, store, sap) + } + } + event?.let { activity.metrics.track(it) } + } + addTabUseCase.invoke( url = appendSearchAttributionToUrlIfNeeded(url), selectTab = true, @@ -386,6 +402,15 @@ class DefaultSessionControlController( activity.openToBrowser(BrowserDirection.FromHome) } + @VisibleForTesting + internal fun getAvailableSearchEngines() = activity + .components + .core + .store + .state + .search + .searchEngines + /** * Append a search attribution query to any provided search engine URL based on the * user's current region. diff --git a/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetry.kt b/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetry.kt index 1be9e832c..f2ad23fea 100644 --- a/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetry.kt +++ b/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetry.kt @@ -59,8 +59,9 @@ class InContentTelemetry(private val metrics: MetricController) : BaseSearchTele // For Bing if it didn't have a valid cookie and for all the other search engines if (resultNotComputedFromCookies(trackKey) && hasValidCode(code, provider)) { + val channel = uri.getQueryParameter(CHANNEL_KEY) val type = getSapType(provider.followOnParams, paramSet) - trackKey = TrackKeyInfo(provider.name, type, code) + trackKey = TrackKeyInfo(provider.name, type, code, channel) } } @@ -145,5 +146,7 @@ class InContentTelemetry(private val metrics: MetricController) : BaseSearchTele private const val SEARCH_TYPE_ORGANIC = "organic" private const val SEARCH_TYPE_SAP = "sap" private const val SEARCH_TYPE_SAP_FOLLOW_ON = "sap-follow-on" + + private const val CHANNEL_KEY = "channel" } } diff --git a/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/TrackKeyInfo.kt b/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/TrackKeyInfo.kt index 73473943f..b67ec1522 100644 --- a/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/TrackKeyInfo.kt +++ b/app/src/main/java/org/mozilla/fenix/search/telemetry/incontent/TrackKeyInfo.kt @@ -9,11 +9,15 @@ import java.util.Locale internal data class TrackKeyInfo( var providerName: String, var type: String, - var code: String? + var code: String?, + var channel: String? = null ) { fun createTrackKey(): String { return "${providerName.toLowerCase(Locale.ROOT)}.in-content" + ".${type.toLowerCase(Locale.ROOT)}" + - ".${code?.toLowerCase(Locale.ROOT) ?: "none"}" + ".${code?.toLowerCase(Locale.ROOT) ?: "none"}" + + if (!channel?.toLowerCase(Locale.ROOT).isNullOrBlank()) + ".${channel?.toLowerCase(Locale.ROOT)}" + else "" } } diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 16275ed79..6025ba8b3 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -8,6 +8,9 @@ import androidx.navigation.NavController import androidx.navigation.NavDirections import io.mockk.every import io.mockk.mockk +import io.mockk.mockkStatic +import io.mockk.spyk +import io.mockk.unmockkStatic import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher @@ -21,6 +24,7 @@ import mozilla.components.browser.state.state.ReaderState import mozilla.components.browser.state.state.SearchState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.state.recover.RecoverableTab +import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.Engine import mozilla.components.feature.session.SessionUseCases @@ -39,6 +43,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.components.Analytics import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.components.metrics.Event.PerformedSearch.EngineSource import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.ext.components @@ -86,6 +91,16 @@ class DefaultSessionControlControllerTest { type = SearchEngine.Type.BUNDLED, resultUrls = listOf("https://example.org/?q={searchTerms}") ) + + private val googleSearchEngine = SearchEngine( + id = "googleTest", + name = "Google Test Engine", + icon = mockk(relaxed = true), + type = SearchEngine.Type.BUNDLED, + resultUrls = listOf("https://www.google.com/?q={searchTerms}"), + suggestUrl = "https://www.google.com/" + ) + private lateinit var store: BrowserStore private lateinit var controller: DefaultSessionControlController @@ -117,7 +132,7 @@ class DefaultSessionControlControllerTest { val restoreUseCase: TabsUseCases.RestoreUseCase = mockk(relaxed = true) - controller = DefaultSessionControlController( + controller = spyk(DefaultSessionControlController( activity = activity, store = store, settings = settings, @@ -136,7 +151,7 @@ class DefaultSessionControlControllerTest { showDeleteCollectionPrompt = showDeleteCollectionPrompt, showTabTray = showTabTray, handleSwipedItemDeletionCancel = handleSwipedItemDeletionCancel - ) + )) } @After @@ -392,6 +407,7 @@ class DefaultSessionControlControllerTest { @Test fun handleSelectGoogleDefaultTopSiteUS() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() @@ -412,6 +428,7 @@ class DefaultSessionControlControllerTest { @Test fun handleSelectGoogleDefaultTopSiteXX() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() @@ -429,9 +446,36 @@ class DefaultSessionControlControllerTest { verify { activity.openToBrowser(BrowserDirection.FromHome) } } + @Test + fun handleSelectGoogleDefaultTopSite_EventPerformedSearchTopSite() { + val topSiteUrl = SupportUtils.GOOGLE_URL + val engineSource = EngineSource.Default(googleSearchEngine, false) + every { controller.getAvailableSearchEngines() } returns listOf(googleSearchEngine) + try { + mockkStatic("mozilla.components.browser.state.state.SearchStateKt") + + every { any().selectedOrDefaultSearchEngine } returns googleSearchEngine + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.DEFAULT) + + verify { + metrics.track( + Event.PerformedSearch( + Event.PerformedSearch.EventSource.TopSite( + engineSource + ) + ) + ) + } + } finally { + unmockkStatic(SearchState::class) + } + } + @Test fun handleSelectGooglePinnedTopSiteUS() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() @@ -452,6 +496,7 @@ class DefaultSessionControlControllerTest { @Test fun handleSelectGooglePinnedTopSiteXX() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() @@ -472,6 +517,7 @@ class DefaultSessionControlControllerTest { @Test fun handleSelectGoogleFrecentTopSiteUS() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() @@ -492,6 +538,7 @@ class DefaultSessionControlControllerTest { @Test fun handleSelectGoogleFrecentTopSiteXX() { val topSiteUrl = SupportUtils.GOOGLE_URL + every { controller.getAvailableSearchEngines() } returns listOf(searchEngine) store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() diff --git a/app/src/test/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetryTest.kt b/app/src/test/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetryTest.kt index b491df390..36e30f6cd 100644 --- a/app/src/test/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetryTest.kt +++ b/app/src/test/java/org/mozilla/fenix/search/telemetry/incontent/InContentTelemetryTest.kt @@ -109,6 +109,15 @@ class InContentTelemetryTest { verify { metrics.track(Event.SearchInContent("google.in-content.sap-follow-on.firefox-b-m")) } } + @Test + fun `track google sap-follow-on and topSite metric`() { + val url = "https://www.google.com/search?q=aaa&client=firefox-b-m&channel=ts&oq=random" + + telemetry.trackPartnerUrlTypeMetric(url, listOf()) + + verify { metrics.track(Event.SearchInContent("google.in-content.sap-follow-on.firefox-b-m.ts")) } + } + @Test fun `track baidu sap-follow-on metric`() { val url = "https://www.baidu.com/from=844b/s?wd=aaa&tn=34046034_firefox&oq=random" diff --git a/docs/metrics.md b/docs/metrics.md index d06c57488..36f60ebaa 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -298,7 +298,7 @@ The following metrics are added to the ping: | metrics.mobile_bookmarks_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter that indicates how many bookmarks a user has in the mobile folder. This value will only be set if the user has at least *one* bookmark. If they have 0, this ping will not get sent, resulting in a null value. To disambiguate between a failed `mobile_bookmarks_count` ping and 0 bookmarks, please see `has_mobile_bookmarks`. |[1](https://github.com/mozilla-mobile/fenix/pull/16942), [2](https://github.com/mozilla-mobile/fenix/pull/16942#issuecomment-742794701)||2021-08-01 |2 | | metrics.mozilla_products |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |A list of all the Mozilla products installed on device. We currently scan for: Firefox, Firefox Beta, Firefox Aurora, Firefox Nightly, Firefox Fdroid, Firefox Lite, Reference Browser, Reference Browser Debug, Fenix, Focus, and Lockwise. |[1](https://github.com/mozilla-mobile/fenix/pull/1953/), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | | metrics.recently_used_pwa_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter that indicates how many PWAs a user has recently used. Threshold for "recency" set in HomeActivity#PWA_RECENTLY_USED_THRESHOLD. Currently we are not told by the OS when a PWA is removed by the user, so we use the "recently used" heuristic to judge how many PWAs are still active, as a proxy for "installed". This value will only be set if the user has at least *one* recently used PWA. If they have 0, this metric will not be sent, resulting in a null value during analysis on the server-side. To disambiguate between a failed `recently_used_pwa_count` metric and 0 recent PWAs, please see `has_recent_pwas`. |[1](https://github.com/mozilla-mobile/fenix/pull/11982#pullrequestreview-437963817), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | -| metrics.search_count |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |The labels for this counter are `.`. If the search engine is bundled with Fenix `search-engine-name` will be the name of the search engine. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be `custom`. `source` will be: `action`, `suggestion`, `widget` or `shortcut` (depending on the source from which the search started). Also added the `other` option for the source but it should never enter on this case. |[1](https://github.com/mozilla-mobile/fenix/pull/1677), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/7310), [4](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | +| metrics.search_count |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |The labels for this counter are `.`. If the search engine is bundled with Fenix `search-engine-name` will be the name of the search engine. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be `custom`. `source` will be: `action`, `suggestion`, `widget`, `shortcut`, `topsite` (depending on the source from which the search started). Also added the `other` option for the source but it should never enter on this case. |[1](https://github.com/mozilla-mobile/fenix/pull/1677), [2](https://github.com/mozilla-mobile/fenix/pull/5216), [3](https://github.com/mozilla-mobile/fenix/pull/7310), [4](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1, 2 | | metrics.search_widget_installed |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |Whether or not the search widget is installed |[1](https://github.com/mozilla-mobile/fenix/pull/10958), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | metrics.tab_view_setting |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string that indicates the setting for tab view: GRID, LIST |[1](https://github.com/mozilla-mobile/fenix/pull/15811#issuecomment-706402952)||2021-08-01 |2 | | metrics.tabs_open_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter that indicates how many NORMAL tabs a user has open. This value will only be set if the user has at least *one* open tab. If they have 0, this ping will not get sent, resulting in a null value. To disambiguate between a failed `tabs_open_count` ping and 0 open tabs, please see `has_open_tabs`. |[1](https://github.com/mozilla-mobile/fenix/pull/12024), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | From 40149bdc42382c350f43bf6ef1201c6e6c2f9783 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 11 Feb 2021 15:34:46 +0000 Subject: [PATCH 109/248] Update Android Components version to 73.0.20210211143129. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 668ad1604..a06170bf3 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210210190047" + const val VERSION = "73.0.20210211143129" } From 41f9388380ae54aabfefa377c903ab52c4544a2a Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 11 Feb 2021 18:29:30 +0200 Subject: [PATCH 110/248] For #17803 - Use the main looper for Handler()s This was already the one inferred. Targeting Android 11 means we need to pass it explicitly. --- .../org/mozilla/fenix/collections/CollectionCreationView.kt | 5 +++-- .../main/java/org/mozilla/fenix/settings/SettingsFragment.kt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt index 63abf3c19..7b23249a9 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.collections import android.os.Handler +import android.os.Looper import android.text.InputFilter import android.view.KeyEvent import android.view.LayoutInflater @@ -168,7 +169,7 @@ class CollectionCreationView( text = context.getString(R.string.create_collection_name_collection) setOnClickListener { name_collection_edittext.hideKeyboard() - val handler = Handler() + val handler = Handler(Looper.getMainLooper()) handler.postDelayed({ interactor.onBackPressed(SaveCollectionStep.NameCollection) }, TRANSITION_DURATION) @@ -214,7 +215,7 @@ class CollectionCreationView( text = context.getString(R.string.collection_rename) setOnClickListener { name_collection_edittext.hideKeyboard() - val handler = Handler() + val handler = Handler(Looper.getMainLooper()) handler.postDelayed({ interactor.onBackPressed(SaveCollectionStep.RenameCollection) }, TRANSITION_DURATION) diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 677f4863d..ea8fd5753 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -14,6 +14,7 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.widget.Toast import androidx.annotation.VisibleForTesting @@ -335,7 +336,7 @@ class SettingsFragment : PreferenceFragmentCompat() { Toast.LENGTH_LONG ).show() - Handler().postDelayed({ + Handler(Looper.getMainLooper()).postDelayed({ exitProcess(0) }, AMO_COLLECTION_OVERRIDE_EXIT_DELAY) } @@ -406,7 +407,7 @@ class SettingsFragment : PreferenceFragmentCompat() { getString(R.string.toast_override_fxa_sync_server_done), Toast.LENGTH_LONG ).show() - Handler().postDelayed({ + Handler(Looper.getMainLooper()).postDelayed({ exitProcess(0) }, FXA_SYNC_OVERRIDE_EXIT_DELAY) } From 13904184839c7f62808537e1f0b3770cc6d94278 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 11 Feb 2021 21:02:51 +0000 Subject: [PATCH 111/248] Update Android Components version to 73.0.20210211190100. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index a06170bf3..1f2f8aad0 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210211143129" + const val VERSION = "73.0.20210211190100" } From 2e45483eb0d69bc6c6fc16147538522a25c6f8f6 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Mon, 1 Feb 2021 17:48:54 -0800 Subject: [PATCH 112/248] For #17816: add ProfilerFactProcessor and register it, tests. --- .../org/mozilla/fenix/FenixApplication.kt | 4 + .../fenix/perf/ProfilerMarkerFactProcessor.kt | 82 +++++++++++++++++ .../perf/ProfilerMarkerFactProcessorTest.kt | 89 +++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessor.kt create mode 100644 app/src/test/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessorTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 7e40e24aa..03db2e676 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -29,6 +29,7 @@ import mozilla.components.lib.crash.CrashReporter import mozilla.components.service.glean.Glean import mozilla.components.service.glean.config.Configuration import mozilla.components.service.glean.net.ConceptFetchHttpUploader +import mozilla.components.support.base.facts.register import mozilla.components.support.base.log.Log import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.android.content.isMainProcess @@ -41,6 +42,7 @@ import mozilla.components.support.webextensions.WebExtensionSupport import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.metrics.MetricServiceType import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.perf.ProfilerMarkerFactProcessor import org.mozilla.fenix.perf.StartupTimeline import org.mozilla.fenix.perf.StorageStatsMetrics import org.mozilla.fenix.perf.runBlockingIncrement @@ -118,6 +120,8 @@ open class FenixApplication : LocaleAwareApplication(), Provider { @CallSuper open fun setupInMainProcessOnly() { + ProfilerMarkerFactProcessor.create { components.core.engine.profiler }.register() + run { // Attention: Do not invoke any code from a-s in this scope. val megazordSetup = setupMegazord() diff --git a/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessor.kt b/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessor.kt new file mode 100644 index 000000000..2e493cb2b --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessor.kt @@ -0,0 +1,82 @@ +/* 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 org.mozilla.fenix.perf + +import android.os.Handler +import android.os.Looper +import androidx.annotation.VisibleForTesting +import androidx.annotation.VisibleForTesting.PRIVATE +import mozilla.components.concept.base.profiler.Profiler +import mozilla.components.support.base.facts.Action +import mozilla.components.support.base.facts.Fact +import mozilla.components.support.base.facts.FactProcessor + +/** + * A fact processor that adds Gecko profiler markers for [Fact]s matching a specific format. + * We look for the following format: + * ``` + * Fact( + * action = Action.IMPLEMENTATION_DETAIL + * item = + * ) + * ``` + * + * This allows us to add profiler markers from android-components code. Using the Fact API for this + * purpose, rather than calling [Profiler.addMarker] directly inside components, has trade-offs. Its + * downsides are that it is less explicit and tooling does not work as well on it. However, we felt + * it was worthwhile because: + * + * 1. we don't know what profiler markers are useful so we want to be able to iterate quickly. + * Adding dependencies on the Profiler and landing these changes across two repos hinders that + * 2. we want to instrument the code as close to specific method calls as possible (e.g. + * GeckoSession.loadUrl) but it's not always easy to do so (e.g. in the previous example, passing a + * Profiler reference to GeckoEngineSession is difficult because GES is not a global dependency) + * 3. we can only add Profiler markers from the main thread so adding markers will become more + * difficult if we have to understand the threading needs of each Profiler call site + * + * An additional benefit with having this infrastructure is that it's easy to add Profiler markers + * for local debugging. + * + * That being said, if we find a location where it would be valuable to have a long term Profiler + * marker, we should consider instrumenting it via the [Profiler] API. + */ +class ProfilerMarkerFactProcessor @VisibleForTesting(otherwise = PRIVATE) constructor( + // We use a provider to defer accessing the profiler until we need it, because the property is a + // child of the engine property and we don't want to initialize it earlier than we intend to. + private val profilerProvider: () -> Profiler?, + private val mainHandler: Handler = Handler(Looper.getMainLooper()), + private val getMyLooper: () -> Looper? = { Looper.myLooper() } +) : FactProcessor { + + override fun process(fact: Fact) { + if (fact.action != Action.IMPLEMENTATION_DETAIL) { + return + } + + val markerName = fact.item + + // Java profiler markers can only be added from the main thread so, for now, we push all + // markers to the the main thread (which also groups all the markers together, + // making it easier to read). + val profiler = profilerProvider() + if (getMyLooper() == mainHandler.looper) { + profiler?.addMarker(markerName) + } else { + // To reduce the performance burden, we could early return if the profiler isn't active. + // However, this would change the performance characteristics from when the profiler is + // active and when it's inactive so we always post instead. + val now = profiler?.getProfilerTime() + mainHandler.post { + // We set now to both start and end time because we want a marker of without duration + // and if end is omitted, the duration is created implicitly. + profiler?.addMarker(markerName, now, now, null) + } + } + } + + companion object { + fun create(profilerProvider: () -> Profiler?) = ProfilerMarkerFactProcessor(profilerProvider) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessorTest.kt b/app/src/test/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessorTest.kt new file mode 100644 index 000000000..d0763e75a --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/perf/ProfilerMarkerFactProcessorTest.kt @@ -0,0 +1,89 @@ +/* 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 org.mozilla.fenix.perf + +import android.os.Handler +import android.os.Looper +import io.mockk.Called +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.mockk +import io.mockk.slot +import io.mockk.verify +import mozilla.components.concept.base.profiler.Profiler +import mozilla.components.support.base.Component +import mozilla.components.support.base.facts.Action +import mozilla.components.support.base.facts.Fact +import org.junit.Before +import org.junit.Test + +class ProfilerMarkerFactProcessorTest { + + @RelaxedMockK lateinit var profiler: Profiler + @RelaxedMockK lateinit var mainHandler: Handler + lateinit var processor: ProfilerMarkerFactProcessor + + var myLooper: Looper? = null + + @Before + fun setUp() { + MockKAnnotations.init(this) + myLooper = null + processor = ProfilerMarkerFactProcessor({ profiler }, mainHandler, { myLooper }) + } + + @Test + fun `GIVEN we are on the main thread WHEN a fact with an implementation detail action is received THEN a profiler marker is added now`() { + myLooper = mainHandler.looper // main thread + + val fact = newFact(Action.IMPLEMENTATION_DETAIL) + processor.process(fact) + + verify { profiler.addMarker(fact.item) } + } + + @Test + fun `GIVEN we are not on the main thread WHEN a fact with an implementation detail action is received THEN adding the marker is posted to the main thread`() { + myLooper = mockk() // off main thread + val mainThreadPostedSlot = slot() + every { profiler.getProfilerTime() } returns 100.0 + + val fact = newFact(Action.IMPLEMENTATION_DETAIL) + processor.process(fact) + + verify { mainHandler.post(capture(mainThreadPostedSlot)) } + verifyProfilerAddMarkerWasNotCalled() + + mainThreadPostedSlot.captured.run() // call the captured function posted to the main thread. + verify { profiler.addMarker(fact.item, 100.0, 100.0, null) } + } + + @Test + fun `WHEN a fact with a non-implementation detail action is received THEN no profiler marker is added`() { + val fact = newFact(Action.CANCEL) + processor.process(fact) + verify { profiler wasNot Called } + } + + private fun verifyProfilerAddMarkerWasNotCalled() { + verify(exactly = 0) { + profiler.addMarker(any()) + profiler.addMarker(any(), any() as Double?) + profiler.addMarker(any(), any() as String?) + profiler.addMarker(any(), any(), any()) + profiler.addMarker(any(), any(), any(), any()) + } + } +} + +private fun newFact( + action: Action, + item: String = "itemName" +) = Fact( + Component.BROWSER_SESSION, + action, + item +) From e9e067615a5b53fcfec52d977ea424d144f1824a Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 9 Feb 2021 11:57:53 -0800 Subject: [PATCH 113/248] For #17920: add ManufacturerCodes. --- .../mozilla/fenix/perf/StrictModeManager.kt | 6 +- .../mozilla/fenix/utils/ManufacturerCodes.kt | 22 ++++++ .../fenix/utils/ManufacturerCodesTest.kt | 69 +++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt create mode 100644 app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt index 391051707..ab3f46ad2 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt @@ -19,12 +19,10 @@ import androidx.fragment.app.FragmentManager import mozilla.components.support.ktx.android.os.resetAfter import org.mozilla.fenix.Config import org.mozilla.fenix.components.Components +import org.mozilla.fenix.utils.ManufacturerCodes import org.mozilla.fenix.utils.Mockable import java.util.concurrent.atomic.AtomicLong -private const val MANUFACTURE_HUAWEI: String = "HUAWEI" -private const val MANUFACTURE_ONE_PLUS: String = "OnePlus" - private val logger = Performance.logger private val mainLooper = Looper.getMainLooper() @@ -145,5 +143,5 @@ class StrictModeManager( * To add a new manufacturer to the list, log "Build.MANUFACTURER" from the device to get the * exact name of the manufacturer. */ - private val strictModeExceptionList = setOf(MANUFACTURE_HUAWEI, MANUFACTURE_ONE_PLUS) + private val strictModeExceptionList = setOf(ManufacturerCodes.HUAWEI, ManufacturerCodes.ONE_PLUS) } diff --git a/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt b/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt new file mode 100644 index 000000000..7915bcf4f --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/utils/ManufacturerCodes.kt @@ -0,0 +1,22 @@ +/* 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 org.mozilla.fenix.utils + +import android.os.Build + +/** + * A listing of codes returned by [android.os.Build.MANUFACTURER] for different manufacturers. + * While we try to get the casing accurate, it may be good to use .equals(str, ignoreCase = true) + * to do the comparison. + */ +object ManufacturerCodes { + const val HUAWEI: String = "HUAWEI" + const val LG = "LGE" + const val ONE_PLUS: String = "OnePlus" + const val SAMSUNG = "samsung" + + val isLG get() = Build.MANUFACTURER.equals(LG, ignoreCase = true) + val isSamsung get() = Build.MANUFACTURER.equals(SAMSUNG, ignoreCase = true) +} diff --git a/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt b/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt new file mode 100644 index 000000000..f277af239 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/utils/ManufacturerCodesTest.kt @@ -0,0 +1,69 @@ +/* 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 org.mozilla.fenix.utils + +import android.os.Build +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import java.lang.reflect.Modifier + +class ManufacturerCodesTest { + + private val manufacturerField = Build::class.java.getDeclaredField("MANUFACTURER") + private var manufacturer: String? + get() = Build.MANUFACTURER + set(value) { manufacturerField.set(null, value) } + + @Before + fun setUp() { + enableManufacturerModifications() + manufacturer = null // reset to default state before test. + assertEquals(null, Build.MANUFACTURER) // sanity check. + } + + private fun enableManufacturerModifications() { + // Mocking, which might be simpler, doesn't seem to work so we use reflection. + // Methodology via https://stackoverflow.com/a/3301720/2219998 + val modifiers = manufacturerField.javaClass.getDeclaredField("modifiers") + modifiers.isAccessible = true + modifiers.setInt(manufacturerField, manufacturerField.modifiers and Modifier.FINAL.inv()) + } + + @After + fun tearDown() { + // After this method, Build.MANUFACTURER appears to return to + // static final so we don't need to undo that. + manufacturer = null + assertEquals(null, Build.MANUFACTURER) // sanity check. + } + + @Test // To reduce boilerplate, we avoid best practice and put several tests in one. + fun testIsLG() { + manufacturer = "LGE" // expected value for lg devices + assertTrue(ManufacturerCodes.isLG) + + manufacturer = "lge" // unexpected value but is still an lg device + assertTrue(ManufacturerCodes.isLG) + + manufacturer = "samsung" + assertFalse(ManufacturerCodes.isLG) + } + + @Test // To reduce boilerplate, we avoid best practice and put several tests in one. + fun testIsSamsung() { + manufacturer = "samsung" // expected value for samsung devices + assertTrue(ManufacturerCodes.isSamsung) + + manufacturer = "SaMsUnG" // unexpected value but is still a samsung device + assertTrue(ManufacturerCodes.isSamsung) + + manufacturer = "LGE" + assertFalse(ManufacturerCodes.isSamsung) + } +} From a86b4ef1bd0d5c63dc45268c91fd3e9e69b98607 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 9 Feb 2021 11:59:03 -0800 Subject: [PATCH 114/248] For 17920: add ThreadPenaltyDeathWithIgnoresListener, tests, helpers. --- .../ThreadPenaltyDeathWithIgnoresListener.kt | 73 +++++++++++++++++ .../org/mozilla/fenix/helpers/StackTraces.kt | 39 ++++++++++ ...readPenaltyDeathWithIgnoresListenerTest.kt | 78 +++++++++++++++++++ .../EdmStorageProviderBaseLogcat.txt | 20 +++++ 4 files changed, 210 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt create mode 100644 app/src/test/java/org/mozilla/fenix/helpers/StackTraces.kt create mode 100644 app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt create mode 100644 app/src/test/resources/EdmStorageProviderBaseLogcat.txt diff --git a/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt b/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt new file mode 100644 index 000000000..fcc7774b3 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListener.kt @@ -0,0 +1,73 @@ +/* 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 org.mozilla.fenix.perf + +import android.os.Build +import android.os.StrictMode +import android.os.strictmode.Violation +import androidx.annotation.RequiresApi +import mozilla.components.support.base.log.logger.Logger +import org.mozilla.fenix.utils.ManufacturerCodes + +private const val FCQN_EDM_STORAGE_PROVIDER_BASE = "com.android.server.enterprise.storage.EdmStorageProviderBase" + +/** + * A [StrictMode.OnThreadViolationListener] that recreates + * [StrictMode.ThreadPolicy.Builder.penaltyDeath] but will ignore some violations. For example, + * sometimes OEMs will add code that violates StrictMode so we can ignore them here instead of + * cluttering up our code with resetAfter. + * + * This class can only be used with Android P+ so we'd have to implement workarounds if the + * violations we want to ignore affect older devices. + */ +@RequiresApi(Build.VERSION_CODES.P) +class ThreadPenaltyDeathWithIgnoresListener( + private val logger: Logger = Performance.logger +) : StrictMode.OnThreadViolationListener { + + override fun onThreadViolation(violation: Violation?) { + if (violation == null) return + + // Unfortunately, this method gets called many (~5+) times with the same violation so we end + // up logging/throwing redundantly. + if (shouldViolationBeIgnored(violation)) { + logger.debug("Ignoring StrictMode ThreadPolicy violation", violation) + } else { + penaltyDeath(violation) + } + } + + @Suppress("TooGenericExceptionThrown") // we throw what StrictMode's penaltyDeath throws. + private fun penaltyDeath(violation: Violation) { + throw RuntimeException("StrictMode ThreadPolicy violation", violation) + } + + private fun shouldViolationBeIgnored(violation: Violation): Boolean = + isSamsungLgEdmStorageProviderStartupViolation(violation) + + private fun isSamsungLgEdmStorageProviderStartupViolation(violation: Violation): Boolean { + // Root issue: https://github.com/mozilla-mobile/fenix/issues/17920 + // + // This fix may address the issues seen in this bug: + // https://github.com/mozilla-mobile/fenix/issues/15430 + // So we might be able to back out the changes made there. However, I don't have a device to + // test so I didn't bother. + // + // This issue occurs on the Galaxy S10e, Galaxy A50, Note 10, and LG G7 FIT but not the S7: + // I'm guessing it's just a problem on recent Samsungs and LGs so it's okay being in this P+ + // listener. + if (!ManufacturerCodes.isSamsung && !ManufacturerCodes.isLG) { + return false + } + + // To ignore this warning, we can inspect the stack trace. There are no parts of the + // violation stack trace that are clearly unique to this violation but + // EdmStorageProviderBase doesn't appear in Android code search so we match against it. + // This class may be used in other violations that we're capable of fixing but this + // code may ignore them. I think it's okay - we keep this code simple and if it was a serious + // issue, we'd catch it on other manufacturers. + return violation.stackTrace.any { it.className == FCQN_EDM_STORAGE_PROVIDER_BASE } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/helpers/StackTraces.kt b/app/src/test/java/org/mozilla/fenix/helpers/StackTraces.kt new file mode 100644 index 000000000..19fc97f62 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/helpers/StackTraces.kt @@ -0,0 +1,39 @@ +/* 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 org.mozilla.fenix.helpers + +/** + * A collection of test helper functions for manipulating stack traces. + */ +object StackTraces { + + /** + * Gets a stack trace from logcat output. To use this, you should remove the name of the + * Exception or "Caused by" lines causing the problem and only use the stack trace lines below + * it. See src/test/resources/EdmStorageProviderBaseLogcat.txt for an example. + */ + fun getStackTraceFromLogcat(logcatResourcePath: String): Array { + val logcat = javaClass.classLoader!!.getResource(logcatResourcePath).readText() + val lines = logcat.split('\n').filter(String::isNotBlank) + return lines.map(::logcatLineToStackTraceElement).toTypedArray() + } + + private fun logcatLineToStackTraceElement(line: String): StackTraceElement { + // Expected format: + // 02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1556) + + // Expected: android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk + val methodInfo = line.substringBefore('(').substringAfterLast(' ') + val methodName = methodInfo.substringAfterLast('.') + val declaringClass = methodInfo.substringBeforeLast('.') + + // Expected: StrictMode.java:1556 + val fileInfo = line.substringAfter('(').substringBefore(')') + val fileName = fileInfo.substringBefore(':') + val lineNumber = fileInfo.substringAfter(':').toInt() + + return StackTraceElement(declaringClass, methodName, fileName, lineNumber) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt b/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt new file mode 100644 index 000000000..f046e406c --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/perf/ThreadPenaltyDeathWithIgnoresListenerTest.kt @@ -0,0 +1,78 @@ +/* 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 org.mozilla.fenix.perf + +import android.os.strictmode.Violation +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.mockkObject +import io.mockk.unmockkAll +import io.mockk.verify +import mozilla.components.support.base.log.logger.Logger +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.mozilla.fenix.helpers.StackTraces +import org.mozilla.fenix.utils.ManufacturerCodes + +class ThreadPenaltyDeathWithIgnoresListenerTest { + + @RelaxedMockK private lateinit var logger: Logger + private lateinit var listener: ThreadPenaltyDeathWithIgnoresListener + @MockK private lateinit var violation: Violation + private lateinit var stackTrace: Array + + @Before + fun setUp() { + MockKAnnotations.init(this) + + listener = ThreadPenaltyDeathWithIgnoresListener(logger) + + stackTrace = emptyArray() + every { violation.stackTrace } answers { stackTrace } + } + + @After + fun tearDown() { + unmockkAll() + } + + @Test(expected = RuntimeException::class) + fun `WHEN provided an arbitrary violation that does not conflict with ignores THEN we throw an exception`() { + stackTrace = Exception().stackTrace + listener.onThreadViolation(violation) + } + + @Test + fun `GIVEN we're on a Samsung WHEN provided the EdmStorageProvider violation THEN it will be ignored and logged`() { + mockkObject(ManufacturerCodes) + every { ManufacturerCodes.isSamsung } returns true + + every { violation.stackTrace } returns getEdmStorageProviderStackTrace() + listener.onThreadViolation(violation) + + verify { logger.debug("Ignoring StrictMode ThreadPolicy violation", violation) } + } + + @Test(expected = RuntimeException::class) + fun `GIVEN we're not on a Samsung or LG WHEN provided the EdmStorageProvider violation THEN we throw an exception`() { + mockkObject(ManufacturerCodes) + every { ManufacturerCodes.isSamsung } returns false + every { ManufacturerCodes.isLG } returns false + + every { violation.stackTrace } returns getEdmStorageProviderStackTrace() + listener.onThreadViolation(violation) + } + + @Test + fun `WHEN violation is null THEN we don't throw an exception`() { + listener.onThreadViolation(null) + } + + private fun getEdmStorageProviderStackTrace() = + StackTraces.getStackTraceFromLogcat("EdmStorageProviderBaseLogcat.txt") +} diff --git a/app/src/test/resources/EdmStorageProviderBaseLogcat.txt b/app/src/test/resources/EdmStorageProviderBaseLogcat.txt new file mode 100644 index 000000000..1eb534116 --- /dev/null +++ b/app/src/test/resources/EdmStorageProviderBaseLogcat.txt @@ -0,0 +1,20 @@ +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1556) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteConnection.applyBlockGuardPolicy(SQLiteConnection.java:1524) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:1193) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:838) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:165) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:152) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:232) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:271) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.enterprise.storage.EdmStorageProviderBase.getValues(EdmStorageProviderBase.java:388) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.enterprise.storage.EdmStorageProviderBase.getValuesList(EdmStorageProviderBase.java:1104) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.enterprise.storage.EdmStorageProvider.getValuesList(EdmStorageProvider.java:300) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.enterprise.application.ApplicationPolicy.getApplicationStateEnabledAsUser(ApplicationPolicy.java:3745) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.enterprise.application.ApplicationPolicy.getApplicationStateEnabledAsUser(ApplicationPolicy.java:3714) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.pm.PackageManagerService.setEnabledSetting(PackageManagerService.java:26031) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.pm.PackageManagerService.setComponentEnabledSetting(PackageManagerService.java:26007) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:3774) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:5145) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.os.Binder.execTransactInternal(Binder.java:1056) +02-08 10:56:02.185 21990 21990 E AndroidRuntime: at android.os.Binder.execTransact(Binder.java:1029) From 5cb296b098d681c184a2ba9ac05f66f2f3ebbd51 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 9 Feb 2021 12:15:21 -0800 Subject: [PATCH 115/248] For #17920: use StrictMode penaltyDeathWithIgnores. --- .../mozilla/fenix/perf/StrictModeManager.kt | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt index ab3f46ad2..9debc8585 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt @@ -10,6 +10,7 @@ package org.mozilla.fenix.perf import android.os.Build +import android.os.Handler import android.os.Looper import android.os.StrictMode import androidx.annotation.VisibleForTesting @@ -21,8 +22,11 @@ import org.mozilla.fenix.Config import org.mozilla.fenix.components.Components import org.mozilla.fenix.utils.ManufacturerCodes import org.mozilla.fenix.utils.Mockable +import java.util.concurrent.Executors import java.util.concurrent.atomic.AtomicLong +private const val DELAY_TO_REMOVE_STRICT_MODE_MILLIS = 1000L + private val logger = Performance.logger private val mainLooper = Looper.getMainLooper() @@ -64,7 +68,7 @@ class StrictModeManager( .detectAll() .penaltyLog() if (setPenaltyDeath && Build.MANUFACTURER !in strictModeExceptionList) { - threadPolicy.penaltyDeath() + threadPolicy.penaltyDeathWithIgnores() } StrictMode.setThreadPolicy(threadPolicy.build()) @@ -94,10 +98,18 @@ class StrictModeManager( fragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { - enableStrictMode(setPenaltyDeath = false) fm.unregisterFragmentLifecycleCallbacks(this) - } - }, false) + + // If we don't post when using penaltyListener on P+, the violation listener is never + // called. My best guess is that, unlike penaltyDeath, the violations are not + // delivered instantaneously so posting gives time for the violation listeners to + // run before they are removed here. This may be a race so we give the listeners a + // little extra time to run too though this way we may accidentally trigger + // violations for non-startup, which we haven't planned to do yet. + Handler(mainLooper).postDelayed({ + enableStrictMode(setPenaltyDeath = false) + }, DELAY_TO_REMOVE_STRICT_MODE_MILLIS) + } }, false) } /** @@ -145,3 +157,18 @@ class StrictModeManager( */ private val strictModeExceptionList = setOf(ManufacturerCodes.HUAWEI, ManufacturerCodes.ONE_PLUS) } + +private fun StrictMode.ThreadPolicy.Builder.penaltyDeathWithIgnores(): StrictMode.ThreadPolicy.Builder { + // If we want to apply ignores based on stack trace contents to APIs below P, we can use this methodology: + // https://medium.com/@tokudu/how-to-whitelist-strictmode-violations-on-android-based-on-stacktrace-eb0018e909aa + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + penaltyDeath() + } else { + // Ideally, we'd use a shared thread pool but we don't have any on the system currently + // (all shared ones are coroutine dispatchers). + val executor = Executors.newSingleThreadExecutor() + penaltyListener(executor, ThreadPenaltyDeathWithIgnoresListener()) + } + + return this +} From b41041c7397bd0a483e095d5902d943c47d8c648 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Tue, 9 Feb 2021 12:18:49 -0800 Subject: [PATCH 116/248] For #17920: move manufacturer StrictMode exception to ignores function. I think this is more consistent and centralizes the violation ignores. --- .../mozilla/fenix/perf/StrictModeManager.kt | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt index 9debc8585..845076d8c 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StrictModeManager.kt @@ -67,7 +67,7 @@ class StrictModeManager( val threadPolicy = StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() - if (setPenaltyDeath && Build.MANUFACTURER !in strictModeExceptionList) { + if (setPenaltyDeath) { threadPolicy.penaltyDeathWithIgnores() } StrictMode.setThreadPolicy(threadPolicy.build()) @@ -147,18 +147,25 @@ class StrictModeManager( functionBlock() } } - - /** - * There are certain manufacturers that have custom font classes for the OS systems. - * These classes violates the [StrictMode] policies on startup. As a workaround, we create - * an exception list for these manufacturers so that dialogs do not show up on start up. - * To add a new manufacturer to the list, log "Build.MANUFACTURER" from the device to get the - * exact name of the manufacturer. - */ - private val strictModeExceptionList = setOf(ManufacturerCodes.HUAWEI, ManufacturerCodes.ONE_PLUS) } +/** + * There are certain manufacturers that have custom font classes for the OS systems. + * These classes violates the [StrictMode] policies on startup. As a workaround, we create + * an exception list for these manufacturers so that dialogs do not show up on start up. + * To add a new manufacturer to the list, log "Build.MANUFACTURER" from the device to get the + * exact name of the manufacturer. + */ +private val strictModeExceptionList = setOf(ManufacturerCodes.HUAWEI, ManufacturerCodes.ONE_PLUS) + private fun StrictMode.ThreadPolicy.Builder.penaltyDeathWithIgnores(): StrictMode.ThreadPolicy.Builder { + // This workaround was added before we realized we can ignored based on violation contents + // (see code below). This solution - blanket disabling StrictMode on some manufacturers - isn't + // great so, if we have time, we should consider reimplementing these fixes using the methods below. + if (Build.MANUFACTURER in strictModeExceptionList) { + return this + } + // If we want to apply ignores based on stack trace contents to APIs below P, we can use this methodology: // https://medium.com/@tokudu/how-to-whitelist-strictmode-violations-on-android-based-on-stacktrace-eb0018e909aa if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { From eabde046797b5e600e6422b9c17fb49ab943ffd2 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Fri, 12 Feb 2021 00:01:39 +0000 Subject: [PATCH 117/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 51 ++++++++++++++----------- app/src/main/res/values-oc/strings.xml | 2 + 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 1dccb9a45..983b3ff1a 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -50,7 +50,7 @@ Colesti del mou d\'esbilla múltiple - Entresti nel mou d\'esbilla múltiple, esbilla les llingüetes pa guardar nuna coleición + Entresti nel mou d\'esbilla múltiple, esbilla les llingüetes pa guardales nuna coleición %1$s ta producíu por Mozilla. @@ -110,7 +110,7 @@ Llingüeta privada nueva - Sitios destacaos + Sitios principales @@ -301,7 +301,7 @@ Cuenta de Firefox - Reconéutate pa siguir cola sincronización + Volvi conectate pa siguir cola sincronización Llingua @@ -454,7 +454,7 @@ Aniciar sesión pa reconectar - Desaniciar la cuenta + Quitar la cuenta @@ -483,6 +483,11 @@ Arrastrar p\'abaxo p\'anovar + + Desplazase p\'anubrir la barra de ferramientes + + Eslizar pa un llau pa cambiar de llingüeta + Sesiones @@ -565,6 +570,8 @@ Amestar una llingüeta + + Amestar una llingüeta privada En privao @@ -592,7 +599,7 @@ Menú de llingüetes abiertes - Desaniciar la llingüeta de la coleición + Quitar la llingüeta de la coleición Esbillar llingüetes @@ -631,7 +638,7 @@ Renomar - Desaniciar + Quitar Desaniciar del historial @@ -687,14 +694,14 @@ - Desaniciáronse les descargues + Quitáronse les descargues - Desanicióse %1$s + Quitóse %1$s Descargues esbillaes: %1$d - Desaniciar + Quitar @@ -952,7 +959,7 @@ Ver - ¡Amestóse a los sitios destacaos! + ¡Amestóse a los sitios principales! Zarróse la llingüeta privada @@ -962,7 +969,7 @@ DESFACER - Desanicióse\'l sitiu + Quitóse\'l sitiu Desfacer @@ -1123,7 +1130,7 @@ La sincronización ta activada - Fallu al aniciar sesión + Hebo un fallu al aniciar sesión Privacidá automática @@ -1197,7 +1204,7 @@ en llinia y con nós. Escanéu d\'un códigu - https://firefox.com/pair]]> + https://firefox.com/pair]]> Escaniar @@ -1270,7 +1277,7 @@ en llinia y con nós. Criptomineros - Buelgues + Xeneradores de buelgues Blóquiase Permítese @@ -1287,7 +1294,7 @@ en llinia y con nós. Evita que los scripts maliciosos consigan accesu al preséu pa minar divises dixitales. - Buelgues + Xeneradores de buelgues Evita la recoyida de datos identificables de forma esclusiva del preséu que puen usase pa rastrexar. @@ -1405,7 +1412,7 @@ en llinia y con nós. Los anicios de sesión y contraseñes d\'estos sitios nun van guardase. - Desaniciar toles esceiciones + Quitar toles esceiciones Buscar anicios de sesión @@ -1560,11 +1567,11 @@ en llinia y con nós. Nun hai nenguna - Artículos destacaos + Artículos principales ¿De xuru que quies desaniciar esti marcador? - Amestar a los sitios destacaos + Amestar a los sitios principales Cola verificación de: %1$s @@ -1615,9 +1622,9 @@ en llinia y con nós. - Algamóse la llende de sitios destacaos + Algamóse la llende de sitios principales - P\'amestar un sitiu destacáu nuevu, desanicia otru. Ten primíu\'l sitiu y esbilla desaniciar. + P\'amestar un sitiu principal nuevu, quita otru. Ten primíu\'l sitiu y esbilla quitar. Val, entendílo @@ -1627,14 +1634,14 @@ en llinia y con nós. Nome - Nome del sitiu destacáu + Nome del sitiu principal Aceutar Encaboxar - Desaniciar + Quitar diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index a6e822cc5..dab397e11 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -873,6 +873,8 @@ Emmagazinatge persistent + + Contengut contrarotlat per DRM Demandar per autorizar From d0fd3e82c51f63532b89ecdd7fe5d373609108fc Mon Sep 17 00:00:00 2001 From: Elise Richards Date: Thu, 11 Feb 2021 18:55:12 -0600 Subject: [PATCH 118/248] For #17771: three-dot menu reorder (#17838) * Feature flag for toolbar menu redesign. Add new items to menu and reorder. * Handle toolbar items in menu controller * Menu controller tests * Make icons invisible * Lint * UI tests reflect design change * Refactor test names * Lint fixes * UI tests --- .../org/mozilla/fenix/ui/ReaderViewTest.kt | 71 ++-- .../mozilla/fenix/ui/SettingsAddonsTest.kt | 30 +- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 8 + .../StrictEnhancedTrackingProtectionTest.kt | 2 + .../mozilla/fenix/ui/ThreeDotMenuMainTest.kt | 93 +++-- .../fenix/ui/robots/ThreeDotMenuMainRobot.kt | 46 +- .../java/org/mozilla/fenix/FeatureFlags.kt | 5 + .../toolbar/BrowserToolbarMenuController.kt | 222 +++++----- .../components/toolbar/DefaultToolbarMenu.kt | 395 ++++++++++++------ .../fenix/components/toolbar/ToolbarMenu.kt | 1 + app/src/main/res/values/colors.xml | 3 + app/src/main/res/values/strings.xml | 6 + ...DefaultBrowserToolbarMenuControllerTest.kt | 256 +++++++----- 13 files changed, 709 insertions(+), 429 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt index d405215ab..980c05aee 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -12,6 +12,8 @@ import org.junit.Rule import org.junit.Test import org.mozilla.fenix.ui.robots.navigationToolbar import androidx.test.espresso.IdlingRegistry +import org.junit.Ignore +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource @@ -29,7 +31,7 @@ import org.mozilla.fenix.ui.robots.mDevice * */ -// @Ignore("Temp disable - reader view page detection issues: https://github.com/mozilla-mobile/fenix/issues/9688 ") +@Ignore("Temp disable - reader view page detection issues: https://github.com/mozilla-mobile/fenix/issues/9688 ") class ReaderViewTest { private lateinit var mockWebServer: MockWebServer private var readerViewNotification: ViewVisibilityIdlingResource? = null @@ -103,39 +105,42 @@ class ReaderViewTest { @Test fun verifyReaderViewToggle() { - val readerViewPage = - TestAssetHelper.getLoremIpsumAsset(mockWebServer) - - navigationToolbar { - }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() + // New three-dot menu design does not have readerview + if (!FeatureFlags.toolbarMenuFeature) { + val readerViewPage = + TestAssetHelper.getLoremIpsumAsset(mockWebServer) + + navigationToolbar { + }.enterURLAndEnterToBrowser(readerViewPage.url) { + mDevice.waitForIdle() + } + + readerViewNotification = ViewVisibilityIdlingResource( + activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), + View.VISIBLE + ) + + IdlingRegistry.getInstance().register(readerViewNotification) + + navigationToolbar { + verifyReaderViewDetected(true) + toggleReaderView() + mDevice.waitForIdle() + } + + browserScreen { + verifyPageContent(estimatedReadingTime) + }.openThreeDotMenu { + verifyReaderViewAppearance(true) + }.closeBrowserMenuToBrowser { } + + navigationToolbar { + toggleReaderView() + mDevice.waitForIdle() + }.openThreeDotMenu { + verifyReaderViewAppearance(false) + }.close { } } - - readerViewNotification = ViewVisibilityIdlingResource( - activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), - View.VISIBLE - ) - - IdlingRegistry.getInstance().register(readerViewNotification) - - navigationToolbar { - verifyReaderViewDetected(true) - toggleReaderView() - mDevice.waitForIdle() - } - - browserScreen { - verifyPageContent(estimatedReadingTime) - }.openThreeDotMenu { - verifyReaderViewAppearance(true) - }.closeBrowserMenuToBrowser { } - - navigationToolbar { - toggleReaderView() - mDevice.waitForIdle() - }.openThreeDotMenu { - verifyReaderViewAppearance(false) - }.close { } } @Test diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt index 79057f88c..9bd09b80b 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SettingsAddonsTest.kt @@ -79,19 +79,23 @@ class SettingsAddonsTest { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) val addonName = "uBlock Origin" - navigationToolbar { - }.openNewTabAndEnterToBrowser(defaultWebPage.url) { - }.openThreeDotMenu { - }.openAddonsManagerMenu { - addonsListIdlingResource = - RecyclerViewIdlingResource(activityTestRule.activity.findViewById(R.id.add_ons_list), 1) - IdlingRegistry.getInstance().register(addonsListIdlingResource!!) - clickInstallAddon(addonName) - verifyAddonPrompt(addonName) - cancelInstallAddon() - clickInstallAddon(addonName) - acceptInstallAddon() - verifyDownloadAddonPrompt(addonName, activityTestRule) + navigationToolbar {} + .openNewTabAndEnterToBrowser(defaultWebPage.url) {} + .openThreeDotMenu {} + .openAddonsManagerMenu { + addonsListIdlingResource = + RecyclerViewIdlingResource( + activityTestRule.activity.findViewById(R.id.add_ons_list), + 1 + ) + IdlingRegistry.getInstance().register(addonsListIdlingResource!!) + clickInstallAddon(addonName) + verifyAddonPrompt(addonName) + cancelInstallAddon() + clickInstallAddon(addonName) + acceptInstallAddon() + + verifyDownloadAddonPrompt(addonName, activityTestRule) } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index a97a7d4c4..18584a0b6 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -14,6 +14,7 @@ import androidx.test.uiautomator.UiDevice import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.R @@ -198,6 +199,7 @@ class SmokeTest { @Test // Verifies the list of items in a tab's 3 dot menu + @Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17870") fun verifyPageMainMenuItemsTest() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -231,6 +233,7 @@ class SmokeTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17798") // Verifies the Synced tabs menu opens from a tab's 3 dot menu fun openMainMenuSyncedTabsItemTest() { homeScreen { @@ -362,6 +365,7 @@ class SmokeTest { @Test // Turns ETP toggle off from Settings and verifies the ETP shield is not displayed in the nav bar + @Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17870") fun verifyETPShieldNotDisplayedIfOFFGlobally() { val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) @@ -537,6 +541,7 @@ class SmokeTest { @Test // Saves a login, then changes it and verifies the update + @Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17870") fun updateSavedLoginTest() { val saveLoginTest = TestAssetHelper.getSaveLoginAsset(mockWebServer) @@ -600,6 +605,7 @@ class SmokeTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17799") // Installs uBlock add-on and checks that the app doesn't crash while loading pages with trackers fun noCrashWithAddonInstalledTest() { // setting ETP to Strict mode to test it works with add-ons @@ -1107,6 +1113,7 @@ class SmokeTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17799") fun mainMenuInstallPWATest() { val pwaPage = "https://rpappalax.github.io/testapp/" @@ -1123,6 +1130,7 @@ class SmokeTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17971") // Verifies that reader mode is detected and the custom appearance controls are displayed fun verifyReaderViewAppearanceUI() { val readerViewPage = diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt index 2107f9d10..c3583b70d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/StrictEnhancedTrackingProtectionTest.kt @@ -8,6 +8,7 @@ import androidx.test.platform.app.InstrumentationRegistry import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.mozilla.fenix.ext.settings @@ -126,6 +127,7 @@ class StrictEnhancedTrackingProtectionTest { } @Test + @Ignore("To be re-implemented with the three dot menu changes https://github.com/mozilla-mobile/fenix/issues/17870") fun testStrictVisitDisable() { val trackingProtectionTest = TestAssetHelper.getEnhancedTrackingProtectionAsset(mockWebServer) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt index 088136fcd..86645af12 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt @@ -12,6 +12,7 @@ import org.junit.Before import org.junit.BeforeClass import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.ui.robots.homeScreen @@ -54,42 +55,68 @@ class ThreeDotMenuMainTest { @Test fun threeDotMenuItemsTest() { - homeScreen { - }.openThreeDotMenu { - verifySettingsButton() - verifyBookmarksButton() - verifyHistoryButton() - verifyHelpButton() - verifyWhatsNewButton() - }.openSettings { - verifySettingsView() - }.goBack { - }.openThreeDotMenu { - }.openHelp { - verifyHelpUrl() - }.openTabDrawer { - closeTab() - } + if (FeatureFlags.toolbarMenuFeature) { + homeScreen { + }.openThreeDotMenu { + }.openHistory { + verifyHistoryMenuView() + }.goBackToBrowser {} - homeScreen { - }.openThreeDotMenu { - }.openWhatsNew { - verifyWhatsNewURL() - }.openTabDrawer { - closeTab() - } + homeScreen { + }.openThreeDotMenu { + }.openBookmarks { + verifyBookmarksMenuView() + }.closeMenu {} - homeScreen { - }.openThreeDotMenu { - }.openBookmarks { - verifyBookmarksMenuView() - }.closeMenu { - } + homeScreen { + }.openThreeDotMenu { + verifySettingsButton() + verifyBookmarksButton() + verifyHistoryButton() + }.openSettings { + verifySettingsView() + }.goBack { + }.openThreeDotMenu { + }.goBack {} + } else { + homeScreen { + }.openThreeDotMenu { + verifySettingsButton() + verifyBookmarksButton() + verifyHistoryButton() + verifyHelpButton() + verifyWhatsNewButton() + }.openSettings { + verifySettingsView() + }.goBack { + }.openThreeDotMenu { + }.openHelp { + verifyHelpUrl() + }.openTabDrawer { + closeTab() + } - homeScreen { - }.openThreeDotMenu { - }.openHistory { - verifyHistoryMenuView() + homeScreen { + }.openThreeDotMenu { + }.openWhatsNew { + verifyWhatsNewURL() + }.openTabDrawer { + closeTab() + } + + homeScreen { + }.openThreeDotMenu { + }.openBookmarks { + verifyBookmarksMenuView() + }.closeMenu { + } + + homeScreen { + }.openThreeDotMenu { + }.openHistory { + verifyHistoryMenuView() + } } + } } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index da61cb380..cc2304f33 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -38,6 +38,7 @@ import androidx.test.uiautomator.Until import org.hamcrest.Matcher import org.hamcrest.Matchers.allOf import org.junit.Assert.assertTrue +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.click @@ -124,21 +125,33 @@ class ThreeDotMenuMainRobot { fun verifyShareTabsOverlay() = assertShareTabsOverlay() fun verifyThreeDotMainMenuItems() { - verifyAddOnsButton() - verifyDownloadsButton() - verifyHistoryButton() - verifyBookmarksButton() - verifySyncedTabsButton() - verifySettingsButton() - verifyFindInPageButton() - verifyAddFirefoxHome() - verifyAddToMobileHome() - verifyDesktopSite() - verifySaveCollection() - verifyAddBookmarkButton() - verifyShareButton() - verifyForwardButton() - verifyRefreshButton() + if (FeatureFlags.toolbarMenuFeature) { + verifyDownloadsButton() + verifyHistoryButton() + verifyBookmarksButton() + verifySettingsButton() + verifyDesktopSite() + verifySaveCollection() + verifyShareButton() + verifyForwardButton() + verifyRefreshButton() + } else { + verifyAddOnsButton() + verifyDownloadsButton() + verifyHistoryButton() + verifyBookmarksButton() + verifySyncedTabsButton() + verifySettingsButton() + verifyFindInPageButton() + verifyAddFirefoxHome() + verifyAddToMobileHome() + verifyDesktopSite() + verifySaveCollection() + verifyAddBookmarkButton() + verifyShareButton() + verifyForwardButton() + verifyRefreshButton() + } } private fun assertShareTabsOverlay() { @@ -390,7 +403,8 @@ private fun assertSettingsButton() = settingsButton() .check(matches(withEffectiveVisibility(Visibility.VISIBLE))) .check(matches(isCompletelyDisplayed())) -private fun addOnsButton() = onView(allOf(withText("Add-ons"))) +private val addOnsText = if (FeatureFlags.toolbarMenuFeature) "Extensions" else "Add-ons" +private fun addOnsButton() = onView(allOf(withText(addOnsText))) private fun assertAddOnsButton() { onView(withId(R.id.mozac_browser_menu_menuView)).perform(swipeDown()) addOnsButton().check(matches(withEffectiveVisibility(Visibility.VISIBLE))) diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 1092fff0e..fd8be54a2 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -30,4 +30,9 @@ object FeatureFlags { * Enables WebAuthn support. */ val webAuthFeature = Config.channel.isNightlyOrDebug + + /** + * Shows new three-dot toolbar menu design. + */ + val toolbarMenuFeature = Config.channel.isDebug } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt index fae8e867a..46dcdb1e6 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt @@ -51,7 +51,7 @@ interface BrowserToolbarMenuController { fun handleToolbarItemInteraction(item: ToolbarMenu.Item) } -@Suppress("LargeClass") +@Suppress("LargeClass", "ForbiddenComment") class DefaultBrowserToolbarMenuController( private val activity: HomeActivity, private val navController: NavController, @@ -87,6 +87,76 @@ class DefaultBrowserToolbarMenuController( trackToolbarItemInteraction(item) Do exhaustive when (item) { + // TODO: These can be removed for https://github.com/mozilla-mobile/fenix/issues/17870 + // todo === Start === + is ToolbarMenu.Item.InstallToHomeScreen -> { + settings.installPwaOpened = true + MainScope().launch { + with(activity.components.useCases.webAppUseCases) { + if (isInstallable()) { + addToHomescreen() + } else { + val directions = + BrowserFragmentDirections.actionBrowserFragmentToCreateShortcutFragment() + navController.navigateSafe(R.id.browserFragment, directions) + } + } + } + } + is ToolbarMenu.Item.OpenInFenix -> { + // Stop the SessionFeature from updating the EngineView and let it release the session + // from the EngineView so that it can immediately be rendered by a different view once + // we switch to the actual browser. + sessionFeature.get()?.release() + + // Strip the CustomTabConfig to turn this Session into a regular tab and then select it + customTabSession!!.customTabConfig = null + sessionManager.select(customTabSession) + + // Switch to the actual browser which should now display our new selected session + activity.startActivity(openInFenixIntent.apply { + // We never want to launch the browser in the same task as the external app + // activity. So we force a new task here. IntentReceiverActivity will do the + // right thing and take care of routing to an already existing browser and avoid + // cloning a new one. + flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK + }) + + // Close this activity (and the task) since it is no longer displaying any session + activity.finishAndRemoveTask() + } + is ToolbarMenu.Item.Quit -> { + // We need to show the snackbar while the browsing data is deleting (if "Delete + // browsing data on quit" is activated). After the deletion is over, the snackbar + // is dismissed. + val snackbar: FenixSnackbar? = activity.getRootView()?.let { v -> + FenixSnackbar.make( + view = v, + duration = Snackbar.LENGTH_LONG, + isDisplayedWithBrowserToolbar = true + ) + .setText(v.context.getString(R.string.deleting_browsing_data_in_progress)) + } + + deleteAndQuit(activity, scope, snackbar) + } + is ToolbarMenu.Item.ReaderModeAppearance -> { + readerModeController.showControls() + metrics.track(Event.ReaderModeAppearanceOpened) + } + is ToolbarMenu.Item.OpenInApp -> { + settings.openInAppOpened = true + + val appLinksUseCases = activity.components.useCases.appLinksUseCases + val getRedirect = appLinksUseCases.appLinkRedirect + currentSession?.let { + val redirect = getRedirect.invoke(it.url) + redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK + appLinksUseCases.openAppLink.invoke(redirect.appIntent) + } + } + // todo === End === + is ToolbarMenu.Item.Back -> { if (item.viewHistory) { navController.navigate( @@ -118,12 +188,24 @@ class DefaultBrowserToolbarMenuController( sessionUseCases.reload.invoke(currentSession, flags = flags) } - ToolbarMenu.Item.Stop -> sessionUseCases.stopLoading.invoke(currentSession) - ToolbarMenu.Item.Settings -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.Stop -> sessionUseCases.stopLoading.invoke(currentSession) + is ToolbarMenu.Item.Share -> { + val directions = NavGraphDirections.actionGlobalShareFragment( + data = arrayOf( + ShareData( + url = getProperUrl(currentSession), + title = currentSession?.title + ) + ), + showPage = true + ) + navController.navigate(directions) + } + is ToolbarMenu.Item.Settings -> browserAnimator.captureEngineViewAndDrawStatically { val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment() navController.nav(R.id.browserFragment, directions) } - ToolbarMenu.Item.SyncedTabs -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.SyncedTabs -> browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment() @@ -133,7 +215,7 @@ class DefaultBrowserToolbarMenuController( item.isChecked, currentSession ) - ToolbarMenu.Item.AddToTopSites -> { + is ToolbarMenu.Item.AddToTopSites -> { scope.launch { val context = swipeRefresh.context val numPinnedSites = @@ -169,7 +251,7 @@ class DefaultBrowserToolbarMenuController( } } } - ToolbarMenu.Item.AddToHomeScreen, ToolbarMenu.Item.InstallToHomeScreen -> { + is ToolbarMenu.Item.AddToHomeScreen -> { settings.installPwaOpened = true MainScope().launch { with(activity.components.useCases.webAppUseCases) { @@ -183,31 +265,17 @@ class DefaultBrowserToolbarMenuController( } } } - ToolbarMenu.Item.Share -> { - val directions = NavGraphDirections.actionGlobalShareFragment( - data = arrayOf( - ShareData( - url = getProperUrl(currentSession), - title = currentSession?.title - ) - ), - showPage = true - ) - navController.navigate(directions) - } - - ToolbarMenu.Item.FindInPage -> { + is ToolbarMenu.Item.FindInPage -> { findInPageLauncher() metrics.track(Event.FindInPageOpened) } - - ToolbarMenu.Item.AddonsManager -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.AddonsManager -> browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, BrowserFragmentDirections.actionGlobalAddonsManagementFragment() ) } - ToolbarMenu.Item.SaveToCollection -> { + is ToolbarMenu.Item.SaveToCollection -> { metrics .track(Event.CollectionSaveButtonPressed(TELEMETRY_BROWSER_IDENTIFIER)) @@ -225,82 +293,35 @@ class DefaultBrowserToolbarMenuController( navController.nav(R.id.browserFragment, directions) } } - ToolbarMenu.Item.OpenInFenix -> { - // Stop the SessionFeature from updating the EngineView and let it release the session - // from the EngineView so that it can immediately be rendered by a different view once - // we switch to the actual browser. - sessionFeature.get()?.release() - - // Strip the CustomTabConfig to turn this Session into a regular tab and then select it - customTabSession!!.customTabConfig = null - sessionManager.select(customTabSession) - - // Switch to the actual browser which should now display our new selected session - activity.startActivity(openInFenixIntent.apply { - // We never want to launch the browser in the same task as the external app - // activity. So we force a new task here. IntentReceiverActivity will do the - // right thing and take care of routing to an already existing browser and avoid - // cloning a new one. - flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK - }) - - // Close this activity (and the task) since it is no longer displaying any session - activity.finishAndRemoveTask() - } - ToolbarMenu.Item.Quit -> { - // We need to show the snackbar while the browsing data is deleting (if "Delete - // browsing data on quit" is activated). After the deletion is over, the snackbar - // is dismissed. - val snackbar: FenixSnackbar? = activity.getRootView()?.let { v -> - FenixSnackbar.make( - view = v, - duration = Snackbar.LENGTH_LONG, - isDisplayedWithBrowserToolbar = true - ) - .setText(v.context.getString(R.string.deleting_browsing_data_in_progress)) - } - - deleteAndQuit(activity, scope, snackbar) - } - ToolbarMenu.Item.ReaderModeAppearance -> { - readerModeController.showControls() - metrics.track(Event.ReaderModeAppearanceOpened) - } - ToolbarMenu.Item.OpenInApp -> { - settings.openInAppOpened = true - - val appLinksUseCases = activity.components.useCases.appLinksUseCases - val getRedirect = appLinksUseCases.appLinkRedirect - currentSession?.let { - val redirect = getRedirect.invoke(it.url) - redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK - appLinksUseCases.openAppLink.invoke(redirect.appIntent) - } - } - ToolbarMenu.Item.Bookmark -> { + is ToolbarMenu.Item.Bookmark -> { sessionManager.selectedSession?.let { getProperUrl(it)?.let { url -> bookmarkTapped(url, it.title) } } } - ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id) ) } - ToolbarMenu.Item.History -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.History -> browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, BrowserFragmentDirections.actionGlobalHistoryFragment() ) } - ToolbarMenu.Item.Downloads -> browserAnimator.captureEngineViewAndDrawStatically { + is ToolbarMenu.Item.Downloads -> browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, BrowserFragmentDirections.actionGlobalDownloadsFragment() ) } + is ToolbarMenu.Item.NewTab -> { + navController.navigate( + BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true) + ) + } } } @@ -318,35 +339,38 @@ class DefaultBrowserToolbarMenuController( @Suppress("ComplexMethod") private fun trackToolbarItemInteraction(item: ToolbarMenu.Item) { val eventItem = when (item) { + // TODO: These can be removed for https://github.com/mozilla-mobile/fenix/issues/17870 + // todo === Start === + is ToolbarMenu.Item.OpenInFenix -> Event.BrowserMenuItemTapped.Item.OPEN_IN_FENIX + is ToolbarMenu.Item.InstallToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN + is ToolbarMenu.Item.Quit -> Event.BrowserMenuItemTapped.Item.QUIT + is ToolbarMenu.Item.ReaderModeAppearance -> + Event.BrowserMenuItemTapped.Item.READER_MODE_APPEARANCE + is ToolbarMenu.Item.OpenInApp -> Event.BrowserMenuItemTapped.Item.OPEN_IN_APP + // todo === End === is ToolbarMenu.Item.Back -> Event.BrowserMenuItemTapped.Item.BACK is ToolbarMenu.Item.Forward -> Event.BrowserMenuItemTapped.Item.FORWARD is ToolbarMenu.Item.Reload -> Event.BrowserMenuItemTapped.Item.RELOAD - ToolbarMenu.Item.Stop -> Event.BrowserMenuItemTapped.Item.STOP - ToolbarMenu.Item.Settings -> Event.BrowserMenuItemTapped.Item.SETTINGS + is ToolbarMenu.Item.Stop -> Event.BrowserMenuItemTapped.Item.STOP + is ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE + is ToolbarMenu.Item.Settings -> Event.BrowserMenuItemTapped.Item.SETTINGS is ToolbarMenu.Item.RequestDesktop -> if (item.isChecked) { Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON } else { Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_OFF } - - ToolbarMenu.Item.FindInPage -> Event.BrowserMenuItemTapped.Item.FIND_IN_PAGE - ToolbarMenu.Item.OpenInFenix -> Event.BrowserMenuItemTapped.Item.OPEN_IN_FENIX - ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE - ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION - ToolbarMenu.Item.AddToTopSites -> Event.BrowserMenuItemTapped.Item.ADD_TO_TOP_SITES - ToolbarMenu.Item.AddToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN - ToolbarMenu.Item.SyncedTabs -> Event.BrowserMenuItemTapped.Item.SYNC_TABS - ToolbarMenu.Item.InstallToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN - ToolbarMenu.Item.Quit -> Event.BrowserMenuItemTapped.Item.QUIT - ToolbarMenu.Item.ReaderModeAppearance -> - Event.BrowserMenuItemTapped.Item.READER_MODE_APPEARANCE - ToolbarMenu.Item.OpenInApp -> Event.BrowserMenuItemTapped.Item.OPEN_IN_APP - ToolbarMenu.Item.Bookmark -> Event.BrowserMenuItemTapped.Item.BOOKMARK - ToolbarMenu.Item.AddonsManager -> Event.BrowserMenuItemTapped.Item.ADDONS_MANAGER - ToolbarMenu.Item.Bookmarks -> Event.BrowserMenuItemTapped.Item.BOOKMARKS - ToolbarMenu.Item.History -> Event.BrowserMenuItemTapped.Item.HISTORY - ToolbarMenu.Item.Downloads -> Event.BrowserMenuItemTapped.Item.DOWNLOADS + is ToolbarMenu.Item.FindInPage -> Event.BrowserMenuItemTapped.Item.FIND_IN_PAGE + is ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION + is ToolbarMenu.Item.AddToTopSites -> Event.BrowserMenuItemTapped.Item.ADD_TO_TOP_SITES + is ToolbarMenu.Item.AddToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN + is ToolbarMenu.Item.SyncedTabs -> Event.BrowserMenuItemTapped.Item.SYNC_TABS + is ToolbarMenu.Item.Bookmark -> Event.BrowserMenuItemTapped.Item.BOOKMARK + is ToolbarMenu.Item.AddonsManager -> Event.BrowserMenuItemTapped.Item.ADDONS_MANAGER + is ToolbarMenu.Item.Bookmarks -> Event.BrowserMenuItemTapped.Item.BOOKMARKS + is ToolbarMenu.Item.History -> Event.BrowserMenuItemTapped.Item.HISTORY + is ToolbarMenu.Item.Downloads -> Event.BrowserMenuItemTapped.Item.DOWNLOADS + is ToolbarMenu.Item.NewTab -> Event.BrowserMenuItemTapped.Item.NEW_TAB } metrics.track(Event.BrowserMenuItemTapped(eventItem)) diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt index 0fc1a3544..ec34aa13b 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt @@ -32,6 +32,7 @@ import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature import mozilla.components.lib.state.ext.flowScoped import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode @@ -69,7 +70,12 @@ class DefaultToolbarMenu( override val menuBuilder by lazy { WebExtensionBrowserMenuBuilder( - menuItems, + items = + if (FeatureFlags.toolbarMenuFeature) { + newCoreMenuItems + } else { + oldCoreMenuItems + }, endOfMenuAlwaysVisible = !shouldReverseItems, store = store, webExtIconTintColorResource = primaryTextColor(), @@ -179,7 +185,148 @@ class DefaultToolbarMenu( } ?: false // End of predicates // - private val menuItems by lazy { + private val oldCoreMenuItems by lazy { + val settings = BrowserMenuHighlightableItem( + label = context.getString(R.string.browser_menu_settings), + startImageResource = R.drawable.ic_settings, + iconTintColorResource = if (hasAccountProblem) + ThemeManager.resolveAttribute(R.attr.syncDisconnected, context) else + primaryTextColor(), + textColorResource = if (hasAccountProblem) + ThemeManager.resolveAttribute(R.attr.primaryText, context) else + primaryTextColor(), + highlight = BrowserMenuHighlight.HighPriority( + endImageResource = R.drawable.ic_sync_disconnected, + backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground), + canPropagate = false + ), + isHighlighted = { hasAccountProblem } + ) { + onItemTapped.invoke(ToolbarMenu.Item.Settings) + } + + val desktopMode = BrowserMenuImageSwitch( + imageResource = R.drawable.ic_desktop, + label = context.getString(R.string.browser_menu_desktop_site), + initialState = { + selectedSession?.content?.desktopMode ?: false + } + ) { checked -> + onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) + } + + val addToTopSites = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_add_to_top_sites), + imageResource = R.drawable.ic_top_sites, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.AddToTopSites) + } + + val addToHomescreen = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_add_to_homescreen), + imageResource = R.drawable.ic_add_to_homescreen, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen) + } + + val syncedTabs = BrowserMenuImageText( + label = context.getString(R.string.synced_tabs), + imageResource = R.drawable.ic_synced_tabs, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs) + } + + val installToHomescreen = BrowserMenuHighlightableItem( + label = context.getString(R.string.browser_menu_install_on_homescreen), + startImageResource = R.drawable.ic_add_to_homescreen, + iconTintColorResource = primaryTextColor(), + highlight = BrowserMenuHighlight.LowPriority( + label = context.getString(R.string.browser_menu_install_on_homescreen), + notificationTint = getColor(context, R.color.whats_new_notification_color) + ), + isHighlighted = { + !context.settings().installPwaOpened + } + ) { + onItemTapped.invoke(ToolbarMenu.Item.InstallToHomeScreen) + } + + val findInPage = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_find_in_page), + imageResource = R.drawable.mozac_ic_search, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.FindInPage) + } + + val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem( + id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID + ) + + val saveToCollection = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_save_to_collection_2), + imageResource = R.drawable.ic_tab_collection, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.SaveToCollection) + } + + val deleteDataOnQuit = BrowserMenuImageText( + label = context.getString(R.string.delete_browsing_data_on_quit_action), + imageResource = R.drawable.ic_exit, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.Quit) + } + + val readerAppearance = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_read_appearance), + imageResource = R.drawable.ic_readermode_appearance, + iconTintColorResource = primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.ReaderModeAppearance) + } + + val openInApp = BrowserMenuHighlightableItem( + label = context.getString(R.string.browser_menu_open_app_link), + startImageResource = R.drawable.ic_open_in_app, + iconTintColorResource = primaryTextColor(), + highlight = BrowserMenuHighlight.LowPriority( + label = context.getString(R.string.browser_menu_open_app_link), + notificationTint = getColor(context, R.color.whats_new_notification_color) + ), + isHighlighted = { !context.settings().openInAppOpened } + ) { + onItemTapped.invoke(ToolbarMenu.Item.OpenInApp) + } + + val historyItem = BrowserMenuImageText( + context.getString(R.string.library_history), + R.drawable.ic_history, + primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.History) + } + + val bookmarksItem = BrowserMenuImageText( + context.getString(R.string.library_bookmarks), + R.drawable.ic_bookmark_filled, + primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.Bookmarks) + } + + val downloadsItem = BrowserMenuImageText( + context.getString(R.string.library_downloads), + R.drawable.ic_download, + primaryTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.Downloads) + } + // Predicates that are called once, during screen init val shouldShowSaveToCollection = (context.asActivity() as? HomeActivity) ?.browsingModeManager?.mode == BrowsingMode.Normal @@ -216,151 +363,149 @@ class DefaultToolbarMenu( } } - private val settings = BrowserMenuHighlightableItem( - label = context.getString(R.string.browser_menu_settings), - startImageResource = R.drawable.ic_settings, - iconTintColorResource = if (hasAccountProblem) - ThemeManager.resolveAttribute(R.attr.syncDisconnected, context) else - primaryTextColor(), - textColorResource = if (hasAccountProblem) - ThemeManager.resolveAttribute(R.attr.primaryText, context) else - primaryTextColor(), - highlight = BrowserMenuHighlight.HighPriority( - endImageResource = R.drawable.ic_sync_disconnected, - backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground), - canPropagate = false - ), - isHighlighted = { hasAccountProblem } - ) { - onItemTapped.invoke(ToolbarMenu.Item.Settings) - } + private val newCoreMenuItems by lazy { + val newTabItem = BrowserMenuImageText( + context.getString(R.string.library_new_tab), + R.drawable.ic_bookmark_filled, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.NewTab) + } - private val desktopMode = BrowserMenuImageSwitch( - imageResource = R.drawable.ic_desktop, - label = context.getString(R.string.browser_menu_desktop_site), - initialState = { - selectedSession?.content?.desktopMode ?: false + val bookmarksItem = BrowserMenuImageText( + context.getString(R.string.library_bookmarks), + R.drawable.ic_bookmark_filled, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.Bookmarks) } - ) { checked -> - onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) - } - private val addToTopSites = BrowserMenuImageText( - label = context.getString(R.string.browser_menu_add_to_top_sites), - imageResource = R.drawable.ic_top_sites, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.AddToTopSites) - } + val historyItem = BrowserMenuImageText( + context.getString(R.string.library_history), + R.drawable.ic_history, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.History) + } - private val addToHomescreen = BrowserMenuImageText( - label = context.getString(R.string.browser_menu_add_to_homescreen), - imageResource = R.drawable.ic_add_to_homescreen, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen) - } + val downloadsItem = BrowserMenuImageText( + context.getString(R.string.library_downloads), + R.drawable.ic_download, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.Downloads) + } - private val syncedTabs = BrowserMenuImageText( - label = context.getString(R.string.synced_tabs), - imageResource = R.drawable.ic_synced_tabs, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs) - } + val extensionsItem = BrowserMenuImageText( + context.getString(R.string.browser_menu_extensions), + R.drawable.ic_addons_extensions, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.AddonsManager) + } - private val installToHomescreen = BrowserMenuHighlightableItem( - label = context.getString(R.string.browser_menu_install_on_homescreen), - startImageResource = R.drawable.ic_add_to_homescreen, - iconTintColorResource = primaryTextColor(), - highlight = BrowserMenuHighlight.LowPriority( - label = context.getString(R.string.browser_menu_install_on_homescreen), - notificationTint = getColor(context, R.color.whats_new_notification_color) - ), - isHighlighted = { - !context.settings().installPwaOpened + val syncedTabsItem = BrowserMenuImageText( + context.getString(R.string.library_synced_tabs), + R.drawable.ic_synced_tabs, + disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.SyncedTabs) } - ) { - onItemTapped.invoke(ToolbarMenu.Item.InstallToHomeScreen) - } - private val findInPage = BrowserMenuImageText( - label = context.getString(R.string.browser_menu_find_in_page), - imageResource = R.drawable.mozac_ic_search, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.FindInPage) - } + val findInPageItem = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_find_in_page), + imageResource = R.drawable.mozac_ic_search, + iconTintColorResource = disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.FindInPage) + } - private val reportSiteIssuePlaceholder = WebExtensionPlaceholderMenuItem( - id = WebCompatReporterFeature.WEBCOMPAT_REPORTER_EXTENSION_ID - ) + val desktopSiteItem = BrowserMenuImageSwitch( + imageResource = R.drawable.ic_desktop, + label = context.getString(R.string.browser_menu_desktop_site), + initialState = { + selectedSession?.content?.desktopMode ?: false + } + ) { checked -> + onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) + } - private val saveToCollection = BrowserMenuImageText( - label = context.getString(R.string.browser_menu_save_to_collection_2), - imageResource = R.drawable.ic_tab_collection, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.SaveToCollection) - } + val addToHomeScreenItem = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_add_to_homescreen), + imageResource = R.drawable.ic_add_to_homescreen, + iconTintColorResource = disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.AddToHomeScreen) + } - private val deleteDataOnQuit = BrowserMenuImageText( - label = context.getString(R.string.delete_browsing_data_on_quit_action), - imageResource = R.drawable.ic_exit, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.Quit) - } + val addToTopSitesItem = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_add_to_top_sites), + imageResource = R.drawable.ic_top_sites, + iconTintColorResource = disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.AddToTopSites) + } - private val readerAppearance = BrowserMenuImageText( - label = context.getString(R.string.browser_menu_read_appearance), - imageResource = R.drawable.ic_readermode_appearance, - iconTintColorResource = primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.ReaderModeAppearance) - } + val saveToCollectionItem = BrowserMenuImageText( + label = context.getString(R.string.browser_menu_save_to_collection_2), + imageResource = R.drawable.ic_tab_collection, + iconTintColorResource = disabledTextColor() + ) { + onItemTapped.invoke(ToolbarMenu.Item.SaveToCollection) + } - private val openInApp = BrowserMenuHighlightableItem( - label = context.getString(R.string.browser_menu_open_app_link), - startImageResource = R.drawable.ic_open_in_app, - iconTintColorResource = primaryTextColor(), - highlight = BrowserMenuHighlight.LowPriority( - label = context.getString(R.string.browser_menu_open_app_link), - notificationTint = getColor(context, R.color.whats_new_notification_color) - ), - isHighlighted = { !context.settings().openInAppOpened } - ) { - onItemTapped.invoke(ToolbarMenu.Item.OpenInApp) - } + val settingsItem = BrowserMenuHighlightableItem( + label = context.getString(R.string.browser_menu_settings), + startImageResource = R.drawable.ic_settings, + iconTintColorResource = disabledTextColor(), + textColorResource = if (hasAccountProblem) + ThemeManager.resolveAttribute(R.attr.primaryText, context) else + primaryTextColor(), + highlight = BrowserMenuHighlight.HighPriority( + endImageResource = R.drawable.ic_sync_disconnected, + backgroundTint = context.getColorFromAttr(R.attr.syncDisconnectedBackground), + canPropagate = false + ), + isHighlighted = { hasAccountProblem } + ) { + onItemTapped.invoke(ToolbarMenu.Item.Settings) + } - val historyItem = BrowserMenuImageText( - context.getString(R.string.library_history), - R.drawable.ic_history, - primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.History) - } + val syncedTabsInTabsTray = context.components.settings + .syncedTabsInTabsTray - val bookmarksItem = BrowserMenuImageText( - context.getString(R.string.library_bookmarks), - R.drawable.ic_bookmark_filled, - primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.Bookmarks) - } + val menuItems = listOfNotNull( + newTabItem, + BrowserMenuDivider(), + bookmarksItem, + historyItem, + downloadsItem, + extensionsItem, + if (syncedTabsInTabsTray) null else syncedTabsItem, + BrowserMenuDivider(), + findInPageItem, + desktopSiteItem, + BrowserMenuDivider(), + addToHomeScreenItem.apply { visible = ::canAddToHomescreen }, + addToTopSitesItem, + saveToCollectionItem, + BrowserMenuDivider(), + settingsItem, + BrowserMenuDivider(), + menuToolbar + ) - val downloadsItem = BrowserMenuImageText( - context.getString(R.string.library_downloads), - R.drawable.ic_download, - primaryTextColor() - ) { - onItemTapped.invoke(ToolbarMenu.Item.Downloads) + menuItems } @ColorRes @VisibleForTesting internal fun primaryTextColor() = ThemeManager.resolveAttribute(R.attr.primaryText, context) + @ColorRes + @VisibleForTesting + internal fun disabledTextColor() = R.color.toolbar_menu_transparent + @VisibleForTesting internal fun registerForIsBookmarkedUpdates() { store.flowScoped(lifecycleOwner) { flow -> diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt index 27b47c309..87cb80ae3 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt @@ -31,6 +31,7 @@ interface ToolbarMenu { object Bookmarks : Item() object History : Item() object Downloads : Item() + object NewTab : Item() } val menuBuilder: BrowserMenuBuilder diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 5f2d1b1a9..f8d09ea35 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -422,4 +422,7 @@ #1415141A + + + @android:color/transparent diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 515b2d760..e6c09d865 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -128,6 +128,8 @@ Edit bookmark Add-ons + + Extensions No add-ons here @@ -517,6 +519,10 @@ Other Bookmarks History + + New tab + + Find in page Synced tabs diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt index 4082077ae..211cf0fc9 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt @@ -45,6 +45,7 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavGraphDirections import org.mozilla.fenix.R @@ -64,6 +65,7 @@ import org.mozilla.fenix.utils.Settings @OptIn(ExperimentalCoroutinesApi::class) @RunWith(FenixRobolectricTestRunner::class) +@Suppress("ForbiddenComment") class DefaultBrowserToolbarMenuControllerTest { @get:Rule @@ -124,8 +126,121 @@ class DefaultBrowserToolbarMenuControllerTest { unmockkObject(FenixSnackbar.Companion) } + // TODO: These can be removed for https://github.com/mozilla-mobile/fenix/issues/17870 + // todo === Start === @Test - fun handleToolbarBackPress() = runBlockingTest { + fun handleToolbarBookmarkPressWithReaderModeInactive() = runBlockingTest { + if (!FeatureFlags.toolbarMenuFeature) { + val item = ToolbarMenu.Item.Bookmark + + val title = "Mozilla" + val readerUrl = "moz-extension://1234" + val readerTab = createTab( + url = readerUrl, + readerState = ReaderState(active = false, activeUrl = "https://1234.org"), + title = title + ) + browserStore = + BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) + every { currentSession.id } returns readerTab.id + every { currentSession.title } returns title + every { currentSession.url } returns "https://mozilla.org" + + val controller = createController(scope = this) + controller.handleToolbarItemInteraction(item) + + verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } + verify { bookmarkTapped("https://mozilla.org", title) } + } + } + + @Test + fun `IF reader mode is active WHEN bookmark menu item is pressed THEN menu item is handled`() = runBlockingTest { + if (!FeatureFlags.toolbarMenuFeature) { + val item = ToolbarMenu.Item.Bookmark + val title = "Mozilla" + val readerUrl = "moz-extension://1234" + val readerTab = createTab( + url = readerUrl, + readerState = ReaderState(active = true, activeUrl = "https://mozilla.org"), + title = title + ) + browserStore = + BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) + every { currentSession.id } returns readerTab.id + every { currentSession.title } returns title + every { currentSession.url } returns readerUrl + + val controller = createController(scope = this) + controller.handleToolbarItemInteraction(item) + + verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } + verify { bookmarkTapped("https://mozilla.org", title) } + } + } + + @Test + fun `WHEN open in Fenix menu item is pressed THEN menu item is handled correctly`() = runBlockingTest { + if (!FeatureFlags.toolbarMenuFeature) { + val controller = createController(scope = this, customTabSession = currentSession) + + val item = ToolbarMenu.Item.OpenInFenix + + every { currentSession.customTabConfig } returns mockk() + every { activity.startActivity(any()) } just Runs + + controller.handleToolbarItemInteraction(item) + + verify { sessionFeature.release() } + verify { currentSession.customTabConfig = null } + verify { sessionManager.select(currentSession) } + verify { activity.startActivity(openInFenixIntent) } + verify { activity.finishAndRemoveTask() } + } + } + + @Test + fun `WHEN quit menu item is pressed THEN menu item is handled correctly`() = runBlockingTest { + if (!FeatureFlags.toolbarMenuFeature) { + val item = ToolbarMenu.Item.Quit + val testScope = this + + val controller = createController(scope = testScope) + + controller.handleToolbarItemInteraction(item) + + verify { deleteAndQuit(activity, testScope, null) } + } + } + + @Test + fun handleToolbarOpenInAppPress() = runBlockingTest { + if (!FeatureFlags.toolbarMenuFeature) { + val item = ToolbarMenu.Item.OpenInApp + + val controller = createController(scope = this) + + controller.handleToolbarItemInteraction(item) + + verify { settings.openInAppOpened = true } + } + } + + @Test + fun `WHEN reader mode menu item is pressed THEN handle appearance change`() = runBlockingTest { + val item = ToolbarMenu.Item.ReaderModeAppearance + + val controller = createController(scope = this) + + controller.handleToolbarItemInteraction(item) + + verify { readerModeController.showControls() } + verify { metrics.track(Event.ReaderModeAppearanceOpened) } + } + // todo === End === + + @Test + fun `WHEN backwards nav menu item is pressed THEN the session navigates back with active session`() = runBlockingTest { val item = ToolbarMenu.Item.Back(false) val controller = createController(scope = this) @@ -136,7 +251,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarBackLongPress() = runBlockingTest { + fun `WHEN backwards nav menu item is long pressed THEN the session navigates back with no active session`() = runBlockingTest { val item = ToolbarMenu.Item.Back(true) val controller = createController(scope = this) @@ -149,7 +264,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarForwardPress() = runBlockingTest { + fun `WHEN forward nav menu item is pressed THEN the session navigates forward to active session`() = runBlockingTest { val item = ToolbarMenu.Item.Forward(false) val controller = createController(scope = this) @@ -160,7 +275,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarForwardLongPress() = runBlockingTest { + fun `WHEN forward nav menu item is long pressed THEN the browser navigates forward with no active session`() = runBlockingTest { val item = ToolbarMenu.Item.Forward(true) val controller = createController(scope = this) @@ -173,7 +288,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarReloadPress() = runBlockingTest { + fun `WHEN reload nav menu item is pressed THEN the session reloads from cache`() = runBlockingTest { val item = ToolbarMenu.Item.Reload(false) val controller = createController(scope = this) @@ -184,7 +299,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarReloadLongPress() = runBlockingTest { + fun `WHEN reload nav menu item is long pressed THEN the session reloads with no cache`() = runBlockingTest { val item = ToolbarMenu.Item.Reload(true) val controller = createController(scope = this) @@ -200,7 +315,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarStopPress() = runBlockingTest { + fun `WHEN stop nav menu item is pressed THEN the session stops loading`() = runBlockingTest { val item = ToolbarMenu.Item.Stop val controller = createController(scope = this) @@ -211,7 +326,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarSettingsPress() = runBlockingTest { + fun `WHEN settings menu item is pressed THEN menu item is handled`() = runBlockingTest { val item = ToolbarMenu.Item.Settings val controller = createController(scope = this) @@ -224,52 +339,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarBookmarkPressWithReaderModeInactive() = runBlockingTest { - val item = ToolbarMenu.Item.Bookmark - val title = "Mozilla" - val readerUrl = "moz-extension://1234" - val readerTab = createTab( - url = readerUrl, - readerState = ReaderState(active = false, activeUrl = "https://1234.org"), - title = title - ) - browserStore = - BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns "https://mozilla.org" - - val controller = createController(scope = this) - controller.handleToolbarItemInteraction(item) - - verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } - verify { bookmarkTapped("https://mozilla.org", title) } - } - - @Test - fun handleToolbarBookmarkPressWithReaderModeActive() = runBlockingTest { - val item = ToolbarMenu.Item.Bookmark - val title = "Mozilla" - val readerUrl = "moz-extension://1234" - val readerTab = createTab( - url = readerUrl, - readerState = ReaderState(active = true, activeUrl = "https://mozilla.org"), - title = title - ) - browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns readerUrl - - val controller = createController(scope = this) - controller.handleToolbarItemInteraction(item) - - verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } - verify { bookmarkTapped("https://mozilla.org", title) } - } - - @Test - fun handleToolbarBookmarksPress() = runBlockingTest { + fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest { val item = ToolbarMenu.Item.Bookmarks val controller = createController(scope = this) @@ -282,7 +352,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarHistoryPress() = runBlockingTest { + fun `WHEN history menu item is pressed THEN navigate to history page`() = runBlockingTest { val item = ToolbarMenu.Item.History val controller = createController(scope = this) @@ -295,7 +365,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarRequestDesktopOnPress() = runBlockingTest { + fun `WHEN request desktop menu item is toggled On THEN desktop site is requested for the session`() = runBlockingTest { val requestDesktopSiteUseCase: SessionUseCases.RequestDesktopSiteUseCase = mockk(relaxed = true) val item = ToolbarMenu.Item.RequestDesktop(true) @@ -315,7 +385,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarRequestDesktopOffPress() = runBlockingTest { + fun `WHEN request desktop menu item is toggled Off THEN mobile site is requested for the session`() = runBlockingTest { val requestDesktopSiteUseCase: SessionUseCases.RequestDesktopSiteUseCase = mockk(relaxed = true) val item = ToolbarMenu.Item.RequestDesktop(false) @@ -335,7 +405,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarAddToTopSitesPressed() = runBlockingTest { + fun `WHEN Add To Top Sites menu item is pressed THEN add site AND show snackbar`() = runBlockingTest { val item = ToolbarMenu.Item.AddToTopSites val addPinnedSiteUseCase: TopSitesUseCases.AddPinnedSiteUseCase = mockk(relaxed = true) @@ -353,7 +423,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarAddonsManagerPress() = runBlockingTest { + fun `WHEN addon extensions menu item is pressed THEN navigate to addons manager`() = runBlockingTest { val item = ToolbarMenu.Item.AddonsManager val controller = createController(scope = this) @@ -363,7 +433,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarAddToHomeScreenPress() = runBlockingTest { + fun `WHEN Add To Home Screen menu item is pressed THEN add site`() = runBlockingTest { val item = ToolbarMenu.Item.AddToHomeScreen val controller = createController(scope = this) @@ -373,7 +443,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarSharePressWithReaderModeInactive() = runBlockingTest { + fun `IF reader mode is inactive WHEN share menu item is pressed THEN navigate to share screen`() = runBlockingTest { val item = ToolbarMenu.Item.Share val title = "Mozilla" val readerUrl = "moz-extension://1234" @@ -404,7 +474,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarSharePressWithReaderModeActive() = runBlockingTest { + fun `IF reader mode is active WHEN share menu item is pressed THEN navigate to share screen`() = runBlockingTest { val item = ToolbarMenu.Item.Share val title = "Mozilla" val readerUrl = "moz-extension://1234" @@ -435,7 +505,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarFindInPagePress() = runBlockingTest { + fun `WHEN Find In Page menu item is pressed THEN launch finder`() = runBlockingTest { val item = ToolbarMenu.Item.FindInPage val controller = createController(scope = this) @@ -446,7 +516,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarSaveToCollectionPressWhenAtLeastOneCollectionExists() = runBlockingTest { + fun `IF one or more collection exists WHEN Save To Collection menu item is pressed THEN navigate to save collection page`() = runBlockingTest { val item = ToolbarMenu.Item.SaveToCollection val cachedTabCollections: List = mockk(relaxed = true) every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollections @@ -474,7 +544,7 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarSaveToCollectionPressWhenNoCollectionsExists() = runBlockingTest { + fun `IF no collection exists WHEN Save To Collection menu item is pressed THEN navigate to create collection page`() = runBlockingTest { val item = ToolbarMenu.Item.SaveToCollection val cachedTabCollectionsEmpty: List = emptyList() every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollectionsEmpty @@ -499,56 +569,22 @@ class DefaultBrowserToolbarMenuControllerTest { } @Test - fun handleToolbarOpenInFenixPress() = runBlockingTest { - val controller = createController(scope = this, customTabSession = currentSession) - - val item = ToolbarMenu.Item.OpenInFenix - - every { currentSession.customTabConfig } returns mockk() - every { activity.startActivity(any()) } just Runs - - controller.handleToolbarItemInteraction(item) - - verify { sessionFeature.release() } - verify { currentSession.customTabConfig = null } - verify { sessionManager.select(currentSession) } - verify { activity.startActivity(openInFenixIntent) } - verify { activity.finishAndRemoveTask() } - } - - @Test - fun handleToolbarQuitPress() = runBlockingTest { - val item = ToolbarMenu.Item.Quit - val testScope = this - - val controller = createController(scope = testScope) - - controller.handleToolbarItemInteraction(item) - - verify { deleteAndQuit(activity, testScope, null) } - } - - @Test - fun handleToolbarReaderModeAppearancePress() = runBlockingTest { - val item = ToolbarMenu.Item.ReaderModeAppearance + fun `WHEN New Tab menu item is pressed THEN navigate to a new tab home`() = runBlockingTest { + val item = ToolbarMenu.Item.NewTab val controller = createController(scope = this) controller.handleToolbarItemInteraction(item) - verify { readerModeController.showControls() } - verify { metrics.track(Event.ReaderModeAppearanceOpened) } - } - - @Test - fun handleToolbarOpenInAppPress() = runBlockingTest { - val item = ToolbarMenu.Item.OpenInApp - - val controller = createController(scope = this) - - controller.handleToolbarItemInteraction(item) - - verify { settings.openInAppOpened = true } + verify { + navController.navigate( + directionsEq( + NavGraphDirections.actionGlobalHome( + focusOnAddressBar = true + ) + ) + ) + } } private fun createController( From 3311e68d14b5f6db1193dfcebe6ed6d7050be8c4 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Mon, 1 Feb 2021 12:30:50 +0200 Subject: [PATCH 119/248] For #17686 - Use a custom behavior to scroll InfoBanner with the top toolbar Previously when the toolbar was on top the banner was inflated in the toolbar's parent - an AppBarLayout. After migrating to use a custom behavior for scrolling the toolbar and not use anymore the AppbarLayout for this we needed a new solution. Using a new behavior to keep this banner in sync with the y translation of the toolbar gives us most of the old behavior back. --- .../mozilla/fenix/browser/BrowserFragment.kt | 3 +- .../browser/OpenInAppOnboardingObserver.kt | 11 ++- .../browser/infobanner/DynamicInfoBanner.kt | 42 +++++++++++ .../infobanner/DynamicInfoBannerBehavior.kt | 50 +++++++++++++ .../browser/{ => infobanner}/InfoBanner.kt | 16 ++--- .../org/mozilla/fenix/tabtray/TabTrayView.kt | 2 +- .../OpenInAppOnboardingObserverTest.kt | 27 ++++++- .../DynamicInfoBannerBehaviorTest.kt | 72 +++++++++++++++++++ .../infobanner/DynamicInfoBannerTest.kt | 39 ++++++++++ 9 files changed, 245 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBanner.kt create mode 100644 app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehavior.kt rename app/src/main/java/org/mozilla/fenix/browser/{ => infobanner}/InfoBanner.kt (85%) create mode 100644 app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehaviorTest.kt create mode 100644 app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index a2f3db7d9..6d0cdb926 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -137,7 +137,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { navController = findNavController(), settings = context.settings(), appLinksUseCases = context.components.useCases.appLinksUseCases, - container = browserLayout as ViewGroup + container = browserLayout as ViewGroup, + shouldScrollWithTopToolbar = !context.settings().shouldUseBottomToolbar ), owner = this, view = view diff --git a/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt b/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt index 65cb98795..9205a26bd 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserver.kt @@ -22,6 +22,8 @@ import mozilla.components.support.base.feature.LifecycleAwareFeature import mozilla.components.support.ktx.kotlin.tryGetHostFromUrl import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged import org.mozilla.fenix.R +import org.mozilla.fenix.browser.infobanner.DynamicInfoBanner +import org.mozilla.fenix.browser.infobanner.InfoBanner import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event.BannerOpenInAppGoToSettings import org.mozilla.fenix.ext.components @@ -40,7 +42,9 @@ class OpenInAppOnboardingObserver( private val navController: NavController, private val settings: Settings, private val appLinksUseCases: AppLinksUseCases, - private val container: ViewGroup + private val container: ViewGroup, + @VisibleForTesting + internal val shouldScrollWithTopToolbar: Boolean = false ) : LifecycleAwareFeature { private var scope: CoroutineScope? = null private var currentUrl: String? = null @@ -93,13 +97,14 @@ class OpenInAppOnboardingObserver( } @VisibleForTesting - internal fun createInfoBanner(): InfoBanner { - return InfoBanner( + internal fun createInfoBanner(): DynamicInfoBanner { + return DynamicInfoBanner( context = context, message = context.getString(R.string.open_in_app_cfr_info_message), dismissText = context.getString(R.string.open_in_app_cfr_negative_button_text), actionText = context.getString(R.string.open_in_app_cfr_positive_button_text), container = container, + shouldScrollWithTopToolbar = shouldScrollWithTopToolbar, dismissAction = ::dismissAction ) { val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment( diff --git a/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBanner.kt b/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBanner.kt new file mode 100644 index 000000000..83e11465c --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBanner.kt @@ -0,0 +1,42 @@ +/* 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 org.mozilla.fenix.browser.infobanner + +import android.content.Context +import android.view.ViewGroup +import androidx.annotation.VisibleForTesting +import androidx.coordinatorlayout.widget.CoordinatorLayout + +/** + * [InfoBanner] that will automatically scroll with the top [BrowserToolbar]. + * Only to be used with [BrowserToolbar]s placed at the top of the screen. + * + * @param shouldScrollWithTopToolbar whether to follow the Y translation of the top toolbar or not + */ +@Suppress("LongParameterList") +class DynamicInfoBanner( + private val context: Context, + container: ViewGroup, + @VisibleForTesting + internal val shouldScrollWithTopToolbar: Boolean = false, + message: String, + dismissText: String, + actionText: String? = null, + dismissByHiding: Boolean = false, + dismissAction: (() -> Unit)? = null, + actionToPerform: (() -> Unit)? = null +) : InfoBanner( + context, container, message, dismissText, actionText, dismissByHiding, dismissAction, actionToPerform +) { + override fun showBanner() { + super.showBanner() + + if (shouldScrollWithTopToolbar) { + (bannerLayout.layoutParams as CoordinatorLayout.LayoutParams).behavior = DynamicInfoBannerBehavior( + context, null + ) + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehavior.kt b/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehavior.kt new file mode 100644 index 000000000..752826248 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehavior.kt @@ -0,0 +1,50 @@ +/* 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 org.mozilla.fenix.browser.infobanner + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.annotation.VisibleForTesting +import androidx.coordinatorlayout.widget.CoordinatorLayout +import mozilla.components.browser.toolbar.BrowserToolbar + +/** + * A [CoordinatorLayout.Behavior] implementation to be used when placing [InfoBanner] + * below the BrowserToolbar with which is has to scroll. + * + * This Behavior will keep the Y translations of [InfoBanner] and the top [BrowserToolbar] in sync + * so that the banner will be shown between: + * - the top of the container, being translated over the initial toolbar height (toolbar fully collapsed) + * - immediately below the toolbar (toolbar fully expanded). + */ +class DynamicInfoBannerBehavior( + context: Context?, + attrs: AttributeSet? +) : CoordinatorLayout.Behavior(context, attrs) { + @VisibleForTesting + internal var toolbarHeight: Int = 0 + + override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean { + if (dependency::class == BrowserToolbar::class) { + toolbarHeight = dependency.height + setBannerYTranslation(child, dependency.translationY) + return true + } + + return super.layoutDependsOn(parent, child, dependency) + } + + override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean { + setBannerYTranslation(child, dependency.translationY) + + return true + } + + @VisibleForTesting + internal fun setBannerYTranslation(banner: View, newYTranslation: Float) { + banner.translationY = toolbarHeight + newYTranslation + } +} diff --git a/app/src/main/java/org/mozilla/fenix/browser/InfoBanner.kt b/app/src/main/java/org/mozilla/fenix/browser/infobanner/InfoBanner.kt similarity index 85% rename from app/src/main/java/org/mozilla/fenix/browser/InfoBanner.kt rename to app/src/main/java/org/mozilla/fenix/browser/infobanner/InfoBanner.kt index d7f4187cc..1d1ba4041 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/InfoBanner.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/infobanner/InfoBanner.kt @@ -2,15 +2,14 @@ * 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 org.mozilla.fenix.browser +package org.mozilla.fenix.browser.infobanner import android.annotation.SuppressLint import android.content.Context import android.view.LayoutInflater import android.view.View.GONE import android.view.ViewGroup -import android.view.ViewGroup.LayoutParams.MATCH_PARENT -import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import androidx.annotation.VisibleForTesting import kotlinx.android.synthetic.main.info_banner.view.* import org.mozilla.fenix.R import org.mozilla.fenix.ext.settings @@ -27,7 +26,7 @@ import org.mozilla.fenix.ext.settings * @param actionToPerform - The action to be performed on action button press */ @SuppressWarnings("LongParameterList") -class InfoBanner( +open class InfoBanner( private val context: Context, private val container: ViewGroup, private val message: String, @@ -38,10 +37,11 @@ class InfoBanner( private val actionToPerform: (() -> Unit)? = null ) { @SuppressLint("InflateParams") - private val bannerLayout = LayoutInflater.from(context) + @VisibleForTesting + internal val bannerLayout = LayoutInflater.from(context) .inflate(R.layout.info_banner, null) - internal fun showBanner() { + internal open fun showBanner() { bannerLayout.banner_info_message.text = message bannerLayout.dismiss.text = dismissText @@ -53,10 +53,6 @@ class InfoBanner( container.addView(bannerLayout) - val params = bannerLayout.layoutParams as ViewGroup.LayoutParams - params.height = WRAP_CONTENT - params.width = MATCH_PARENT - bannerLayout.dismiss.setOnClickListener { dismissAction?.invoke() if (dismissByHiding) { bannerLayout.visibility = GONE } else { dismiss() } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt index bf97ba942..a748291ee 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt @@ -46,10 +46,10 @@ import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.util.dpToPx import mozilla.components.ui.tabcounter.TabCounter.Companion.INFINITE_CHAR_PADDING_BOTTOM import org.mozilla.fenix.R -import org.mozilla.fenix.browser.InfoBanner import org.mozilla.fenix.components.metrics.Event import mozilla.components.ui.tabcounter.TabCounter.Companion.MAX_VISIBLE_TABS import mozilla.components.ui.tabcounter.TabCounter.Companion.SO_MANY_TABS_OPEN +import org.mozilla.fenix.browser.infobanner.InfoBanner import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.updateAccessibilityCollectionInfo diff --git a/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt b/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt index ec8405f3f..3645bf604 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/OpenInAppOnboardingObserverTest.kt @@ -24,12 +24,16 @@ import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.feature.app.links.AppLinksUseCases import mozilla.components.support.test.ext.joinBlocking +import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.After +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.browser.infobanner.DynamicInfoBanner import org.mozilla.fenix.ext.components import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings @@ -46,7 +50,7 @@ class OpenInAppOnboardingObserverTest { private lateinit var appLinksUseCases: AppLinksUseCases private lateinit var context: Context private lateinit var container: ViewGroup - private lateinit var infoBanner: InfoBanner + private lateinit var infoBanner: DynamicInfoBanner private val testDispatcher = TestCoroutineDispatcher() @@ -76,7 +80,8 @@ class OpenInAppOnboardingObserverTest { navController = navigationController, settings = settings, appLinksUseCases = appLinksUseCases, - container = container + container = container, + shouldScrollWithTopToolbar = true )) every { openInAppOnboardingObserver.createInfoBanner() } returns infoBanner } @@ -157,6 +162,24 @@ class OpenInAppOnboardingObserverTest { verify(exactly = 1) { infoBanner.dismiss() } } + @Test + fun `GIVEN a observer WHEN createInfoBanner() THEN the scrollWithTopToolbar is passed to the DynamicInfoBanner`() { + // Mockk currently doesn't support verifying constructor parameters + // But we can check the values found in the constructed objects + + openInAppOnboardingObserver = spyk(OpenInAppOnboardingObserver( + testContext, mockk(), mockk(), mockk(), mockk(), mockk(), mockk(), shouldScrollWithTopToolbar = true + )) + val banner1 = openInAppOnboardingObserver.createInfoBanner() + assertTrue(banner1.shouldScrollWithTopToolbar) + + openInAppOnboardingObserver = spyk(OpenInAppOnboardingObserver( + testContext, mockk(), mockk(), mockk(), mockk(), mockk(), mockk(), shouldScrollWithTopToolbar = false + )) + val banner2 = openInAppOnboardingObserver.createInfoBanner() + assertFalse(banner2.shouldScrollWithTopToolbar) + } + internal class MockedLifecycleOwner(initialState: Lifecycle.State) : LifecycleOwner { val lifecycleRegistry = LifecycleRegistry(this).apply { currentState = initialState diff --git a/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehaviorTest.kt b/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehaviorTest.kt new file mode 100644 index 000000000..69fd5d8ca --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerBehaviorTest.kt @@ -0,0 +1,72 @@ +/* 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 org.mozilla.fenix.browser.infobanner + +import android.view.View +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import mozilla.components.browser.toolbar.BrowserToolbar +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class DynamicInfoBannerBehaviorTest { + @Test + fun `layoutDependsOn should not do anything if not for BrowserToolbar as a dependency`() { + val behavior = spyk(DynamicInfoBannerBehavior(mockk(), null)) + + behavior.layoutDependsOn(mockk(), mockk(), mockk()) + + verify(exactly = 0) { behavior.toolbarHeight } + verify(exactly = 0) { behavior.toolbarHeight = any() } + verify(exactly = 0) { behavior.setBannerYTranslation(any(), any()) } + } + + @Test + fun `layoutDependsOn should update toolbarHeight and translate the banner`() { + val behavior = spyk(DynamicInfoBannerBehavior(mockk(), null)) + val banner: View = mockk(relaxed = true) + val toolbar: BrowserToolbar = mockk { + every { height } returns 99 + every { translationY } returns -33f + } + + assertEquals(0, behavior.toolbarHeight) + + behavior.layoutDependsOn(mockk(), banner, toolbar) + + assertEquals(99, behavior.toolbarHeight) + verify { behavior.setBannerYTranslation(banner, -33f) } + } + + @Test + fun `onDependentViewChanged should translate the banner`() { + val behavior = spyk(DynamicInfoBannerBehavior(mockk(), null)) + val banner: View = mockk(relaxed = true) + val toolbar: BrowserToolbar = mockk { + every { height } returns 50 + every { translationY } returns -23f + } + + behavior.layoutDependsOn(mockk(), banner, toolbar) + + verify { behavior.setBannerYTranslation(banner, -23f) } + } + + @Test + fun `setBannerYTranslation should set banner translation to be toolbarHeight + it's translation`() { + val behavior = spyk(DynamicInfoBannerBehavior(mockk(), null)) + val banner: View = mockk(relaxed = true) + behavior.toolbarHeight = 30 + + behavior.setBannerYTranslation(banner, -20f) + + verify { banner.translationY = 10f } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerTest.kt b/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerTest.kt new file mode 100644 index 000000000..d894071ab --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/browser/infobanner/DynamicInfoBannerTest.kt @@ -0,0 +1,39 @@ +/* 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 org.mozilla.fenix.browser.infobanner + +import androidx.coordinatorlayout.widget.CoordinatorLayout +import io.mockk.spyk +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class DynamicInfoBannerTest { + @Test + fun `showBanner should set DynamicInfoBannerBehavior as behavior if scrollWithTopToolbar`() { + val banner = spyk(DynamicInfoBanner( + testContext, CoordinatorLayout(testContext), true, "", "" + )) + + banner.showBanner() + + assertTrue((banner.bannerLayout.layoutParams as CoordinatorLayout.LayoutParams).behavior is DynamicInfoBannerBehavior) + } + + @Test + fun `showBanner should not set a behavior if not scrollWithTopToolbar`() { + val banner = spyk(DynamicInfoBanner( + testContext, CoordinatorLayout(testContext), false, "", "" + )) + + banner.showBanner() + + assertNull((banner.bannerLayout.layoutParams as CoordinatorLayout.LayoutParams).behavior) + } +} From b97c737a479ab3c01f4a0ff9616e2258600542d5 Mon Sep 17 00:00:00 2001 From: alexandru-io <47977085+alexandru-io@users.noreply.github.com> Date: Fri, 12 Feb 2021 23:52:37 +0200 Subject: [PATCH 120/248] Bug 1674442 - Add a "visual-metrics" tag to the browsertime visual-metrics data (#17900) Co-authored-by: Alex Ionescu --- taskcluster/docker/visual-metrics/run-visual-metrics.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/taskcluster/docker/visual-metrics/run-visual-metrics.py b/taskcluster/docker/visual-metrics/run-visual-metrics.py index 799207a8d..698d66237 100755 --- a/taskcluster/docker/visual-metrics/run-visual-metrics.py +++ b/taskcluster/docker/visual-metrics/run-visual-metrics.py @@ -171,7 +171,12 @@ def append_result(log, suites, test_name, name, result, extra_options): subtests = suites.setdefault( test_name, - {"name": orig_test_name, "subtests": {}, "extraOptions": extra_options}, + { + "name": orig_test_name, + "tags": extra_options + ["visual"], + "subtests": {}, + "extraOptions": extra_options, + }, )["subtests"] if name not in subtests: From bab7693b9d776afc3ea37b1e5c7954c34dc2129a Mon Sep 17 00:00:00 2001 From: Elise Richards Date: Fri, 12 Feb 2021 17:01:38 -0600 Subject: [PATCH 121/248] Remove unneeded temporary UI test ignores (#17980) --- .../org/mozilla/fenix/ui/ReaderViewTest.kt | 54 ++++++++++--------- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 1 - 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt index 980c05aee..3d37cf44e 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ReaderViewTest.kt @@ -31,7 +31,6 @@ import org.mozilla.fenix.ui.robots.mDevice * */ -@Ignore("Temp disable - reader view page detection issues: https://github.com/mozilla-mobile/fenix/issues/9688 ") class ReaderViewTest { private lateinit var mockWebServer: MockWebServer private var readerViewNotification: ViewVisibilityIdlingResource? = null @@ -105,45 +104,46 @@ class ReaderViewTest { @Test fun verifyReaderViewToggle() { - // New three-dot menu design does not have readerview - if (!FeatureFlags.toolbarMenuFeature) { - val readerViewPage = - TestAssetHelper.getLoremIpsumAsset(mockWebServer) + // New three-dot menu design does not have readerview appearance menu item + val readerViewPage = + TestAssetHelper.getLoremIpsumAsset(mockWebServer) - navigationToolbar { - }.enterURLAndEnterToBrowser(readerViewPage.url) { - mDevice.waitForIdle() - } + navigationToolbar { + }.enterURLAndEnterToBrowser(readerViewPage.url) { + mDevice.waitForIdle() + } - readerViewNotification = ViewVisibilityIdlingResource( - activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), - View.VISIBLE - ) + readerViewNotification = ViewVisibilityIdlingResource( + activityIntentTestRule.activity.findViewById(R.id.mozac_browser_toolbar_page_actions), + View.VISIBLE + ) - IdlingRegistry.getInstance().register(readerViewNotification) + IdlingRegistry.getInstance().register(readerViewNotification) - navigationToolbar { - verifyReaderViewDetected(true) - toggleReaderView() - mDevice.waitForIdle() - } + navigationToolbar { + verifyReaderViewDetected(true) + toggleReaderView() + mDevice.waitForIdle() + } + if (!FeatureFlags.toolbarMenuFeature) { browserScreen { verifyPageContent(estimatedReadingTime) }.openThreeDotMenu { verifyReaderViewAppearance(true) }.closeBrowserMenuToBrowser { } - - navigationToolbar { - toggleReaderView() - mDevice.waitForIdle() - }.openThreeDotMenu { - verifyReaderViewAppearance(false) - }.close { } } + + navigationToolbar { + toggleReaderView() + mDevice.waitForIdle() + }.openThreeDotMenu { + verifyReaderViewAppearance(false) + }.close { } } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17971") fun verifyReaderViewAppearanceFontToggle() { val readerViewPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer) @@ -184,6 +184,7 @@ class ReaderViewTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17971") fun verifyReaderViewAppearanceFontSizeToggle() { val readerViewPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer) @@ -230,6 +231,7 @@ class ReaderViewTest { } @Test + @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17971") fun verifyReaderViewAppearanceColorSchemeChange() { val readerViewPage = TestAssetHelper.getLoremIpsumAsset(mockWebServer) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index 18584a0b6..78693bf7c 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -233,7 +233,6 @@ class SmokeTest { } @Test - @Ignore("To be re-implemented in https://github.com/mozilla-mobile/fenix/issues/17798") // Verifies the Synced tabs menu opens from a tab's 3 dot menu fun openMainMenuSyncedTabsItemTest() { homeScreen { From acfaf2d5da49627c752e9cafd3c151c2e3fc7e9d Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Fri, 12 Feb 2021 21:39:54 +0000 Subject: [PATCH 122/248] Update Android Components version to 73.0.20210212205146. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 1f2f8aad0..8e62e446e 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210211190100" + const val VERSION = "73.0.20210212205146" } From 3c54562504068e7d97d3d6cb15aad4a82b1a3318 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sat, 13 Feb 2021 00:05:50 +0000 Subject: [PATCH 123/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 2 + app/src/main/res/values-co/strings.xml | 6 +++ app/src/main/res/values-de/strings.xml | 6 +++ app/src/main/res/values-dsb/strings.xml | 6 +++ app/src/main/res/values-es-rAR/strings.xml | 6 +++ app/src/main/res/values-fy-rNL/strings.xml | 6 +++ app/src/main/res/values-gl/strings.xml | 55 +++++++++++++++++++++- app/src/main/res/values-gn/strings.xml | 6 +++ app/src/main/res/values-hr/strings.xml | 6 +++ app/src/main/res/values-hsb/strings.xml | 6 +++ app/src/main/res/values-it/strings.xml | 6 +++ app/src/main/res/values-iw/strings.xml | 6 +++ app/src/main/res/values-ko/strings.xml | 6 +++ app/src/main/res/values-nl/strings.xml | 6 +++ app/src/main/res/values-pt-rBR/strings.xml | 6 +++ app/src/main/res/values-rm/strings.xml | 6 +++ app/src/main/res/values-ru/strings.xml | 6 +++ app/src/main/res/values-sv-rSE/strings.xml | 6 +++ app/src/main/res/values-tr/strings.xml | 6 +++ app/src/main/res/values-uk/strings.xml | 6 +++ app/src/main/res/values-zh-rCN/strings.xml | 6 +++ app/src/main/res/values-zh-rTW/strings.xml | 6 +++ 22 files changed, 176 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 983b3ff1a..a8c3d6299 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -697,6 +697,8 @@ Quitáronse les descargues Quitóse %1$s + + Nun hai ficheros baxaos Descargues esbillaes: %1$d diff --git a/app/src/main/res/values-co/strings.xml b/app/src/main/res/values-co/strings.xml index f2a4f31da..c42c30624 100644 --- a/app/src/main/res/values-co/strings.xml +++ b/app/src/main/res/values-co/strings.xml @@ -135,6 +135,8 @@ Mudificà l’indetta Moduli addiziunali + + Estensioni Nisunu modulu quì @@ -534,6 +536,10 @@ Altre indette Cronolugia + + Nova unghjetta + + Circà in a pagina Unghjette sincrunizate diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f47ff3448..0f8097498 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -133,6 +133,8 @@ Lesezeichen bearbeiten Add-ons + + Erweiterungen Hier sind keine Add-ons @@ -537,6 +539,10 @@ Weitere Lesezeichen Chronik + + Neuer Tab + + In Seite suchen Synchronisierte Tabs diff --git a/app/src/main/res/values-dsb/strings.xml b/app/src/main/res/values-dsb/strings.xml index 3ac0e3a1d..e9c24bd68 100644 --- a/app/src/main/res/values-dsb/strings.xml +++ b/app/src/main/res/values-dsb/strings.xml @@ -130,6 +130,8 @@ Cytańske znamje wobźěłaś Dodanki + + Rozšyrjenja Žedne dodanki how @@ -527,6 +529,10 @@ Druge cytańske znamjenja Historija + + Nowy rejtarik + + Na boku pytaś Synchronizěrowane rejtariki diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index 3967f2e4d..ed695f4e1 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -131,6 +131,8 @@ Editar marcador Complementos + + Extensiones No hay complementos aquí @@ -540,6 +542,10 @@ Otros marcadores Historial + + Nueva pestaña + + Buscar en la página Pestañas sincronizadas diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 576094712..2bfaa8d9f 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -132,6 +132,8 @@ Blêdwizer bewurkje Add-ons + + Utwreidingen Gjin add-ons hjir @@ -528,6 +530,10 @@ Oare blêdwizers Skiednis + + Nij ljepblêd + + Sykje op side Syngronisearre ljepblêden diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 7620187e7..cd25c2457 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -161,6 +161,12 @@ Aberto en %1$s + + CREADO POR %1$s + + Creado por %1$s Modo de lectura @@ -971,6 +977,8 @@ Abrir Eliminar e abrir + + Creado por Colección eliminada @@ -1066,6 +1074,8 @@ Libera espazo de almacenamento Permisos do sitio + + Descargas Eliminar datos de navegación @@ -1188,6 +1198,9 @@ A súa privacidade + + Deseñamos %s para darlle o control sobre o que comparte en liña e o que comparte con nós. Lea a nosa política de privacidade @@ -1481,6 +1494,10 @@ Configurar agora Desbloquear o dispositivo + + Zoom sobre todos os sitios + + Activa o permiso para toque e aumento, incluso en sitios web que bloquean este xesto. Nome (A-Z) @@ -1626,4 +1643,40 @@ Non hai lapelas abertas - + + + Acadouse o límite superior do sitio + + Para engadir un novo sitio primario, retire outro. Toque e manteña a presión sobre o sitio e seleccione retiralo. + + De acordo, entendín + + Amosar os sitios máis visitados + + Nome + + Nome do sitio primario + + De acordo + + Cancelar + + + Retirar + + + Obter o máximo de %s. + + + Premer para obter máis detalles + + + Colla as cousas que lle importan + + Agrupar xuntas as buscar semellantes, sitios e lapelas para ter un acceso rápido despois. + + Iniciou sesión como %s noutro navegador Firefox neste móbil. Confirma que quere iniciar sesión con esta conta? + + Pode engadir doadamente este sitio web á pantalla principal do seu móbil para ter acceso instantáneo e navegar máis rápido cunha experiencia de tipo app. + diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index 9f8eb6a81..c36665e03 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -132,6 +132,8 @@ Techaukaha mbosako’i Moĩmbaha + + Jepysokue Ndaipóri moĩmbaha ápe @@ -534,6 +536,10 @@ Ambue techaukahakuéra Tembiasakue + + Tendayke pyahu + + Eheka kuatiaroguépe Tendayke mbojuehepyre diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 2c36aef30..aa9c48cfa 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -129,6 +129,8 @@ Uredi zabilješku Dodaci + + Proširenja Ovdje nema dodataka @@ -530,6 +532,10 @@ Druge zabilješke Povijest + + Nova kartica + + Pronađi na stranici Sinkronizirane kartice diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index 01625cf31..d5c0ee0c1 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -131,6 +131,8 @@ Zapołožku wobdźěłać Přidatki + + Rozšěrjenja Žane přidatki tu @@ -529,6 +531,10 @@ Druhe zapołožki Historija + + Nowy rajtark + + Na stronje pytać Synchronizowane rajtarki diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 60f385327..26865d46d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -130,6 +130,8 @@ Modifica segnalibro Componenti aggiuntivi + + Estensioni Nessun componente aggiuntivo @@ -540,6 +542,10 @@ Altri segnalibri Cronologia + + Nuova scheda + + Trova nella pagina Schede sincronizzate diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 84b471376..937e2f0f4 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -130,6 +130,8 @@ עריכת סימנייה תוספות + + הרחבות אין תוספות כאן @@ -525,6 +527,10 @@ סימניות אחרות היסטוריה + + לשונית חדשה + + חיפוש בדף לשוניות מסונכרנות diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 6090e5fca..fb70a453e 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -137,6 +137,8 @@ 북마크 편집 부가 기능 + + 확장 기능 부가 기능 없음 @@ -542,6 +544,10 @@ 다른 북마크 기록 + + 새 탭 + + 페이지에서 찾기 동기화된 탭 diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 3695b01ae..4b6326bee 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -135,6 +135,8 @@ Bladwijzer bewerken Add-ons + + Extensies Geen add-ons hier @@ -533,6 +535,10 @@ Andere bladwijzers Geschiedenis + + Nieuw tabblad + + Zoeken op pagina Gesynchroniseerde tabbladen diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 98029fca7..ad3f87d62 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -130,6 +130,8 @@ Editar favorito Extensões + + Extensões Nenhuma extensão aqui @@ -528,6 +530,10 @@ Outros favoritos Histórico + + Nova aba + + Procurar na página Abas sincronizadas diff --git a/app/src/main/res/values-rm/strings.xml b/app/src/main/res/values-rm/strings.xml index ff55b6944..25257d506 100644 --- a/app/src/main/res/values-rm/strings.xml +++ b/app/src/main/res/values-rm/strings.xml @@ -128,6 +128,8 @@ Modifitgar il segnapagina Supplements + + Extensiuns Nagins supplements qua @@ -523,6 +525,10 @@ Auters segnapaginas Cronologia + + Nov tab + + Tschertgar en la pagina Tabs sincronisads diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index c94262694..2d9349101 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -138,6 +138,8 @@ Изменить закладку Дополнения + + Расширения Дополнения отсутствуют @@ -540,6 +542,10 @@ Другие закладки История + + Новая вкладка + + Найти на странице Облачные вкладки diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 07610a415..bd11b0686 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -132,6 +132,8 @@ Redigera bokmärke Tillägg + + Tillägg Inga tillägg här @@ -537,6 +539,10 @@ Andra bokmärken Historik + + Ny flik + + Hitta på sidan Synkade flikar diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 4204cd7d1..438f1572d 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -130,6 +130,8 @@ Yer imini düzenle Eklentiler + + Eklentiler Hiç eklenti yok @@ -529,6 +531,10 @@ Diğer yer imleri Geçmiş + + Yeni sekme + + Sayfada bul Eşitlenmiş sekmeler diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index cd49b22be..a53c6d1df 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -130,6 +130,8 @@ Змінити закладку Додатки + + Розширення Немає додатків @@ -535,6 +537,10 @@ Інші закладки Історія + + Нова вкладка + + Знайти на сторінці Синхронізовані вкладки diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ff7cc6fce..d7137ead5 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -134,6 +134,8 @@ 编辑书签 附加组件 + + 扩展 这里没有附加组件 @@ -544,6 +546,10 @@ 其他书签 历史 + + 新建标签页 + + 在页面中查找 受同步的标签页 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 2a1a9dc55..3de38393a 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -131,6 +131,8 @@ 編輯書籤 附加元件 + + 擴充套件 無附加元件 @@ -536,6 +538,10 @@ 其他書籤 瀏覽紀錄 + + 開新分頁 + + 在頁面中搜尋 同步的分頁 From ed0a188e7ea66875b27aba061519eef948daa8eb Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sun, 14 Feb 2021 00:04:29 +0000 Subject: [PATCH 124/248] Import l10n. --- app/src/main/res/values-el/strings.xml | 6 ++++++ app/src/main/res/values-lt/strings.xml | 6 ++++++ app/src/main/res/values-pa-rIN/strings.xml | 6 ++++++ app/src/main/res/values-pl/strings.xml | 6 ++++++ app/src/main/res/values-sl/strings.xml | 6 ++++++ app/src/main/res/values-sv-rSE/strings.xml | 4 ++-- app/src/main/res/values-vi/strings.xml | 6 ++++++ 7 files changed, 38 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 814fd4851..c9dce3184 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -135,6 +135,8 @@ Επεξεργασία σελιδοδείκτη Πρόσθετα + + Επεκτάσεις Δεν βρέθηκαν πρόσθετα @@ -536,6 +538,10 @@ Άλλοι σελιδοδείκτες Ιστορικό + + Νέα καρτέλα + + Εύρεση στη σελίδα Συγχρονισμένες καρτέλες diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index fb380ecc0..7a58543c2 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -129,6 +129,8 @@ Redaguoti adresyno įrašą Priedai + + Priedai Čia nėra jokių priedų @@ -529,6 +531,10 @@ Kiti adresai Žurnalas + + Nauja kortelė + + Rasti tinklalapyje Sinchronizuotos kortelės diff --git a/app/src/main/res/values-pa-rIN/strings.xml b/app/src/main/res/values-pa-rIN/strings.xml index 68bdccd77..e65606abf 100644 --- a/app/src/main/res/values-pa-rIN/strings.xml +++ b/app/src/main/res/values-pa-rIN/strings.xml @@ -135,6 +135,8 @@ ਬੁੱਕਮਾਰਕ ਸੋਧੋ ਐਡ-ਆਨ + + ਇਕਸਟੈਨਸ਼ਨਾਂ ਕੋਈ ਐਡ-ਆਨ ਨਹੀਂ ਹੈ @@ -542,6 +544,10 @@ ਹੋਰ ਬੁੱਕਮਾਰਕ ਅਤੀਤ + + ਨਵੀਂ ਟੈਬ + + ਸਫ਼ੇ ‘ਚ ਲੱਭੋ ਸਿੰਕ ਕੀਤੀਆਂ ਟੈਬਾਂ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 2626a7078..d6ffee801 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -131,6 +131,8 @@ Edytuj zakładkę Dodatki + + Rozszerzenia Nie ma żadnych dodatków @@ -532,6 +534,10 @@ Pozostałe zakładki Historia + + Nowa karta + + Znajdź na stronie Karty z innych urządzeń diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 7e06ccef1..b722f3d88 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -131,6 +131,8 @@ Uredi zaznamek Dodatki + + Razširitve Tukaj ni dodatkov @@ -536,6 +538,10 @@ Drugi zaznamki Zgodovina + + Nov zavihek + + Najdi na strani Sinhronizirani zavihki diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index bd11b0686..bf9433a22 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -30,7 +30,7 @@ %1$s öppna flikar. Tryck för att växla mellan flikar. - %1$d markerad + %1$d markerade Lägg till ny samling @@ -749,7 +749,7 @@ Inga nedladdade filer - %1$d markerad + %1$d markerade Öppen diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 5684ce9ea..6dd96748a 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -131,6 +131,8 @@ Chỉnh sửa dấu trang Tiện ích + + Tiện ích mở rộng Không có tiện ích nào ở đây @@ -526,6 +528,10 @@ Dấu trang khác Lịch sử + + Thẻ mới + + Tìm trong trang Các thẻ đã đồng bộ From 9fee34960098817f1dbdb3c9bea99b0ad011d283 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Mon, 15 Feb 2021 00:06:07 +0000 Subject: [PATCH 125/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 17 ++++++++++++++--- app/src/main/res/values-ca/strings.xml | 6 ++++++ app/src/main/res/values-cs/strings.xml | 6 ++++++ app/src/main/res/values-es-rES/strings.xml | 6 ++++++ app/src/main/res/values-fi/strings.xml | 6 ++++++ app/src/main/res/values-hr/strings.xml | 10 +++++----- app/src/main/res/values-kab/strings.xml | 6 ++++++ app/src/main/res/values-nb-rNO/strings.xml | 6 ++++++ app/src/main/res/values-nn-rNO/strings.xml | 6 ++++++ app/src/main/res/values-pt-rPT/strings.xml | 6 ++++++ app/src/main/res/values-sk/strings.xml | 6 ++++++ app/src/main/res/values-sr/strings.xml | 6 ++++++ 12 files changed, 79 insertions(+), 8 deletions(-) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index a8c3d6299..27739e371 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -30,7 +30,7 @@ %1$s llingüetes abiertes. Toca pa cambiar a otra. - %1$d esbillaes + %1$d na esbilla Coleición nueva @@ -44,14 +44,17 @@ Guardar les llingüetes esbillaes nuna coleición - Esbillóse %1$s + %1$s na esbilla - Deseleicionóse %1$s + %1$s fuera de la esbilla Colesti del mou d\'esbilla múltiple Entresti nel mou d\'esbilla múltiple, esbilla les llingüetes pa guardales nuna coleición + + Na esbilla + %1$s ta producíu por Mozilla. @@ -507,6 +510,8 @@ Otros marcadores Historial + + Llingüeta nueva Llingüetes sincronizaes @@ -720,6 +725,9 @@ Restaurar la llingüeta + + + Menú de los marcadores ¿De xuru que quies desaniciar esta carpeta? @@ -1489,6 +1497,9 @@ en llinia y con nós. Últimu usu + + Menú pa ordenar los anicios sesión + Amestar un motor de busca diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 4ea32843a..dbff35f4c 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -129,6 +129,8 @@ Edita l’adreça d’interès Complements + + Extensions No hi ha cap complement @@ -530,6 +532,10 @@ Altres adreces d’interès Historial + + Pestanya nova + + Cerca a la pàgina Pestanyes sincronitzades diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 530ab0a9c..5d3a4477e 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -131,6 +131,8 @@ Upravit záložku Doplňky + + Rozšíření Žádné doplňky @@ -537,6 +539,10 @@ Ostatní záložky Historie + + Nový panel + + Najít na stránce Synchronizované panely diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 0285eea56..824db4a5d 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -132,6 +132,8 @@ Editar marcador Complementos + + Extensiones No hay complementos aquí @@ -538,6 +540,10 @@ Otros marcadores Historial + + Nueva pestaña + + Buscar en la página Pestañas sincronizadas diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index a53f0a1fd..16521e369 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -131,6 +131,8 @@ Muokkaa kirjanmerkkiä Lisäosat + + Laajennukset Ei lisäosia täällä @@ -535,6 +537,10 @@ Muut kirjanmerkit Historia + + Uusi välilehti + + Etsi sivulta Synkronoidut välilehdet diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index aa9c48cfa..b5058c516 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -292,7 +292,7 @@ Alatna traka - Motiv + Tema Početna @@ -501,7 +501,7 @@ Postavljeno u postavkama za štednju baterije - Slijedi motiv uređaja + Slijedi temu uređaja @@ -1239,16 +1239,16 @@ Odaberi modus - Štedi energiju i zaštiti oči pomoću tamnog motiva. + Štedi energiju i zaštiti oči pomoću tamne teme. Automatski Prilagođava se postavkama uređaja - Tamni motiv + Tamna tema - Svijetli motiv + Svijetla tema Kartice su poslane! diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index a81126fb4..585c5bed8 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -133,6 +133,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Beddel tacreḍt n usebter Izegrar + + Isiɣzaf Ulac izegrar da @@ -535,6 +537,10 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Ticrad nniḍen Amazray + + Iccer amaynut + + Af deg usebter Iccaren yemtawin diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index f7ba461ff..1bd2dc55a 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -132,6 +132,8 @@ Rediger bokmerke Tillegg + + Utvidelser Ingen utvidelser her @@ -535,6 +537,10 @@ Andre bokmerker Historikk + + Ny fane + + Søk på siden Synkroniserte faner diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index a3a44291e..0c50a0747 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -133,6 +133,8 @@ Rediger bokmerke Tillegg + + Utvidingar Ingen tillegg her @@ -533,6 +535,10 @@ Andre bokmerke Historikk + + Ny fane + + Finn på sida Synkroniserte faner diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 9bb5c1a90..909deec7d 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -131,6 +131,8 @@ Editar marcador Extras + + Extensões Sem extras aqui @@ -530,6 +532,10 @@ Outros marcadores Histórico + + Novo separador + + Localizar na página Separadores sincronizados diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 9355c3540..81e5a7464 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -131,6 +131,8 @@ Upraviť záložku Doplnky + + Rozšírenia Nemáte žiadne doplnky @@ -535,6 +537,10 @@ Ostatné záložky História + + Nová karta + + Hľadať na stránke Synchronizované karty diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 11275b18e..491094655 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -128,6 +128,8 @@ Уреди забелешку Додаци + + Проширења Овде нема додатака @@ -529,6 +531,10 @@ Остале забелешке Историјат + + Нови језичак + + Пронађи на страници Синхронизовани језичци From ec5439763776eaeb5f10a005a33908de422b04b5 Mon Sep 17 00:00:00 2001 From: Codrut Topliceanu <60002907+codrut-topliceanu@users.noreply.github.com> Date: Mon, 15 Feb 2021 11:22:09 +0200 Subject: [PATCH 126/248] For #17352 - Fixes deleted downloads reappearing (#17930) * For #17352 - Fixes deleted downloads reappearing The `getDeleteDownloadItemsOperation` job would check fragment context not null after the fragment was stopped. Removing that check and only passing the downloadUseCase as a parameter fixes the problem. --- .../library/downloads/DownloadFragment.kt | 48 ++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt b/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt index d05b3bbc4..f9687e8ad 100644 --- a/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/library/downloads/DownloadFragment.kt @@ -25,6 +25,7 @@ import mozilla.components.browser.state.state.BrowserState import kotlinx.coroutines.launch import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.feature.downloads.AbstractFetchDownloadService +import mozilla.components.feature.downloads.DownloadsUseCases import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.support.base.feature.UserInteractionHandler import org.mozilla.fenix.HomeActivity @@ -50,6 +51,7 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan private lateinit var metrics: MetricController private var undoScope: CoroutineScope? = null private var pendingDownloadDeletionJob: (suspend () -> Unit)? = null + private lateinit var downloadsUseCases: DownloadsUseCases override fun onCreateView( inflater: LayoutInflater, @@ -59,6 +61,7 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan val view = inflater.inflate(R.layout.fragment_downloads, container, false) val items = provideDownloads(requireComponents.core.store.state) + downloadsUseCases = requireContext().components.useCases.downloadUseCases downloadStore = StoreProvider.get(this) { DownloadFragmentStore( @@ -85,6 +88,10 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan return view } + /** + * Returns a list of available downloads to be displayed to the user. + * Downloads must be COMPLETED and existent on disk. + */ @VisibleForTesting internal fun provideDownloads(state: BrowserState): List { return state.downloads.values @@ -128,9 +135,7 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan setPositiveButton(R.string.delete_browsing_data_prompt_allow) { dialog: DialogInterface, _ -> // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with. lifecycleScope.launch(IO) { - context.let { - it.components.useCases.downloadUseCases.removeAllDownloads() - } + downloadsUseCases.removeAllDownloads() updatePendingDownloadToDelete(downloadStore.state.items.toSet()) launch(Dispatchers.Main) { showSnackBar( @@ -146,6 +151,11 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan } } + /** + * Schedules [items] for deletion. + * Note: When tapping on a download item's "trash" button + * (itemView.overflow_menu) this [items].size() will be 1. + */ private fun deleteDownloadItems(items: Set) { metrics.track(Event.DownloadsItemDeleted) @@ -155,10 +165,10 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan requireView(), getMultiSelectSnackBarMessage(items), getString(R.string.bookmark_undo_deletion), - { + onCancel = { undoPendingDeletion(items) }, - getDeleteDownloadItemsOperation(items) + operation = getDeleteDownloadItemsOperation(downloadsUseCases, items) ) } @@ -210,6 +220,9 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan else -> super.onOptionsItemSelected(item) } + /** + * Provides a message to the Undo snackbar. + */ private fun getMultiSelectSnackBarMessage(downloadItems: Set): String { return if (downloadItems.size > 1) { getString(R.string.download_delete_multiple_items_snackbar_1) @@ -246,14 +259,18 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan metrics.track(Event.DownloadsItemOpened) } - private fun getDeleteDownloadItemsOperation(items: Set): (suspend () -> Unit) { + /** + * Launches the coroutine to delete the provided [items]. + */ + private fun getDeleteDownloadItemsOperation( + downloadUseCases: DownloadsUseCases, + items: Set + ): (suspend () -> Unit) { return { CoroutineScope(IO).launch { downloadStore.dispatch(DownloadFragmentAction.EnterDeletionMode) - context?.let { - for (item in items) { - it.components.useCases.downloadUseCases.removeDownload(item.id) - } + for (item in items) { + downloadUseCases.removeDownload(item.id) } downloadStore.dispatch(DownloadFragmentAction.ExitDeletionMode) pendingDownloadDeletionJob = null @@ -261,8 +278,14 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan } } + /** + * Queues the [getDeleteDownloadItemsOperation] job in [pendingDownloadDeletionJob] in case + * the user exits the fragment and we need to quickly execute the queued deletion. + * And adds the [items] to be deleted to the list of [DownloadFragmentStore.pendingDeletionIds], + * which is used to determine what items to show and what items to hide from the user. + */ private fun updatePendingDownloadToDelete(items: Set) { - pendingDownloadDeletionJob = getDeleteDownloadItemsOperation(items) + pendingDownloadDeletionJob = getDeleteDownloadItemsOperation(downloadsUseCases, items) val ids = items.map { item -> item.id }.toSet() downloadStore.dispatch(DownloadFragmentAction.AddPendingDeletionSet(ids)) } @@ -273,6 +296,9 @@ class DownloadFragment : LibraryPageFragment(), UserInteractionHan downloadStore.dispatch(DownloadFragmentAction.UndoPendingDeletionSet(ids)) } + /** + * Executes pending job(s) when leaving [DownloadFragment]. + */ private fun invokePendingDeletion() { pendingDownloadDeletionJob?.let { viewLifecycleOwner.lifecycleScope.launch { From 5a5cf9cd12a3a9a884e171bc5c0656dad0ceed66 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Fri, 12 Feb 2021 10:56:05 -0500 Subject: [PATCH 127/248] Refactor BrowserToolbarController to use browser store --- .../fenix/browser/BaseBrowserFragment.kt | 4 +- .../toolbar/BrowserToolbarController.kt | 24 +++++------ .../DefaultBrowserToolbarControllerTest.kt | 40 +++++++------------ 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 7530c2ceb..820cc2c0b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -281,14 +281,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit ) val browserToolbarController = DefaultBrowserToolbarController( store = store, + tabsUseCases = requireComponents.useCases.tabsUseCases, activity = activity, navController = findNavController(), metrics = requireComponents.analytics.metrics, readerModeController = readerMenuController, - sessionManager = requireComponents.core.sessionManager, engineView = engineView, homeViewModel = homeViewModel, - customTabSession = customTabSessionId?.let { sessionManager.findSessionById(it) }, + customTabSessionId = customTabSessionId, onTabCounterClicked = { thumbnailsFeature.get()?.requestScreenshot() findNavController().nav( diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt index 69c384865..942390abd 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt @@ -5,11 +5,14 @@ package org.mozilla.fenix.components.toolbar import androidx.navigation.NavController -import mozilla.components.browser.session.Session -import mozilla.components.browser.session.SessionManager import mozilla.components.browser.state.action.ContentAction +import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab +import mozilla.components.browser.state.selector.getNormalOrPrivateTabs +import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.EngineView +import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.support.ktx.kotlin.isUrl import mozilla.components.ui.tabcounter.TabCounterMenu import org.mozilla.fenix.HomeActivity @@ -22,7 +25,6 @@ import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.nav -import org.mozilla.fenix.ext.sessionsOfType import org.mozilla.fenix.ext.settings import org.mozilla.fenix.home.HomeScreenViewModel @@ -41,20 +43,20 @@ interface BrowserToolbarController { class DefaultBrowserToolbarController( private val store: BrowserStore, + private val tabsUseCases: TabsUseCases, private val activity: HomeActivity, private val navController: NavController, private val metrics: MetricController, private val readerModeController: ReaderModeController, - private val sessionManager: SessionManager, private val engineView: EngineView, private val homeViewModel: HomeScreenViewModel, - private val customTabSession: Session?, + private val customTabSessionId: String?, private val onTabCounterClicked: () -> Unit, - private val onCloseTab: (Session) -> Unit + private val onCloseTab: (SessionState) -> Unit ) : BrowserToolbarController { private val currentSession - get() = customTabSession ?: sessionManager.selectedSession + get() = store.state.findCustomTabOrSelectedTab(customTabSessionId) override fun handleToolbarPaste(text: String) { navController.nav( @@ -112,18 +114,16 @@ class DefaultBrowserToolbarController( metrics.track( Event.TabCounterMenuItemTapped(Event.TabCounterMenuItemTapped.Item.CLOSE_TAB) ) - sessionManager.selectedSession?.let { + store.state.selectedTab?.let { // When closing the last tab we must show the undo snackbar in the home fragment - if (sessionManager.sessionsOfType(it.private).count() == 1) { + if (store.state.getNormalOrPrivateTabs(it.content.private).count() == 1) { homeViewModel.sessionToDelete = it.id navController.navigate( BrowserFragmentDirections.actionGlobalHome() ) } else { onCloseTab.invoke(it) - // The removeTab use case does not currently select a parent session, so - // we are using sessionManager.remove - sessionManager.remove(it, selectParentIfExists = true) + tabsUseCases.removeTab(it.id, selectParentIfExists = true) } } } diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarControllerTest.kt index ab7cacbbc..546ae4fea 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarControllerTest.kt @@ -15,17 +15,19 @@ import io.mockk.just import io.mockk.mockk import io.mockk.slot import io.mockk.verify -import mozilla.components.browser.session.Session -import mozilla.components.browser.session.SessionManager import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.ContentAction +import mozilla.components.browser.state.action.TabListAction import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.EngineView import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.session.SessionUseCases +import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.top.sites.TopSitesUseCases +import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.libstate.ext.waitUntilIdle import mozilla.components.support.test.middleware.CaptureActionsMiddleware import mozilla.components.ui.tabcounter.TabCounterMenu @@ -61,17 +63,11 @@ class DefaultBrowserToolbarControllerTest { private lateinit var onTabCounterClicked: () -> Unit @RelaxedMockK - private lateinit var onCloseTab: (Session) -> Unit - - @RelaxedMockK - private lateinit var sessionManager: SessionManager + private lateinit var onCloseTab: (SessionState) -> Unit @MockK(relaxUnitFun = true) private lateinit var engineView: EngineView - @MockK - private lateinit var currentSession: Session - @RelaxedMockK private lateinit var metrics: MetricController @@ -81,6 +77,9 @@ class DefaultBrowserToolbarControllerTest { @RelaxedMockK private lateinit var sessionUseCases: SessionUseCases + @RelaxedMockK + private lateinit var tabsUseCases: TabsUseCases + @RelaxedMockK private lateinit var browserAnimator: BrowserAnimator @@ -103,12 +102,9 @@ class DefaultBrowserToolbarControllerTest { every { activity.components.useCases.sessionUseCases } returns sessionUseCases every { activity.components.useCases.searchUseCases } returns searchUseCases every { activity.components.useCases.topSitesUseCase } returns topSitesUseCase - every { sessionManager.selectedSession } returns currentSession every { navController.currentDestination } returns mockk { every { id } returns R.id.browserFragment } - every { currentSession.id } returns "1" - every { currentSession.private } returns false val onComplete = slot<() -> Unit>() every { browserAnimator.captureEngineViewAndDrawStatically(capture(onComplete)) } answers { onComplete.captured.invoke() } @@ -248,14 +244,6 @@ class DefaultBrowserToolbarControllerTest { @Test fun handleToolbarCloseTabPressWithLastPrivateSession() { val item = TabCounterMenu.Item.CloseTab - val sessions = listOf( - mockk { - every { private } returns true - } - ) - - every { currentSession.private } returns true - every { sessionManager.sessions } returns sessions val controller = createController() controller.handleTabCounterItemInteraction(item) @@ -269,11 +257,13 @@ class DefaultBrowserToolbarControllerTest { fun handleToolbarCloseTabPress() { val item = TabCounterMenu.Item.CloseTab - every { sessionManager.sessions } returns emptyList() + val testTab = createTab("https://www.firefox.com") + store.dispatch(TabListAction.AddTabAction(testTab)).joinBlocking() + store.dispatch(TabListAction.SelectTabAction(testTab.id)).joinBlocking() val controller = createController() controller.handleTabCounterItemInteraction(item) - verify { sessionManager.remove(currentSession, selectParentIfExists = true) } + verify { tabsUseCases.removeTab(testTab.id, selectParentIfExists = true) } } @Test @@ -324,17 +314,17 @@ class DefaultBrowserToolbarControllerTest { private fun createController( activity: HomeActivity = this.activity, - customTabSession: Session? = null + customTabSessionId: String? = null ) = DefaultBrowserToolbarController( store = store, + tabsUseCases = tabsUseCases, activity = activity, navController = navController, metrics = metrics, engineView = engineView, homeViewModel = homeViewModel, - customTabSession = customTabSession, + customTabSessionId = customTabSessionId, readerModeController = readerModeController, - sessionManager = sessionManager, onTabCounterClicked = onTabCounterClicked, onCloseTab = onCloseTab ) From ade15e312ac6f209dc9797495be93486478fcacd Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 14 Feb 2021 15:35:11 +0000 Subject: [PATCH 128/248] Update Android Components version to 73.0.20210213190052. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 8e62e446e..bae65d094 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210212205146" + const val VERSION = "73.0.20210213190052" } From 30738f77b2d9c25b3f626167cf01ff08b3d87930 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 15 Feb 2021 15:34:36 +0000 Subject: [PATCH 129/248] Update Android Components version to 73.0.20210215143146. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index bae65d094..dd3e76ce5 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210213190052" + const val VERSION = "73.0.20210215143146" } From f5cb3a9920f4e89e576f03f1322cd5c8aa67775b Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Tue, 16 Feb 2021 00:04:28 +0000 Subject: [PATCH 130/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 4 ++-- app/src/main/res/values-cy/strings.xml | 6 ++++++ app/src/main/res/values-en-rGB/strings.xml | 6 ++++++ app/src/main/res/values-eo/strings.xml | 11 +++++++++-- app/src/main/res/values-te/strings.xml | 2 ++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 27739e371..d13fff47d 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -181,7 +181,7 @@ - Nun pue conectase porque nun se reconoz l\'esquema de la URL. + Nun ye posible conectase porque nun se reconoz l\'esquema de la URL. @@ -1207,7 +1207,7 @@ en llinia y con nós. ¡Unvióse la llingüeta! - Nun pue unviase + Nun ye posible unviar RETENTAR diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index b29656c9f..f96d976c2 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -130,6 +130,8 @@ Golygu nod tudalen Ychwanegion + + Estyniadau Dim ychwanegion yma @@ -527,6 +529,10 @@ Nodau Tudalen Eraill Hanes + + Tab newydd + + Canfod yn y dudalen Tabiau wedi’u Cydweddu diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 93aa4747f..9cc34c0cd 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -129,6 +129,8 @@ Edit bookmark Add-ons + + Extensions No add-ons here @@ -524,6 +526,10 @@ Other Bookmarks History + + New tab + + Find in page Synchronised tabs diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index a32a44b64..fc99a3785 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -127,6 +127,8 @@ Redakti legosignon Aldonaĵoj + + Etendaĵoj Neniu aldonaĵo estas ĉi tie @@ -527,6 +529,10 @@ Aliaj legosignoj Historio + + Nova langeto + + Serĉi en la paĝo Spegulitaj langetoj @@ -1096,6 +1102,8 @@ Permesoj por retejoj + + Elŝutoj Forigi retumajn datumojn @@ -1218,8 +1226,7 @@ Via privateco - Ni kreis %s por doni al vi la eblon plene regi kion vi dividas -en la reto kaj kion vi dividas kun ni. + Ni kreis %s por doni al vi la eblon plene regi kion vi dividas en la reto kaj kion vi dividas kun ni. Legu nian rimarkon pri privateco diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 25e6030c3..09fc2c4f1 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -507,6 +507,8 @@ చరిత్ర + + కొత్త ట్యాబు సింకైన ట్యాబులు From 23cc3522aa1e5b4a85ae708ac5c4c2f79e7922b0 Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Tue, 16 Feb 2021 11:26:27 +0200 Subject: [PATCH 131/248] For #17484, #18003 UI tests: retry closing tab if it fails --- .../mozilla/fenix/ui/TabbedBrowsingTest.kt | 32 ++----------- .../mozilla/fenix/ui/robots/TabDrawerRobot.kt | 45 ++++++++++++++----- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt index 54b59f22a..73a3a4977 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TabbedBrowsingTest.kt @@ -10,7 +10,6 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior import okhttp3.mockwebserver.MockWebServer import org.junit.After import org.junit.Before -import org.junit.BeforeClass import org.junit.Rule import org.junit.Test import org.mozilla.fenix.helpers.AndroidAssetDispatcher @@ -54,16 +53,6 @@ class TabbedBrowsingTest { } } - // changing the device preference for Touch and Hold delay, to avoid long-clicks instead of a single-click - companion object { - @BeforeClass - @JvmStatic - fun setDevicePreference() { - val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mDevice.executeShellCommand("settings put secure long_press_timeout 3000") - } - } - @After fun tearDown() { mockWebServer.shutdown() @@ -95,16 +84,9 @@ class TabbedBrowsingTest { @Test fun openNewPrivateTabTest() { - homeScreen { }.dismissOnboarding() - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) - homeScreen { }.togglePrivateBrowsingMode() - - homeScreen { - verifyPrivateSessionMessage() - verifyTabButton() - } + homeScreen {}.togglePrivateBrowsingMode() navigationToolbar { }.openNewTabAndEnterToBrowser(defaultWebPage.url) { @@ -112,7 +94,7 @@ class TabbedBrowsingTest { verifyTabCounter("1") }.openTabDrawer { verifyExistingTabList() - verifyCloseTabsButton("Test_Page_1") + verifyPrivateModeSelected() }.toggleToNormalTabs { verifyNoTabsOpened() }.toggleToPrivateTabs { @@ -160,7 +142,6 @@ class TabbedBrowsingTest { }.openNewTabAndEnterToBrowser(genericURL.url) { }.openTabDrawer { verifyExistingOpenTabs("Test_Page_1") - verifyCloseTabsButton("Test_Page_1") closeTabViaXButton("Test_Page_1") verifySnackBarText("Tab closed") snackBarButtonClick("UNDO") @@ -191,8 +172,7 @@ class TabbedBrowsingTest { browserScreen { }.openTabDrawer { verifyExistingOpenTabs("Test_Page_1") - }.openNewTab { - }.dismissSearchBar { } + }.closeTabDrawer { } } @Test @@ -283,8 +263,6 @@ class TabbedBrowsingTest { @Test fun verifyEmptyTabTray() { - homeScreen { }.dismissOnboarding() - navigationToolbar { }.openTabTray { verifyNoTabsOpened() @@ -299,8 +277,6 @@ class TabbedBrowsingTest { @Test fun verifyOpenTabDetails() { - homeScreen { }.dismissOnboarding() - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { @@ -318,8 +294,6 @@ class TabbedBrowsingTest { @Test fun verifyContextMenuShortcuts() { - homeScreen { }.dismissOnboarding() - val defaultWebPage = TestAssetHelper.getGenericAsset(mockWebServer, 1) navigationToolbar { diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index f0fd1cd8c..10bd50d4d 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -86,23 +86,46 @@ class TabDrawerRobot { mDevice.findObject( UiSelector().resourceId("org.mozilla.fenix.debug:id/mozac_browser_tabstray_close") ).waitForExists(waitingTime) - closeTabButton().click() + + var retries = 0 // number of retries before failing, will stop at 2 + do { + closeTabButton().click() + retries++ + } while (mDevice.findObject( + UiSelector().resourceId("org.mozilla.fenix.debug:id/mozac_browser_tabstray_close") + ).exists() && retries < 3 + ) } - fun swipeTabRight(title: String) = - tab(title).perform(ViewActions.swipeRight()) + fun swipeTabRight(title: String) { + var retries = 0 // number of retries before failing, will stop at 2 + while (mDevice.findObject(UiSelector().text(title)).exists() && retries < 3) { + tab(title).perform(ViewActions.swipeRight()) + retries++ + } + } - fun swipeTabLeft(title: String) = - tab(title).perform(ViewActions.swipeLeft()) + fun swipeTabLeft(title: String) { + var retries = 0 // number of retries before failing, will stop at 2 + while (mDevice.findObject(UiSelector().text(title)).exists() && retries < 3) { + tab(title).perform(ViewActions.swipeLeft()) + retries++ + } + } fun closeTabViaXButton(title: String) { - val closeButton = onView( - allOf( - withId(R.id.mozac_browser_tabstray_close), - withContentDescription("Close tab $title") + mDevice.findObject(UiSelector().text(title)).waitForExists(waitingTime) + var retries = 0 // number of retries before failing, will stop at 2 + do { + val closeButton = onView( + allOf( + withId(R.id.mozac_browser_tabstray_close), + withContentDescription("Close tab $title") + ) ) - ) - closeButton.perform(click()) + closeButton.perform(click()) + retries++ + } while (mDevice.findObject(UiSelector().text(title)).exists() && retries < 3) } fun verifySnackBarText(expectedText: String) { From 32493491fa8ddf0e2c350d303bd01d09600d3bbc Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 11 Feb 2021 12:42:05 +0200 Subject: [PATCH 132/248] For #17195 - Test a potential fix for the test --- .../mozilla/fenix/ui/robots/TabDrawerRobot.kt | 34 ++++++++++++++++--- .../taskcluster/androidTest/flank-x86.yml | 8 ++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index 10bd50d4d..2f77988ab 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -7,6 +7,8 @@ package org.mozilla.fenix.ui.robots import android.content.Context +import android.view.InputDevice +import android.view.MotionEvent import android.view.View import androidx.recyclerview.widget.RecyclerView import androidx.test.core.app.ApplicationProvider @@ -15,7 +17,12 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.UiController import androidx.test.espresso.ViewAction +import androidx.test.espresso.action.GeneralClickAction +import androidx.test.espresso.action.GeneralLocation +import androidx.test.espresso.action.Press +import androidx.test.espresso.action.Tap import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.action.ViewActions.actionWithAssertions import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.assertion.ViewAssertions.doesNotExist @@ -255,7 +262,19 @@ class TabDrawerRobot { } fun clickTopBar(interact: TabDrawerRobot.() -> Unit): Transition { - onView(withId(R.id.topBar)).click() + // The topBar contains other views. + // Don't do the default click in the middle, rather click in some free space - top right. + onView(withId(R.id.topBar)).perform( + actionWithAssertions( + GeneralClickAction( + Tap.SINGLE, + GeneralLocation.TOP_RIGHT, + Press.FINGER, + InputDevice.SOURCE_UNKNOWN, + MotionEvent.BUTTON_PRIMARY + ) + ) + ) TabDrawerRobot().interact() return Transition() } @@ -280,8 +299,11 @@ class TabDrawerRobot { } fun waitForTabTrayBehaviorToIdle(interact: TabDrawerRobot.() -> Unit): Transition { + // Need to get the behavior of tab_wrapper and wait for that to idle. var behavior: BottomSheetBehavior<*>? = null - onView(withId(R.id.tab_wrapper)).perform(object : ViewAction { + + // Null check here since it's possible that the view is already animated away from the screen. + onView(withId(R.id.tab_wrapper))?.perform(object : ViewAction { override fun getDescription(): String { return "Postpone actions to after the BottomSheetBehavior has settled" } @@ -294,9 +316,13 @@ class TabDrawerRobot { behavior = BottomSheetBehavior.from(view!!) } }) - runWithIdleRes(BottomSheetBehaviorStateIdlingResource(behavior!!)) { - TabDrawerRobot().interact() + + behavior?.let { + runWithIdleRes(BottomSheetBehaviorStateIdlingResource(it)) { + TabDrawerRobot().interact() + } } + return Transition() } diff --git a/automation/taskcluster/androidTest/flank-x86.yml b/automation/taskcluster/androidTest/flank-x86.yml index 15e72ac14..e1b5ceee8 100644 --- a/automation/taskcluster/androidTest/flank-x86.yml +++ b/automation/taskcluster/androidTest/flank-x86.yml @@ -38,8 +38,9 @@ gcloud: performance-metrics: true test-targets: - - package org.mozilla.fenix.ui - - package org.mozilla.fenix.glean + - package org.mozilla.fenix.ui.TabbedBrowsingTest#verifyTabTrayNotShowingStateHalfExpanded +# - package org.mozilla.fenix.ui +# - package org.mozilla.fenix.glean device: - model: Pixel2 @@ -52,5 +53,4 @@ flank: max-test-shards: 50 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x - num-test-runs: 1 - + num-test-runs: 50 From 611ff8f25bc0ec799acf817f06431708287c4b5f Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 11 Feb 2021 13:48:45 +0200 Subject: [PATCH 133/248] For #17195 - Don't try setting an idle resource if the View is already off screen Speculative fix based on the Firebase logs which shows that on a second check of R.id.tab_wrapper it is not found the screen. It may be because after `advanceToHalfExpandedState` and before getting a reference to it in `waitForTabTrayBehaviorToIdle` it was already animated off the screen. With this in mind I've added a null check for the view reference before trying to register an idling resource on it's Behavior. Also added and used a way to click at a specific location in a View, not just in the default middle in the View. It was observed from the Firebase videos that a "click" on the topBar actually selected the private tabs section. This would leave us to believe that the "click" was caught by that other View which was placed above the x,y middle of the topBar. --- .../fenix/helpers/ext/ViewInteraction.kt | 25 +++++++++++++++++++ .../mozilla/fenix/ui/robots/TabDrawerRobot.kt | 19 ++------------ .../taskcluster/androidTest/flank-x86.yml | 8 +++--- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/ext/ViewInteraction.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/ext/ViewInteraction.kt index 601c450cf..e818a0733 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/ext/ViewInteraction.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/ext/ViewInteraction.kt @@ -4,7 +4,14 @@ package org.mozilla.fenix.helpers +import android.view.InputDevice +import android.view.MotionEvent +import androidx.test.espresso.ViewAction import androidx.test.espresso.ViewInteraction +import androidx.test.espresso.action.GeneralClickAction +import androidx.test.espresso.action.GeneralLocation +import androidx.test.espresso.action.Press +import androidx.test.espresso.action.Tap import androidx.test.espresso.action.ViewActions import androidx.test.espresso.assertion.ViewAssertions.matches @@ -21,3 +28,21 @@ fun ViewInteraction.assertIsChecked(isChecked: Boolean): ViewInteraction { fun ViewInteraction.assertIsSelected(isSelected: Boolean): ViewInteraction { return this.check(matches(isSelected(isSelected)))!! } + +/** + * Perform a click (simulate the finger touching the View) at a specific location in the View + * rather than the default middle of the View. + * + * Useful in situations where the View we want clicked contains other Views in it's x,y middle + * and we need to simulate the touch in some other free space of the View we want clicked. + */ +fun ViewInteraction.clickAtLocationInView(locationInView: GeneralLocation): ViewAction = + ViewActions.actionWithAssertions( + GeneralClickAction( + Tap.SINGLE, + locationInView, + Press.FINGER, + InputDevice.SOURCE_UNKNOWN, + MotionEvent.BUTTON_PRIMARY + ) + ) diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt index 2f77988ab..0f84a9ef0 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/TabDrawerRobot.kt @@ -7,8 +7,6 @@ package org.mozilla.fenix.ui.robots import android.content.Context -import android.view.InputDevice -import android.view.MotionEvent import android.view.View import androidx.recyclerview.widget.RecyclerView import androidx.test.core.app.ApplicationProvider @@ -17,12 +15,8 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.UiController import androidx.test.espresso.ViewAction -import androidx.test.espresso.action.GeneralClickAction import androidx.test.espresso.action.GeneralLocation -import androidx.test.espresso.action.Press -import androidx.test.espresso.action.Tap import androidx.test.espresso.action.ViewActions -import androidx.test.espresso.action.ViewActions.actionWithAssertions import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.action.ViewActions.replaceText import androidx.test.espresso.assertion.ViewAssertions.doesNotExist @@ -51,6 +45,7 @@ import org.mozilla.fenix.helpers.TestAssetHelper import org.mozilla.fenix.helpers.TestAssetHelper.waitingTime import org.mozilla.fenix.helpers.TestHelper.packageName import org.mozilla.fenix.helpers.click +import org.mozilla.fenix.helpers.clickAtLocationInView import org.mozilla.fenix.helpers.ext.waitNotNull import org.mozilla.fenix.helpers.idlingresource.BottomSheetBehaviorStateIdlingResource import org.mozilla.fenix.helpers.matchers.BottomSheetBehaviorHalfExpandedMaxRatioMatcher @@ -264,17 +259,7 @@ class TabDrawerRobot { fun clickTopBar(interact: TabDrawerRobot.() -> Unit): Transition { // The topBar contains other views. // Don't do the default click in the middle, rather click in some free space - top right. - onView(withId(R.id.topBar)).perform( - actionWithAssertions( - GeneralClickAction( - Tap.SINGLE, - GeneralLocation.TOP_RIGHT, - Press.FINGER, - InputDevice.SOURCE_UNKNOWN, - MotionEvent.BUTTON_PRIMARY - ) - ) - ) + onView(withId(R.id.topBar)).clickAtLocationInView(GeneralLocation.TOP_RIGHT) TabDrawerRobot().interact() return Transition() } diff --git a/automation/taskcluster/androidTest/flank-x86.yml b/automation/taskcluster/androidTest/flank-x86.yml index e1b5ceee8..15e72ac14 100644 --- a/automation/taskcluster/androidTest/flank-x86.yml +++ b/automation/taskcluster/androidTest/flank-x86.yml @@ -38,9 +38,8 @@ gcloud: performance-metrics: true test-targets: - - package org.mozilla.fenix.ui.TabbedBrowsingTest#verifyTabTrayNotShowingStateHalfExpanded -# - package org.mozilla.fenix.ui -# - package org.mozilla.fenix.glean + - package org.mozilla.fenix.ui + - package org.mozilla.fenix.glean device: - model: Pixel2 @@ -53,4 +52,5 @@ flank: max-test-shards: 50 # num-test-runs: the amount of times to run the tests. # 1 runs the tests once. 10 runs all the tests 10x - num-test-runs: 50 + num-test-runs: 1 + From 74ee459c114b140c1423b2dbedd3b3c71371b6eb Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Wed, 10 Feb 2021 14:10:40 +0100 Subject: [PATCH 134/248] Issue #17819: Get leanplum artifacts from leanplum repository. --- build.gradle | 19 +++++++----- .../toolchain/android-gradle-dependencies.sh | 2 +- .../android-gradle-dependencies/after.sh | 1 + .../android-gradle-dependencies/nexus.xml | 31 +++++++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 356605f2a..093a4fcd2 100644 --- a/build.gradle +++ b/build.gradle @@ -146,13 +146,6 @@ allprojects { // https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/ //////////////////////////////////////////////////////////////////////////////// - // Leanplum - // The docs mention a custom repository (repo.leanplum.com) that we may be able - // to switch to. - includeVersion("com.leanplum", "leanplum-core", "5.4.0") - includeVersion("com.leanplum", "leanplum-push", "5.4.0") - includeVersion("com.leanplum", "leanplum-fcm", "5.4.0") - // Used by Android Gradle Plugin // Issue for publishing to maven central: https://youtrack.jetbrains.com/issue/IDEA-261387 // Related plugin issue: https://issuetracker.google.com/issues/179291081 @@ -174,6 +167,18 @@ allprojects { } } } + + maven { + name "LeanplumRepo" + if (project.hasProperty("leanplumRepo")) { + url project.property("leanplumRepo") + } else { + url "https://repo.leanplum.com" + } + content { + includeGroup("com.leanplum") + } + } } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { diff --git a/taskcluster/scripts/toolchain/android-gradle-dependencies.sh b/taskcluster/scripts/toolchain/android-gradle-dependencies.sh index 7117fe288..ece18653a 100755 --- a/taskcluster/scripts/toolchain/android-gradle-dependencies.sh +++ b/taskcluster/scripts/toolchain/android-gradle-dependencies.sh @@ -19,7 +19,7 @@ pushd $PROJECT_DIR . taskcluster/scripts/toolchain/android-gradle-dependencies/before.sh NEXUS_PREFIX='http://localhost:8081/nexus/content/repositories' -GRADLE_ARGS="--parallel -PgoogleRepo=$NEXUS_PREFIX/google/ -PjcenterRepo=$NEXUS_PREFIX/jcenter/ -PcentralRepo=$NEXUS_PREFIX/central/" +GRADLE_ARGS="--parallel -PgoogleRepo=$NEXUS_PREFIX/google/ -PjcenterRepo=$NEXUS_PREFIX/jcenter/ -PcentralRepo=$NEXUS_PREFIX/central/ -PleanplumRepo=$NEXUS_PREFIX/leanplum/" # We build everything to be sure to fetch all dependencies ./gradlew $GRADLE_ARGS assemble assembleAndroidTest testClasses ktlint detekt # Some tests may be flaky, although they still download dependencies. So we let the following diff --git a/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh b/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh index eed8d01fb..430974e5a 100644 --- a/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh +++ b/taskcluster/scripts/toolchain/android-gradle-dependencies/after.sh @@ -23,6 +23,7 @@ mkdir -p android-gradle-dependencies /builds/worker/artifacts cp -R ${NEXUS_WORK}/storage/jcenter android-gradle-dependencies cp -R ${NEXUS_WORK}/storage/google android-gradle-dependencies cp -R ${NEXUS_WORK}/storage/central android-gradle-dependencies +cp -R ${NEXUS_WORK}/storage/leanplum android-gradle-dependencies tar cf - android-gradle-dependencies | xz > /builds/worker/artifacts/android-gradle-dependencies.tar.xz diff --git a/taskcluster/scripts/toolchain/android-gradle-dependencies/nexus.xml b/taskcluster/scripts/toolchain/android-gradle-dependencies/nexus.xml index 2b40bedf3..1dfc16205 100644 --- a/taskcluster/scripts/toolchain/android-gradle-dependencies/nexus.xml +++ b/taskcluster/scripts/toolchain/android-gradle-dependencies/nexus.xml @@ -54,6 +54,37 @@ true + + leanplum + leanplum + org.sonatype.nexus.proxy.repository.Repository + maven2 + IN_SERVICE + true + 1440 + true + true + true + READ_ONLY + true + true + + file + + + https://repo.leanplum.com/ + + + RELEASE + STRICT + true + false + -1 + 1440 + 1440 + true + + gradle-plugins Gradle Plugins From a89e13bf73b6eebffcdd3a2235b618af3da86e3a Mon Sep 17 00:00:00 2001 From: Ben Hearsum Date: Tue, 16 Feb 2021 11:47:16 -0500 Subject: [PATCH 135/248] Don't run tasks for mergify branches on push (#17489) --- .taskcluster.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.taskcluster.yml b/.taskcluster.yml index e11debf8a..2e71a5c7b 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -103,7 +103,7 @@ tasks: $if: > tasks_for in ["action", "cron"] || (tasks_for == "github-pull-request" && pullRequestAction in ["opened", "reopened", "synchronize"]) - || (tasks_for == "github-push" && head_branch[:10] != "refs/tags/") && (head_branch != "staging.tmp") && (head_branch != "trying.tmp") + || (tasks_for == "github-push" && head_branch[:10] != "refs/tags/") && (head_branch != "staging.tmp") && (head_branch != "trying.tmp") && (head_branch[:8] != "mergify/") || (tasks_for == "github-release" && releaseAction == "published" && (ownerEmail != "mozilla-release-automation-bot@users.noreply.github.com") && (ownerEmail != "mozilla-release-automation-bot-staging@users.noreply.github.com")) then: $let: From 2ceb65125418ea7615b0a80b58b5f603f0304486 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 16 Feb 2021 15:37:23 +0000 Subject: [PATCH 136/248] Update Android Components version to 73.0.20210216143146. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index dd3e76ce5..7bfa4b60c 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210215143146" + const val VERSION = "73.0.20210216143146" } From 3e9ab1b1508d58883a62f66aa932098413e1643c Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Mon, 15 Feb 2021 10:10:45 +0100 Subject: [PATCH 137/248] Glean: Check for renamed reason --- .../java/org/mozilla/fenix/glean/BaselinePingTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt b/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt index afcc8d50e..c3a26ae21 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/glean/BaselinePingTest.kt @@ -152,7 +152,7 @@ class BaselinePingTest { .click() // Validate the received data. - val baselinePing = waitForPingContent("baseline", "background")!! + val baselinePing = waitForPingContent("baseline", "inactive")!! val metrics = baselinePing.getJSONObject("metrics") From db6bd915ae962dd3c4a8fb779bc7acf1cfd0d98b Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Tue, 16 Feb 2021 15:38:04 -0500 Subject: [PATCH 138/248] Update Android Components version to 73.0.20210216190306 --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 7bfa4b60c..41551c7bb 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210216143146" + const val VERSION = "73.0.20210216190306" } From dfc5628ca114e10e658b034afe2e89332e10bc12 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Wed, 17 Feb 2021 00:06:16 +0000 Subject: [PATCH 139/248] Import l10n. --- app/src/main/res/values-cak/strings.xml | 11 +- app/src/main/res/values-fr/strings.xml | 6 + app/src/main/res/values-hi-rIN/strings.xml | 6 + app/src/main/res/values-ja/strings.xml | 6 + app/src/main/res/values-ka/strings.xml | 6 + app/src/main/res/values-tl/strings.xml | 525 +++++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 2 +- 7 files changed, 559 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-cak/strings.xml b/app/src/main/res/values-cak/strings.xml index f5964eabf..2f8dc2818 100644 --- a/app/src/main/res/values-cak/strings.xml +++ b/app/src/main/res/values-cak/strings.xml @@ -135,6 +135,8 @@ Taq tz\'aqat + + Taq k\'amal Majun tz\'aqat wakami @@ -547,6 +549,10 @@ Ch\'aqa\' chik taq Yaketal Natab\'äl + + K\'ak\'a\' ruwi\' + + Tikanöx pa ruxaq Ximon taq ruwi\' @@ -1118,6 +1124,8 @@ Taq ruya\'oj q\'ij ruxaq + + Taq qasanïk Keyuj taq rutzij okem pa k\'amaya\'l @@ -1243,8 +1251,7 @@ - Xqawachib\'ej %s richin nachajij ri nakomonij - pa k\'amab\'ey chuqa\' ri nakomonij qik\'in. + Xqawachib\'ej %s richin nachajij ri nakomonij pa k\'amab\'ey chuqa\' ri nakomonij qik\'in. Tasik\'ij ri rutzijol qichinanem diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2c88e7fb3..e488d63f4 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -131,6 +131,8 @@ Modifier le marque-page Modules complémentaires + + Extensions Aucun module ici @@ -537,6 +539,10 @@ Autres marque-pages Historique + + Nouvel onglet + + Rechercher dans la page Onglets synchronisés diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index c6f044e44..5e972d85c 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -472,6 +472,8 @@ अन्य बुकमार्क इतिहास + + नया टैब सिंक हुए टैब @@ -629,6 +631,10 @@ यहां कोई इतिहास नहीं + + खोलें + + माफ़ कीजिए। %1$s उस पृष्ठ को लोड नहीं कर सकता हैं। diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 0cb6e8306..d01111e83 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -133,6 +133,8 @@ ブックマークを編集 アドオン + + 拡張機能 アドオンがありません @@ -537,6 +539,10 @@ 他のブックマーク 履歴 + + 新しいタブ + + ページ内検索 同期したタブ diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 101644b65..9a06d3b3c 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -127,6 +127,8 @@ სანიშნის ჩასწორება დამატებები + + გაფართოებები დამატებები არ არის @@ -526,6 +528,10 @@ სხვა სანიშნები ისტორია + + ახალი ჩანართი + + პოვნა გვერდზე დასინქრონებული ჩანართები diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index 93f5ed5e4..22c3f7cce 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -113,6 +113,8 @@ i-Edit ang Bookmark Mga Add-on + + Mga extension Walang mga add-on dito @@ -175,6 +177,9 @@ Sundin ang wika sa device + + Wika ng paghanap + i-Scan @@ -193,6 +198,8 @@ Payagan ang mga mungkahi sa paghahanap sa mga pribadong session? + + Ibabahagi ng %s ang lahat ng ita-type mo sa address bar sa iyong default na search engine. Alamin @@ -216,6 +223,8 @@ Pangkalahatan Tungkol sa + + Default na search engine Hanapin @@ -237,6 +246,8 @@ Mga credit card at tirahan Itakda bilang default browser + + Advanced Pribasiya @@ -249,10 +260,18 @@ Buksan ang mga link sa pribadong tab Payagan ang mga screenshot sa private browsing + + Kapag pinayagan, makikita rin ang mga pribadong tab kapag maraming nakabukas na app Magdagdag ng private browsing shortcut Accessibility + + Pasadya na Firefox Account server + + Pasadya na Sync server + + Nabago ang Firefox Account/Sync server. Magsasara na ang application para mailapat ang mga pagbabago… Account @@ -281,6 +300,8 @@ Mga pamimilian sa data Pagkolekta ng data + + Paunawa sa privacy Developer tools @@ -316,6 +337,9 @@ Mga abiso + + + Pasadyang koleksyon ng mga Add-on OK @@ -327,6 +351,9 @@ May-ari ng collection (User ID) + + Nabago ang Add-on collection. Magsasara na ang application para mailapat ang mga pagbabago… + Hindi suportado ang add-on @@ -371,6 +398,8 @@ Mga natanggap na tab + + Mga abiso para sa mga tab na natanggap mula sa ibang mga Firefox device. May natanggap na tab @@ -396,17 +425,28 @@ Alamin + + Nakasara sa pangkalahatan, pumunta sa Mga Setting para buksan ito. + Telemetry Usage at technical data + + Ibinabahagi sa Mozilla ang datos patungkol sa performance, paggamit, hardware at customization sa browser mo para mapaganda lalo ang %1$s Marketing data + + Ibinabahagi ang datos tungkol sa mga feature na ginagamit mo sa %1$s kay Leanplum, ang aming mobile marketing vendor. Mga pag-aaral + + Pinapayagan ang Mozilla para magkabit at magpatakbo ng mga pag-aaral Mga eksperimento + + Pinapayagan ang Mozilla para magkabit at magkolekta ng datos para sa mga eksperimental na feature Crash reporter @@ -447,6 +487,8 @@ Madilim + + Nakatakda sa Battery Saver Sundin ang tema ng device @@ -479,6 +521,10 @@ Iba pang mga Bookmark Kasaysayan + + Bagong tab + + Hanapin sa pahina Mga naka-sync na tab @@ -568,6 +614,8 @@ Isara Ibahagi ang mga piniling mga tab + + Tanggalin ang tab sa collection Piliin ang mga tab @@ -703,6 +751,8 @@ Ibahagi ang session + + i-Edit ang bookmark Pumili ng folder @@ -777,12 +827,46 @@ Mga permiso Pumunta sa mga Setting + + Inirerekomenda + + Autoplay Camera Mikropono Lokasyon + + Mga abiso + + Persistent Storage + + DRM-controlled content + + Tanungin para payagan + + Hinarang + + Pinapayagan + + Hinarang ng Android + + Mga exception + + Nakabukas + + Nakasara + + Payagan ang audio at video + + Harangin ang audio at video kapag naka-cellular data lamang + + Aandar ang audio at video sa Wi-Fi + + Harangin ang audio lamang + + Harangin ang audio at video On @@ -791,22 +875,463 @@ Mga Koleksyon + + Collection menu + + Kolektahin ang mga bagay na mahalaga sa iyo.\nPangkatin ang mga magkakatulad na hinahanap, site, at tab para madaling makuha sa susunod. + + Piliin ang mga Tab + + Piliin ang collection + + Pangalanan ang collection + + Magdagdag ng bagong collection Piliin lahat + + Tanggalin lahat sa pagkakapili + + Piliin ang mga tab na ise-save + + %d piniling mga tab + + %d piniling tab + + Na-save na ang mga tab! + + Na-save na ang collection! + + Na-save na ang tab! Isara + + i-Save + + Tingnan + + + Ika-%d collection + + + + Ipadala at Ibahagi Ibahagi Ibahagi + + Magbahagi ng link + + Ipadala sa device + + Lahat ng pagkilos + + Kagagamit lamang + + Mag-sign in sa Sync + + Ipadala sa lahat ng mga device + + Kumonekta muli sa Sync + + Offline + + Magkonekta ng isa pang device + + Para makapagpadala ng tab, mag-sign in sa Firefox sa isa pang device. + + Nakuha ko + + Hindi kayang maibahagi sa app na ito + + Ipadala sa device + + Walang Nakakonektang mga Device + + Alamin ang Tungkol sa Pagpapadala ng mga Tab… + + Magkonekta ng Isa Pang Device… + + + + Private browsing session + + Burahin ang mga pribadong tab + + Isara ang mga pribadong tab + + Buksan + + Burahin at Buksan + + Pinatatakbo Ng + + Nabura na ang collection + + Nabago na ang pangalan ng collection + + Nabura na ang tab + + Nabura na ang mga tab + + Naisara na ang tab + + Naisara na ang mga tab + + Naisara na ang mga tab! + + Na-save na ang mga bookmark! Tingnan + + Naidagdag na sa mga top site! + + Naisara na ang pribadong tab + + Naisara na ang mga pribadong tab + + Nabura na ang mga pribadong tab + + i-UNDO + + Natanggal na ang site + + i-Undo + + Kumpirmahin + + Payagan ang %1$s na buksan ang %2$s + + PAYAGAN + + TANGGIHAN + + Sigurado ka bang gusto mong burahin ang %1$s? + + Ang pagbura sa tab na ito ay magdudulot ng pagkabura ng buong collection. Maaari kang gumawa ng bagong collection anumang oras. + + Burahin ang %1$s? + + Burahin + + Kanselahin + + Pumapasok sa full screen mode Kopyahin ang URL + + Ito ay halimbawa lamang. Nandito ang tekstong ito para maipakita ang itsura kapag nilakihan o niliitan ang sukat sa setting na ito. + + Palakihin o paliitin ang teksto sa mga website + + Laki ng Font + + + Awtomatikong sukat ng font + + Ang laki ng font ay itatapat sa setting sa iyong Android. I-disable para ma-manage ang laki ng font dito. + + + Burahin ang browsing data + + Mga nakabukas na tab + + %d tab + + %d address + + Kasaysayan + + %d pahina + + Mga cookie + + Mala-log out ka sa karamihan ng mga site + + Mga naka-cache na larawan at file + + Mga site permission + + Mga download + + Burahin ang browsing data + + Burahin ang browsing data sa pag-alis + + Kusang magbubura ng browsing data kapag pinili mo ang "Umalis" mula sa main menu + + + Kusang magbubura ng browsing data kapag pinili mo ang \"Umalis\" mula sa main menu + + Umalis + + + Buburahin nito lahat ng iyong browsing data. + + Buburahin ng %s ang mga napiling browsing data. + + Kanselahin + + Burahin + + Nabura na ang browsing data + + Binubura ang browsing data… + + + + Ang Firefox Preview ay Firefox Nightly na ngayon + + + Gabi-gabing naa-update ang Firefox Nightly at may mga eksperimental na bagong feature. + Subalit maaari itong maging sirain. I-download ang aming beta browser para sa mas panatag na karanasan. + + Kunin ang Firefox para sa Android Beta + + + Lumipat na ang Firefox Nightly + + + Ang app na ito ay hindi na makatatanggap ng mga security update. Tigilan nang gamitin ang app na ito at lumipat na sa bagong Nightly. + \n\nPara mailipat ang iyong mga bookmark, login, at kasaysayan sa isa pang app, gumawa ng isang Firefox account. + + Lumipat na sa bagong Nightly + + + Lumipat na ang Firefox Nightly + + + Ang app na ito ay hindi na makatatanggap ng mga security update. Kunin na ang bagong Nightly at tigilan nang gamitin ang app na ito. + \n\nPara mailipat ang iyong mga bookmark, login, at kasaysayan sa isa pang app, gumawa ng isang Firefox account. + + Kunin na ang bagong Nightly + + + + Maligayang pagdating sa %s! + + Mayroon nang account? + + Kilalanin ang %s + + Tingnan kung ano ang bago + + May mga katanungan tungkol sa bagong-disenyong %s? Nais malaman alin ang nabago? + + Kumuha ng mga kasagutan dito + + Magsimulang mag-sync ng mga bookmark, password, at iba pa gamit ang iyong Firefox account. + + + Alamin + + Naka-sign in ka bilang %s sa isa pang Firefox browser sa device na ito. Nais mo bang mag-sign in gamit ito? + + Oo, i-sign in mo ako + + Nagsa-sign in… + + Mag-sign in sa Firefox + + Manatiling naka-sign out + + Nakabukas ang Sync + + Bigong makapag-sign-in + + Karaniwan (default) + + Humaharang ng mas kaunting mga tracker. Normal na maglo-load ang mga pahina. + + Mahigpit (inirerekomenda) + + Mahigpit + + Humaharang ng mas maraming mga tracker, ad, at popup. Mas mabilis maglo-load ang mga pahina, pero baka may mga bagay na hindi gagana. + + Makibaka + + Subukan ang pag-browse sa isang kamay gamit ang toolbar sa ibaba o ilipat ito sa tuktok. + + Mag-browse nang pribado + + Magbukas ng isang pribadong tab: I-tap ang %s icon. + + Magbukas ng pribadong tab sa bawat pagkakataon: I-update ang iyong mga setting sa pribadong pag-browse. + + Buksan ang mga setting + + Ang iyong pribasiya + + + Dinisenyo namin ang %s para bigyan ka ng kontrol sa mga ibinahabagi mo online at kung ano ang ibinabahagi mo sa amin. + + Basahin ang aming paunawa sa privacy + + Isara + + + Simulan nang mag-browse + + + + Pumili ng iyong tema + + Makatipid sa baterya at iyong paningin gamit ang dark mode. + + Kusa + + Umaangkop sa mga setting ng iyong device + + Madilim na tema + + Maliwanag na tema + + + Napadala na ang mga tab! + + Napadala na ang tab! + + Bigong mapadala + + SUBUKAN MULI + + I-scan ang code + + https://firefox.com/pair]]> + + Handa nang mag-scan + + Mag-sign in gamit ang iyong camera + + Gumamit na lang ng email + + Gumawa ng isa para makapag-sync ng Firefox sa mga device.]]> + + Titigil na ang Firefox sa pag-sync sa iyong account, pero hindi nito buburahin ang kahit anong browsing data sa device na ito. + + Titigil na ang %s sa pag-sync sa iyong account, pero hindi nito buburahin ang kahit anong browsing data sa device na ito. + + Mag-disconnect + + Kanselahin + + Hindi ma-edit ang mga default folder + + + + Mga Protection Setting + + Enhanced Tracking Protection + + Mag-browse nang hindi sinusundan + + Itago mo ang data na para sa iyo lamang. Pinoprotektahan ka ng %s mula sa mga pinakakaraniwang tracker na nagmamanman sa mga gawain mo online. + + Alamin + + Karaniwan (default) + + Humaharang ng mas kaunting mga tracker. Normal na maglo-load ang mga pahina. + + Ano ang mga hinaharang sa karaniwang tracking protection + + Mahigpit + + Humaharang ng mas maraming mga tracker, ad, at popup. Mas mabilis maglo-load ang mga pahina, pero baka may mga bagay na hindi gagana. + + Ano ang mga hinaharang sa mahigpit na tracking protection + + Pasadya + + + Piliin kung aling mga tracker at script ang dapat harangin. + + Ano ang mga hinaharang sa pasadyang tracking protection + + + Mga cookie + + Mga cross-site at social media tracker + + Mga cookie mula sa mga hindi pa nabisitang site + + Lahat ng mga third-party na cookie (maaaring maging sanhi upang masira ang mga website) + + Lahat ng mga cookie (tiyak na ikasisira ng mga website) + + Tracking content + + Sa lahat ng mga tab + + Sa mga Pribadong tab lamang + + Sa mga Pasadyang tab lamang + + Mga cryptominer + + Mga fingerprinter + Hinarang + + Pinapayagan + + Mga Social Media Tracker + + Nililimitahan ang kakayahan ng mga social network para subaybayan ang iyong browsing activity sa web. + + Mga Cross-Site Tracking Cookie + + Hinaharang ang mga cookie na ginagamit ng mga ad network at analytics company para pagsama-samahin ang iyong browsing data sa iba\'t-ibang mga site. + + Mga cryptominer + + Mga fingerprinter + + Tracking Content + + Pinipigilang mag-load ang mga panlabas na mga ad, video, at iba pang content na nagtataglay ng tracking code. Maaaring maapektuhan ang ilang aspeto ng website. + + Tuwing kulay lila ang kalasag, may naharang na mga tracker ang %s sa site. I-tap para sa karagdagang impormasyon. + + NAKABUKAS ang mga protection sa site na ito + + SARADO ang mga protection sa site na ito + + Sarado ang Enhanced Tracking Protection sa mga website na ito + + Bumalik + + Ang iyong mga karapatan + + Mga open source library na ginagamit namin + + Ano’ng bago sa %s + + %s | Mga OSS Library + + Mga Redirect Tracker + Kopyahin diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d7137ead5..e7b592867 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -898,7 +898,7 @@ 阻止 - 已允许 + 允许 被 Android 阻止 From 4e4bbcc334b0b4817d5bd95ed76dee1bbdd5320d Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Wed, 17 Feb 2021 15:23:41 +0200 Subject: [PATCH 140/248] For #16317: resets long press delay at the end of UI tests --- .../fenix/helpers/HomeActivityTestRule.kt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt index 10b8b5d33..797105dfe 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt @@ -27,9 +27,14 @@ class HomeActivityTestRule( ActivityTestRule(HomeActivity::class.java, initialTouchMode, launchActivity) { override fun beforeActivityLaunched() { super.beforeActivityLaunched() - setLongTapTimeout() + setLongTapTimeout("3000") if (skipOnboarding) { skipOnboardingBeforeLaunch() } } + + override fun afterActivityFinished() { + super.afterActivityFinished() + setLongTapTimeout("400") + } } /** @@ -48,15 +53,20 @@ class HomeActivityIntentTestRule( IntentsTestRule(HomeActivity::class.java, initialTouchMode, launchActivity) { override fun beforeActivityLaunched() { super.beforeActivityLaunched() - setLongTapTimeout() + setLongTapTimeout("3000") if (skipOnboarding) { skipOnboardingBeforeLaunch() } } + + override fun afterActivityFinished() { + super.afterActivityFinished() + setLongTapTimeout("400") + } } // changing the device preference for Touch and Hold delay, to avoid long-clicks instead of a single-click -fun setLongTapTimeout() { +fun setLongTapTimeout(delay: String) { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) - mDevice.executeShellCommand("settings put secure long_press_timeout 3000") + mDevice.executeShellCommand("settings put secure long_press_timeout $delay") } private fun skipOnboardingBeforeLaunch() { From b6fb9e4f2e7b81eb16d8cd5501a7cd97bd61afb3 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Wed, 17 Feb 2021 15:33:40 +0000 Subject: [PATCH 141/248] Update Android Components version to 73.0.20210217143150. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 41551c7bb..c36591b84 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210216190306" + const val VERSION = "73.0.20210217143150" } From 56914cd42d094173946f55ea7e1d4ce0d7f25b0a Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Thu, 17 Dec 2020 14:28:30 +1100 Subject: [PATCH 142/248] Reset experiment telemetry identifiers on data prefs change. When the user opts out of telemetry, we need to reset the user identifiers used by the experiment system, so that there's no risk of tracking the user across the reset event if they later decide to re-enable telemetry. --- .../java/org/mozilla/fenix/settings/DataChoicesFragment.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt index 03f7d5deb..ca0229a2a 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/DataChoicesFragment.kt @@ -31,6 +31,10 @@ class DataChoicesFragment : PreferenceFragmentCompat() { } else { context.components.analytics.metrics.stop(MetricServiceType.Data) } + // Reset experiment identifiers on both opt-in and opt-out; it's likely + // that in future we will need to pass in the new telemetry client_id + // to this method when the user opts back in. + context.components.analytics.experiments.resetTelemetryIdentifiers() } else if (key == getPreferenceKey(R.string.pref_key_marketing_telemetry)) { if (context.settings().isMarketingTelemetryEnabled) { context.components.analytics.metrics.start(MetricServiceType.Marketing) From 7e70eccca099579cb63394c48839a0998ad098bc Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Thu, 18 Feb 2021 00:09:18 +0000 Subject: [PATCH 143/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 12 ++++++++++++ app/src/main/res/values-be/strings.xml | 6 ++++++ app/src/main/res/values-hu/strings.xml | 6 ++++++ app/src/main/res/values-in/strings.xml | 6 ++++++ app/src/main/res/values-oc/strings.xml | 6 ++++++ 5 files changed, 36 insertions(+) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index d13fff47d..43f581789 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -130,6 +130,8 @@ Amestar a marcadores Complementos + + Estensiones Equí nun hai complementos @@ -289,6 +291,8 @@ Modificóse\'l sirvidor de cuentes/sincronización de Firefox. Colando de l\'aplicación p\'aplicar los cambeos… Cuenta + + Aniciar sesión Barra de ferramientes @@ -351,6 +355,8 @@ Encaboxar + + Nome de la coleición Modificóse la coleición de complementos. L\'aplicación va zarrase p\'aplicar los cambeos… @@ -454,6 +460,8 @@ Activación de Sync + + Aniciar sesión Aniciar sesión pa reconectar @@ -519,6 +527,8 @@ Axustes + + Menú d\'un elementu del historial Zarrar @@ -1603,6 +1613,8 @@ en llinia y con nós. El campu de testu editable pal nome d\'usuariu del aniciu de sesión. El campu de testu editable pa la contraseña del aniciu de sesión. + + Escartar los cambeos Edición diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 38df7ab9c..b85bf1509 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -128,6 +128,8 @@ Рэдагаваць закладку Дадаткі + + Пашырэнні Няма дадаткаў @@ -531,6 +533,10 @@ Іншыя закладкі Гісторыя + + Новая картка + + Знайсці на старонцы Сінхранізаваныя карткі diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 8a40ad023..d0876285c 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -130,6 +130,8 @@ Könyvjelző szerkesztése Kiegészítők + + Kiegészítők Nincsenek kiegészítők @@ -532,6 +534,10 @@ Más könyvjelzők Előzmények + + Új lap + + Keresés az oldalon Szinkronizált lapok diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 95a0295e8..51fe05685 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -132,6 +132,8 @@ Edit markah Pengaya + + Ekstensi Tidak ada pengaya di sini @@ -540,6 +542,10 @@ Markah Lain Riwayat + + Tab baru + + Temukan di laman Tab yang disinkronkan diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index dab397e11..cbe0452dd 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -129,6 +129,8 @@ Modificar lo marcapagina Moduls + + Extensions Cap d’extension aquí @@ -532,6 +534,10 @@ Autres marcapaginas Istoric + + Onglet novèl + + Recercar dins la pagina Onglets sincronizats From d7f1117e17d16a712c65a10868c89e0baafe524f Mon Sep 17 00:00:00 2001 From: Oana Horvath Date: Thu, 18 Feb 2021 11:37:16 +0200 Subject: [PATCH 144/248] For #16317 UI tests: save longTap preference to restore it --- .../mozilla/fenix/helpers/HomeActivityTestRule.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt index 797105dfe..a3f049647 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/helpers/HomeActivityTestRule.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.helpers +import android.view.ViewConfiguration.getLongPressTimeout import androidx.test.espresso.intent.rule.IntentsTestRule import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.ActivityTestRule @@ -25,15 +26,17 @@ class HomeActivityTestRule( private val skipOnboarding: Boolean = false ) : ActivityTestRule(HomeActivity::class.java, initialTouchMode, launchActivity) { + private val longTapUserPreference = getLongPressTimeout() + override fun beforeActivityLaunched() { super.beforeActivityLaunched() - setLongTapTimeout("3000") + setLongTapTimeout(3000) if (skipOnboarding) { skipOnboardingBeforeLaunch() } } override fun afterActivityFinished() { super.afterActivityFinished() - setLongTapTimeout("400") + setLongTapTimeout(longTapUserPreference) } } @@ -51,20 +54,22 @@ class HomeActivityIntentTestRule( private val skipOnboarding: Boolean = false ) : IntentsTestRule(HomeActivity::class.java, initialTouchMode, launchActivity) { + private val longTapUserPreference = getLongPressTimeout() + override fun beforeActivityLaunched() { super.beforeActivityLaunched() - setLongTapTimeout("3000") + setLongTapTimeout(3000) if (skipOnboarding) { skipOnboardingBeforeLaunch() } } override fun afterActivityFinished() { super.afterActivityFinished() - setLongTapTimeout("400") + setLongTapTimeout(longTapUserPreference) } } // changing the device preference for Touch and Hold delay, to avoid long-clicks instead of a single-click -fun setLongTapTimeout(delay: String) { +fun setLongTapTimeout(delay: Int) { val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) mDevice.executeShellCommand("settings put secure long_press_timeout $delay") } From af9c32983f5c3faf90a3817880205e19deb9342a Mon Sep 17 00:00:00 2001 From: mcarare Date: Wed, 17 Feb 2021 18:51:01 +0200 Subject: [PATCH 145/248] For #17807: Fix systemWindowInset deprecation. --- .../mozilla/fenix/tabtray/TabTrayDialogFragment.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index 05b34235a..664206d32 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -44,6 +44,9 @@ import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.view.showKeyboard +import mozilla.components.support.utils.ext.bottom +import mozilla.components.support.utils.ext.left +import mozilla.components.support.utils.ext.right import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavGraphDirections import org.mozilla.fenix.R @@ -244,13 +247,13 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler view.tabLayout.setOnApplyWindowInsetsListener { v, insets -> v.updatePadding( - left = insets.systemWindowInsetLeft, - right = insets.systemWindowInsetRight, - bottom = insets.systemWindowInsetBottom + left = insets.left(), + right = insets.right(), + bottom = insets.bottom() ) tabTrayView.view.tab_wrapper.updatePadding( - bottom = insets.systemWindowInsetBottom + bottom = insets.bottom() ) insets From 9b65e6342299993c2144d361240b16541213d164 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Thu, 18 Feb 2021 15:00:36 +0100 Subject: [PATCH 146/248] Closes #18006: DefaultSessionControlControllerTest: Correctly unmock SearchStateKt class. The test class left SearchStateKt mocked and caused other tests to fail intermittently when running after it. --- .../mozilla/fenix/home/DefaultSessionControlControllerTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 6025ba8b3..794d34039 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -468,7 +468,7 @@ class DefaultSessionControlControllerTest { ) } } finally { - unmockkStatic(SearchState::class) + unmockkStatic("mozilla.components.browser.state.state.SearchStateKt") } } From 6908526aae6a3afaf77a12d8c5cd16046a35c0dd Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 18 Feb 2021 15:43:28 +0000 Subject: [PATCH 147/248] Update Android Components version to 73.0.20210218143118. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index c36591b84..fac632fa5 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210217143150" + const val VERSION = "73.0.20210218143118" } From 2193be27b20c4cb366e208da3ce2a598cf5e9255 Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 18 Feb 2021 13:15:00 -0300 Subject: [PATCH 148/248] Solves Leaks on SavedLoginFragment disables options menu to avoid leak removes on click listener to avoid leak --- .../fenix/settings/logins/fragment/SavedLoginsFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt index 130e856a6..9339dcdbe 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/logins/fragment/SavedLoginsFragment.kt @@ -150,6 +150,8 @@ class SavedLoginsFragment : Fragment() { toolbarChildContainer.visibility = View.GONE (activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().setDisplayShowTitleEnabled(true) sortingStrategyMenu.menuController.dismiss() + sortLoginsMenuRoot.setOnClickListener(null) + setHasOptionsMenu(false) redirectToReAuth(listOf(R.id.loginDetailFragment), findNavController().currentDestination?.id) super.onPause() From 6270c8da8c37cd9cdd96636fc168af42edc21c0d Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Thu, 18 Feb 2021 12:02:52 -0500 Subject: [PATCH 149/248] Workflow to build contributor PRs (#17843) --- .github/workflows/build-contributor-pr.yml | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 .github/workflows/build-contributor-pr.yml diff --git a/.github/workflows/build-contributor-pr.yml b/.github/workflows/build-contributor-pr.yml new file mode 100644 index 000000000..969873a67 --- /dev/null +++ b/.github/workflows/build-contributor-pr.yml @@ -0,0 +1,103 @@ +name: Android build PR +on: [pull_request] +jobs: + run-build: + runs-on: ubuntu-20.04 + if: github.repository != 'mozilla-mobile/fenix' + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: "Clean & Assemble Debug" + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: clean app:assembleDebug + + run-testDebugUnitTest: + runs-on: ubuntu-20.04 + if: github.repository != 'mozilla-mobile/fenix' + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: "Test Debug Unit Tests" + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: testDebugUnitTest + + run-detekt: + runs-on: ubuntu-20.04 + if: github.repository != 'mozilla-mobile/fenix' + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: "Detekt" + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: detekt + - name: Archive detekt results + uses: actions/upload-artifact@v2 + with: + name: detekt report + path: build/reports/detekt.html + + run-ktlint: + runs-on: ubuntu-20.04 + if: github.repository != 'mozilla-mobile/fenix' + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: "Ktlint" + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: ktlint + + run-lintDebug: + runs-on: ubuntu-20.04 + if: github.repository != 'mozilla-mobile/fenix' + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: "Lint Debug" + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: lintDebug + - name: Archive lint results + uses: actions/upload-artifact@v2 + with: + name: lintDebug report + path: app/build/reports/lint-results-debug.html + From b6ac5079b2fa37d8a6979a231a196624c11dbab1 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Thu, 18 Feb 2021 11:08:13 -0500 Subject: [PATCH 150/248] For issue #18049 Download complete dialog is not showing in custom tab. --- .../fenix/browser/BaseBrowserFragment.kt | 28 +++++--- .../fenix/browser/BaseBrowserFragmentTest.kt | 64 +++++++++++++++++++ 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 820cc2c0b..d3525c2f2 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -458,9 +458,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit downloadFeature.onDownloadStopped = { downloadState, _, downloadJobStatus -> // If the download is just paused, don't show any in-app notification - if (downloadJobStatus == DownloadState.Status.COMPLETED || - downloadJobStatus == DownloadState.Status.FAILED - ) { + if (shouldShowCompletedDownloadDialog(downloadState, downloadJobStatus)) { saveDownloadDialogState( downloadState.sessionId, @@ -488,16 +486,13 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit onDismiss = { sharedViewModel.downloadDialogState.remove(downloadState.sessionId) } ) - // Don't show the dialog if we aren't in the tab that started the download - if (downloadState.sessionId == sessionManager.selectedSession?.id) { - dynamicDownloadDialog.show() - browserToolbarView.expand() - } + dynamicDownloadDialog.show() + browserToolbarView.expand() } } resumeDownloadDialogState( - sessionManager.selectedSession?.id, + getCurrentTab()?.id, store, view, context, toolbarHeight ) @@ -1152,7 +1147,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit } } - private fun getCurrentTab(): SessionState? { + @VisibleForTesting + internal fun getCurrentTab(): SessionState? { return requireComponents.core.store.state.findCustomTabOrSelectedTab(customTabSessionId) } @@ -1358,4 +1354,16 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit */ @VisibleForTesting internal fun getSwipeRefreshLayout() = swipeRefresh + + @VisibleForTesting + internal fun shouldShowCompletedDownloadDialog( + downloadState: DownloadState, + status: DownloadState.Status + ): Boolean { + + val isValidStatus = status in listOf(DownloadState.Status.COMPLETED, DownloadState.Status.FAILED) + val isSameTab = downloadState.sessionId == getCurrentTab()?.id ?: false + + return isValidStatus && isSameTab + } } diff --git a/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt index 64b824432..d65605fbd 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt @@ -12,8 +12,12 @@ import io.mockk.mockk import io.mockk.slot import io.mockk.spyk import io.mockk.verify +import junit.framework.TestCase.assertFalse +import junit.framework.TestCase.assertTrue import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.browser.state.state.SessionState +import mozilla.components.browser.state.state.content.DownloadState +import mozilla.components.browser.state.state.createTab import mozilla.components.concept.engine.EngineView import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.session.behavior.EngineViewBrowserToolbarBehavior @@ -111,6 +115,66 @@ class BaseBrowserFragmentTest { verify { (swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 13 } } + + @Test + fun `WHEN status is equals to FAILED or COMPLETED and it is the same tab then shouldShowCompletedDownloadDialog will be true`() { + every { fragment.getCurrentTab() } returns createTab(id = "1", url = "") + + val download = DownloadState( + url = "", + sessionId = "1" + ) + + val status = DownloadState.Status.values() + .filter { it == DownloadState.Status.COMPLETED && it == DownloadState.Status.FAILED } + + status.forEach { + val result = + fragment.shouldShowCompletedDownloadDialog(download, it) + + assertTrue(result) + } + } + + @Test + fun `WHEN status is different from FAILED or COMPLETED then shouldShowCompletedDownloadDialog will be false`() { + every { fragment.getCurrentTab() } returns createTab(id = "1", url = "") + + val download = DownloadState( + url = "", + sessionId = "1" + ) + + val status = DownloadState.Status.values() + .filter { it != DownloadState.Status.COMPLETED && it != DownloadState.Status.FAILED } + + status.forEach { + val result = + fragment.shouldShowCompletedDownloadDialog(download, it) + + assertFalse(result) + } + } + + @Test + fun `WHEN the tab is different from the initial one then shouldShowCompletedDownloadDialog will be false`() { + every { fragment.getCurrentTab() } returns createTab(id = "1", url = "") + + val download = DownloadState( + url = "", + sessionId = "2" + ) + + val status = DownloadState.Status.values() + .filter { it != DownloadState.Status.COMPLETED && it != DownloadState.Status.FAILED } + + status.forEach { + val result = + fragment.shouldShowCompletedDownloadDialog(download, it) + + assertFalse(result) + } + } } @ExperimentalCoroutinesApi From c9b8f57f96e9188746391885a065428df62f3ff9 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Wed, 17 Feb 2021 10:20:06 -0500 Subject: [PATCH 151/248] Refactor BrowserToolbarMenuController to use browser store --- .../fenix/browser/BaseBrowserFragment.kt | 4 +- .../toolbar/BrowserToolbarMenuController.kt | 95 ++++++----- ...DefaultBrowserToolbarMenuControllerTest.kt | 156 +++++++++--------- 3 files changed, 137 insertions(+), 118 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index d3525c2f2..e8ed31cee 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -318,17 +318,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit } ) val browserToolbarMenuController = DefaultBrowserToolbarMenuController( + store = store, activity = activity, navController = findNavController(), metrics = requireComponents.analytics.metrics, settings = context.settings(), readerModeController = readerMenuController, - sessionManager = requireComponents.core.sessionManager, sessionFeature = sessionFeature, findInPageLauncher = { findInPageIntegration.withFeature { it.launch() } }, swipeRefresh = swipeRefresh, browserAnimator = browserAnimator, - customTabSession = customTabSessionId?.let { sessionManager.findSessionById(it) }, + customTabSessionId = customTabSessionId, openInFenixIntent = openInFenixIntent, bookmarkTapped = { url: String, title: String -> viewLifecycleOwner.lifecycleScope.launch { diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt index 46dcdb1e6..d72f9b133 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt @@ -15,9 +15,10 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import mozilla.appservices.places.BookmarkRoot -import mozilla.components.browser.session.Session -import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.engine.EngineSession.LoadUrlFlags import mozilla.components.concept.engine.prompt.ShareData @@ -53,17 +54,17 @@ interface BrowserToolbarMenuController { @Suppress("LargeClass", "ForbiddenComment") class DefaultBrowserToolbarMenuController( + private val store: BrowserStore, private val activity: HomeActivity, private val navController: NavController, private val metrics: MetricController, private val settings: Settings, private val readerModeController: ReaderModeController, private val sessionFeature: ViewBoundFeatureWrapper, - private val sessionManager: SessionManager, private val findInPageLauncher: () -> Unit, private val browserAnimator: BrowserAnimator, private val swipeRefresh: SwipeRefreshLayout, - private val customTabSession: Session?, + private val customTabSessionId: String?, private val openInFenixIntent: Intent, private val bookmarkTapped: (String, String) -> Unit, private val scope: CoroutineScope, @@ -73,7 +74,7 @@ class DefaultBrowserToolbarMenuController( ) : BrowserToolbarMenuController { private val currentSession - get() = customTabSession ?: sessionManager.selectedSession + get() = store.state.findCustomTabOrSelectedTab(customTabSessionId) // We hold onto a reference of the inner scope so that we can override this with the // TestCoroutineScope to ensure sequential execution. If we didn't have this, our tests @@ -84,6 +85,7 @@ class DefaultBrowserToolbarMenuController( @Suppress("ComplexMethod", "LongMethod") override fun handleToolbarItemInteraction(item: ToolbarMenu.Item) { val sessionUseCases = activity.components.useCases.sessionUseCases + val customTabUseCases = activity.components.useCases.customTabsUseCases trackToolbarItemInteraction(item) Do exhaustive when (item) { @@ -104,26 +106,27 @@ class DefaultBrowserToolbarMenuController( } } is ToolbarMenu.Item.OpenInFenix -> { - // Stop the SessionFeature from updating the EngineView and let it release the session - // from the EngineView so that it can immediately be rendered by a different view once - // we switch to the actual browser. - sessionFeature.get()?.release() + customTabSessionId?.let { + // Stop the SessionFeature from updating the EngineView and let it release the session + // from the EngineView so that it can immediately be rendered by a different view once + // we switch to the actual browser. + sessionFeature.get()?.release() - // Strip the CustomTabConfig to turn this Session into a regular tab and then select it - customTabSession!!.customTabConfig = null - sessionManager.select(customTabSession) + // Turn this Session into a regular tab and then select it + customTabUseCases.migrate(customTabSessionId, select = true) - // Switch to the actual browser which should now display our new selected session - activity.startActivity(openInFenixIntent.apply { - // We never want to launch the browser in the same task as the external app - // activity. So we force a new task here. IntentReceiverActivity will do the - // right thing and take care of routing to an already existing browser and avoid - // cloning a new one. - flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK - }) + // Switch to the actual browser which should now display our new selected session + activity.startActivity(openInFenixIntent.apply { + // We never want to launch the browser in the same task as the external app + // activity. So we force a new task here. IntentReceiverActivity will do the + // right thing and take care of routing to an already existing browser and avoid + // cloning a new one. + flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK + }) - // Close this activity (and the task) since it is no longer displaying any session - activity.finishAndRemoveTask() + // Close this activity (and the task) since it is no longer displaying any session + activity.finishAndRemoveTask() + } } is ToolbarMenu.Item.Quit -> { // We need to show the snackbar while the browsing data is deleting (if "Delete @@ -150,7 +153,7 @@ class DefaultBrowserToolbarMenuController( val appLinksUseCases = activity.components.useCases.appLinksUseCases val getRedirect = appLinksUseCases.appLinkRedirect currentSession?.let { - val redirect = getRedirect.invoke(it.url) + val redirect = getRedirect.invoke(it.content.url) redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK appLinksUseCases.openAppLink.invoke(redirect.appIntent) } @@ -161,22 +164,26 @@ class DefaultBrowserToolbarMenuController( if (item.viewHistory) { navController.navigate( BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( - activeSessionId = customTabSession?.id + activeSessionId = customTabSessionId ) ) } else { - sessionUseCases.goBack.invoke(currentSession) + currentSession?.let { + sessionUseCases.goBack.invoke(it.id) + } } } is ToolbarMenu.Item.Forward -> { if (item.viewHistory) { navController.navigate( BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( - activeSessionId = customTabSession?.id + activeSessionId = customTabSessionId ) ) } else { - sessionUseCases.goForward.invoke(currentSession) + currentSession?.let { + sessionUseCases.goForward.invoke(it.id) + } } } is ToolbarMenu.Item.Reload -> { @@ -186,15 +193,21 @@ class DefaultBrowserToolbarMenuController( LoadUrlFlags.none() } - sessionUseCases.reload.invoke(currentSession, flags = flags) + currentSession?.let { + sessionUseCases.reload.invoke(it.id, flags = flags) + } + } + is ToolbarMenu.Item.Stop -> { + currentSession?.let { + sessionUseCases.stopLoading.invoke(it.id) + } } - is ToolbarMenu.Item.Stop -> sessionUseCases.stopLoading.invoke(currentSession) is ToolbarMenu.Item.Share -> { val directions = NavGraphDirections.actionGlobalShareFragment( data = arrayOf( ShareData( url = getProperUrl(currentSession), - title = currentSession?.title + title = currentSession?.content?.title ) ), showPage = true @@ -211,10 +224,14 @@ class DefaultBrowserToolbarMenuController( BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment() ) } - is ToolbarMenu.Item.RequestDesktop -> sessionUseCases.requestDesktopSite.invoke( - item.isChecked, - currentSession - ) + is ToolbarMenu.Item.RequestDesktop -> { + currentSession?.let { + sessionUseCases.requestDesktopSite.invoke( + item.isChecked, + it.id + ) + } + } is ToolbarMenu.Item.AddToTopSites -> { scope.launch { val context = swipeRefresh.context @@ -234,7 +251,7 @@ class DefaultBrowserToolbarMenuController( ioScope.launch { currentSession?.let { with(activity.components.useCases.topSitesUseCase) { - addPinnedSites(it.title, it.url) + addPinnedSites(it.content.title, it.content.url) } } }.join() @@ -294,8 +311,8 @@ class DefaultBrowserToolbarMenuController( } } is ToolbarMenu.Item.Bookmark -> { - sessionManager.selectedSession?.let { - getProperUrl(it)?.let { url -> bookmarkTapped(url, it.title) } + store.state.selectedTab?.let { + getProperUrl(it)?.let { url -> bookmarkTapped(url, it.content.title) } } } is ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically { @@ -325,13 +342,13 @@ class DefaultBrowserToolbarMenuController( } } - private fun getProperUrl(currentSession: Session?): String? { + private fun getProperUrl(currentSession: SessionState?): String? { return currentSession?.id?.let { val currentTab = browserStore.state.findTab(it) if (currentTab?.readerState?.active == true) { currentTab.readerState.activeUrl } else { - currentSession.url + currentSession.content.url } } } diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt index 211cf0fc9..da473a25d 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt @@ -24,10 +24,11 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runBlockingTest import mozilla.appservices.places.BookmarkRoot -import mozilla.components.browser.session.Session -import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.state.action.CustomTabListAction import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.ReaderState +import mozilla.components.browser.state.state.TabSessionState +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.EngineSession @@ -36,9 +37,11 @@ import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.tab.collections.TabCollection +import mozilla.components.feature.tabs.CustomTabsUseCases import mozilla.components.feature.top.sites.DefaultTopSitesStorage import mozilla.components.feature.top.sites.TopSitesUseCases import mozilla.components.support.base.feature.ViewBoundFeatureWrapper +import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.After import org.junit.Before @@ -76,13 +79,12 @@ class DefaultBrowserToolbarMenuControllerTest { @RelaxedMockK private lateinit var navController: NavController @RelaxedMockK private lateinit var findInPageLauncher: () -> Unit @RelaxedMockK private lateinit var bookmarkTapped: (String, String) -> Unit - @RelaxedMockK private lateinit var sessionManager: SessionManager - @RelaxedMockK private lateinit var currentSession: Session @RelaxedMockK private lateinit var openInFenixIntent: Intent @RelaxedMockK private lateinit var metrics: MetricController @RelaxedMockK private lateinit var settings: Settings @RelaxedMockK private lateinit var searchUseCases: SearchUseCases @RelaxedMockK private lateinit var sessionUseCases: SessionUseCases + @RelaxedMockK private lateinit var customTabUseCases: CustomTabsUseCases @RelaxedMockK private lateinit var browserAnimator: BrowserAnimator @RelaxedMockK private lateinit var snackbar: FenixSnackbar @RelaxedMockK private lateinit var tabCollectionStorage: TabCollectionStorage @@ -91,7 +93,9 @@ class DefaultBrowserToolbarMenuControllerTest { @MockK private lateinit var sessionFeatureWrapper: ViewBoundFeatureWrapper @RelaxedMockK private lateinit var sessionFeature: SessionFeature @RelaxedMockK private lateinit var topSitesStorage: DefaultTopSitesStorage - @RelaxedMockK private lateinit var browserStore: BrowserStore + + private lateinit var browserStore: BrowserStore + private lateinit var selectedTab: TabSessionState @Before fun setUp() { @@ -106,18 +110,25 @@ class DefaultBrowserToolbarMenuControllerTest { every { FenixSnackbar.make(any(), any(), any(), any()) } returns snackbar every { activity.components.useCases.sessionUseCases } returns sessionUseCases + every { activity.components.useCases.customTabsUseCases } returns customTabUseCases every { activity.components.useCases.searchUseCases } returns searchUseCases every { activity.components.useCases.topSitesUseCase } returns topSitesUseCase - every { sessionManager.selectedSession } returns currentSession every { sessionFeatureWrapper.get() } returns sessionFeature every { navController.currentDestination } returns mockk { every { id } returns R.id.browserFragment } - every { currentSession.id } returns "1" every { settings.topSitesMaxLimit } returns 16 val onComplete = slot<() -> Unit>() every { browserAnimator.captureEngineViewAndDrawStatically(capture(onComplete)) } answers { onComplete.captured.invoke() } + + selectedTab = createTab("https://www.mozilla.org", id = "1") + browserStore = BrowserStore( + initialState = BrowserState( + tabs = listOf(selectedTab), + selectedTabId = selectedTab.id + ) + ) } @After @@ -134,23 +145,20 @@ class DefaultBrowserToolbarMenuControllerTest { val item = ToolbarMenu.Item.Bookmark val title = "Mozilla" - val readerUrl = "moz-extension://1234" - val readerTab = createTab( - url = readerUrl, + val url = "https://mozilla.org" + val regularTab = createTab( + url = url, readerState = ReaderState(active = false, activeUrl = "https://1234.org"), title = title ) - browserStore = - BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns "https://mozilla.org" + val store = + BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id)) - val controller = createController(scope = this) + val controller = createController(scope = this, store = store) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } - verify { bookmarkTapped("https://mozilla.org", title) } + verify { bookmarkTapped(url, title) } } } @@ -167,11 +175,8 @@ class DefaultBrowserToolbarMenuControllerTest { ) browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns readerUrl - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } @@ -182,18 +187,22 @@ class DefaultBrowserToolbarMenuControllerTest { @Test fun `WHEN open in Fenix menu item is pressed THEN menu item is handled correctly`() = runBlockingTest { if (!FeatureFlags.toolbarMenuFeature) { - val controller = createController(scope = this, customTabSession = currentSession) + + val customTab = createCustomTab("https://mozilla.org") + browserStore.dispatch(CustomTabListAction.AddCustomTabAction(customTab)).joinBlocking() + val controller = createController( + scope = this, + store = browserStore, + customTabSessionId = customTab.id + ) val item = ToolbarMenu.Item.OpenInFenix - every { currentSession.customTabConfig } returns mockk() every { activity.startActivity(any()) } just Runs - controller.handleToolbarItemInteraction(item) verify { sessionFeature.release() } - verify { currentSession.customTabConfig = null } - verify { sessionManager.select(currentSession) } + verify { customTabUseCases.migrate(customTab.id, true) } verify { activity.startActivity(openInFenixIntent) } verify { activity.finishAndRemoveTask() } } @@ -205,7 +214,7 @@ class DefaultBrowserToolbarMenuControllerTest { val item = ToolbarMenu.Item.Quit val testScope = this - val controller = createController(scope = testScope) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) @@ -218,7 +227,7 @@ class DefaultBrowserToolbarMenuControllerTest { if (!FeatureFlags.toolbarMenuFeature) { val item = ToolbarMenu.Item.OpenInApp - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) @@ -230,7 +239,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN reader mode menu item is pressed THEN handle appearance change`() = runBlockingTest { val item = ToolbarMenu.Item.ReaderModeAppearance - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) @@ -243,18 +252,18 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN backwards nav menu item is pressed THEN the session navigates back with active session`() = runBlockingTest { val item = ToolbarMenu.Item.Back(false) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BACK)) } - verify { sessionUseCases.goBack(currentSession) } + verify { sessionUseCases.goBack(browserStore.state.selectedTabId!!) } } @Test fun `WHEN backwards nav menu item is long pressed THEN the session navigates back with no active session`() = runBlockingTest { val item = ToolbarMenu.Item.Back(true) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null) @@ -267,18 +276,18 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN forward nav menu item is pressed THEN the session navigates forward to active session`() = runBlockingTest { val item = ToolbarMenu.Item.Forward(false) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.FORWARD)) } - verify { sessionUseCases.goForward(currentSession) } + verify { sessionUseCases.goForward(selectedTab.id) } } @Test fun `WHEN forward nav menu item is long pressed THEN the browser navigates forward with no active session`() = runBlockingTest { val item = ToolbarMenu.Item.Forward(true) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null) @@ -291,24 +300,24 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN reload nav menu item is pressed THEN the session reloads from cache`() = runBlockingTest { val item = ToolbarMenu.Item.Reload(false) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) } - verify { sessionUseCases.reload(currentSession) } + verify { sessionUseCases.reload(selectedTab.id) } } @Test fun `WHEN reload nav menu item is long pressed THEN the session reloads with no cache`() = runBlockingTest { val item = ToolbarMenu.Item.Reload(true) - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) } verify { sessionUseCases.reload( - currentSession, + selectedTab.id, EngineSession.LoadUrlFlags.select(EngineSession.LoadUrlFlags.BYPASS_CACHE) ) } @@ -318,18 +327,18 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN stop nav menu item is pressed THEN the session stops loading`() = runBlockingTest { val item = ToolbarMenu.Item.Stop - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.STOP)) } - verify { sessionUseCases.stopLoading(currentSession) } + verify { sessionUseCases.stopLoading(selectedTab.id) } } @Test fun `WHEN settings menu item is pressed THEN menu item is handled`() = runBlockingTest { val item = ToolbarMenu.Item.Settings - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment() @@ -342,7 +351,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest { val item = ToolbarMenu.Item.Bookmarks - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) val directions = BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id) @@ -355,7 +364,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN history menu item is pressed THEN navigate to history page`() = runBlockingTest { val item = ToolbarMenu.Item.History - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) val directions = BrowserFragmentDirections.actionGlobalHistoryFragment() @@ -372,14 +381,14 @@ class DefaultBrowserToolbarMenuControllerTest { every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON)) } verify { requestDesktopSiteUseCase.invoke( true, - currentSession + selectedTab.id ) } } @@ -392,14 +401,14 @@ class DefaultBrowserToolbarMenuControllerTest { every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_OFF)) } verify { requestDesktopSiteUseCase.invoke( false, - currentSession + selectedTab.id ) } } @@ -414,10 +423,10 @@ class DefaultBrowserToolbarMenuControllerTest { swipeRefreshLayout.context.getString(R.string.snackbar_added_to_top_sites) } returns "Added to top sites!" - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) - verify { addPinnedSiteUseCase.invoke(currentSession.title, currentSession.url) } + verify { addPinnedSiteUseCase.invoke(selectedTab.content.title, selectedTab.content.url) } verify { snackbar.setText("Added to top sites!") } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_TOP_SITES)) } } @@ -426,7 +435,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN addon extensions menu item is pressed THEN navigate to addons manager`() = runBlockingTest { val item = ToolbarMenu.Item.AddonsManager - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADDONS_MANAGER)) } @@ -436,7 +445,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN Add To Home Screen menu item is pressed THEN add site`() = runBlockingTest { val item = ToolbarMenu.Item.AddToHomeScreen - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN)) } @@ -446,18 +455,14 @@ class DefaultBrowserToolbarMenuControllerTest { fun `IF reader mode is inactive WHEN share menu item is pressed THEN navigate to share screen`() = runBlockingTest { val item = ToolbarMenu.Item.Share val title = "Mozilla" - val readerUrl = "moz-extension://1234" - val readerTab = createTab( - url = readerUrl, + val url = "https://mozilla.org" + val regularTab = createTab( + url = url, readerState = ReaderState(active = false, activeUrl = "https://1234.org"), title = title ) - browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns "https://mozilla.org" - - val controller = createController(scope = this) + browserStore = BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id)) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) } @@ -484,11 +489,7 @@ class DefaultBrowserToolbarMenuControllerTest { title = title ) browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) - every { currentSession.id } returns readerTab.id - every { currentSession.title } returns title - every { currentSession.url } returns readerUrl - - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) } @@ -508,7 +509,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN Find In Page menu item is pressed THEN launch finder`() = runBlockingTest { val item = ToolbarMenu.Item.FindInPage - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { findInPageLauncher() } @@ -521,7 +522,7 @@ class DefaultBrowserToolbarMenuControllerTest { val cachedTabCollections: List = mockk(relaxed = true) every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollections - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { @@ -537,8 +538,8 @@ class DefaultBrowserToolbarMenuControllerTest { val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment( saveCollectionStep = SaveCollectionStep.SelectCollection, - tabIds = arrayOf(currentSession.id), - selectedTabIds = arrayOf(currentSession.id) + tabIds = arrayOf(selectedTab.id), + selectedTabIds = arrayOf(selectedTab.id) ) verify { navController.navigate(directionsEq(directions), null) } } @@ -549,7 +550,7 @@ class DefaultBrowserToolbarMenuControllerTest { val cachedTabCollectionsEmpty: List = emptyList() every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollectionsEmpty - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION)) } @@ -562,8 +563,8 @@ class DefaultBrowserToolbarMenuControllerTest { } val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment( saveCollectionStep = SaveCollectionStep.NameCollection, - tabIds = arrayOf(currentSession.id), - selectedTabIds = arrayOf(currentSession.id) + tabIds = arrayOf(selectedTab.id), + selectedTabIds = arrayOf(selectedTab.id) ) verify { navController.navigate(directionsEq(directions), null) } } @@ -572,7 +573,7 @@ class DefaultBrowserToolbarMenuControllerTest { fun `WHEN New Tab menu item is pressed THEN navigate to a new tab home`() = runBlockingTest { val item = ToolbarMenu.Item.NewTab - val controller = createController(scope = this) + val controller = createController(scope = this, store = browserStore) controller.handleToolbarItemInteraction(item) @@ -589,23 +590,24 @@ class DefaultBrowserToolbarMenuControllerTest { private fun createController( scope: CoroutineScope, + store: BrowserStore, activity: HomeActivity = this.activity, - customTabSession: Session? = null + customTabSessionId: String? = null ) = DefaultBrowserToolbarMenuController( + store = store, activity = activity, navController = navController, metrics = metrics, settings = settings, findInPageLauncher = findInPageLauncher, browserAnimator = browserAnimator, - customTabSession = customTabSession, + customTabSessionId = customTabSessionId, openInFenixIntent = openInFenixIntent, scope = scope, swipeRefresh = swipeRefreshLayout, tabCollectionStorage = tabCollectionStorage, bookmarkTapped = bookmarkTapped, readerModeController = readerModeController, - sessionManager = sessionManager, sessionFeature = sessionFeatureWrapper, topSitesStorage = topSitesStorage, browserStore = browserStore From 2d87307144994e3ce6d99b9ebd6c82874594761f Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Thu, 18 Feb 2021 10:54:17 -0500 Subject: [PATCH 152/248] Remove remaining usages of Session[Manager] in BrowserFragment --- .../fenix/browser/BaseBrowserFragment.kt | 42 ++++++------------- .../mozilla/fenix/browser/BrowserFragment.kt | 2 +- .../components/toolbar/BrowserToolbarView.kt | 10 ++--- .../mozilla/fenix/utils/ToolbarPopupWindow.kt | 8 ++-- .../fenix/utils/ToolbarPopupWindowTest.kt | 6 +-- 5 files changed, 25 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index e8ed31cee..19644bf42 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -38,13 +38,15 @@ import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import mozilla.appservices.places.BookmarkRoot -import mozilla.components.browser.session.Session import mozilla.components.browser.state.action.ContentAction +import mozilla.components.browser.state.selector.findCustomTab import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab import mozilla.components.browser.state.selector.getNormalOrPrivateTabs import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.CustomTabSessionState import mozilla.components.browser.state.state.SessionState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.state.content.DownloadState @@ -254,7 +256,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit @CallSuper internal open fun initializeUI(view: View, tab: SessionState) { val context = requireContext() - val sessionManager = context.components.core.sessionManager val store = context.components.core.store val activity = requireActivity() as HomeActivity @@ -350,7 +351,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit container = view.browserLayout, toolbarPosition = context.settings().toolbarPosition, interactor = browserInteractor, - customTabSession = customTabSessionId?.let { sessionManager.findSessionById(it) }, + customTabSession = customTabSessionId?.let { store.state.findCustomTab(it) }, lifecycleOwner = viewLifecycleOwner ) @@ -551,7 +552,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit val directions = NavGraphDirections.actionGlobalShareFragment( data = arrayOf(shareData), showPage = true, - sessionId = getSessionById()?.id + sessionId = getCurrentTab()?.id ) findNavController().navigate(directions) } @@ -585,14 +586,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit searchFeature.set( feature = SearchFeature(store, customTabSessionId) { request, tabId -> - val parentSession = sessionManager.findSessionById(tabId) + val parentSession = store.state.findTabOrCustomTab(tabId) val useCase = if (request.isPrivate) { requireComponents.useCases.searchUseCases.newPrivateTabSearch } else { requireComponents.useCases.searchUseCases.newTabSearch } - if (parentSession?.isCustomTabSession() == true) { + if (parentSession is CustomTabSessionState) { useCase.invoke(request.query) requireActivity().startActivity(openInFenixIntent) } else { @@ -1016,7 +1017,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit final override fun onViewStateRestored(savedInstanceState: Bundle?) { super.onViewStateRestored(savedInstanceState) savedInstanceState?.getString(KEY_CUSTOM_TAB_SESSION_ID)?.let { - if (requireComponents.core.sessionManager.findSessionById(it)?.customTabConfig != null) { + if (requireComponents.core.store.state.findCustomTab(it) != null) { customTabSessionId = it } } @@ -1054,22 +1055,18 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit * or if it has a parent session and no more history */ protected open fun removeSessionIfNeeded(): Boolean { - getSessionById()?.let { session -> + getCurrentTab()?.let { session -> return if (session.source == SessionState.Source.ACTION_VIEW) { activity?.finish() requireComponents.useCases.tabsUseCases.removeTab(session.id) true } else { - if (session.hasParentSession) { - // The removeTab use case does not currently select a parent session, so - // we are using sessionManager.remove - requireComponents.core.sessionManager.remove( - session, - selectParentIfExists = true - ) + val hasParentSession = session is TabSessionState && session.parentId != null + if (hasParentSession) { + requireComponents.useCases.tabsUseCases.removeTab(session.id, selectParentIfExists = true) } // We want to return to home if this session didn't have a parent session to select. - val goToOverview = !session.hasParentSession + val goToOverview = !hasParentSession !goToOverview } } @@ -1134,19 +1131,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit (activity as HomeActivity).browsingModeManager.mode = sessionMode } - /** - * Returns the current session. - */ - protected fun getSessionById(): Session? { - val sessionManager = requireComponents.core.sessionManager - val localCustomTabId = customTabSessionId - return if (localCustomTabId != null) { - sessionManager.findSessionById(localCustomTabId) - } else { - sessionManager.selectedSession - } - } - @VisibleForTesting internal fun getCurrentTab(): SessionState? { return requireComponents.core.store.state.findCustomTabOrSelectedTab(customTabSessionId) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index 6d0cdb926..58515a908 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -84,7 +84,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { visible = { readerModeAvailable }, - selected = getSessionById()?.let { + selected = getCurrentTab()?.let { activity?.components?.core?.store?.state?.findTab(it.id)?.readerState?.active } ?: false, listener = browserInteractor::onReaderModePressed diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index af57953a5..d8e7e306f 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -16,8 +16,8 @@ import androidx.lifecycle.LifecycleOwner import kotlinx.android.extensions.LayoutContainer import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.browser.domains.autocomplete.ShippedDomainsProvider -import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.CustomTabSessionState import mozilla.components.browser.state.state.ExternalAppType import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.browser.toolbar.behavior.BrowserToolbarBehavior @@ -52,7 +52,7 @@ class BrowserToolbarView( private val container: ViewGroup, private val toolbarPosition: ToolbarPosition, private val interactor: BrowserToolbarViewInteractor, - private val customTabSession: Session?, + private val customTabSession: CustomTabSessionState?, private val lifecycleOwner: LifecycleOwner ) : LayoutContainer { @@ -78,8 +78,8 @@ class BrowserToolbarView( @VisibleForTesting internal val isPwaTabOrTwaTab: Boolean - get() = customTabSession?.customTabConfig?.externalAppType == ExternalAppType.PROGRESSIVE_WEB_APP || - customTabSession?.customTabConfig?.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY + get() = customTabSession?.config?.externalAppType == ExternalAppType.PROGRESSIVE_WEB_APP || + customTabSession?.config?.externalAppType == ExternalAppType.TRUSTED_WEB_ACTIVITY init { val isCustomTabSession = customTabSession != null @@ -185,7 +185,7 @@ class BrowserToolbarView( view, menuToolbar, customTabSession.id, - isPrivate = customTabSession.private + isPrivate = customTabSession.content.private ) } else { DefaultToolbarIntegration( diff --git a/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt b/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt index 21c56576b..f9b349fce 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/ToolbarPopupWindow.kt @@ -15,8 +15,8 @@ import androidx.annotation.VisibleForTesting import androidx.core.view.isVisible import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.browser_toolbar_popup_window.view.* -import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.selectedTab +import mozilla.components.browser.state.state.CustomTabSessionState import mozilla.components.browser.state.store.BrowserStore import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar @@ -27,7 +27,7 @@ import java.lang.ref.WeakReference object ToolbarPopupWindow { fun show( view: WeakReference, - customTabSession: Session? = null, + customTabSession: CustomTabSessionState? = null, handlePasteAndGo: (String) -> Unit, handlePaste: (String) -> Unit, copyVisible: Boolean = true @@ -101,10 +101,10 @@ object ToolbarPopupWindow { @VisibleForTesting internal fun getUrlForClipboard( store: BrowserStore, - customTabSession: Session? = null + customTabSession: CustomTabSessionState? = null ): String? { return if (customTabSession != null) { - customTabSession.url + customTabSession.content.url } else { val selectedTab = store.state.selectedTab selectedTab?.readerState?.activeUrl ?: selectedTab?.content?.url diff --git a/app/src/test/java/org/mozilla/fenix/utils/ToolbarPopupWindowTest.kt b/app/src/test/java/org/mozilla/fenix/utils/ToolbarPopupWindowTest.kt index 12ec801cd..69ef82b3a 100644 --- a/app/src/test/java/org/mozilla/fenix/utils/ToolbarPopupWindowTest.kt +++ b/app/src/test/java/org/mozilla/fenix/utils/ToolbarPopupWindowTest.kt @@ -4,11 +4,10 @@ package org.mozilla.fenix.utils -import io.mockk.every import io.mockk.mockk -import mozilla.components.browser.session.Session import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.ReaderState +import mozilla.components.browser.state.state.createCustomTab import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore import org.junit.Assert.assertEquals @@ -21,8 +20,7 @@ class ToolbarPopupWindowTest { @Test fun getUrlForClipboard() { - val customTabSession: Session = mockk() - every { customTabSession.url } returns "https://mozilla.org" + val customTabSession = createCustomTab("https://mozilla.org") // Custom tab assertEquals( From e07f4ac590f85d4bc1209cff1325315aeb4c0ba2 Mon Sep 17 00:00:00 2001 From: Christian Sadilek Date: Thu, 18 Feb 2021 13:31:00 -0500 Subject: [PATCH 153/248] Deprecate SessionManager component --- app/src/main/java/org/mozilla/fenix/components/Components.kt | 2 ++ app/src/main/java/org/mozilla/fenix/components/Core.kt | 3 +++ .../test/java/org/mozilla/fenix/components/TestComponents.kt | 1 + 3 files changed, 6 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt index 457c7f638..d1f714984 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -56,6 +56,7 @@ class Components(private val context: Context) { } val services by lazyMonitored { Services(context, backgroundServices.accountManager) } val core by lazyMonitored { Core(context, analytics.crashReporter, strictMode) } + @Suppress("Deprecation") val useCases by lazyMonitored { UseCases( context, @@ -66,6 +67,7 @@ class Components(private val context: Context) { core.topSitesStorage ) } + @Suppress("Deprecation") val intentProcessors by lazyMonitored { IntentProcessors( context, diff --git a/app/src/main/java/org/mozilla/fenix/components/Core.kt b/app/src/main/java/org/mozilla/fenix/components/Core.kt index 9a4889eff..41dfa2543 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Core.kt @@ -201,10 +201,12 @@ class Core( ) } + @Suppress("Deprecation") private fun lookupSessionManager(): SessionManager { return sessionManager } + @Suppress("Deprecation") private fun findSessionById(tabId: String): Session? { return sessionManager.findSessionById(tabId) } @@ -227,6 +229,7 @@ class Core( * sessions from the [SessionStorage], and with a default session (about:blank) in * case all sessions/tabs are closed. */ + @Deprecated("Use browser store (for reading) and use cases (for writing) instead") val sessionManager by lazyMonitored { SessionManager(engine, store).also { // Install the "icons" WebExtension to automatically load icons for every visited website. diff --git a/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt b/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt index 577790914..dfc88b0e9 100644 --- a/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt +++ b/app/src/test/java/org/mozilla/fenix/components/TestComponents.kt @@ -16,6 +16,7 @@ class TestComponents(private val context: Context) : Components(context) { } override val services by lazy { Services(context, backgroundServices.accountManager) } override val core by lazy { TestCore(context, analytics.crashReporter) } + @Suppress("Deprecation") override val useCases by lazy { UseCases( context, From 21d10aa931c56f52d3658d1f87100569ad9b40cf Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Thu, 18 Feb 2021 14:27:34 -0500 Subject: [PATCH 154/248] Update toolbar autoplay strings --- .../quicksettings/QuickSettingsFragmentState.kt | 6 +++--- app/src/main/res/values/strings.xml | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentState.kt b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentState.kt index 056db2e20..2caf3fc60 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentState.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentState.kt @@ -234,17 +234,17 @@ sealed class AutoplayValue( val rules = settings.getSitePermissionsCustomSettingsRules() return listOf( AllowAll( - context.getString(R.string.preference_option_autoplay_allowed2), + context.getString(R.string.quick_setting_option_autoplay_allowed), rules, sitePermission ), BlockAll( - context.getString(R.string.preference_option_autoplay_blocked3), + context.getString(R.string.quick_setting_option_autoplay_blocked), rules, sitePermission ), BlockAudible( - context.getString(R.string.preference_option_autoplay_block_audio2), + context.getString(R.string.quick_setting_option_autoplay_block_audio), rules, sitePermission ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6c09d865..602b07df6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -867,16 +867,22 @@ On Off - + Allow audio and video + + Allow audio and video Block audio and video on cellular data only Audio and video will play on Wi-Fi - + Block audio only - + + Block audio only + Block audio and video + + Block audio and video On From 666833c2e5032aad80be1c347366041cdaaf7a36 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Fri, 19 Feb 2021 00:04:59 +0000 Subject: [PATCH 155/248] Import l10n. --- app/src/main/res/values-gl/strings.xml | 6 ++ app/src/main/res/values-hr/strings.xml | 2 +- app/src/main/res/values-su/strings.xml | 6 ++ app/src/main/res/values-th/strings.xml | 6 ++ app/src/main/res/values-tl/strings.xml | 109 ++++++++++++++++++++++--- l10n.toml | 2 + 6 files changed, 118 insertions(+), 13 deletions(-) diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index cd25c2457..816bbd5c4 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -128,6 +128,8 @@ Editar marcador Complementos + + Extensións Aquí non hai complementos @@ -520,6 +522,10 @@ Outros marcadores Historial + + Nova lapela + + Atopar na páxina Lapelas sincronizadas diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index b5058c516..9cd85a0f9 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -61,7 +61,7 @@ Nalaziš se u privatnoj sesiji - %1$s čisti tvoju kronologiju pretraživanja i pregledavanja kad izađeš iz aplikacije ili kad zatvoriš sve kartice i prozore privatnog pregledavanja. Ovo te ne čini anonimnim prema web-stranicama ili tvom pružatelju internet usluga, ali olakšava da zadržiš privatnim ono što radiš na internetu od ostalih osoba koje koriste ovo računalo. + %1$s čisti tvoju povijest pretraživanja i pregledavanja u privatnim karticama kada ih zatvoriš ili izađeš iz aplikacije. Ovo te ne čini anonimnim prema web-stranicama ili tvom pružatelju internetskih usluga, ali olakšava da zadržiš privatnim ono što radiš na internetu od ostalih osoba koje koriste ovaj uređaj. Česti mitovi o privatnom pregledavanju Izbriši sesiju diff --git a/app/src/main/res/values-su/strings.xml b/app/src/main/res/values-su/strings.xml index 7ce8f19e5..18bae542f 100644 --- a/app/src/main/res/values-su/strings.xml +++ b/app/src/main/res/values-su/strings.xml @@ -128,6 +128,8 @@ Émboh + + Éksténsi Teu aya add-on di dieu @@ -533,6 +535,10 @@ Markah Lianna Jujutan + + Tab anyar + + Téangan dina kaca Tab singkron diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index db8d6885d..9c6848e64 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -129,6 +129,8 @@ แก้ไขที่คั่นหน้า ส่วนเสริม + + ส่วนขยาย ไม่มีส่วนเสริมที่นี่ @@ -526,6 +528,10 @@ ที่คั่นหน้าอื่น ๆ ประวัติ + + แท็บใหม่ + + ค้นหาในหน้า แท็บที่ซิงค์ diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index 22c3f7cce..f2cdaa2ba 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -50,14 +50,20 @@ Napili - %1$s ay gawa ng Mozilla. + Ang %1$s ay gawa ng Mozilla. Ikaw ay nasa pribadong sesyon + + Mga karaniwang pamahiin tungkol sa pribadong pag-browse + Burahin ang sesyon + + + Magdagdag ng shortcut para makapagbukas ng mga pribadong tab mula sa iyong Home screen. Magdagdag ng shortcut @@ -78,6 +84,8 @@ Alisin + + Itakda na kusang magsara ang mga nakabukas na tab na hindi napansin sa nakaraang araw, linggo, o buwan. Tingnan ang mga pagpipilian @@ -226,7 +234,7 @@ Default na search engine - Hanapin + Paghahanap Address bar @@ -239,7 +247,7 @@ The first parameter is the name of the app defined in app_name (for example: Fenix) --> Tungkol sa %1$s - Your Rights + Ang Iyong mga Karapatan Mga Password @@ -283,7 +291,7 @@ Home - Gestures + Mga gesture Customize @@ -306,7 +314,7 @@ Developer tools - Remote debugging via USB + Remote debugging sa USB Ipakita ang mga search engine @@ -332,7 +340,7 @@ Hiwalay na download manager - Add-ons + Mga add-on Mga abiso @@ -362,7 +370,7 @@ - Sync now + Mag-sync na Piliin alin ang isi-sync @@ -457,7 +465,7 @@ - Turn on Sync + Buksan ang Sync Scan pairing code in desktop Firefox @@ -469,7 +477,7 @@ - firefox.com/pair]]> + firefox.com/pair]]> Buksan ang Camera @@ -483,7 +491,7 @@ - Light + Maliwanag Madilim @@ -539,7 +547,7 @@ Mga isinarang tab kamakailan - Ipakita ang kumpletong kasaysayan + Ipakita ang buong kasaysayan %d mga tab @@ -1215,7 +1223,7 @@ SUBUKAN MULI - I-scan ang code + i-Scan ang code https://firefox.com/pair]]> @@ -1332,10 +1340,61 @@ Mga Redirect Tracker + + Suporta + + Mga crash + + Paunawa sa privacy + + Alamin ang iyong mga karapatan + + Impormasyon sa paglisensiya + + Mga library na ginagamit namin + Kopyahin + + Mga login at password + + i-Save ang mga login at password + + Tanungin kung ise-save + + Huwag mag-save kailanman + + Nakabukas + + Nakasara + + Mag-sign in sa Sync + + Mga naka-save na login + + Ang mga login na naka-save o naka-sync sa %s ay magpapakita rito. + + Alamin ang tungkol sa Sync. + + Mag exception + + Ang mga login at password na hindi naka-save ay ipapakita rito. + + Hindi ise-save ang mga login at password para sa mga site na ito. + + Hanapin sa mga login + + Ginamit kamakailan + + Site + + Username + + Password + + Muling ipasok ang PIN Kopyahin ang password @@ -1343,4 +1402,30 @@ Kopyahin ang site + + Buksan ang site sa browser + + Ipakita ang password + + Itago ang password + + Pakaingatan ang iyong mga login at password + + + Magtakda ng device lock pattern, PIN, o password para maprotektahan ang mga naka-save mong login at password sakaling may ibang may hawak sa device mo. + + Mag-zoom sa lahat ng mga website + + Paganahin para makapag-pinch at zoom, kahit sa mga website na pinipigilan ang gesture na ito. + + Pangalan (A-Z) + + Huling ginamit + + + Idagdag sa mga top site + + + Ipakita ang pinakamadalas na bisitahing site + diff --git a/l10n.toml b/l10n.toml index ef8242192..e74207276 100644 --- a/l10n.toml +++ b/l10n.toml @@ -13,6 +13,7 @@ locales = [ "bs", "ca", "cak", + "ceb", "co", "cs", "cy", @@ -42,6 +43,7 @@ locales = [ "gu-IN", "he", "hi-IN", + "hil", "hr", "hsb", "hu", From fc80dbfb57d4225d6aed26fd275934d2c8a256b9 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Thu, 18 Feb 2021 16:14:05 +0100 Subject: [PATCH 156/248] Update Kotlin to 1.4.30 and Coroutines to 1.4.2. --- .../fenix/downloads/DynamicDownloadDialogBehaviorTest.kt | 2 +- .../test/java/org/mozilla/fenix/share/ShareControllerTest.kt | 4 ++-- buildSrc/src/main/java/Dependencies.kt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/test/java/org/mozilla/fenix/downloads/DynamicDownloadDialogBehaviorTest.kt b/app/src/test/java/org/mozilla/fenix/downloads/DynamicDownloadDialogBehaviorTest.kt index 526125006..6b55b53d5 100644 --- a/app/src/test/java/org/mozilla/fenix/downloads/DynamicDownloadDialogBehaviorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/downloads/DynamicDownloadDialogBehaviorTest.kt @@ -60,7 +60,7 @@ class DynamicDownloadDialogBehaviorTest { } @Test - fun `Behavior will snap the dialog up if it is more than 50% visible`() { + fun `Behavior will snap the dialog up if it is more than 50 percent visible`() { val behavior = spyk(DynamicDownloadDialogBehavior(testContext, attrs = null, bottomToolbarHeight = 10f)) every { behavior.shouldScroll } returns true diff --git a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt index 09e4421b8..1fd46f9f5 100644 --- a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt @@ -361,12 +361,12 @@ class ShareControllerTest { } @Test - fun `getShareSubject will return "shareSubject" if that is non null`() { + fun `getShareSubject will return 'shareSubject' if that is non null`() { assertEquals(shareSubject, controller.getShareSubject()) } @Test - fun `getShareSubject will return a concatenation of tab titles if "shareSubject" is null`() { + fun `getShareSubject will return a concatenation of tab titles if 'shareSubject' is null`() { val controller = DefaultShareController( context, null, shareData, sendTabUseCases, snackbar, navController, recentAppStorage, testCoroutineScope, testDispatcher, dismiss diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index b132351d4..44e5323a6 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -3,8 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object Versions { - const val kotlin = "1.4.10" - const val coroutines = "1.3.9" + const val kotlin = "1.4.30" + const val coroutines = "1.4.2" // These versions are linked: lint should be X+23.Y.Z of gradle_plugin version, according to: // https://github.com/alexjlockwood/android-lint-checks-demo/blob/0245fc027463137b1b4afb97c5295d60dce998b6/dependencies.gradle#L3 From a2566f9e9e1a8637dba4ff04f4ff0b93a83a842d Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Fri, 5 Feb 2021 10:54:23 +0100 Subject: [PATCH 157/248] Issue #12731: Collect telemetry about the content process of tabs getting killed. --- app/metrics.yaml | 52 +++++++ .../org/mozilla/fenix/TelemetryMiddleware.kt | 42 +++++ .../mozilla/fenix/TelemetryMiddlewareTest.kt | 147 +++++++++++++++++- docs/metrics.md | 3 + 4 files changed, 243 insertions(+), 1 deletion(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 3eced0a56..82175a8f7 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -4402,3 +4402,55 @@ contextual_menu: notification_emails: - fenix-core@mozilla.com expires: "2021-06-01" + +engine: + tab_kills: + type: labeled_counter + labels: + - foreground + - background + description: | + How often was the content process of a foreground (selected) or + background tab killed. + bugs: + - https://github.com/mozilla-mobile/android-components/issues/9366 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17864 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + - skaspari@mozilla.com + expires: "2021-12-31" + kill_foreground_age: + type: timespan + time_unit: millisecond + description: | + Measures the age of the engine session of a foreground (selected) tab + at the time its content process got killed. + bugs: + - https://github.com/mozilla-mobile/android-components/issues/9366 + data_reviews: + - TBD + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + - skaspari@mozilla.com + expires: "2021-12-31" + kill_background_age: + type: timespan + time_unit: millisecond + description: | + Measures the age of the engine session of a background tab at the + time its content process got killed. + bugs: + - https://github.com/mozilla-mobile/android-components/issues/9366 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17864 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + - skaspari@mozilla.com + expires: "2021-12-31" diff --git a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt index c39b97e5f..f16cae272 100644 --- a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt @@ -8,17 +8,23 @@ import androidx.annotation.VisibleForTesting import mozilla.components.browser.state.action.BrowserAction import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.action.DownloadAction +import mozilla.components.browser.state.action.EngineAction import mozilla.components.browser.state.action.TabListAction import mozilla.components.browser.state.selector.findTab +import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.selector.normalTabs import mozilla.components.browser.state.state.BrowserState +import mozilla.components.browser.state.state.EngineState +import mozilla.components.browser.state.state.SessionState import mozilla.components.lib.state.Middleware import mozilla.components.lib.state.MiddlewareContext +import mozilla.components.support.base.android.Clock import mozilla.components.support.base.log.logger.Logger import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry import org.mozilla.fenix.utils.Settings +import org.mozilla.fenix.GleanMetrics.Engine as EngineMetrics /** * [Middleware] to record telemetry in response to [BrowserAction]s. @@ -90,6 +96,10 @@ class TelemetryMiddleware( is DownloadAction.AddDownloadAction -> { metrics.track(Event.DownloadAdded) } + is EngineAction.KillEngineSessionAction -> { + val tab = context.state.findTabOrCustomTab(action.sessionId) + onEngineSessionKilled(context.state, tab) + } } next(action) @@ -112,4 +122,36 @@ class TelemetryMiddleware( } } } + + /** + * Collecting some engine-specific (GeckoView) telemetry. + * https://github.com/mozilla-mobile/android-components/issues/9366 + */ + private fun onEngineSessionKilled(state: BrowserState, tab: SessionState?) { + if (tab == null) { + logger.debug("Could not find tab for killed engine session") + return + } + + val isSelected = tab.id == state.selectedTabId + val ageNanos = tab.engineState.ageNanos() + + // Increment the counter of killed foreground/background tabs + val tabKillLabel = if (isSelected) { "foreground" } else { "background" } + EngineMetrics.tabKills[tabKillLabel].add() + + // Record the age of the engine session of the killed foreground/background tab. + if (isSelected && ageNanos != null) { + EngineMetrics.killForegroundAge.setRawNanos(ageNanos) + } else if (ageNanos != null) { + EngineMetrics.killBackgroundAge.setRawNanos(ageNanos) + } + } +} + +@Suppress("MagicNumber") +private fun EngineState.ageNanos(): Long? { + val timestamp = (timestamp ?: return null) + val now = Clock.elapsedRealtime() + return (now - timestamp) * 1_000_000 } diff --git a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt index 355c2bd10..35c5421ea 100644 --- a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt +++ b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt @@ -4,20 +4,28 @@ package org.mozilla.fenix +import androidx.test.core.app.ApplicationProvider import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher +import mozilla.components.browser.session.engine.EngineMiddleware import mozilla.components.browser.state.action.ContentAction import mozilla.components.browser.state.action.DownloadAction +import mozilla.components.browser.state.action.EngineAction import mozilla.components.browser.state.action.TabListAction +import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.LoadRequestState import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.store.BrowserStore +import mozilla.components.service.glean.testing.GleanTestRule +import mozilla.components.support.base.android.Clock import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.mock import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After +import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull @@ -30,6 +38,7 @@ import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry import org.mozilla.fenix.utils.Settings +import org.mozilla.fenix.GleanMetrics.Engine as EngineMetrics @RunWith(FenixRobolectricTestRunner::class) @ExperimentalCoroutinesApi @@ -45,8 +54,15 @@ class TelemetryMiddlewareTest { @get:Rule val coroutinesTestRule = MainCoroutineRule(testDispatcher) + @get:Rule + val gleanRule = GleanTestRule(ApplicationProvider.getApplicationContext()) + + private val clock = FakeClock() + @Before fun setUp() { + Clock.delegate = clock + settings = Settings(testContext) metrics = mockk(relaxed = true) adsTelemetry = mockk() @@ -55,7 +71,15 @@ class TelemetryMiddlewareTest { adsTelemetry, metrics ) - store = BrowserStore(middleware = listOf(telemetryMiddleware)) + store = BrowserStore( + middleware = listOf(telemetryMiddleware) + EngineMiddleware.create(engine = mockk(), sessionLookup = { null }), + initialState = BrowserState() + ) + } + + @After + fun tearDown() { + Clock.reset() } @Test @@ -244,4 +268,125 @@ class TelemetryMiddlewareTest { verify { metrics.track(Event.DownloadAdded) } } + + @Test + fun `WHEN foreground tab getting killed THEN middleware counts it`() { + store.dispatch(TabListAction.RestoreAction( + listOf( + createTab("https://www.mozilla.org", id = "foreground"), + createTab("https://getpocket.com", id = "background_pocket"), + createTab("https://theverge.com", id = "background_verge") + ), + selectedTabId = "foreground" + )).joinBlocking() + + Assert.assertFalse(EngineMetrics.tabKills["foreground"].testHasValue()) + Assert.assertFalse(EngineMetrics.tabKills["background"].testHasValue()) + + store.dispatch( + EngineAction.KillEngineSessionAction("foreground") + ).joinBlocking() + + Assert.assertTrue(EngineMetrics.tabKills["foreground"].testHasValue()) + } + + @Test + fun `WHEN background tabs getting killed THEN middleware counts it`() { + store.dispatch(TabListAction.RestoreAction( + listOf( + createTab("https://www.mozilla.org", id = "foreground"), + createTab("https://getpocket.com", id = "background_pocket"), + createTab("https://theverge.com", id = "background_verge") + ), + selectedTabId = "foreground" + )).joinBlocking() + + Assert.assertFalse(EngineMetrics.tabKills["foreground"].testHasValue()) + Assert.assertFalse(EngineMetrics.tabKills["background"].testHasValue()) + + store.dispatch( + EngineAction.KillEngineSessionAction("background_pocket") + ).joinBlocking() + + Assert.assertFalse(EngineMetrics.tabKills["foreground"].testHasValue()) + Assert.assertTrue(EngineMetrics.tabKills["background"].testHasValue()) + assertEquals(1, EngineMetrics.tabKills["background"].testGetValue()) + + store.dispatch( + EngineAction.KillEngineSessionAction("background_verge") + ).joinBlocking() + + Assert.assertFalse(EngineMetrics.tabKills["foreground"].testHasValue()) + Assert.assertTrue(EngineMetrics.tabKills["background"].testHasValue()) + assertEquals(2, EngineMetrics.tabKills["background"].testGetValue()) + } + + @Test + fun `WHEN foreground tab gets killed THEN middleware records foreground age`() { + store.dispatch(TabListAction.RestoreAction( + listOf( + createTab("https://www.mozilla.org", id = "foreground"), + createTab("https://getpocket.com", id = "background_pocket"), + createTab("https://theverge.com", id = "background_verge") + ), + selectedTabId = "foreground" + )).joinBlocking() + + clock.elapsedTime = 100 + + store.dispatch(EngineAction.LinkEngineSessionAction( + sessionId = "foreground", + engineSession = mock() + )).joinBlocking() + + Assert.assertFalse(EngineMetrics.killForegroundAge.testHasValue()) + Assert.assertFalse(EngineMetrics.killBackgroundAge.testHasValue()) + + clock.elapsedTime = 500 + + store.dispatch( + EngineAction.KillEngineSessionAction("foreground") + ).joinBlocking() + + Assert.assertTrue(EngineMetrics.killForegroundAge.testHasValue()) + Assert.assertFalse(EngineMetrics.killBackgroundAge.testHasValue()) + assertEquals(400, EngineMetrics.killForegroundAge.testGetValue()) + } + + @Test + fun `WHEN background tab gets killed THEN middleware records background age`() { + store.dispatch(TabListAction.RestoreAction( + listOf( + createTab("https://www.mozilla.org", id = "foreground"), + createTab("https://getpocket.com", id = "background_pocket"), + createTab("https://theverge.com", id = "background_verge") + ), + selectedTabId = "foreground" + )).joinBlocking() + + clock.elapsedTime = 100 + + store.dispatch(EngineAction.LinkEngineSessionAction( + sessionId = "background_pocket", + engineSession = mock() + )).joinBlocking() + + clock.elapsedTime = 700 + + Assert.assertFalse(EngineMetrics.killForegroundAge.testHasValue()) + Assert.assertFalse(EngineMetrics.killBackgroundAge.testHasValue()) + + store.dispatch( + EngineAction.KillEngineSessionAction("background_pocket") + ).joinBlocking() + + Assert.assertTrue(EngineMetrics.killBackgroundAge.testHasValue()) + Assert.assertFalse(EngineMetrics.killForegroundAge.testHasValue()) + assertEquals(600, EngineMetrics.killBackgroundAge.testGetValue()) + } +} + +private class FakeClock : Clock.Delegate { + var elapsedTime: Long = 0 + override fun elapsedRealtime(): Long = elapsedTime } diff --git a/docs/metrics.md b/docs/metrics.md index 36f60ebaa..463f8fa6c 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -280,6 +280,9 @@ The following metrics are added to the ping: | browser.search.ad_clicks |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |Records clicks of adverts on SERP pages. The key format is ‘’. |[1](https://github.com/mozilla-mobile/fenix/pull/10112), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | browser.search.in_content |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |Records the type of interaction a user has on SERP pages. |[1](https://github.com/mozilla-mobile/fenix/pull/10167), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | browser.search.with_ads |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |Records counts of SERP pages with adverts displayed. The key format is ‘’. |[1](https://github.com/mozilla-mobile/fenix/pull/10112), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | +| engine.kill_background_age |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |Measures the age of the engine session of a background tab at the time its content process got killed. |[1](https://github.com/mozilla-mobile/fenix/pull/17864)||2021-12-31 |1 | +| engine.kill_foreground_age |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |Measures the age of the engine session of a foreground (selected) tab at the time its content process got killed. |[1](TBD)||2021-12-31 |1 | +| engine.tab_kills |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |How often was the content process of a foreground (selected) or background tab killed. |[1](https://github.com/mozilla-mobile/fenix/pull/17864)|
  • foreground
  • background
|2021-12-31 |1 | | events.total_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This does not include background page requests and URIs from embedded pages or private browsing but may be incremented without user interaction by website scripts that programmatically redirect to a new location. |[1](https://github.com/mozilla-mobile/fenix/pull/1785), [2](https://github.com/mozilla-mobile/fenix/pull/8314), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | metrics.adjust_ad_group |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust ad group ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[1](https://github.com/mozilla-mobile/fenix/pull/9253), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | metrics.adjust_campaign |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust campaign ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[1](https://github.com/mozilla-mobile/fenix/pull/5579), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | From 1989d20ff691479a39e6459d149462d48d9d26ef Mon Sep 17 00:00:00 2001 From: sarentz <79221620+sarentz@users.noreply.github.com> Date: Fri, 19 Feb 2021 10:26:51 -0500 Subject: [PATCH 158/248] Only run the build-contributor-pr workflow on forks (#18082) --- .github/workflows/build-contributor-pr.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-contributor-pr.yml b/.github/workflows/build-contributor-pr.yml index 969873a67..b966cb796 100644 --- a/.github/workflows/build-contributor-pr.yml +++ b/.github/workflows/build-contributor-pr.yml @@ -3,7 +3,7 @@ on: [pull_request] jobs: run-build: runs-on: ubuntu-20.04 - if: github.repository != 'mozilla-mobile/fenix' + if: github.event.pull_request.head.repo.full_name != github.repository steps: - name: Checkout repository uses: actions/checkout@v2 @@ -21,7 +21,7 @@ jobs: run-testDebugUnitTest: runs-on: ubuntu-20.04 - if: github.repository != 'mozilla-mobile/fenix' + if: github.event.pull_request.head.repo.full_name != github.repository steps: - name: Checkout repository uses: actions/checkout@v2 @@ -39,7 +39,7 @@ jobs: run-detekt: runs-on: ubuntu-20.04 - if: github.repository != 'mozilla-mobile/fenix' + if: github.event.pull_request.head.repo.full_name != github.repository steps: - name: Checkout repository uses: actions/checkout@v2 @@ -62,7 +62,7 @@ jobs: run-ktlint: runs-on: ubuntu-20.04 - if: github.repository != 'mozilla-mobile/fenix' + if: github.event.pull_request.head.repo.full_name != github.repository steps: - name: Checkout repository uses: actions/checkout@v2 @@ -80,7 +80,7 @@ jobs: run-lintDebug: runs-on: ubuntu-20.04 - if: github.repository != 'mozilla-mobile/fenix' + if: github.event.pull_request.head.repo.full_name != github.repository steps: - name: Checkout repository uses: actions/checkout@v2 From 64f32b9d95d72f70f9d63b234009060e61c0792e Mon Sep 17 00:00:00 2001 From: Roger Yang Date: Fri, 19 Feb 2021 10:37:07 -0500 Subject: [PATCH 159/248] Closes #17089: Add metric to track both normal and private URI opened (#17935) --- app/metrics.yaml | 19 +++++++++++++++++++ .../org/mozilla/fenix/TelemetryMiddleware.kt | 10 +++++++--- .../mozilla/fenix/components/metrics/Event.kt | 1 + .../components/metrics/GleanMetricsService.kt | 3 +++ .../mozilla/fenix/TelemetryMiddlewareTest.kt | 4 ++++ docs/metrics.md | 1 + 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 82175a8f7..7aed730d5 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -234,6 +234,25 @@ events: notification_emails: - fenix-core@mozilla.com expires: "2021-08-01" + normal_and_private_uri_count: + type: counter + description: | + A counter of URIs visited by the user in the current session, including + page reloads. This includes private browsing. This does not include + background page requests and URIs from embedded pages but may be + incremented without user interaction by website scripts that + programmatically redirect to a new location. + send_in_pings: + - metrics + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17089 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17935 + data_sensitivity: + - interaction + notification_emails: + - fenix-core@mozilla.com + expires: "2022-08-01" preference_toggled: type: event description: | diff --git a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt index f16cae272..53a55bdfd 100644 --- a/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/TelemetryMiddleware.kt @@ -55,7 +55,7 @@ class TelemetryMiddleware( } } - @Suppress("TooGenericExceptionCaught", "ComplexMethod") + @Suppress("TooGenericExceptionCaught", "ComplexMethod", "NestedBlockDepth") override fun invoke( context: MiddlewareContext, next: (BrowserAction) -> Unit, @@ -66,8 +66,12 @@ class TelemetryMiddleware( is ContentAction.UpdateLoadingStateAction -> { context.state.findTab(action.sessionId)?.let { tab -> // Record UriOpened event when a non-private page finishes loading - if (tab.content.loading && !action.loading && !tab.content.private) { - metrics.track(Event.UriOpened) + if (tab.content.loading && !action.loading) { + if (!tab.content.private) { + metrics.track(Event.UriOpened) + } + + metrics.track(Event.NormalAndPrivateUriOpened) } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index 974e6b83a..c7e2431ea 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -52,6 +52,7 @@ sealed class Event { object CustomTabsActionTapped : Event() object CustomTabsMenuOpened : Event() object UriOpened : Event() + object NormalAndPrivateUriOpened : Event() object SyncAuthOpened : Event() object SyncAuthClosed : Event() object SyncAuthSignUp : Event() diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 404ae9aff..d122d34a7 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -237,6 +237,9 @@ private val Event.wrapper: EventWrapper<*>? is Event.UriOpened -> EventWrapper( { Events.totalUriCount.add(1) } ) + is Event.NormalAndPrivateUriOpened -> EventWrapper( + { Events.normalAndPrivateUriCount.add(1) } + ) is Event.ErrorPageVisited -> EventWrapper( { ErrorPage.visitedError.record(it) }, { ErrorPage.visitedErrorKeys.valueOf(it) } diff --git a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt index 35c5421ea..3f086f68f 100644 --- a/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt +++ b/app/src/test/java/org/mozilla/fenix/TelemetryMiddlewareTest.kt @@ -182,9 +182,11 @@ class TelemetryMiddlewareTest { store.dispatch(TabListAction.AddTabAction(tab)).joinBlocking() store.dispatch(ContentAction.UpdateLoadingStateAction(tab.id, true)).joinBlocking() verify(exactly = 0) { metrics.track(Event.UriOpened) } + verify(exactly = 0) { metrics.track(Event.NormalAndPrivateUriOpened) } store.dispatch(ContentAction.UpdateLoadingStateAction(tab.id, false)).joinBlocking() verify(exactly = 1) { metrics.track(Event.UriOpened) } + verify(exactly = 1) { metrics.track(Event.NormalAndPrivateUriOpened) } } @Test @@ -193,9 +195,11 @@ class TelemetryMiddlewareTest { store.dispatch(TabListAction.AddTabAction(tab)).joinBlocking() store.dispatch(ContentAction.UpdateLoadingStateAction(tab.id, true)).joinBlocking() verify(exactly = 0) { metrics.track(Event.UriOpened) } + verify(exactly = 0) { metrics.track(Event.NormalAndPrivateUriOpened) } store.dispatch(ContentAction.UpdateLoadingStateAction(tab.id, false)).joinBlocking() verify(exactly = 0) { metrics.track(Event.UriOpened) } + verify(exactly = 1) { metrics.track(Event.NormalAndPrivateUriOpened) } } @Test diff --git a/docs/metrics.md b/docs/metrics.md index 463f8fa6c..413204af1 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -283,6 +283,7 @@ The following metrics are added to the ping: | engine.kill_background_age |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |Measures the age of the engine session of a background tab at the time its content process got killed. |[1](https://github.com/mozilla-mobile/fenix/pull/17864)||2021-12-31 |1 | | engine.kill_foreground_age |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |Measures the age of the engine session of a foreground (selected) tab at the time its content process got killed. |[1](TBD)||2021-12-31 |1 | | engine.tab_kills |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |How often was the content process of a foreground (selected) or background tab killed. |[1](https://github.com/mozilla-mobile/fenix/pull/17864)|
  • foreground
  • background
|2021-12-31 |1 | +| events.normal_and_private_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This includes private browsing. This does not include background page requests and URIs from embedded pages but may be incremented without user interaction by website scripts that programmatically redirect to a new location. |[1](https://github.com/mozilla-mobile/fenix/pull/17935)||2022-08-01 |2 | | events.total_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This does not include background page requests and URIs from embedded pages or private browsing but may be incremented without user interaction by website scripts that programmatically redirect to a new location. |[1](https://github.com/mozilla-mobile/fenix/pull/1785), [2](https://github.com/mozilla-mobile/fenix/pull/8314), [3](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | metrics.adjust_ad_group |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust ad group ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[1](https://github.com/mozilla-mobile/fenix/pull/9253), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | metrics.adjust_campaign |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust campaign ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[1](https://github.com/mozilla-mobile/fenix/pull/5579), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | From 6e0a64897b0cab11ec2808d218dbf35ddaea5174 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Mon, 8 Feb 2021 19:34:12 +0200 Subject: [PATCH 160/248] For #17899 - Expand toolbar when returning from fullscreen video This was the previous behavior for both the top and bottom toolbars. Regressed when changing to use a new custom behavior for the top toolbar. When entering fullscreen we will now collapse and hide the toolbar, allow the browser to expand to the entire screen estate and then, when exiting fullscreen expand the toolbar. Collapsing and then expanding the toolbar will trigger the EngineViewBrowserToolbarBehavior to place the browser below the toolbar. --- .../fenix/browser/BaseBrowserFragment.kt | 3 +- .../components/toolbar/BrowserToolbarView.kt | 11 +++++ .../toolbar/BrowserToolbarViewTest.kt | 47 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 19644bf42..3718b2dfe 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -1220,6 +1220,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit .setText(getString(R.string.full_screen_notification)) .show() activity?.enterToImmersiveMode() + browserToolbarView.collapse() browserToolbarView.view.isVisible = false val browserEngine = swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams browserEngine.bottomMargin = 0 @@ -1227,7 +1228,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit swipeRefresh.translationY = 0f engineView.setDynamicToolbarMaxHeight(0) - browserToolbarView.expand() // Without this, fullscreen has a margin at the top. engineView.setVerticalClipping(0) @@ -1241,6 +1241,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit browserToolbarView.view.isVisible = true val toolbarHeight = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height) initializeEngineView(toolbarHeight) + browserToolbarView.expand() } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index d8e7e306f..1b25af105 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -215,6 +215,17 @@ class BrowserToolbarView( } } + fun collapse() { + // collapse only for normal tabs and custom tabs not for PWA or TWA. Mirror expand() + if (isPwaTabOrTwaTab) { + return + } + + (view.layoutParams as? CoordinatorLayout.LayoutParams)?.apply { + (behavior as? BrowserToolbarBehavior)?.forceCollapse(view) + } + } + fun dismissMenu() { view.dismissMenu() } diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt index f75b1d448..df34475e5 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt @@ -5,6 +5,7 @@ package org.mozilla.fenix.components.toolbar import androidx.coordinatorlayout.widget.CoordinatorLayout +import io.mockk.confirmVerified import io.mockk.every import io.mockk.mockk @@ -193,4 +194,50 @@ class BrowserToolbarViewTest { assertNotNull((toolbar.layoutParams as CoordinatorLayout.LayoutParams).behavior) } + + @Test + fun `expand should not do anything if isPwaTabOrTwaTab`() { + val toolbarViewSpy = spyk(toolbarView) + every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + + toolbarViewSpy.expand() + + verify { toolbarViewSpy.expand() } + verify { toolbarViewSpy.isPwaTabOrTwaTab } + // verify that no other interactions than the expected ones took place + confirmVerified(toolbarViewSpy) + } + + @Test + fun `expand should call forceExpand if not isPwaTabOrTwaTab`() { + val toolbarViewSpy = spyk(toolbarView) + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + + toolbarViewSpy.expand() + + verify { behavior.forceExpand(toolbar) } + } + + @Test + fun `collapse should not do anything if isPwaTabOrTwaTab`() { + val toolbarViewSpy = spyk(toolbarView) + every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + + toolbarViewSpy.collapse() + + verify { toolbarViewSpy.collapse() } + verify { toolbarViewSpy.isPwaTabOrTwaTab } + // verify that no other interactions than the expected ones took place + confirmVerified(toolbarViewSpy) + } + + @Test + fun `collapse should call forceExpand if not isPwaTabOrTwaTab`() { + val toolbarViewSpy = spyk(toolbarView) + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + + toolbarViewSpy.collapse() + + verify { behavior.forceCollapse(toolbar) } + } } From 993428cd0f994ccfa1b6f9fd1c724e6ad0ff45ec Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Thu, 11 Feb 2021 15:19:26 -0800 Subject: [PATCH 161/248] For #17969: add duration probes for App.onCreate and HomeActivity.onCreate. --- app/metrics.yaml | 32 +++++++++++++++++ .../org/mozilla/fenix/FenixApplication.kt | 5 +++ .../java/org/mozilla/fenix/HomeActivity.kt | 3 +- .../org/mozilla/fenix/FenixApplicationTest.kt | 35 +++++++++++++++++++ .../org/mozilla/fenix/HomeActivityTest.kt | 23 ++++++++++++ docs/metrics.md | 2 ++ 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt diff --git a/app/metrics.yaml b/app/metrics.yaml index 7aed730d5..ee9289f5d 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -3962,6 +3962,38 @@ startup.timeline: - mcomella@mozilla.com expires: "2021-08-01" +perf.startup: + application_on_create: + type: timing_distribution + time_unit: millisecond + description: | + The duration of `FenixApplication.onCreate` in the main process. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17969 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17973#issue-572183889 + data_sensitivity: + - technical + notification_emails: + - perf-android-fe@mozilla.com + - mcomella@mozilla.com + expires: "2021-08-11" + home_activity_on_create: + type: timing_distribution + time_unit: millisecond + description: | + The duration of `HomeActivity.onCreate`. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17969 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/17973#issue-572183889 + data_sensitivity: + - technical + notification_emails: + - perf-android-fe@mozilla.com + - mcomella@mozilla.com + expires: "2021-08-11" + perf.awesomebar: history_suggestions: send_in_pings: diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 03db2e676..d3ddf601b 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -39,6 +39,7 @@ import mozilla.components.support.rusthttp.RustHttpConfig import mozilla.components.support.rustlog.RustLog import mozilla.components.support.utils.logElapsedTime import mozilla.components.support.webextensions.WebExtensionSupport +import org.mozilla.fenix.GleanMetrics.PerfStartup import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.metrics.MetricServiceType import org.mozilla.fenix.ext.settings @@ -71,6 +72,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { private set override fun onCreate() { + val methodDurationTimerId = PerfStartup.applicationOnCreate.start() // DO NOT MOVE ANYTHING ABOVE HERE. super.onCreate() setupInAllProcesses() @@ -92,6 +94,9 @@ open class FenixApplication : LocaleAwareApplication(), Provider { } setupInMainProcessOnly() + + // We use start/stop instead of measure so we don't measure outside the main process. + PerfStartup.applicationOnCreate.stopAndAccumulate(methodDurationTimerId) // DO NOT MOVE ANYTHING BELOW HERE. } protected open fun initializeGlean() { diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index e07844bd9..a648c64a7 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -65,6 +65,7 @@ import mozilla.components.support.utils.SafeIntent import mozilla.components.support.utils.toSafeIntent import mozilla.components.support.webextensions.WebExtensionPopupFeature import org.mozilla.fenix.GleanMetrics.Metrics +import org.mozilla.fenix.GleanMetrics.PerfStartup import org.mozilla.fenix.addons.AddonDetailsFragmentDirections import org.mozilla.fenix.addons.AddonPermissionsDetailsFragmentDirections import org.mozilla.fenix.browser.browsingmode.BrowsingMode @@ -163,7 +164,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { private lateinit var navigationToolbar: Toolbar - final override fun onCreate(savedInstanceState: Bundle?) { + final override fun onCreate(savedInstanceState: Bundle?): Unit = PerfStartup.homeActivityOnCreate.measure { // DO NOT MOVE ANYTHING ABOVE THIS addMarker CALL. components.core.engine.profiler?.addMarker("Activity.onCreate", "HomeActivity") diff --git a/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt b/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt new file mode 100644 index 000000000..c3f21d59a --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt @@ -0,0 +1,35 @@ +/* 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 org.mozilla.fenix + +import androidx.test.core.app.ApplicationProvider +import mozilla.components.service.glean.testing.GleanTestRule +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.GleanMetrics.PerfStartup +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class FenixApplicationTest { + + @get:Rule val gleanTestRule = GleanTestRule(ApplicationProvider.getApplicationContext()) + + private lateinit var application: FenixApplication + + @Before + fun setUp() { + application = ApplicationProvider.getApplicationContext() + } + + @Test + fun `GIVEN onCreate is called THEN the duration is measured`() { + // application.onCreate is called before the test as part of test set up: + // https://robolectric.blogspot.com/2013/04/the-test-lifecycle-in-20.html + assertTrue(PerfStartup.applicationOnCreate.testHasValue()) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt b/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt index 9d83d5360..9c086a9f5 100644 --- a/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt +++ b/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt @@ -6,10 +6,12 @@ package org.mozilla.fenix import android.content.Intent import android.os.Bundle +import androidx.test.core.app.ApplicationProvider import io.mockk.every import io.mockk.mockk import io.mockk.spyk import io.mockk.verify +import mozilla.components.service.glean.testing.GleanTestRule import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.utils.toSafeIntent import org.junit.Assert.assertEquals @@ -18,8 +20,10 @@ import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mozilla.fenix.GleanMetrics.PerfStartup import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager @@ -28,10 +32,13 @@ import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.utils.Settings +import org.robolectric.Robolectric @RunWith(FenixRobolectricTestRunner::class) class HomeActivityTest { + @get:Rule val gleanTestRule = GleanTestRule(ApplicationProvider.getApplicationContext()) + private lateinit var activity: HomeActivity @Before @@ -131,4 +138,20 @@ class HomeActivityTest { assertFalse(activity.isActivityColdStarted(startingIntent, Bundle())) } + + @Test + fun `WHEN onCreate is called THEN the duration is measured`() { + assertFalse(PerfStartup.homeActivityOnCreate.testHasValue()) // sanity check. + + // For some reason, the androidx replacement for this method, ActivityScenario, fails so we + // use the old Robolectric version. Perhaps it's because it forces the Activity to the + // RESUMED state (unlike Robolectric where we can get to CREATED) so not enough code is + // mocked for that to work. + // + // There are various exceptions thrown on background threads when this test runs but it + // doesn't seem to impact correctness so we ignore them. + Robolectric.buildActivity(HomeActivity::class.java) + .create() + assertTrue(PerfStartup.homeActivityOnCreate.testHasValue()) + } } diff --git a/docs/metrics.md b/docs/metrics.md index 413204af1..a3026ee72 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -315,6 +315,8 @@ The following metrics are added to the ping: | perf.awesomebar.session_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a session awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | | perf.awesomebar.shortcuts_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a shortcuts awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | | perf.awesomebar.synced_tabs_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a synced tabs awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | +| perf.startup.application_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `FenixApplication.onCreate` in the main process. |[1](todo)||2021-08-11 |1 | +| perf.startup.home_activity_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `HomeActivity.onCreate`. |[1](todo)||2021-08-11 |1 | | preferences.accessibility_services |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has touch exploration or switch services enabled. These are built into the Android OS, not Fenix prefs. default: "" |[1](https://github.com/mozilla-mobile/fenix/pull/11211), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | preferences.open_links_in_a_private_tab |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has enabled open links in a private tab. default: false |[1](https://github.com/mozilla-mobile/fenix/pull/11211), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | preferences.open_links_in_app |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has the open links in apps feature enabled. default: false |[1](https://github.com/mozilla-mobile/fenix/pull/11446), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | From 012cc215214f1e43a1e2b0132cfa3dcf22c66318 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Wed, 17 Feb 2021 19:34:10 -0800 Subject: [PATCH 162/248] For #17972: add client id to startup-timeline ping, update docs. This addresses the root problem we're experiencing for this issue - data not showing up in GLAM. --- app/pings.yaml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/pings.yaml b/app/pings.yaml index 771cde2b7..1a8502827 100644 --- a/app/pings.yaml +++ b/app/pings.yaml @@ -35,14 +35,18 @@ startup-timeline: description: | This ping is intended to provide an understanding of startup performance. - The ping is intended to be captured by performance testing automation to - report results there, in addition to user telemetry. We place these metrics - into their own ping in order to isolate them and make this process easier. - include_client_id: false + In addition to being captured on real devices, the ping data was prematurely + optimized into this separate ping to be isolated from other metrics to be + more easily captured by performance testing automation but that hasn't + happened in practice. We would have removed it but implementation + details don't make that possible: + https://github.com/mozilla-mobile/fenix/issues/17972#issuecomment-781002987 + include_client_id: true bugs: - https://github.com/mozilla-mobile/fenix/issues/8803 + - https://github.com/mozilla-mobile/fenix/issues/17972 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626 notification_emails: - perf-android-fe@mozilla.com - - esmyth@mozilla.com + - mcomella@mozilla.com From 359f27abc17619a7a96362e1fb4de736ac6501d7 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Wed, 17 Feb 2021 20:13:45 -0800 Subject: [PATCH 163/248] For #17972: split frameworkStart into two metrics. We do this in order to make it easier to analyze in GLAM: see the metric descriptions for more details. Additionally, we change the time unit to milliseconds to make it easier to analyze in GLAM. --- app/metrics.yaml | 40 +++++++-- app/pings.yaml | 1 + .../perf/StartupFrameworkStartMeasurement.kt | 20 +++-- .../StartupFrameworkStartMeasurementTest.kt | 87 ++++++++++++++++--- docs/metrics.md | 18 ++-- 5 files changed, 136 insertions(+), 30 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index ee9289f5d..53e09d98e 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -3878,14 +3878,21 @@ addons: expires: "2021-04-01" startup.timeline: - framework_start: + framework_primary: send_in_pings: - startup-timeline type: timespan - time_unit: nanosecond + time_unit: millisecond description: | The duration the Android framework takes to start before letting us run - code in `*Application.init`. This is calculated from `appInitTimestamp - + code in `*Application.init` when this device has `clock_ticks_per_second` + equal to 100: if it's not equal to 100, then this value is captured in + `framework_secondary`. We split this into two metrics to make it easier + to analyze in GLAM. We split on 100 because when we did our initial brief + analysis - https://sql.telemetry.mozilla.org/queries/75591 - the results + for clocks ticks were overwhelmingly 100. + + The duration is calculated from `appInitTimestamp - processStartTimestamp`. `processStartTimestamp` is derived from the clock tick time unit, which is expected to be less granular than nanoseconds. Therefore, we convert and round our timestamps to clock ticks before @@ -3895,9 +3902,30 @@ startup.timeline: devices, is also reported as a metric bugs: - https://github.com/mozilla-mobile/fenix/issues/8803 + - https://github.com/mozilla-mobile/fenix/issues/17972 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626 - https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068 + - https://github.com/mozilla-mobile/fenix/pull/18043#issue-575389284 + data_sensitivity: + - technical + notification_emails: + - perf-android-fe@mozilla.com + - mcomella@mozilla.com + expires: "2021-08-01" + framework_secondary: + send_in_pings: + - startup-timeline + type: timespan + time_unit: millisecond + description: | + The duration the Android framework takes to start before letting us run + code in `*Application.init` when this device has `clock_ticks_per_second` + not equal to 100. For more details on this metric, see `framework_primary` + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17972 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18043#issue-575389284 data_sensitivity: - technical notification_emails: @@ -3909,9 +3937,9 @@ startup.timeline: - startup-timeline type: boolean description: | - An error when attempting to record `framework_start` - the application - init timestamp returned a negative value - which is likely indicative of a - bug in the implementation. + An error when attempting to record `framework_primary/secondary` - the + application init timestamp returned a negative value - which is likely + indicative of a bug in the implementation. bugs: - https://github.com/mozilla-mobile/fenix/issues/8803 data_reviews: diff --git a/app/pings.yaml b/app/pings.yaml index 1a8502827..bd726ff12 100644 --- a/app/pings.yaml +++ b/app/pings.yaml @@ -47,6 +47,7 @@ startup-timeline: - https://github.com/mozilla-mobile/fenix/issues/17972 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626 + - https://github.com/mozilla-mobile/fenix/pull/18043#issue-575389284 notification_emails: - perf-android-fe@mozilla.com - mcomella@mozilla.com diff --git a/app/src/main/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurement.kt b/app/src/main/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurement.kt index dbc4d2c24..47953d9b7 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurement.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurement.kt @@ -54,20 +54,30 @@ internal class StartupFrameworkStartMeasurement( if (applicationInitNanos < 0) { telemetry.frameworkStartError.set(true) } else { + val clockTicksPerSecond = stat.clockTicksPerSecond.also { + // framework* is derived from the number of clock ticks per second. To ensure this + // value does not throw off our result, we capture it too. + telemetry.clockTicksPerSecond.add(it.toInt()) + } + + // In our brief analysis, clock ticks per second was overwhelmingly equal to 100. To make + // analysis easier in GLAM, we split the results into two separate metrics. See the + // metric descriptions for more details. + @Suppress("MagicNumber") // it's more confusing to separate the comment above from the value declaration. + val durationMetric = + if (clockTicksPerSecond == 100L) telemetry.frameworkPrimary else telemetry.frameworkSecondary + try { - telemetry.frameworkStart.setRawNanos(getFrameworkStartNanos()) + durationMetric.setRawNanos(getFrameworkStartNanos()) } catch (e: FileNotFoundException) { // Privacy managers can add hooks that block access to reading system /proc files. // We want to catch these exception and report an error on accessing the file // rather than an implementation error. telemetry.frameworkStartReadError.set(true) } - - // frameworkStart is derived from the number of clock ticks per second. To ensure this - // value does not throw off our result, we capture it too. - telemetry.clockTicksPerSecond.add(stat.clockTicksPerSecond.toInt()) } } + /** * @throws [java.io.FileNotFoundException] */ diff --git a/app/src/test/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurementTest.kt b/app/src/test/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurementTest.kt index 7fadf1f28..fa465b2fb 100644 --- a/app/src/test/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurementTest.kt +++ b/app/src/test/java/org/mozilla/fenix/perf/StartupFrameworkStartMeasurementTest.kt @@ -17,7 +17,8 @@ import org.junit.Before import org.junit.Test import org.mozilla.fenix.GleanMetrics.StartupTimeline as Telemetry -private const val CLOCK_TICKS_PER_SECOND = 100L +private const val PRIMARY_TICKS = 100L +private const val SECONDARY_TICKS = 50L class StartupFrameworkStartMeasurementTest { @@ -27,10 +28,13 @@ class StartupFrameworkStartMeasurementTest { // We'd prefer to use the Glean test methods over these mocks but they require us to add // Robolectric and it's not worth the impact on test duration. @MockK private lateinit var telemetry: Telemetry - @MockK(relaxed = true) private lateinit var frameworkStart: TimespanMetricType + @MockK(relaxed = true) private lateinit var frameworkPrimary: TimespanMetricType + @MockK(relaxed = true) private lateinit var frameworkSecondary: TimespanMetricType @MockK(relaxed = true) private lateinit var frameworkStartError: BooleanMetricType @MockK(relaxed = true) private lateinit var clockTicksPerSecond: CounterMetricType + private var clockTicksPerSecondValue = -1L + private var elapsedRealtimeNanos = -1L private var processStartTimeTicks = -1L @@ -41,13 +45,17 @@ class StartupFrameworkStartMeasurementTest { elapsedRealtimeNanos = -1 processStartTimeTicks = -1 + // This value is hard-coded in the OS so we default to it as it's the expected value. + clockTicksPerSecondValue = PRIMARY_TICKS + stat = spyk(object : Stat() { - override val clockTicksPerSecond: Long get() = CLOCK_TICKS_PER_SECOND + override val clockTicksPerSecond: Long get() = clockTicksPerSecondValue }) every { stat.getProcessStartTimeTicks(any()) } answers { processStartTimeTicks } val getElapsedRealtimeNanos = { elapsedRealtimeNanos } - every { telemetry.frameworkStart } returns frameworkStart + every { telemetry.frameworkPrimary } returns frameworkPrimary + every { telemetry.frameworkSecondary } returns frameworkSecondary every { telemetry.frameworkStartError } returns frameworkStartError every { telemetry.clockTicksPerSecond } returns clockTicksPerSecond @@ -67,13 +75,32 @@ class StartupFrameworkStartMeasurementTest { } @Test - fun `GIVEN app init is set to valid values WHEN metrics are set THEN frameworkStart is set with the correct value`() { + fun `GIVEN app init is set to valid values and clock ticks per second is 100 WHEN metrics are set THEN frameworkPrimary is set with the correct value`() { + clockTicksPerSecondValue = PRIMARY_TICKS + setProcessAppInitAndMetrics(processStart = 166_636_813, appInit = 1_845_312_345_673_925) + verifyFrameworkStartSuccess(178_944_220_000_000, isPrimary = true) // calculated by hand. + } + + @Test + fun `GIVEN app init is set to valid values and clock ticks per second is not 100 WHEN metrics are set THEN frameworkSecondary is set with the correct value`() { + clockTicksPerSecondValue = SECONDARY_TICKS setProcessAppInitAndMetrics(processStart = 166_636_813, appInit = 1_845_312_345_673_925) - verifyFrameworkStartSuccess(178_944_220_000_000) // calculated by hand. + verifyFrameworkStartSuccess(178_944_220_000_000, isPrimary = false) // calculated by hand. } @Test // this overlaps with the success case test. - fun `GIVEN app init has valid values WHEN onAppInit is called twice and metrics are set THEN frameworkStart uses the first app init value`() { + fun `GIVEN app init has valid values and clock ticks per second is 100 WHEN onAppInit is called twice and metrics are set THEN frameworkPrimary uses the first app init value`() { + clockTicksPerSecondValue = PRIMARY_TICKS + testAppInitCalledTwice(isPrimary = true) + } + + @Test // this overlaps with the success case test. + fun `GIVEN app init has valid values and clock ticks per second is not 100 WHEN onAppInit is called twice and metrics are set THEN frameworkSecondary uses the first app init value`() { + clockTicksPerSecondValue = SECONDARY_TICKS + testAppInitCalledTwice(isPrimary = false) + } + + private fun testAppInitCalledTwice(isPrimary: Boolean) { processStartTimeTicks = 166_636_813 elapsedRealtimeNanos = 1_845_312_345_673_925 @@ -82,14 +109,28 @@ class StartupFrameworkStartMeasurementTest { metrics.onApplicationInit() metrics.setExpensiveMetric() - verifyFrameworkStartSuccess(178_944_220_000_000) // calculated by hand. + verifyFrameworkStartSuccess(178_944_220_000_000, isPrimary) // calculated by hand. } @Test - fun `GIVEN app init have valid values WHEN metrics are set twice THEN frameworkStart is only set once`() { + fun `GIVEN app init have valid values and clock ticks per second is 100 WHEN metrics are set twice THEN frameworkPrimary is only set once`() { + clockTicksPerSecondValue = PRIMARY_TICKS + testMetricsSetTwice(isPrimary = true) + } + + @Test + fun `GIVEN app init have valid values and clock ticks per second is not 100 WHEN metrics are set twice THEN frameworkSecondary is only set once`() { + clockTicksPerSecondValue = SECONDARY_TICKS + testMetricsSetTwice(isPrimary = false) + } + + private fun testMetricsSetTwice(isPrimary: Boolean) { setProcessAppInitAndMetrics(10, 100) metrics.setExpensiveMetric() - verify(exactly = 1) { frameworkStart.setRawNanos(any()) } + + val (setMetric, unsetMetric) = getSetAndUnsetMetric(isPrimary) + verify(exactly = 1) { setMetric.setRawNanos(any()) } + verify { unsetMetric wasNot Called } verify(exactly = 1) { clockTicksPerSecond.add(any()) } verify { frameworkStartError wasNot Called } } @@ -103,15 +144,33 @@ class StartupFrameworkStartMeasurementTest { metrics.setExpensiveMetric() } - private fun verifyFrameworkStartSuccess(nanos: Long) { - verify { frameworkStart.setRawNanos(nanos) } - verify { clockTicksPerSecond.add(CLOCK_TICKS_PER_SECOND.toInt()) } + private fun verifyFrameworkStartSuccess(nanos: Long, isPrimary: Boolean) { + val (setMetric, unsetMetric) = getSetAndUnsetMetric(isPrimary) + verify { setMetric.setRawNanos(nanos) } + verify { unsetMetric wasNot Called } + + val expectedClockTicksPerSecond = getExpectedClockTicksPerSecond(isPrimary) + verify { clockTicksPerSecond.add(expectedClockTicksPerSecond.toInt()) } verify { frameworkStartError wasNot Called } } private fun verifyFrameworkStartError() { verify { frameworkStartError.set(true) } - verify { frameworkStart wasNot Called } + verify { frameworkPrimary wasNot Called } + verify { frameworkSecondary wasNot Called } verify { clockTicksPerSecond wasNot Called } } + + private fun getSetAndUnsetMetric(isPrimary: Boolean): Pair { + return if (isPrimary) { + Pair(frameworkPrimary, frameworkSecondary) + } else { + Pair(frameworkSecondary, frameworkPrimary) + } + } + + // This hard-codes some data that's passed into the test but I don't want to spend more time + // so I don't bother cleaning it up now. + private fun getExpectedClockTicksPerSecond(isPrimary: Boolean): Long = + if (isPrimary) PRIMARY_TICKS else SECONDARY_TICKS } diff --git a/docs/metrics.md b/docs/metrics.md index a3026ee72..4412b58ab 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -346,26 +346,34 @@ The following metrics are added to the ping: This ping is intended to provide an understanding of startup performance. -The ping is intended to be captured by performance testing automation to -report results there, in addition to user telemetry. We place these metrics -into their own ping in order to isolate them and make this process easier. +In addition to being captured on real devices, the ping data was prematurely +optimized into this separate ping to be isolated from other metrics to be +more easily captured by performance testing automation but that hasn't +happened in practice. We would have removed it but implementation +details don't make that possible: +https://github.com/mozilla-mobile/fenix/issues/17972#issuecomment-781002987 +This ping includes the [client id](https://mozilla.github.io/glean/book/user/pings/index.html#the-client_info-section). + **Data reviews for this ping:** - +- **Bugs related to this ping:** - +- The following metrics are added to the ping: | Name | Type | Description | Data reviews | Extras | Expiration | [Data Sensitivity](https://wiki.mozilla.org/Firefox/Data_Collection) | | --- | --- | --- | --- | --- | --- | --- | | startup.timeline.clock_ticks_per_second |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |The number of clock tick time units that occur in one second on this particular device. This value is expected to be used in conjunction with the `framework_start` metric. |[1](https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | -| startup.timeline.framework_start |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |The duration the Android framework takes to start before letting us run code in `*Application.init`. This is calculated from `appInitTimestamp - processStartTimestamp`. `processStartTimestamp` is derived from the clock tick time unit, which is expected to be less granular than nanoseconds. Therefore, we convert and round our timestamps to clock ticks before computing the difference and convert back to nanoseconds to report. For debugging purposes, `clock_ticks_per_second`, which may vary between devices, is also reported as a metric |[1](https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | -| startup.timeline.framework_start_error |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |An error when attempting to record `framework_start` - the application init timestamp returned a negative value - which is likely indicative of a bug in the implementation. |[1](https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | +| startup.timeline.framework_primary |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |The duration the Android framework takes to start before letting us run code in `*Application.init` when this device has `clock_ticks_per_second` equal to 100: if it's not equal to 100, then this value is captured in `framework_secondary`. We split this into two metrics to make it easier to analyze in GLAM. We split on 100 because when we did our initial brief analysis - https://sql.telemetry.mozilla.org/queries/75591 - the results for clocks ticks were overwhelmingly 100. The duration is calculated from `appInitTimestamp - processStartTimestamp`. `processStartTimestamp` is derived from the clock tick time unit, which is expected to be less granular than nanoseconds. Therefore, we convert and round our timestamps to clock ticks before computing the difference and convert back to nanoseconds to report. For debugging purposes, `clock_ticks_per_second`, which may vary between devices, is also reported as a metric |[1](https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068), [3](https://github.com/mozilla-mobile/fenix/pull/18043#issue-575389284)||2021-08-01 |1 | +| startup.timeline.framework_secondary |[timespan](https://mozilla.github.io/glean/book/user/metrics/timespan.html) |The duration the Android framework takes to start before letting us run code in `*Application.init` when this device has `clock_ticks_per_second` not equal to 100. For more details on this metric, see `framework_primary` |[1](https://github.com/mozilla-mobile/fenix/pull/18043#issue-575389284)||2021-08-01 |1 | +| startup.timeline.framework_start_error |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |An error when attempting to record `framework_primary/secondary` - the application init timestamp returned a negative value - which is likely indicative of a bug in the implementation. |[1](https://github.com/mozilla-mobile/fenix/pull/9788#pullrequestreview-394228626), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | | startup.timeline.framework_start_read_error |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |An error when attempting to read stats from /proc pseudo-filesystem - privacy managers can block access to reading these files - the application will catch a file reading exception. |[1](https://github.com/mozilla-mobile/fenix/pull/10481), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 | From 516a6a343f480310a116b3aa006d9e63458006e2 Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sat, 20 Feb 2021 00:06:06 +0000 Subject: [PATCH 164/248] Import l10n. --- app/src/main/res/values-be/strings.xml | 12 +++++++++--- app/src/main/res/values-cak/strings.xml | 12 +++++++++--- app/src/main/res/values-de/strings.xml | 12 +++++++++--- app/src/main/res/values-el/strings.xml | 12 +++++++++--- app/src/main/res/values-en-rCA/strings.xml | 18 +++++++++++++++--- app/src/main/res/values-kmr/strings.xml | 18 +++++++++++++++--- app/src/main/res/values-ko/strings.xml | 12 +++++++++--- app/src/main/res/values-nb-rNO/strings.xml | 12 +++++++++--- app/src/main/res/values-pt-rBR/strings.xml | 12 +++++++++--- app/src/main/res/values-sl/strings.xml | 12 +++++++++--- app/src/main/res/values-sq/strings.xml | 6 ++++++ app/src/main/res/values-sv-rSE/strings.xml | 12 +++++++++--- app/src/main/res/values-tg/strings.xml | 6 ++++++ app/src/main/res/values-uk/strings.xml | 12 +++++++++--- app/src/main/res/values-zh-rCN/strings.xml | 12 +++++++++--- app/src/main/res/values-zh-rTW/strings.xml | 12 +++++++++--- 16 files changed, 150 insertions(+), 42 deletions(-) diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index b85bf1509..10f6219ff 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -894,16 +894,22 @@ Уключана Выключана - + Дазволіць гук і відэа + + Дазволіць гук і відэа Блакаваць аўдыё і відэа толькі на мабільных дадзеных Аўдыё і відэа будуць прайгравацца праз Wi-Fi - + Блакаваць толькі гук - + + Блакаваць толькі гук + Блакаваць гук і відэа + + Блакаваць гук і відэа Уключана diff --git a/app/src/main/res/values-cak/strings.xml b/app/src/main/res/values-cak/strings.xml index 2f8dc2818..b2f1ce800 100644 --- a/app/src/main/res/values-cak/strings.xml +++ b/app/src/main/res/values-cak/strings.xml @@ -910,16 +910,22 @@ Titzij Tichup - + Tiya\' q\'ij k\'oxom chuqa\' silowäch + + Tiya\' q\'ij k\'oxom chuqa\' silowäch Keq\'at k\'oxom chuqa\' silowäch xa xe rik\'in kitzij selular Ri k\'oxom chuqa\' silowäch xketzij rik\'in Wi-Fi - + Xa xe tiq\'at k\'oxom - + + Xa xe tiq\'at k\'oxom + Tiq\'at k\'oxom chuqa\' silowäch + + Tiq\'at k\'oxom chuqa\' silowäch Titzij diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 0f8097498..4022803bc 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -902,16 +902,22 @@ Aus - + Audio und Video erlauben + + Audio und Video erlauben Audio und Video nur bei Mobilfunkverbindung blockieren Audio und Video werden bei WLAN-Verbindung wiedergegeben - + Nur Audio blockieren - + + Nur Audio blockieren + Audio und Video blockieren + + Audio und Video blockieren Ein diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index c9dce3184..11643d358 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -896,16 +896,22 @@ Ενεργό Ανενεργό - + Αποδοχή ήχου και βίντεο + + Αποδοχή ήχου και βίντεο Φραγή ήχου και βίντεο μόνο σε σύνδεση δεδομένων κινητής Η αναπαραγωγή ήχων/βίντεο θα γίνεται σε Wi-Fi - + Φραγή ήχου μόνο - + + Φραγή ήχου μόνο + Φραγή ήχου και βίντεο + + Φραγή ήχου και βίντεο Ενεργό diff --git a/app/src/main/res/values-en-rCA/strings.xml b/app/src/main/res/values-en-rCA/strings.xml index f9baeb8e9..be3b6e3c0 100644 --- a/app/src/main/res/values-en-rCA/strings.xml +++ b/app/src/main/res/values-en-rCA/strings.xml @@ -130,6 +130,8 @@ Edit bookmark Add-ons + + Extensions No add-ons here @@ -524,6 +526,10 @@ Other Bookmarks History + + New tab + + Find in page Synced tabs @@ -873,16 +879,22 @@ On Off - + Allow audio and video + + Allow audio and video Block audio and video on cellular data only Audio and video will play on Wi-Fi - + Block audio only - + + Block audio only + Block audio and video + + Block audio and video On diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index a883ba0e3..63b5aa242 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -131,6 +131,8 @@ Favoriyan serast bike Pêvek + + Pêvek Ti pêvek li vir tune @@ -530,6 +532,10 @@ Favoriyên din Raborî + + Hilpekîna nû + + Di rûpelê de bibîne Hilpekînên hevsengkirî @@ -881,16 +887,22 @@ Vekirî Girtî - + Destûrê bide deng û vîdyoyê + + Destûrê bide deng û vîdyoyê Deng û vîdyoyê tenê di daneya hucreyî de asteng bike Deng û vîdyo ew ê tenê di Wi-Fi de bên vekirin - + Tenê dengan asteng bike - + + Tenê dengan asteng bike + Deng û vîdyoyê asteng bike + + Deng û vîdyoyê asteng bike Vekirî diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index fb70a453e..d9bc1aaeb 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -911,16 +911,22 @@ 꺼짐 - + 오디오 및 비디오 허용 + + 오디오 및 비디오 허용 셀룰러 데이터에서만 오디오 및 비디오 차단 오디오 및 비디오가 Wi-Fi에서 재생됩니다 - + 오디오만 차단 - + + 오디오만 차단 + 오디오 및 비디오 차단 + + 오디오 및 비디오 차단 켜짐 diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 1bd2dc55a..1e016c1d7 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -895,16 +895,22 @@ Av - + Tillat lyd og video + + Tillat lyd og video Blokker lyd og video bare på mobildata Lyd og video spilles av på Wi-Fi - + Blokker bare lyd - + + Blokker bare lyd + Blokker lyd og video + + Blokker lyd og video diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index ad3f87d62..b69673ddb 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -885,16 +885,22 @@ Ativada Desativada - + Permitir áudio e vídeo + + Permitir áudio e vídeo Bloquear áudio e vídeo apenas em rede móvel Áudio e vídeo só são reproduzidos automaticamente se o dispositivo estiver conectado a uma rede Wi-Fi - + Bloquear apenas áudio - + + Bloquear apenas áudio + Bloquear áudio e vídeo + + Bloquear áudio e vídeo Ativado diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index b722f3d88..96d8b30f2 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -896,17 +896,23 @@ Vklopljeno Izklopljeno - + Dovoli zvok in video + + Dovoli zvok in video Zavrni zvok in video samo na mobilnih podatkih Zvok in Video se bosta predvajala na Wi-Fi - + Zavrni samo zvok - + + Zavrni samo zvok + Zavrni zvok in video + + Zavrni zvok in video Vključeno diff --git a/app/src/main/res/values-sq/strings.xml b/app/src/main/res/values-sq/strings.xml index a4f867572..b496567c0 100644 --- a/app/src/main/res/values-sq/strings.xml +++ b/app/src/main/res/values-sq/strings.xml @@ -128,6 +128,8 @@ Përpunoni faqerojtësin Shtesa + + Zgjerime S’ka shtesa këtu @@ -525,6 +527,10 @@ Faqerojtës të Tjerë Historik + + Skedë e re + + Gjej në faqe Skeda të njëkohësuara diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index bf9433a22..33703b47f 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -897,16 +897,22 @@ Av - + Tillåt ljud och video + + Tillåt ljud och video Blockera ljud och video endast vid mobildata Ljud och video spelas upp på Wi-Fi - + Blockera ljud endast - + + Blockera endast ljud + Blockera ljud och video + + Blockera ljud och video diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index f380493ee..7e3488988 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -130,6 +130,8 @@ Таҳрир кардани хатбарак Ҷузъҳои иловагӣ + + Васеъшавиҳо Дар ин ҷо ягон ҷузъи иловагӣ нест @@ -525,6 +527,10 @@ Хатбаракҳои дигар Таърих + + Варақаи нав + + Ҷустуҷӯ дар саҳифа Варақаҳои ҳамоҳангшуда diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index a53c6d1df..9e242df11 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -893,16 +893,22 @@ Увімкнено Вимкнено - + Дозволити аудіо та відео + + Дозволити аудіо та відео Блокувати аудіо та відео лише для стільникових даних Аудіо та відео відтворюватимуться через Wi-Fi - + Блокувати лише аудіо - + + Блокувати лише аудіо + Блокувати аудіо та відео + + Блокувати аудіо та відео Увімкнено diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e7b592867..cb934be6f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -908,16 +908,22 @@ 关闭 - + 允许音频和视频 + + 允许音频和视频 在蜂窝数据下阻止音频和视频 将在 Wi-Fi 下播放音频和视频 - + 仅阻止音频 - + + 仅阻止音频 + 阻止音频和视频 + + 阻止音频和视频 开启 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 3de38393a..7f9b0a1c9 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -899,16 +899,22 @@ 關閉 - + 允許自動播放影音內容 + + 允許自動播放影音內容 僅在使用行動網路時封鎖影音內容 使用 Wi-Fi 網路時,仍會自動播放影音內容 - + 僅封鎖音訊 - + + 僅封鎖音訊 + 封鎖影音內容 + + 封鎖影音內容 開啟 From 2f6fcbf19622c589370d0f73ab51dddd0fbc90d9 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Thu, 4 Feb 2021 19:55:54 +0400 Subject: [PATCH 165/248] Close #13892: Remove Synced Tabs appended to tabs tray --- .../java/org/mozilla/fenix/FeatureFlags.kt | 7 - .../components/toolbar/DefaultToolbarMenu.kt | 9 +- .../java/org/mozilla/fenix/home/HomeMenu.kt | 2 +- .../fenix/settings/SecretSettingsFragment.kt | 9 -- .../mozilla/fenix/sync/SyncedTabsFragment.kt | 6 - .../mozilla/fenix/sync/SyncedTabsLayout.kt | 4 - .../fenix/tabtray/SyncedTabsController.kt | 87 ----------- .../fenix/tabtray/TabTrayController.kt | 11 -- .../fenix/tabtray/TabTrayDialogFragment.kt | 1 - .../tabtray/TabTrayFragmentInteractor.kt | 10 -- .../org/mozilla/fenix/tabtray/TabTrayView.kt | 29 ---- .../java/org/mozilla/fenix/utils/Settings.kt | 8 - app/src/main/res/values/preference_keys.xml | 2 - .../res/xml/secret_settings_preferences.xml | 5 - .../tabtray/DefaultTabTrayControllerTest.kt | 10 -- .../fenix/tabtray/SyncedTabsControllerTest.kt | 140 ------------------ .../tabtray/TabTrayFragmentInteractorTest.kt | 6 - 17 files changed, 3 insertions(+), 343 deletions(-) delete mode 100644 app/src/main/java/org/mozilla/fenix/tabtray/SyncedTabsController.kt delete mode 100644 app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index fd8be54a2..ed9bacea0 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -14,13 +14,6 @@ object FeatureFlags { */ val pullToRefreshEnabled = Config.channel.isNightlyOrDebug - /** - * Shows Synced Tabs in the tabs tray. - * - * Tracking issue: https://github.com/mozilla-mobile/fenix/issues/13892 - */ - val syncedTabsInTabsTray = Config.channel.isNightlyOrDebug - /** * Enables the Nimbus experiments library. */ diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt index ec34aa13b..10018c227 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt @@ -332,14 +332,12 @@ class DefaultToolbarMenu( ?.browsingModeManager?.mode == BrowsingMode.Normal val shouldDeleteDataOnQuit = context.components.settings .shouldDeleteBrowsingDataOnQuit - val syncedTabsInTabsTray = context.components.settings - .syncedTabsInTabsTray val menuItems = listOfNotNull( downloadsItem, historyItem, bookmarksItem, - if (syncedTabsInTabsTray) null else syncedTabs, + syncedTabs, settings, if (shouldDeleteDataOnQuit) deleteDataOnQuit else null, BrowserMenuDivider(), @@ -471,9 +469,6 @@ class DefaultToolbarMenu( onItemTapped.invoke(ToolbarMenu.Item.Settings) } - val syncedTabsInTabsTray = context.components.settings - .syncedTabsInTabsTray - val menuItems = listOfNotNull( newTabItem, BrowserMenuDivider(), @@ -481,7 +476,7 @@ class DefaultToolbarMenu( historyItem, downloadsItem, extensionsItem, - if (syncedTabsInTabsTray) null else syncedTabsItem, + syncedTabsItem, BrowserMenuDivider(), findInPageItem, desktopSiteItem, diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt b/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt index 027e6cb26..6c1a32760 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt @@ -190,7 +190,7 @@ class HomeMenu( if (settings.shouldDeleteBrowsingDataOnQuit) quitItem else null, settingsItem, BrowserMenuDivider(), - if (settings.syncedTabsInTabsTray) null else syncedTabsItem, + syncedTabsItem, bookmarksItem, historyItem, downloadsItem, diff --git a/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt index d63bfeee0..54c91d802 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt @@ -6,10 +6,7 @@ package org.mozilla.fenix.settings import android.os.Bundle import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreference -import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R -import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar class SecretSettingsFragment : PreferenceFragmentCompat() { @@ -21,11 +18,5 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.secret_settings_preferences, rootKey) - - requirePreference(R.string.pref_key_synced_tabs_tabs_tray).apply { - isVisible = FeatureFlags.syncedTabsInTabsTray - isChecked = context.settings().syncedTabsInTabsTray - onPreferenceChangeListener = SharedPreferenceUpdater() - } } } diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsFragment.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsFragment.kt index 8acfbab99..2c5018629 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsFragment.kt @@ -17,7 +17,6 @@ import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.SyncedTabsFeature import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import org.mozilla.fenix.BrowserDirection -import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.ext.components @@ -28,11 +27,6 @@ import org.mozilla.fenix.theme.ThemeManager class SyncedTabsFragment : LibraryPageFragment() { private val syncedTabsFeature = ViewBoundFeatureWrapper() - init { - // Sanity-check: Remove this class when the feature flag is always enabled. - FeatureFlags.syncedTabsInTabsTray - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt index 56255910c..b6c65b90e 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt @@ -19,7 +19,6 @@ import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.SyncedDeviceTabs import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.view.SyncedTabsView -import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController @@ -47,9 +46,6 @@ class SyncedTabsLayout @JvmOverloads constructor( synced_tabs_list.adapter = adapter synced_tabs_pull_to_refresh.setOnRefreshListener { listener?.onRefresh() } - - // Sanity-check: Remove this class when the feature flag is always enabled. - FeatureFlags.syncedTabsInTabsTray } override fun onError(error: SyncedTabsView.ErrorType) { diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/SyncedTabsController.kt b/app/src/main/java/org/mozilla/fenix/tabtray/SyncedTabsController.kt deleted file mode 100644 index b982ca21a..000000000 --- a/app/src/main/java/org/mozilla/fenix/tabtray/SyncedTabsController.kt +++ /dev/null @@ -1,87 +0,0 @@ -/* 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 org.mozilla.fenix.tabtray - -import android.view.View -import androidx.fragment.app.FragmentManager.findFragment -import androidx.lifecycle.LifecycleOwner -import androidx.navigation.NavController -import androidx.navigation.fragment.findNavController -import androidx.recyclerview.widget.ConcatAdapter -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.collect -import kotlinx.coroutines.flow.drop -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import mozilla.components.browser.storage.sync.SyncedDeviceTabs -import mozilla.components.feature.syncedtabs.view.SyncedTabsView -import mozilla.components.lib.state.ext.flowScoped -import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged -import org.mozilla.fenix.components.metrics.MetricController -import org.mozilla.fenix.sync.ListenerDelegate -import org.mozilla.fenix.sync.SyncedTabsAdapter -import org.mozilla.fenix.sync.ext.toAdapterList -import org.mozilla.fenix.sync.ext.toAdapterItem -import org.mozilla.fenix.sync.ext.toStringRes -import kotlin.coroutines.CoroutineContext - -@OptIn(ExperimentalCoroutinesApi::class) -class SyncedTabsController( - lifecycleOwner: LifecycleOwner, - private val view: View, - store: TabTrayDialogFragmentStore, - private val concatAdapter: ConcatAdapter, - coroutineContext: CoroutineContext = Dispatchers.Main, - metrics: MetricController -) : SyncedTabsView { - override var listener: SyncedTabsView.Listener? = null - - val adapter = SyncedTabsAdapter(ListenerDelegate(metrics) { listener }) - - private val scope: CoroutineScope = CoroutineScope(coroutineContext) - - init { - store.flowScoped(lifecycleOwner) { flow -> - flow.map { it.mode } - .ifChanged() - .drop(1) - .collect { mode -> - when (mode) { - is TabTrayDialogFragmentState.Mode.Normal -> { - concatAdapter.addAdapter(adapter) - } - is TabTrayDialogFragmentState.Mode.MultiSelect -> { - concatAdapter.removeAdapter(adapter) - } - } - } - } - } - - override fun displaySyncedTabs(syncedTabs: List) { - scope.launch { - val tabsList = listOf(SyncedTabsAdapter.AdapterItem.Title) + syncedTabs.toAdapterList() - // Reverse layout for TabTrayView which does things backwards. - adapter.submitList(tabsList.reversed()) - } - } - - override fun onError(error: SyncedTabsView.ErrorType) { - scope.launch { - val navController: NavController? = try { - findFragment(view).findNavController() - } catch (exception: IllegalStateException) { - null - } - - val descriptionResId = error.toStringRes() - val errorItem = error.toAdapterItem(descriptionResId, navController) - - adapter.submitList(listOf(errorItem)) - } - } -} diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt index f38e01d96..4ce4c635c 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt @@ -20,7 +20,6 @@ import mozilla.components.concept.engine.prompt.ShareData import mozilla.components.concept.storage.BookmarksStorage import mozilla.components.concept.tabstray.Tab import mozilla.components.feature.tabs.TabsUseCases -import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager @@ -28,7 +27,6 @@ import org.mozilla.fenix.components.TabCollectionStorage import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.home.HomeFragment -import mozilla.components.browser.storage.sync.Tab as SyncTab /** * [TabTrayDialogFragment] controller. @@ -42,7 +40,6 @@ interface TabTrayController { fun handleTabSettingsClicked() fun handleShareTabsOfTypeClicked(private: Boolean) fun handleShareSelectedTabsClicked(selectedTabs: Set) - fun handleSyncedTabClicked(syncTab: SyncTab) fun handleSaveToCollectionClicked(selectedTabs: Set) fun handleBookmarkSelectedTabs(selectedTabs: Set) fun handleDeleteSelectedTabs(selectedTabs: Set) @@ -197,14 +194,6 @@ class DefaultTabTrayController( } } - override fun handleSyncedTabClicked(syncTab: SyncTab) { - activity.openToBrowserAndLoad( - searchTermOrURL = syncTab.active().url, - newTab = true, - from = BrowserDirection.FromTabTray - ) - } - @OptIn(ExperimentalCoroutinesApi::class) override fun handleCloseAllTabsClicked(private: Boolean) { val sessionsToClose = if (private) { diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index 664206d32..ef6f3fe70 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -215,7 +215,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler showBookmarksSnackbar = ::showBookmarksSnackbar ) ), - store = tabTrayDialogStore, isPrivate = isPrivate, isInLandscape = ::isInLandscape, lifecycleOwner = viewLifecycleOwner diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractor.kt index 8dc718225..7f7eae7a2 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractor.kt @@ -5,7 +5,6 @@ package org.mozilla.fenix.tabtray import mozilla.components.concept.tabstray.Tab -import mozilla.components.browser.storage.sync.Tab as SyncTab @Suppress("TooManyFunctions") interface TabTrayInteractor { @@ -54,11 +53,6 @@ interface TabTrayInteractor { */ fun onCloseAllTabsClicked(private: Boolean) - /** - * Called when the user clicks on a synced tab entry. - */ - fun onSyncedTabClicked(syncTab: SyncTab) - /** * Called when the physical back button is clicked. */ @@ -146,10 +140,6 @@ class TabTrayFragmentInteractor(private val controller: TabTrayController) : Tab controller.handleCloseAllTabsClicked(private) } - override fun onSyncedTabClicked(syncTab: SyncTab) { - controller.handleSyncedTabClicked(syncTab) - } - override fun onBackPressed(): Boolean { return controller.handleBackPressed() } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt index a748291ee..db3768a32 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt @@ -41,8 +41,6 @@ import mozilla.components.browser.state.selector.privateTabs import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.tabstray.TabViewHolder -import mozilla.components.feature.syncedtabs.SyncedTabsFeature -import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.ktx.android.util.dpToPx import mozilla.components.ui.tabcounter.TabCounter.Companion.INFINITE_CHAR_PADDING_BOTTOM import org.mozilla.fenix.R @@ -59,7 +57,6 @@ import org.mozilla.fenix.utils.Settings import java.text.NumberFormat import kotlin.math.max import kotlin.math.roundToInt -import mozilla.components.browser.storage.sync.Tab as SyncTab /** * View that contains and configures the BrowserAwesomeBar @@ -69,7 +66,6 @@ class TabTrayView( private val container: ViewGroup, private val tabsAdapter: FenixTabsAdapter, private val interactor: TabTrayInteractor, - store: TabTrayDialogFragmentStore, isPrivate: Boolean, private val isInLandscape: () -> Boolean, lifecycleOwner: LifecycleOwner, @@ -97,11 +93,6 @@ class TabTrayView( private var tabsTouchHelper: TabsTouchHelper private val collectionsButtonAdapter = SaveToCollectionsButtonAdapter(interactor, isPrivate) - private val metrics = container.context.components.analytics.metrics - - private val syncedTabsController = - SyncedTabsController(lifecycleOwner, view, store, concatAdapter, metrics = metrics) - private val syncedTabsFeature = ViewBoundFeatureWrapper() private var hasLoaded = false @@ -167,21 +158,6 @@ class TabTrayView( setTopOffset(isInLandscape()) - if (view.context.settings().syncedTabsInTabsTray) { - syncedTabsFeature.set( - feature = SyncedTabsFeature( - context = container.context, - storage = components.backgroundServices.syncedTabsStorage, - accountManager = components.backgroundServices.accountManager, - view = syncedTabsController, - lifecycleOwner = lifecycleOwner, - onTabClicked = ::handleTabClicked - ), - owner = lifecycleOwner, - view = view - ) - } - updateTabsTrayLayout() view.tabsTray.apply { @@ -197,7 +173,6 @@ class TabTrayView( tabsAdapter.tabTrayInteractor = interactor tabsAdapter.onTabsUpdated = { concatAdapter.addAdapter(collectionsButtonAdapter) - concatAdapter.addAdapter(syncedTabsController.adapter) if (hasAccessibilityEnabled) { tabsAdapter.notifyItemRangeChanged(0, tabs.size) @@ -344,10 +319,6 @@ class TabTrayView( } } - private fun handleTabClicked(tab: SyncTab) { - interactor.onSyncedTabClicked(tab) - } - private fun adjustNewTabButtonsForNormalMode() { view.tab_tray_new_tab.apply { isVisible = hasAccessibilityEnabled diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 0ddb3c35e..5b42b4dcc 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -26,12 +26,10 @@ import mozilla.components.support.ktx.android.content.longPreference import mozilla.components.support.ktx.android.content.stringPreference import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.Config -import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.metrics.MozillaProductDetector import org.mozilla.fenix.components.settings.counterPreference -import org.mozilla.fenix.components.settings.featureFlagPreference import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.getPreferenceKey @@ -123,12 +121,6 @@ class Settings(private val appContext: Context) : PreferencesHolder { val canShowCfr: Boolean get() = (System.currentTimeMillis() - lastCfrShownTimeInMillis) > THREE_DAYS_MS - var syncedTabsInTabsTray by featureFlagPreference( - appContext.getPreferenceKey(R.string.pref_key_synced_tabs_tabs_tray), - default = false, - featureFlag = FeatureFlags.syncedTabsInTabsTray - ) - var forceEnableZoom by booleanPreference( appContext.getPreferenceKey(R.string.pref_key_accessibility_force_enable_zoom), default = false diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index e0ad6b502..35b38f4dd 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -213,8 +213,6 @@ pref_key_migrating_from_fenix_tip pref_key_master_password_tip - pref_key_synced_tabs_tabs_tray - pref_key_debug_settings pref_key_open_tabs_count diff --git a/app/src/main/res/xml/secret_settings_preferences.xml b/app/src/main/res/xml/secret_settings_preferences.xml index 7f9722266..c9a243d18 100644 --- a/app/src/main/res/xml/secret_settings_preferences.xml +++ b/app/src/main/res/xml/secret_settings_preferences.xml @@ -4,9 +4,4 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt index 8e7f7599a..3c974a981 100644 --- a/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt @@ -32,7 +32,6 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test -import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode @@ -179,15 +178,6 @@ class DefaultTabTrayControllerTest { } } - @Test - fun onSyncedTabClicked() { - controller.handleSyncedTabClicked(mockk(relaxed = true)) - - verify { - activity.openToBrowserAndLoad(any(), true, BrowserDirection.FromTabTray) - } - } - @Test fun handleBackPressed() { every { tabTrayFragmentStore.state.mode } returns TabTrayDialogFragmentState.Mode.MultiSelect( diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt deleted file mode 100644 index 01e9c598f..000000000 --- a/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt +++ /dev/null @@ -1,140 +0,0 @@ -package org.mozilla.fenix.tabtray - -import android.view.LayoutInflater -import android.view.View -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.LifecycleRegistry -import androidx.recyclerview.widget.ConcatAdapter -import io.mockk.Called -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.TestCoroutineDispatcher -import kotlinx.coroutines.test.runBlockingTest -import mozilla.components.browser.storage.sync.SyncedDeviceTabs -import mozilla.components.feature.syncedtabs.view.SyncedTabsView.ErrorType -import mozilla.components.support.test.ext.joinBlocking -import mozilla.components.support.test.robolectric.testContext -import mozilla.components.support.test.rule.MainCoroutineRule -import org.junit.After -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mozilla.fenix.R -import org.mozilla.fenix.components.metrics.MetricController -import org.mozilla.fenix.helpers.FenixRobolectricTestRunner -import org.mozilla.fenix.sync.SyncedTabsViewHolder -import org.mozilla.fenix.tabtray.TabTrayDialogFragmentAction.EnterMultiSelectMode -import org.mozilla.fenix.tabtray.TabTrayDialogFragmentAction.ExitMultiSelectMode -import org.mozilla.fenix.tabtray.TabTrayDialogFragmentState.Mode - -@ExperimentalCoroutinesApi -@RunWith(FenixRobolectricTestRunner::class) -class SyncedTabsControllerTest { - - private val testDispatcher = TestCoroutineDispatcher() - @get:Rule - val coroutinesTestRule = MainCoroutineRule(testDispatcher) - - private lateinit var view: View - private lateinit var controller: SyncedTabsController - private lateinit var lifecycleOwner: LifecycleOwner - private lateinit var lifecycle: LifecycleRegistry - private lateinit var concatAdapter: ConcatAdapter - private lateinit var store: TabTrayDialogFragmentStore - - @Before - fun setup() = runBlockingTest { - lifecycleOwner = mockk() - lifecycle = LifecycleRegistry(lifecycleOwner) - lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START) - every { lifecycleOwner.lifecycle } returns lifecycle - - concatAdapter = mockk() - every { concatAdapter.addAdapter(any()) } returns true - every { concatAdapter.removeAdapter(any()) } returns true - - store = TabTrayDialogFragmentStore( - initialState = TabTrayDialogFragmentState( - mode = Mode.Normal, - browserState = mockk(relaxed = true) - ) - ) - - view = LayoutInflater.from(testContext).inflate(R.layout.about_list_item, null) - val metrics: MetricController = mockk() - controller = - SyncedTabsController(lifecycleOwner, view, store, concatAdapter, coroutineContext, metrics) - } - - @After - fun cleanUp() { - testDispatcher.cleanupTestCoroutines() - } - - @Test - fun `display synced tabs in reverse`() { - val tabs = listOf( - SyncedDeviceTabs( - device = mockk(relaxed = true), - tabs = listOf( - mockk(relaxed = true), - mockk(relaxed = true) - ) - ) - ) - - controller.displaySyncedTabs(tabs) - - val itemCount = controller.adapter.itemCount - - // title + device name + 2 tabs - assertEquals(4, itemCount) - assertEquals( - SyncedTabsViewHolder.TitleViewHolder.LAYOUT_ID, - controller.adapter.getItemViewType(itemCount - 1) - ) - assertEquals( - SyncedTabsViewHolder.DeviceViewHolder.LAYOUT_ID, - controller.adapter.getItemViewType(itemCount - 2) - ) - assertEquals( - SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID, - controller.adapter.getItemViewType(itemCount - 3) - ) - assertEquals( - SyncedTabsViewHolder.TabViewHolder.LAYOUT_ID, - controller.adapter.getItemViewType(itemCount - 4) - ) - } - - @Test - fun `show error when we go kaput`() { - controller.onError(ErrorType.SYNC_NEEDS_REAUTHENTICATION) - - assertEquals(1, controller.adapter.itemCount) - assertEquals( - SyncedTabsViewHolder.ErrorViewHolder.LAYOUT_ID, - controller.adapter.getItemViewType(0) - ) - } - - @Test - fun `do nothing on init, drop first event`() { - verify { concatAdapter wasNot Called } - } - - @Test - fun `concatAdapter updated on mode changes`() = testDispatcher.runBlockingTest { - store.dispatch(EnterMultiSelectMode).joinBlocking() - verify { concatAdapter.removeAdapter(any()) } - - store.dispatch(ExitMultiSelectMode).joinBlocking() - // When returning from Multiselect the adapter should be added at the end - verify { concatAdapter.addAdapter(any()) } - } -} diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractorTest.kt index a0e50b017..5504c715a 100644 --- a/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabtray/TabTrayFragmentInteractorTest.kt @@ -89,12 +89,6 @@ class TabTrayFragmentInteractorTest { verify { controller.handleCloseAllTabsClicked(true) } } - @Test - fun onSyncedTabClicked() { - interactor.onSyncedTabClicked(mockk(relaxed = true)) - verify { controller.handleSyncedTabClicked(any()) } - } - @Test fun onBackPressed() { interactor.onBackPressed() From 6fd93dfe1539516cff99b551eeccee4dbd61d12b Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Sun, 21 Feb 2021 00:06:36 +0000 Subject: [PATCH 166/248] Import l10n. --- app/src/main/res/values-ast/strings.xml | 33 +- app/src/main/res/values-es-rAR/strings.xml | 12 +- app/src/main/res/values-es-rCL/strings.xml | 18 +- app/src/main/res/values-fi/strings.xml | 12 +- app/src/main/res/values-fr/strings.xml | 12 +- app/src/main/res/values-hsb/strings.xml | 12 +- app/src/main/res/values-it/strings.xml | 12 +- app/src/main/res/values-ja/strings.xml | 12 +- app/src/main/res/values-ka/strings.xml | 12 +- app/src/main/res/values-kab/strings.xml | 12 +- app/src/main/res/values-kmr/strings.xml | 333 ++++++++++----------- app/src/main/res/values-lt/strings.xml | 14 +- app/src/main/res/values-pl/strings.xml | 12 +- app/src/main/res/values-th/strings.xml | 12 +- app/src/main/res/values-tl/strings.xml | 304 ++++++++++++++++++- app/src/main/res/values-tr/strings.xml | 12 +- app/src/main/res/values-vi/strings.xml | 12 +- 17 files changed, 629 insertions(+), 217 deletions(-) diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 43f581789..54b3faa96 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -520,10 +520,14 @@ Historial Llingüeta nueva + + Atopar na llibrería Llingüetes sincronizaes Llista de llectura + + Buscar Axustes @@ -605,6 +609,8 @@ Zarrar toles llingüetes Llingüeta nueva + + Dir pal aniciu Amestar a Marcadores @@ -687,6 +693,9 @@ Elementos esbillaos: %1$d + + Desaniciar %1$d elementos Güei @@ -717,6 +726,8 @@ Descargues esbillaes: %1$d + + Abrir Quitar @@ -738,6 +749,10 @@ Menú de los marcadores + + Edición d\'un marcador + + Esbilla d\'una carpeta ¿De xuru que quies desaniciar esta carpeta? @@ -816,6 +831,8 @@ Aconséyase Reafitamientu de permisos + + Reafitar el permisu Reafitar los permisos de tolos sitios @@ -848,16 +865,22 @@ Non - + Permitir l\'audiu y videu + + Permitir l\'audiu y videu Bloquiar namás l\'audiu y videu colos datos móviles L\'audiu y videu va reproducise namás per Wi-Fi - + Bloquiar namás l\'audiu - + + Bloquiar namás l\'audiu + Bloquiar l\'audiu y videu + + Bloquiar l\'audiu y videu @@ -930,6 +953,8 @@ Unviar a tolos preseos Reconexón con Sync + + Ensin conexón Coneutar otru preséu @@ -1166,7 +1191,7 @@ Estricta - Bloquia más rastrexadores, anuncios y ventanos emerxentes. Los páxines van cargar más rápido mas dalgunes funcionalidaes quiciabes nun funcionen. + Bloquia más rastrexadores, anuncios y ventanos emerxentes. Les páxines van cargar más rápido mas dalgunes funcionalidaes quiciabes nun funcionen. diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index ed695f4e1..4359cce87 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -905,16 +905,22 @@ Desactivada - + Permitir audio y video + + Permitir audio y video Bloquear audio y video solo en datos celulares El audio y el video se van a reproducir con Wi-Fi - + Bloquear solo audio - + + Bloquear solo audio + Bloquear audio y video + + Bloquear audio y video Activado diff --git a/app/src/main/res/values-es-rCL/strings.xml b/app/src/main/res/values-es-rCL/strings.xml index 273e96c24..8479fbabf 100644 --- a/app/src/main/res/values-es-rCL/strings.xml +++ b/app/src/main/res/values-es-rCL/strings.xml @@ -129,6 +129,8 @@ Editar marcador Complementos + + Extensiones No hay complementos aquí @@ -526,6 +528,10 @@ Otros marcadores Historial + + Nueva pestaña + + Buscar en la página Pestañas sincronizadas @@ -877,16 +883,22 @@ No - + Permitir audio y video + + Permitir audio y video Bloquear audio y video solo en datos celulares El audio y video se reproducirán en Wi-Fi - + Bloquear solo audio - + + Bloquear solo audio + Bloquear audio y video + + Bloquear audio y video diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 16521e369..eaacce8de 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -897,16 +897,22 @@ Pois - + Salli ääni ja video + + Salli ääni ja video Estä ääni ja video vain käytettäessä matkapuhelinverkon datayhteyttä Ääni ja video toistetaan käytettäessä Wi-Fi-yhteyttä - + Estä vain ääni - + + Estä vain ääni + Estä ääni ja video + + Estä ääni ja video Päällä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index e488d63f4..342192fed 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -899,16 +899,22 @@ Désactivée - + Autoriser l’audio et la vidéo + + Autoriser l’audio et la vidéo Bloquer l’audio et la vidéo depuis les données mobiles uniquement L’audio et la vidéo seront lus avec une connexion Wi-Fi - + Bloquer l’audio uniquement - + + Bloquer l’audio uniquement + Bloquer l’audio et la vidéo + + Bloquer l’audio et la vidéo Activé diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index d5c0ee0c1..a6082b0aa 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -889,16 +889,22 @@ Zapinjeny Wupinjeny - + Awdio a widejo dowolić + + Awdio a widejo dowolić Awdio a widejo jenož za mobilny zwisk blokować Awdio a widejo so přez WLAN wothrawatej - + Jenož awdio blokować - + + Jenož awdio blokować + Awdio a widejo blokować + + Awdio a widejo blokować Zapinjeny diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 26865d46d..38a0bb45b 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -903,16 +903,22 @@ Disattivata - + Consenti audio e video + + Consenti audio e video Blocca audio e video solo con connessione dati Audio e video saranno riprodotti con una connessione Wi-Fi - + Blocca solo l’audio - + + Blocca solo l’audio + Blocca audio e video + + Blocca audio e video Attivato diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d01111e83..c0a54e3bc 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -901,16 +901,22 @@ オフ - + 音声と動画の再生を許可 + + 音声と動画の再生を許可 データ通信時のみ音声と動画をブロック Wi-Fi 接続時は音声と動画を再生します - + 音声のみブロック - + + 音声のみブロック + 音声と動画をブロック + + 音声と動画をブロック オン diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index 9a06d3b3c..a8f0fd919 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -885,16 +885,22 @@ ჩართ. გამორთ. - + ხმისა და ვიდეოს დაშვება + + ხმისა და ვიდეოს დაშვება ხმისა და ვიდეოს შეზღუდვა, მხოლოდ ფიჭურ ინტერნეტზე ხმისა და ვიდეოს დაშვება Wi-Fi-ზე - + მხოლოდ ხმის შეზღუდვა - + + მხოლოდ ხმის შეზღუდვა + ხმისა და ვიდეოს შეზღუდვა + + ხმისა და ვიდეოს შეზღუდვა ჩართ. diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 585c5bed8..1da682bfa 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -898,16 +898,22 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Irmed Insa - + Sireg ameslaw d uvidyu + + Sireg ameslaw d tvidyut Sewḥel imeslawen d tvidyutin ded yisefka izirazen kan Imeslawen d tividyutin ad uraren deg WI-FI - + Sewḥel kan imeslawen - + + Sewḥel kan ameslaw + Sewḥel imeslawen d tvidyutin + + Sewḥel ameslaw d tvidyut Irmed diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index 63b5aa242..a06128ed7 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -14,7 +14,7 @@ Gerîna veşartî bigire - Lêgerîn yan navnîşanek + Lêgerîn an jî navnîşan Hilpekînên te yên vekirî ew ê li vir bên nîşandan. @@ -36,19 +36,19 @@ Koleksiyonê hilbijêre - Ji moda pir-bijartinê derkeve + Ji moda bijartina-pir derkeve Hilpekînên bijartî li koleksiyonê qeyd bike %1$s hat bijartin - Bıjartina %1$s hate rakirin + Bijartina %1$s hate rakirin - Ji moda pir-bijartinê hate derketin + Ji moda bijartina-pir hate derketin - Tu ket moda pir-bijartinê, ji bo tomarkirina li koleksiyonê hilpekînan hilbijêre + Tu ket moda bijartina-pir, ji bo tomarkirina li koleksiyonê hilpekînan hilbijêre Hate bijartin @@ -61,9 +61,9 @@ - %1$s, dema ku te hilpekînên veşartî girtin an jî tu ji sepanê derket ew ê raboriya te ya gerîn û lêgerînê ji hilpekînên veşartî bên paqijkirin. Ev, rê li ber şopandina/nedîtina te ya ji aliyê malper û peydakerên servîsê ve nagirê lê heke hin kesên din ên vê cîhazê bi kar tînin hebin ew ê bihêle ku tu raboriya xwe ji wan veşêrî. + %1$s, dema ku te hilpekînên veşartî girtin an jî tu ji sepanê derket ew ê raboriya te ya gerîn û lêgerînê ji hilpekînên veşartî bên paqijkirin. Ev, rê li ber şopandina te ya ji aliyê malper û peydakerên servîsê ve nagirê lê heke hin kesên din ên vê cîhazê bi kar tînin hebin ew ê bihêle ku tu raboriya xwe ji wan veşêrî. - Efsaneyên berbelav ên derbarê gerîna veşartî de + Efsaneyên berbelav ên têkildarî gerîna veşartî Rûniştinê jê bibe @@ -85,7 +85,7 @@ Bigire - Gihîna kamerayê hewce ye. Here sazkariyên Androidê ji beşa destûran, destûrê bide. + Gihîna li kamerayê hewce ye. Here sazkariyên Androidê ji beşa destûran, destûrê bide. Here sazkariyan @@ -99,7 +99,7 @@ Bigire - Tu dikarî raxistina hilpekînên vekirî biguherînî. Here sazkariyan û ji bin "xuyabûna hilpekînê" gridê hilbijêre. + Tu dikarî raxistina hilpekînên vekirî biguherînî. Here sazkariyan û ji bin "xuyabûna hilpekînan" grîdê hilbijêre. Here sazkariyan @@ -126,9 +126,9 @@ Rawestîne - Favorî + Tevlî favoriyan bike - Favoriyan serast bike + Favoriyan sererast bike Pêvek @@ -198,13 +198,13 @@ - Sken + Sken bike Motora lêgerînê Sazkariyên motora lêgerînê - Îja ka bi vê bigere: + Îja ka bi vê lê bigere: Girêdanê ji panoyê bîne @@ -212,9 +212,9 @@ Destûrê nede - Di rûniştina veşartî de bila pêşniyarên lêgerînê werin pêş te? + Bila pêşniyarên lêgerînê di rûniştina veşartî de werin pêş te? - %s dê hemû tiştên tu li darikê navnîşanan binivîsî bi motora te ya lêgerînê ya derbasdar re parve bike. + %s dê hemû tiştên tu li darika navnîşanan binivîsî bi motora te ya lêgerînê ya derbasdar re parve bike. Zêdetir bizane @@ -242,7 +242,7 @@ Lêgerîn - Dariikê navnîşanan + Darika navnîşanê Alîkarî @@ -251,7 +251,7 @@ Paşragihandinê bişîne - Derbarê %1$s + Derbarê %1$s de @@ -275,39 +275,39 @@ Girêdanan di hilpekîna veşartî de veke - Destûrê bide girtina wêneyê ekranê di gera nepen de + Di gerîna veşartî de, bihêle bila wêneyê ekranê bê kişandin - Heke destûrê bidî, gava gelek bernamok vekirî bin hilpekînên nepen dê xuya bibin + Heke destûr bê dayîn, dema ku gelek sepan vekirî bin jî ew ê hilpekînên veşartî xuya bibin - Kurteriya gera nepen lê zêde bike + Kurterêya gerîna veşartî tevlî bike Gihînbarî Servera taybet a hesabê Firefoxê - Servera taybet a Sync`ê + Servera Sync’ê ya taybet - Hesabê Firefoxê/PÊşkêşkara Sync hat guhertin. Ji bo sepandina guhertinan ji bernameyê derdikeve… + Servera Sync/Hesabê Firefoxê hat guhertin. Ji bo sepandina guhertinan ji sepanê derdikeve… Hesab Têkeve - Darikê amûran + Darika amûran Rûkar Serrûpel - Îşaretên tiliyan + Hereketên tiliyan Taybet bike - Bi hesabê xwe yê Firefoxê favorî, mêjû û zêdetir tiştên xwe hevseng bike + Bi hesabê xwe yê Firefoxê favorî, raborî û zêdetirî wan senkronîze bike Hesabê Firefoxê - Ji bo dewamkirina hevsengkirinê dîsgirêdanê çêke + Ji bo senkronîzekirinê bidomînî, dîsa girê bide Ziman @@ -319,7 +319,7 @@ Amûrên pêşvebirinê - Bi riya USBê ji dûr ve neqandina çewtiyan + Bi rêya USB’ê ji dûr ve neqandina çewtiyan Motorên lêgerînê nîşan bide @@ -333,9 +333,9 @@ Di raboriya gerînê de lê bigere - Di favoriyan de bigere + Di favoriyan de lê bigere - Di hilpekînên hevsengkirî de bigere + Di hilpekînên senkronîzekirî de lê bigere Sazkariyên hesêb @@ -343,7 +343,7 @@ Girêdanan di sepanan de veke - Rêvebera jêbarkirinê ya derveyî + Rêvebera daxistinê ya derveyî Pêvek @@ -362,15 +362,14 @@ Xwediyê koleksiyonê (nasnameya bikarhêner) - Koleksiyona pêvekan hat guhertin. Ji bo sepandina guhertinan ji bernamokê derdikeve… + Koleksiyona pêvekan hat guhertin. Ji bo sepandina guhertinan ji sepanê derdikeve… Pêvek nayê piştgirîkirin - Pêvek jixwe sazkirî ye - + Pêvek jixwe sazkirî ye @@ -411,13 +410,13 @@ - Hilpekînên hatine wergirtin + Hilpekînên hatine stendin - Danezanên ji bo hilpekînên ji amûrên din yên Firefoxê hatî + Danezanên hilpekînan ên ji cîhazên Firefoxê tên stendin. - Hilpekîn hate wergirtin + Hilpekîn hate stendin - Hilpekîn hatin wergirtin + Hilpekîn hatin stendin Hilpekîna ji %s ve hat @@ -428,7 +427,7 @@ Parastina ji Şopandinê - Naverok û skrîptên li ser înternetê te dişopînin asteng bike + Naverok û skrîptên ku li ser înternetê te dişopînin asteng bike Istisna @@ -436,17 +435,19 @@ Ji bo hemû malperan veke - Istisna dihêle ku tu dikaribî ji bo malperên hilbijartî parastina şopandinê bigirî. + Istisna dihêlin ku tu bikaribî ji bo malperên hilbijartî parastina ji şopandinê bigirî. Zêdetir bizane - Bi temamî hat girtin, ji bo vekirinê here Eyaran. + Bi temamî hat girtin, ji bo vekirinê here Sazkariyan. Telemetrî Daneyên bikaranînê û teknîkî + + Performans, bikaranîn, reqalav û daneyên taybetkirinê yên têkildarî geroka te bi Mozillayê re parve dike, ji bo ku em karibin pê %1$s’ê baştir bikin Daneyên bazarkirinê @@ -470,11 +471,11 @@ Sync’ê veke - Koda hevsengkirinê ya di Firefoxa Sermaseyê de sken bike + Koda hevcotkirinê ya di Firefoxa Sermaseyê de sken bike Têkeve - Ji bo dîsberibandinê têkevinê + Ji bo dîsa girê bibî, têkeve Hesêb rake @@ -499,7 +500,7 @@ Tarî - Li gorî teserufa akuyê + Li gorî teserufa bateryayê Rûkara cîhazê bi kar bîne @@ -507,11 +508,11 @@ Ji bo nûkirinê bikişîne - Ji bo veşartina derikê amûran bişemitîne + Ji bo veşartina derika amûran, bişemitîne - Ji bo guhertina hilpekînê darikê amûran bi kêlekê ve kaş bike + Ji bo guhertina hilpekînê, darika amûran bi kêlekê ve biherikîne - Ji bo vekirina hilpekînan darikê amûran bi jorê ve bikişîne + Ji bo vekirina hilpekînan, darika amûran bi jorê ve biherikîne @@ -525,9 +526,9 @@ Favoriyên Sermaseyê - Menuya Favoriyan + Menûya Favoriyan - Darikê Amûran yê Favoriyan + Darika Amûran a Favoriyan Favoriyên din @@ -537,7 +538,7 @@ Di rûpelê de bibîne - Hilpekînên hevsengkirî + Hilpekînên senkronîzekirî Lîsteya xwendinê @@ -550,9 +551,9 @@ Bigire - Hilpekînên dawiyê hatî girtin + Hilpekînên herî dawî hatine girtin - Mêjûyê hemû nîşan bide + Raboriyê gişî nişan bide %d hilpekîn @@ -561,17 +562,17 @@ %d hilpekîn - Hilpekîna di nêzîk de hatî girtin nîn in + Hilpekîna berî niha hatiye girtin tune Hilpekîn - Xuyabûna hilpekînê + Xuyabûna hilpekînan Lîste - Grid + Grîd Hilpekînan bigire @@ -615,7 +616,7 @@ Hemû hilpekînan parve bike - Hilpekînên dawiyê hatî girtin + Hilpekînên herî dawî hatine girtin Sazkariyên hilpekînê @@ -633,7 +634,7 @@ Hilpekînên hilbijartî parve bike - Menuya hilpekînên hilbijartî + Menûya hilpekînên hilbijartî Hilpekînê ji koleksiyê rake @@ -697,7 +698,7 @@ Paqij bike - Kopî + Kopî bike Parve bike @@ -768,9 +769,9 @@ - Menuya Favoriyan + Menûya favoriyan - Favoriyan serast bike + Favoriyan sererast bike Peldankê hilbijêre @@ -808,11 +809,11 @@ The first parameter is the number of bookmarks selected --> %1$d hatin bijartin - Favoriyan serast bike + Favoriyan sererast bike Peldankê sererast bike - Ji bo favoriyan hevsengirî bibînî têkevê + Ji bo favoriyên senkronêzekirî bibînî, têkeve NAVNÎŞAN @@ -848,7 +849,7 @@ - Rûpela sazkariyên zû + Rûpela sazkariyên bilez Tê pêşniyarkirin @@ -878,7 +879,7 @@ Hate astengkirin - Destûrgirtî + Destûr hat dayîn Ji hêla Androidê ve hate astengkirin @@ -914,7 +915,7 @@ Menûya koleksiyonê - Tiştên ji te re girîng berhev bike.\nLêgerîn, malper û hilpekînên dixwazî xwe zû bigihînî wan bîne cem hev. + Tiştên ku ji te re girîng in berhev bike.\nLêgerîn, malper û hilpekînên ku tu dixwazî xwe zû bigihînî wan bîne cem hev. Hilpekînan hilbijêre @@ -966,7 +967,7 @@ Hemû çalakî - Dawiyê hatî bikaranîn + Bikaranînên herî dawî Têkeve Sync’ê @@ -978,29 +979,29 @@ Cîhazeke din girê bide - Ji bo şandina hilpekînekê herî kêm ji amûreke din têkeve Firefoxê. + Ji bo şandina hilpekînekê, herî kêm ji cîhazeke din têkeve Firefoxê. Min fêm kir - Bi vê amûrê re nayê parvekirin + Bi vê sepanê re nayê parvekirin Bişîne cîhazê - Amûra girêdayî nîn e + Cîhaza girêdayî tune - Derbarê Şandina Hilpekînan de agahiyan bistîne… + Derbarê şandina hilpekînan de agahiyan bistîne… - Bi amûreke din ve girê bide… + Cîhazeke din girê bide… - Danişîna gera nepen + Rûniştina gerîna veşartî - Hilpekînên nepen jê bibe + Hilpekînên veşartî jê bibe - Hilpekînên nepen bigire + Hilpekînên veşartî bigire Veke @@ -1043,7 +1044,7 @@ Bipejirîne - Destûrê bide %1$sê ku %2$sê veke + Destûrê bide %1$s’ê ku %2$s’ê veke BIHÊLE @@ -1051,7 +1052,7 @@ Tu bi rastî jî dixwazî koleksiyana %1$s’ê were jêbirin? - Jêbirina vê hilpekînê dê hemû koleksiyê jê bibe. Kengê bixwazî dikarî koleksiyoneke nû biafirînî. + Jêbirina vê hilpekînê dê hemû koleksiyonê jê bibe. Kengî bixwazî dikarî koleksiyoneke nû biafirînî. %1$s’ê jê bibe? @@ -1063,16 +1064,16 @@ URL hate kopîkirin - Ev nivîseke nimûneyî ye. Li virê xuya dibe ka gava tu bi vê sazkariyê mezinahiyê biguherînî dê çawa be. + Ev, nivîsa nimûne ye. Dema ku tu bi vê eyarê mezinbûnê biguherînî dê çawaniya nivîsê li vir xuya bibe. - Nivîsên li ser malperan mezintir yan biçûktir bike + Nivîsên li ser malperan mezintir an jî biçûktir bike Mezinahiya fontê - Lêaîna mezinahiya nivîsan ya xweber + Mezinkirina fontê ya bixweber - Mezinahiya nivîsan dê li gorî sazkariyên Androîda te be. Ji bo mezinahiyê nivîsê li virê biguherînî vê wê betal bike. + Mezinahiya fontê ew ê li gorî sazkariyên Androida te be. Ji bo mezinahiya fontê li vir biguherînî, vê eyarê betal bike. Daneyên gerînê jê bibe @@ -1093,11 +1094,11 @@ Kûkî - Danişînên li ser gelek malperan dê bên girtin + Têketinên te yên li ser gelek malperan dê bên girtin - Wêne û pelên di pêşbîrê de + Wêne û dosyeyên di pêşbîrê de - Ciyê depokirinê vala dike + Qada depokirinê vala dike Destûrên malperan @@ -1105,25 +1106,25 @@ Daneyên gerînê jê bibe - Daneyên gerê di dema derketinê de jê bibe + Di derketinê de daneyên gerînê jê bibe - Gava tu ji menuya giştî "Derkeve"yê hilbijêrî daneyên gerê xweber paqij dike + Gava tu ji menûya giştî "Derkeve"yê hilbijêrî daneyên gerînê xweber paqij dike - Gava tu ji menuya giştî \"Derkeve\"yê hilbijêrî daneyên gerê xweber paqij dike + Gava tu ji menûya giştî \"Derkeve\"yê hilbijêrî daneyên gerînê xweber paqij dike Derkeve - Ev ê hemû daneyên te yên gerê jê bibe + Ev ê hemû daneyên te yên gerînê jê bibe - %s dê daneyên gerê yên hilbijartî jê bibe. + %s dê daneyên gerînê yên hilbijartî jê bibe. Betal bike Jê bibe - Daneyên gerînê hate jêbirin + Daneyên gerînê hatin jêbirin Daneyên gerînê tên jêbirin… @@ -1133,28 +1134,28 @@ - Firefox Nightly her şev tê nûkirin û tê de taybetiyên nû yên ceribandinê hene. - Lê belê, dibe ku hindiktir stabîl be. Ji bo ceribandineke stabîltir geroka me ya beta jêbar bike. + Firefox Nightly her şev tê nûvekirin û tê de taybetiyên nû yên ceribandinê hene. + Lê belê, dibe ku hindiktir stabîl be. Ji bo ceribandineke stabîltir geroka me ya betayê daxîne. - Firefox Betaya ji bo Andoîdê jêbar bikin + Betaya Firefoxê ji bo Androidê daxîne - Firefox Nightlyê bar kir + Firefox Nightly hat veguhastin - Ev sepan dê venûkirinên ewlekariyê êdî wernegire. Êdî vê sepanê bi kar neyne û derbasî Nightlya nû bibe. - \ n \ nJi bo transferkirina favorî, têketin û mêjûya xwe bo sepaneke din, hesabekî Firefoxê biafirîne. + Ev sepan ew ê êdî nûvekirinên ewlekariyê wernegire. Êdî vê sepanê bi kar neyîne û derbasî Nightlya nû bibe. + \ n \ nJi bo transferkirina favorî, hesab û raboriya xwe li sepaneke din, hesabekî Firefoxê biafirîne. Derbasî Nightlya nû bibe - Firefox Nightlyê bar kir + Firefox Nightly hat veguhastin - Ev sepan dê venûkirinên ewlekariyê êdî wernegire. Êdî vê sepanê bi kar neyne û derbasî Nightlya nû bibe. - \ n \ nJi bo transferkirina favorî, têketin û mêjûya xwe bo sepaneke din, hesabekî Firefoxê biafirîne. + Ev sepan ew ê êdî nûvekirinên ewlekariyê wernegire. Êdî vê sepanê bi kar neyîne û derbasî Nightlya nû bibe. + \ n \ nJi bo transferkirina favorî, hesab û raboriya xwe li sepaneke din, hesabekî Firefoxê biafirîne. - Nightlya nû jêbar bike + Nightlya nû daxîne - Pirsên te derbarê %sa nû de hene? Dixwazî bizanî ka çi guheriye? + Pirsên te derbarê %s’ê ya nû de hene? Dixwazî bizanî ka çi guheriye? Bersiv li vir in - Bi hesabê xwe yê Firefoxê dest bi hevsengkirina favoriyan, şîfreyan û zêdetir tiştên xwe bike. + Bi hesabê xwe yê Firefoxê dest bi senkronîzekirina favoriyan, pêborînan û zêdetirî wan, bike. Zêdetir bizane - Te li ser vê amûrê wekî %s li ser gerokeke din a Firefoxê têketin pêk anî. Tu dixwazî bi vî hesabî têkeviyê? + Tu li ser vê cîhazê di gerokeke din a Firefoxê de wekî %s têketî yê. Tu dixwazî bi vî hesabî têkevî? Erê, têkeve @@ -1196,7 +1197,7 @@ Nihêniya otomatîk - Sazkariyên nepeniyê û ewlekariyê şopîneran û sepanên niyetxirab û şirketên dixwazin te bişopînin asteng dike. + Sazkariyên nihênî û ewlekariyê şopîneran û sepanên niyetxerab û şirketênku dixwazin te bişopînin asteng dike. Standard (jixweber) @@ -1206,20 +1207,20 @@ Tund - Zêdetir şopîneran, reklaman û popupan asteng dike. Rûpel zûtir vedibin, lê dibe ku hin taybetî nexebitin. + Zêdetir şopîneran, reklaman û pencereyên vebûnok asteng dike. Rûpel zûtir vedibin, lê dibe ku hin taybetî nexebitin. Aliyê xwe hilbijêre - Bi darikê amûran yê li xwarê gera bi destekî biceribîne yan jî wê bibe jorê. + Darika amûran a jêrîn bi destekî biceribîne an jî wê bibe jorê tu bi kêfa xwe yî. - Bi nepenî bigere + Bi nihênî bigere - Carekê hilpekîneke nepen veke: Pêl îkona %sê bike. + Ji bo carekê hilpekîneke veşartî veke: Li îkona %s’ê bitikîne. - Her car hilpekînên nepen veke: Sazkariyên xwe yên gera nepen venû bike. + Her carê hilpekînên veşartî veke: Sazkariyên xwe yên gerîna veşartî nûve bike. Sazkariyan veke @@ -1239,11 +1240,11 @@ Rûkara xwe hilbijêre - Bi çalakkirina moda tarî him ji bataryayê teseruf bike him çavên xwe vehesîne. + Bi çalakkirina moda tarî him ji bataryayê teserûf bike him jî çavên xwe rehet bike. Otomatîk - Xwe li sazkariyên amûra te tîne + Xwe li sazkariyên cîhaza te adabte dike Rûkara tarî @@ -1260,36 +1261,36 @@ Kodê sken bike - https://firefox.com/pair]]> + https://firefox.com/pair]]> Ji bo skenkirinê amade me - Bi kameraya xwe têkevê + Bi kameraya xwe têkeve - Bi e-peyamê têkevê + Bi emaîlê têkeve - Yekê biafirîne ku Firefoxê di navbera amûran de hevseng bikî.]]> + Hesêb veke.]]> - Firefox dê hevsengkirina bi hesabê te re asteng bike, lê dê daneyên te yên gerê yên li ser vê amûrê jê nebe. + Firefox dê bi hesabê te re senkronîzekirinê rawestîne, lê ti daneyên te yên gerînê yên di vê cîhazê de nayên jêbirin. - %s dê hevsengkirina bi hesabê te re asteng bike, lê dê daneyên te yên gerê yên li ser vê amûrê jê nebe. + %s ew ê bi hesabê te re senkronîzekirinê rawestîne, lê ti daneyên te yên gerînê yên di vê cîhazê de nayên jêbirin. Girêdanê qut bike Betal bike - Peldankên standard nayên serastkirin + Peldankên standard nayên sererastkirin Sazkariyên parastinê - Parastina şopandinê ya pêşketî + Parastina ji şopandinê ya pêşketî - Bêyî ku bêtî şopandin bigere + Bêyî ku tu bê şopandin bigere - Bila daneyên te ji te re bimînin. %s te ji piraniya şopîneran diparêze ku tiştên tu li ser înternetê dikî dişopînin. + Bila daneyên te ji te re bimînin. %s te ji gelek şopdarên dilxerab diparêze û nahêle tiştên ku tu li ser înternetê dikî ji aliyê wan ve bên dîtin. Zêdetir bizane @@ -1297,32 +1298,32 @@ Hindiktir şopîneran asteng bike. Rûpel dê asayî vebin. - Bi parastina şopandinê ya standard çi tên astengkirin? + Bi parastina ji şopandinê ya standard çi tên astengkirin? Tund - Zêdetir şopîneran, reklaman û popupan asteng dike. Rûpel zûtir tên barkirin, lê dibe ku hin taybetî nexebitin. + Zêdetir şopîneran, reklaman û pencereyên vebûnok asteng dike. Rûpel zûtir vedibin, lê dibe ku hin taybetî nexebitin. - Bi parastina şopandinê ya tund çi tên astengkirin? + Bi parastina ji şopandinê ya tund çi tên astengkirin? Taybet Hilbijêre ka kîjan şopîner û skrîpt bên astengkirin. - Bi parastina şopandina taybet çi tên astengkirin? + Bi parastina ji şopandinê ya taybet çi tên astengkirin? Kûkî Şopînerên nav-malperî û şopînerên medyaya civakî - Çerezên malperên nehatine bikaranîn + Çerezên ji malperên ku nehatine ziyaretkirin - Hemû çerezên partiya sêyemîn (dibe ku hin malper xira bibin) + Hemû çerezên partiya sêyemîn (dibe ku hin malper xera bibin) - Hemû çerezan (dibe ku hin malper xira bibin) + Hemû çerez (dibe ku hin malper xera bibin) - Naverokên şopandinê + Naverokên ji bo şopandinê Di hemû hilpekînan de @@ -1333,7 +1334,7 @@ Kankerên krîpto Berhevkarên şoptiliyan - Astengker + Yên astengbûyî Destûrgirtî @@ -1353,32 +1354,30 @@ Naverokên şopandinê - Barkirina reklam, vidyo û naverokên din yên tê de koda şopandin heye asteng dike. Dibe ku bandorê li taybetiyên hin malperan bike. + Nahêle reklam, vîdyo û naverokên din ên tê de koda şopandinê hene bên barkirin. Dibe ku bandorê li taybetiyên hin malperan bike. - Gava mertal bû rengê mor, nexwe %sê şopîner asteng kirine. Ji bo agahiyên zêdetir bipelîne. + Gava mertal bû rengê mor, tê vê wateyê ku %s’ê şopîner asteng kirine. Ji bo agahiyên zêdetir, bitepîne. - Parastin ji bo v malperê VEKIRÎ ne. + Parastin ji bo vê malperê VEKIRÎ ne. Parastin ji bo vê malperê GIRTÎ ne - Parastina şopandinê ya pêşketî ji bo van malperan hat girtin + Parastina ji şopandinê ya pêşketî ji bo van malperan hat girtin Paşve here Mafên te - Pirtûkxaneyên çavkaniya azad yên em bi kar tînin + Pirtûkxaneyên çavkaniya azad ên em bi kar tînin - Di %s çi tiştên nû hene? + Di %s’ê de çi tiştên nû hene? %s | Pirtûkxaneyên OSS’ê Şoînerên beralîkirinê - - Çerezên aîdî beralîkirinên ji bo malperên şopandinê yên naskirî asteng dike. Piştgirî @@ -1392,12 +1391,12 @@ Agahiyên lîsanskirinê - Pirtûkxaneyên em bikar tînin + Pirtûkxaneyên em bi kar tînin - Menuya neqandina çewtiyan: Ji bo çalakkirinê %1$d tikandin man + Menûya neqandina çewtiyan: Ji bo çalakkirinê %1$d tikandin man - Menuya neqandina çewtiyan hat çalakkirin + Menûya neqandina çewtiyan çalek e 1 hilpekîn @@ -1426,7 +1425,7 @@ Navê kurterêyê - Tu dikarî vê malperê bi hêsanî li ekrana Serûpela amûra xwe zêde bikî ku zû bigihiyê û wê wekî sepanekê bi kar bînî. + Tu dikarî vê malperê bi hêsanî li ekrana Destpêkê ya cîhaza xwe zêde bikî ku ji wir zûtir bigihîjî wê û wê wekî sepanekê bi kar bînî. Hesab û pêborîn @@ -1451,15 +1450,15 @@ Hesabên tomarkirî - Têketinên te tomar kirine yan hevsengkirinên bi %sê re dê li virê bên nîşandan. + Hesabên ku te tomar kirine yan jî te bi %s’ê re senkronîze kirine dê li vir bên nîşandan. Derbarê Sync’ê de agahî bistîne. Istisna - Têketin û şîfreyên nehatine tomarkirin dê li virê bên nîşandan. + Hesab û pêborînên nehatine tomarkirin dê li vir bên nîşandan. - Têketin û şîfre dê ji bo van malperan neyên tomarkirin. + Hesab û pêborîn dê ji bo van malperan neyên tomarkirin. Hemû istisnayan jê bibe @@ -1467,7 +1466,7 @@ Alfabetîkî - Dawiyê hatî bikaranîn + Bikaranînên herî dawî Malper @@ -1477,9 +1476,9 @@ PIN’a xwe dîsa binivîse - Ji bo têketinên xwe yên tomarkirî bibînî kilîdê veke + Ji bo hesabên xwe yên tomarkirî bibînî, kilîdê veke - Ev girêdan ne ewle ye. Îhtîmal heye têketinên li virê bên bidestxistin. + Ev girêdan ne ewle ye. Îhtîmal heye agahiyên hesêb ên li vir hatine nivîsîn bên bidestxistin. Zêdetir bizane @@ -1528,7 +1527,7 @@ Bikaranîna dawî - Menuya rêzkirina têketinan + Menûya rêzkirina hesaban Motora lêgerînê tevlî bike @@ -1549,9 +1548,9 @@ Nav - Rêzeya lêgerînê ya ji bo bikaranînê + Rêzika lêgerînê ya ji bo bikaranînê - Daxwazê bi “%s”. Mînak:\nhttps://www.google.com/search?q=%sê biguherîne + Lêpirsînê bi “%s”ê pev biguherîne. Mînak:\nhttps://www.google.com/search?q=%s Zêdetir Bizane @@ -1565,11 +1564,11 @@ Motora lêgerînê ya bi navê “%s” jixwe heye. - Rêzikeek lêgerînê binivîse + Rêzikeke lêgerînê binivîse - Kontrol bike ka rêzika lêgerînê û formata Mînak li hev dikin yan na + Kontrol bike ka rêzika lêgerînê û formata nimûne li hev dikin an na - Êewtiya girêdana bi “%s”ê ve + Li “%s”ê ve nehate girêdan %s hat afirandin @@ -1578,13 +1577,13 @@ %s hat jêbirin - Bi xêr hatî geroka %sê ya nipînû + Bi xêr hatî geroka %s’ê ya nipînû Me geroka te bi performans û taybetiyên pêşxistî ji serî heta binî nû kir ku tu dikarî li ser înternetê tiştên zêdetir bikî.\n\nTika ye heta %sê van venû bike li bendê bin... %s tê nûvekirin… - %sê bide destpêkirin + %s’ê bide destpêkirin Veguhestin qediya @@ -1595,24 +1594,24 @@ 1. Here sazkariyên Androidê - Destûrê bitikîne]]> + Destûr’ê bitikîne]]> - %1$sê bike VEKIRÎ]]> + %1$s’ê bike VEKIRÎ]]> Girêdana ewle Girêdana neewle - Tu ji dil dizanî hemû destûrên li ser hemû malperan jê bibî? + Tu ji dil dixwazî hemû destûrên li ser hemû malperan jê bibî? - Tu ji dil dizanî hemû destûran ji bo hemû malperan jê bibî? + Tu ji dil dixwazî hemû destûran ji bo vê malperê jê bibî? Tu ji dil dixwazî vê destûrê ji bo vê malperê jê bibî? Istisnayên malperê tune - Gotarên Serekî + Gotarên serekî Tu ji dil dixwazî vê favoriyê jê bibî? @@ -1634,9 +1633,9 @@ Qada nivîsê ya ji bo navnîşana webê ya têketinê - Qada nivîsê ya ji bo navê bikarhêneriyê ya têketinê. + Qada nivîsê ya ji bo navê bikarhêneriyê yê têketinê. - Qada nivîsê ya ji bo şîfreya têketinê. + Qada nivîsê ya ji bo pêborîna têketinê. Guhertinan li hesêb tomar bike. @@ -1660,9 +1659,9 @@ Ji kerema xwe, senkronîzekirina hilpekînê veke. - Li ser amûrên din ti hilpekîneke di Firefoxê de vekirî tune ye. + Di Firefoxên li ser cîhazên te yên din de ti hilpekîneke vekirî tune ye. - Lîsteyeke hilpekînan ya ji amûrên xwe yên din bibîne. + Lîsteyeke hilpekînan a ji cîhazên xwe yên din bibîne. Têkeve Sync’ê @@ -1673,7 +1672,7 @@ Gihîşte sînorê malperên sereke - Ji bo malpereke din a sereke lê zêde bikî, yekê jê bibe. Li malperê bitikîne û li ser bihêle piştre rakirinê hilbijêre. + Ji bo malpereke din a sereke lê zêde bikî, yekê jê bibe. Li malperê bitikîne û li ser bihêle, piştre rakirinê hilbijêre. Baş e @@ -1692,7 +1691,7 @@ - Ji %sa xwe fêdeya herî zêde bibînin. + Ji %s’ê fêdeya herî zêde bibînin. Ji bo agahiyên zêdetir, bitikîne @@ -1700,7 +1699,7 @@ Tiştên ku ji te re girîng in berhev bike - Lêgerîn, malper û hilpekînên wekî hev bi hev re bike kom da ku paşê xwe zû bigihîniyê. + Lêgerîn, malper û hilpekînên wekhev, bike kom da ku paşê tu karibî xwe zû bigihînî wan. - Tu li ser vê telefonê di gerokeke din ya Firefoxê de wekî %s têketiyê. Tu dixwazî bi vî hesabî têkeviyê? + Tu li ser vê telefonê di gerokeke din a Firefoxê de wekî %s têketî yê. Tu dixwazî bi vî hesabî têkevî? diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 7a58543c2..cba115244 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -607,6 +607,8 @@ Atvertos kortelės Įtraukti į rinkinį + + Pasirinkti Dalintis visomis kortelėmis @@ -887,16 +889,22 @@ Įjungta Išjungta - + Leisti garsus ir vaizdus + + Leisti garsus ir vaizdus Blokuoti garsus ir vaizdus tik naudojant mobilųjį ryšį Garsai ir vaizdai gros tik per „Wi-Fi“ - + Blokuoti tik garsus - + + Blokuoti tik garsus + Blokuoti garsus ir vaizdus + + Blokuoti garsus ir vaizdus Įjungta diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d6ffee801..7bb5a4f72 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -892,16 +892,22 @@ Wyłączona - + Zezwalaj na dźwięk i wideo + + Zezwalaj na dźwięk i wideo Blokuj dźwięk i wideo tylko w sieciach komórkowych Dźwięk i wideo będą odtwarzane w sieciach Wi-Fi - + Blokuj tylko dźwięk - + + Blokuj tylko dźwięk + Blokuj dźwięk i wideo + + Blokuj dźwięk i wideo Włączone diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 9c6848e64..a2b32e0c9 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -884,16 +884,22 @@ เปิด ปิด - + อนุญาตเสียงและวิดีโอ + + อนุญาตเสียงและวิดีโอ ปิดกั้นเสียงและวิดีโอบนการใช้งานมือถือ เสียงและวิดีโอจะเล่นบน Wi-Fi - + ปิดกั้นเสียงเท่านั้น - + + ปิดกั้นเสียงเท่านั้น + ปิดกั้นเสียงและวิดีโอ + + ปิดกั้นเสียงและวิดีโอ เปิด diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index f2cdaa2ba..2439c1c5f 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -55,6 +55,10 @@ Ikaw ay nasa pribadong sesyon + + + Inaalis ng %1$s ang iyong bakas sa paghahanap at pag-browse sa mga pribadong tab kapag isinara mo sila o umalis sa app. Bagaman makikilala ka pa rin ng mga website o internet service provider mo, nakatutulong pa rin ito para mapanatiling pribado ang mga gawain mo online sa ibang gagamit ng device na ito. Mga karaniwang pamahiin tungkol sa pribadong pag-browse @@ -91,6 +95,8 @@ Alisin + + Baguhin ang layout ng mga nakabukas na tab. Pumunta sa mga setting at piliin ang grid sa tab view. Pumunta sa settings @@ -541,6 +547,8 @@ Hanapin Mga Setting + + Menu para sa listahan ng kasaysayan Isara @@ -561,6 +569,8 @@ Mga Tab + + Tab view Listahan @@ -616,12 +626,18 @@ Isara lahat ng mga tab Bagong Tab + + Pumunta sa home + + i-Toggle ang tab mode Bookmark Isara Ibahagi ang mga piniling mga tab + + Menu para sa mga napiling tab Tanggalin ang tab sa collection @@ -759,6 +775,9 @@ Ibahagi ang session + + + Bookmark menu i-Edit ang bookmark @@ -835,8 +854,20 @@ Mga permiso Pumunta sa mga Setting + + Listahan ng mga quick setting Inirerekomenda + + i-Manage ang mga site permission + + Alisin ang pahintulot + + Alisin ang pahintulot + + Alisin ang mga pahintulot sa lahat ng site Autoplay @@ -865,16 +896,22 @@ Nakabukas Nakasara - + Payagan ang audio at video + + Payagan ang audio at video Harangin ang audio at video kapag naka-cellular data lamang Aandar ang audio at video sa Wi-Fi - + Harangin ang audio lamang - + + Harangin ang audio lamang + Harangin ang audio at video + + Harangin ang audio at video On @@ -1053,6 +1090,8 @@ Mga nakabukas na tab %d tab + + Kasaysayan ng pag-browse at site data %d address @@ -1067,6 +1106,8 @@ Mala-log out ka sa karamihan ng mga site Mga naka-cache na larawan at file + + Nagpapaluwag ng storage space Mga site permission @@ -1161,6 +1202,11 @@ Nakabukas ang Sync Bigong makapag-sign-in + + Awtomatikong pribasiya + + Hinaharang ng mga setting ng pribasiya at seguridad ang mga tracker, malware, at kumpanyang nagmamanman sa iyo. Karaniwan (default) @@ -1311,8 +1357,12 @@ Hinaharang ang mga cookie na ginagamit ng mga ad network at analytics company para pagsama-samahin ang iyong browsing data sa iba\'t-ibang mga site. Mga cryptominer + + Pinipigilan ang mga mapanghamak na script sa pag-access sa device mo para magmina ng digital currency. Mga fingerprinter + + Pinipigilang makolekta ang mga bukod-tanging data ng pagkakakilanlan sa device mo na pwedeng gamitin sa pagsubaybay. Tracking Content @@ -1340,6 +1390,9 @@ Mga Redirect Tracker + + Inaalis ang mga cookie na itinakda ng mga redirect sa mga kilalang tracking website. + Suporta @@ -1353,10 +1406,41 @@ Mga library na ginagamit namin + + Debug menu: %1$d natitirang click para ma-enable + Naka-enable na ang debug menu + + + 1 tab + + %d tab + Kopyahin + + i-Paste at Puntahan + + i-Paste + + Nakopya na ang URL sa clipboard + + + Idagdag sa Home screen + + + Kanselahin + + Idagdag + + Magpatuloy sa website + + Pangalan ng shortcut + + Madali lang maidagdag ang website na ito sa Home screen ng iyong device para agarang ma-access at ma-browse na parang app lamang. + Mga login at password @@ -1365,10 +1449,16 @@ Tanungin kung ise-save Huwag mag-save kailanman + + Autofill + + Mag-sync ng mga login Nakabukas Nakasara + + Kumonekta muli Mag-sign in sa Sync @@ -1383,8 +1473,12 @@ Ang mga login at password na hindi naka-save ay ipapakita rito. Hindi ise-save ang mga login at password para sa mga site na ito. + + Burahin lahat ng mga exception Hanapin sa mga login + + Alpabetikal Ginamit kamakailan @@ -1395,10 +1489,32 @@ Password Muling ipasok ang PIN + + i-Unlock para makita ang mga naka-save na login + + Ang koneksyong ito ay di-ligtas. Maaaring makompromiso ang mga login na ipapasok dito. + + Alamin + + Gusto mo bang i-save ng %s ang login na ito? + + i-Save + + Huwag i-save + + Nakopya na ang password sa clipboard + + Nakopya na ang username sa clipboard + + Nakopya na ang site sa clipboard Kopyahin ang password + + Alisin ang password Kopyahin ang username + + Alisin ang username Kopyahin ang site @@ -1408,11 +1524,19 @@ Ipakita ang password Itago ang password + + i-Unlock para makita ang mga naka-save na login Pakaingatan ang iyong mga login at password Magtakda ng device lock pattern, PIN, o password para maprotektahan ang mga naka-save mong login at password sakaling may ibang may hawak sa device mo. + + Mamaya + + Mag-set up ngayon din + + i-Unlock ang iyong device Mag-zoom sa lahat ng mga website @@ -1422,10 +1546,182 @@ Huling ginamit + + Menu sa pagsunud-sunod ng login + + + Magdagdag ng search engine + + i-Edit ang search engine + + Magdagdag + + i-Save + + i-Edit + + Burahin + + + Iba pa + + Pangalan + + + Gagamiting teksto ng paghahanap + + Palitan ang query ng “%s”. Halimbawa:\nhttps://www.google.com/search?q=%s + + Alamin + + Pasadyang detalye ng search engine + + + Link para sa Alamin + + + Ipasok ang pangalan ng search engine + + Mayroon nang search engine na nagngangalang “%s”. + + Magpasok ng search string + + Siguruhing tugma ang search string sa format ng halimbawa + + Nagkaproblema kumonekta sa “%s” + + Nalikha na ang %s + + Nai-save na ang %s + + Nabura na ang %s + + + Maligayang pagdating sa isang bagung-bagong %s + + Nasa harapan mo ang isang bagong-disenyong browser, na pinaghusay ang performance at mga feature na makatutulong sa iyo nang husto online.\n\nMangyaring maghintay habang ina-update namin ang %s kasama ang iyong + + Ina-update ang %s… + + Simulan ang %s + + Tapos na ang pag-angkat + + Mga password + + + Para payagan ito: + + 1. Pumunta sa Android Settings + + Mga pahintulot]]> + + %1$s sa nakabukas]]> + + + Ligtas na Koneksyon + + Hindi Ligtas na Koneksyon + + Sigurado ka bang gusto mong alisin lahat ng mga pahintulot sa lahat ng mga site? + + Sigurado ka bang gusto mong alisin lahat ng mga pahintulot sa site na ito? + + Sigurado ka bang gusto mong alisin itong pahintulot sa site na ito? + + Walang mga site exception + + Mga Pangunahing Artikulo + + Sigurado ka bang gusto mong burahin itong bookmark? Idagdag sa mga top site + + Pinatunayan Ni: %1$s + + Burahin + + i-Edit + + Sigurado ka bang gusto mong burahin itong login? + + Burahin + + Mga pagpipilian sa login + + Ang editable text field para sa web address ng login. + + Ang editable text field para sa username ng login. + + Ang editable text field para sa password ng login. + + i-Save ang mga pagbabago sa login. + + Isantabi ang mga pagbabago + + i-Edit + + Kinakailangan ang password + + Paghanap gamit ang boses + + Magsalita na + + Mayroon nang login na may ganyang username + + + + Magkonekta ng isa pang device. + + Mangyaring mag-re-authenticate. + + Paki-enable ang pag-sync ng tab. + + Wala kang mga nakabukas na tab sa Firefox sa iba mo pang mga device. + + Tingnan ang listahan ng mga tab mula sa iba mong mga device. + + Mag-sign in sa sync + + Walang nakabukas na mga tab + + + + Naabot na ang hangganan ng bilang sa top site + + Magtanggal ng isa para makapagdagdag ng bagong pangunahing site. Pindutin nang matagal ang site at piliin ang tanggalin. + + OK, Nakuha ko Ipakita ang pinakamadalas na bisitahing site - + + Pangalan + + Pangalan ng pangunahing site + + OK + + Kanselahin + + + Tanggalin + + + Sulitin ang %s. + + + Pindutin para sa karagdagang detalye + + + Kolektahin ang mga bagay na mahalaga sa iyo + + Pangkatin ang mga magkakatulad na hinahanap, site, at tab para madaling makuha sa susunod. + + Naka-sign in ka bilang %s sa isa pang Firefox browser sa teleponong ito. Nais mo bang mag-sign in gamit ito? + + Madali lang maidagdag ang website na ito sa Home screen ng iyong telepono para agarang ma-access at ma-browse na parang app lamang. + diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 438f1572d..7e87abc75 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -887,16 +887,22 @@ Kapalı - + Ses ve videoya izin ver + + Ses ve videoya izin ver Ses ve videoyu yalnızca hücresel veride engelle Ses ve videolar yalnızca Wi-Fi’da oynatılacak - + Yalnızca sesi engelle - + + Yalnızca sesi engelle + Ses ve videoyu engelle + + Ses ve videoyu engelle Açık diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 6dd96748a..d56306626 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -883,16 +883,22 @@ Bật Tắt - + Cho phép âm thanh và video + + Cho phép âm thanh và video Chỉ chặn âm thanh và video trên dữ liệu di động Âm thanh và video sẽ phát trên Wi-Fi - + Chỉ chặn âm thanh - + + Chỉ chặn âm thanh + Chặn âm thanh và video + + Chặn âm thanh và video Bật From cb246ed4bb8e980ad67d15c655d4deb9ff09eb16 Mon Sep 17 00:00:00 2001 From: mcarare Date: Fri, 19 Feb 2021 13:07:18 +0200 Subject: [PATCH 167/248] For #18075: Add SaveVideoAudioCandidate for custom tabs context menu. --- .../org/mozilla/fenix/browser/CustomTabContextMenuCandidate.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/org/mozilla/fenix/browser/CustomTabContextMenuCandidate.kt b/app/src/main/java/org/mozilla/fenix/browser/CustomTabContextMenuCandidate.kt index ed96a50cd..4753360c3 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/CustomTabContextMenuCandidate.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/CustomTabContextMenuCandidate.kt @@ -29,6 +29,7 @@ class CustomTabContextMenuCandidate { ), ContextMenuCandidate.createShareLinkCandidate(context), ContextMenuCandidate.createSaveImageCandidate(context, contextMenuUseCases), + ContextMenuCandidate.createSaveVideoAudioCandidate(context, contextMenuUseCases), ContextMenuCandidate.createCopyImageLocationCandidate( context, snackBarParentView, From c9ed8a5b929656043cc02a3a3147e91291bec922 Mon Sep 17 00:00:00 2001 From: rxu Date: Mon, 1 Feb 2021 13:02:44 +0800 Subject: [PATCH 168/248] Add MOZILLA_ONLINE_ADDON_EXCLUSIONS for Mozilla Online builds --- app/build.gradle | 12 ++++++++++++ .../mozilla/fenix/addons/AddonsManagementFragment.kt | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index a0ad61917..2676cc592 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,6 +41,18 @@ android { buildConfigField "String", "AMO_BASE_URL", "\"https://addons.mozilla.org\"" buildConfigField "String", "AMO_COLLECTION_NAME", "\"7dfae8669acc4312a65e8ba5553036\"" buildConfigField "String", "AMO_COLLECTION_USER", "\"mozilla\"" + // These add-ons should be excluded for Mozilla Online builds. + buildConfigField "String[]", "MOZILLA_ONLINE_ADDON_EXCLUSIONS", + "{" + + "\"uBlock0@raymondhill.net\"," + + "\"firefox@ghostery.com\"," + + "\"jid1-MnnxcxisBPnSXQ@jetpack\"," + + "\"adguardadblocker@adguard.com\"," + + "\"foxyproxy@eric.h.jung\"," + + "\"{73a6fe31-595d-460b-a920-fcc0f8843232}\"," + + "\"jid1-BoFifL9Vbdl2zQ@jetpack\"," + + "\"woop-NoopscooPsnSXQ@jetpack\"" + + "}" // This should be the base URL used to call the AMO API. buildConfigField "String", "AMO_SERVER_URL", "\"https://services.addons.mozilla.org\"" def deepLinkSchemeValue = "fenix-dev" diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index 06a8555cc..ccffe192e 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -29,6 +29,8 @@ import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment import mozilla.components.feature.addons.ui.AddonsManagerAdapter import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.translateName +import org.mozilla.fenix.BuildConfig +import org.mozilla.fenix.Config import org.mozilla.fenix.GleanMetrics.Addons import org.mozilla.fenix.R import org.mozilla.fenix.components.FenixSnackbar @@ -105,6 +107,13 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) lifecycleScope.launch(IO) { try { val addons = requireContext().components.addonManager.getAddons(allowCache = allowCache) + // Add-ons that should be excluded in Mozilla Online builds + val excludedAddonIDs = if (Config.channel.isMozillaOnline && + !BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.isNullOrEmpty()) { + BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.toList() + } else { + emptyList() + } lifecycleScope.launch(Dispatchers.Main) { runIfFragmentIsAttached { if (!shouldRefresh) { @@ -112,7 +121,8 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) requireContext().components.addonCollectionProvider, managementView, addons, - style = createAddonStyle(requireContext()) + style = createAddonStyle(requireContext()), + excludedAddonIDs ) } isInstallationInProgress = false From 8c51e069658f7921796531809836939ce3dba7a6 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Mon, 22 Feb 2021 11:13:33 +0100 Subject: [PATCH 169/248] Add l10n.toml to list of auto-merge files. --- .mergify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mergify.yml b/.mergify.yml index b585bbebd..adcad0387 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -21,7 +21,7 @@ pull_request_rules: conditions: - author=mozilla-l10n-automation-bot - status-success=pr-complete - - files~=(strings.xml) + - files~=(strings.xml|l10n.toml) actions: review: type: APPROVE From 0a0f75d2ab89412df38da0d1e91a2174a26e7e90 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Fri, 19 Feb 2021 17:45:56 +0200 Subject: [PATCH 170/248] For #18027 - Also fix the bottom toolbar in place when a11y is enabled We previously only set the top toolbar as fixed if an a11y service was running. --- .../fenix/browser/BaseBrowserFragment.kt | 7 +--- .../components/toolbar/BrowserToolbarView.kt | 2 +- .../fenix/browser/BaseBrowserFragmentTest.kt | 20 ++++++++++ .../toolbar/BrowserToolbarViewTest.kt | 40 ++++++++++++++++++- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 3718b2dfe..ecc49681e 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -822,12 +822,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit internal fun initializeEngineView(toolbarHeight: Int) { val context = requireContext() - // If there is an a11y service enabled and the user hasn't explicitly set bottom toolbar - val isTopToolbarForced = - !context.settings().shouldUseBottomToolbar && - context.settings().shouldUseFixedTopToolbar - - if (!isTopToolbarForced && context.settings().isDynamicToolbarEnabled) { + if (!context.settings().shouldUseFixedTopToolbar && context.settings().isDynamicToolbarEnabled) { getEngineView().setDynamicToolbarMaxHeight(toolbarHeight) val toolbarPosition = if (context.settings().shouldUseBottomToolbar) { diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt index 1b25af105..b3b97311d 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarView.kt @@ -245,7 +245,7 @@ class BrowserToolbarView( fun setToolbarBehavior(shouldDisableScroll: Boolean = false) { when (settings.toolbarPosition) { ToolbarPosition.BOTTOM -> { - if (settings.isDynamicToolbarEnabled && !isPwaTabOrTwaTab) { + if (settings.isDynamicToolbarEnabled && !isPwaTabOrTwaTab && !settings.shouldUseFixedTopToolbar) { setDynamicToolbarBehavior(MozacToolbarPosition.BOTTOM) } else { expandToolbarAndMakeItFixed() diff --git a/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt index d65605fbd..c0d486e17 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/BaseBrowserFragmentTest.kt @@ -60,6 +60,16 @@ class BaseBrowserFragmentTest { verify { engineView.setDynamicToolbarMaxHeight(0) } } + @Test + fun `initializeEngineView should setDynamicToolbarMaxHeight to 0 if bottom toolbar is forced for a11y`() { + every { testContext.settings().shouldUseBottomToolbar } returns true + every { testContext.settings().shouldUseFixedTopToolbar } returns true + + fragment.initializeEngineView(13) + + verify { engineView.setDynamicToolbarMaxHeight(0) } + } + @Test fun `initializeEngineView should setDynamicToolbarMaxHeight to toolbar height if dynamic toolbar is enabled`() { every { testContext.settings().shouldUseFixedTopToolbar } returns false @@ -116,6 +126,16 @@ class BaseBrowserFragmentTest { verify { (swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 13 } } + @Test + fun `initializeEngineView should set toolbar height as EngineView parent's bottom margin if bottom toolbar is forced for a11y`() { + every { testContext.settings().shouldUseBottomToolbar } returns true + every { testContext.settings().shouldUseFixedTopToolbar } returns true + + fragment.initializeEngineView(13) + + verify { (swipeRefreshLayout.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 13 } + } + @Test fun `WHEN status is equals to FAILED or COMPLETED and it is the same tab then shouldShowCompletedDownloadDialog will be true`() { every { fragment.getCurrentTab() } returns createTab(id = "1", url = "") diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt index df34475e5..727f4f6a8 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/BrowserToolbarViewTest.kt @@ -50,11 +50,12 @@ class BrowserToolbarViewTest { } @Test - fun `setToolbarBehavior(false) should setDynamicToolbarBehavior if bottom toolbar is dynamic and the tab is not for a PWA or TWA`() { + fun `setToolbarBehavior(false) should setDynamicToolbarBehavior if no a11y, bottom toolbar is dynamic and the tab is not for a PWA or TWA`() { val toolbarViewSpy = spyk(toolbarView) every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns true every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns false toolbarViewSpy.setToolbarBehavior(false) @@ -66,6 +67,8 @@ class BrowserToolbarViewTest { val toolbarViewSpy = spyk(toolbarView) every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns false + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns false toolbarViewSpy.setToolbarBehavior(false) @@ -78,6 +81,20 @@ class BrowserToolbarViewTest { every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns true every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + every { testContext.settings().shouldUseFixedTopToolbar } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(false) should expandToolbarAndMakeItFixed if bottom toolbar is dynamic tab is not for a PWA or TWA but a11y is enabled`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns true toolbarViewSpy.setToolbarBehavior(false) @@ -85,11 +102,14 @@ class BrowserToolbarViewTest { } @Test - fun `setToolbarBehavior(true) should setDynamicToolbarBehavior if bottom toolbar is dynamic and the tab is not for a PWA or TWA`() { + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed bottom toolbar is dynamic, the tab is not for a PWA or TWA and a11y is disabled`() { + // All intrinsic checks are met but the method was called with `shouldDisableScroll` = true + val toolbarViewSpy = spyk(toolbarView) every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns true every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns false toolbarViewSpy.setToolbarBehavior(false) @@ -101,6 +121,8 @@ class BrowserToolbarViewTest { val toolbarViewSpy = spyk(toolbarView) every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns false + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns false toolbarViewSpy.setToolbarBehavior(false) @@ -113,6 +135,20 @@ class BrowserToolbarViewTest { every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM every { testContext.settings().isDynamicToolbarEnabled } returns true every { toolbarViewSpy.isPwaTabOrTwaTab } returns true + every { testContext.settings().shouldUseFixedTopToolbar } returns false + + toolbarViewSpy.setToolbarBehavior(false) + + verify { toolbarViewSpy.expandToolbarAndMakeItFixed() } + } + + @Test + fun `setToolbarBehavior(true) should expandToolbarAndMakeItFixed if bottom toolbar is dynamic, the tab is for a PWA or TWA and a11 is enabled`() { + val toolbarViewSpy = spyk(toolbarView) + every { testContext.settings().toolbarPosition } returns ToolbarPosition.BOTTOM + every { testContext.settings().isDynamicToolbarEnabled } returns true + every { toolbarViewSpy.isPwaTabOrTwaTab } returns false + every { testContext.settings().shouldUseFixedTopToolbar } returns true toolbarViewSpy.setToolbarBehavior(false) From d0cb6c0c006835a933e91f7914c234ee5af5156b Mon Sep 17 00:00:00 2001 From: Mugurell Date: Tue, 23 Feb 2021 08:52:34 +0200 Subject: [PATCH 171/248] For #18027 - Document shouldUseFixedTopToolbar --- app/src/main/java/org/mozilla/fenix/utils/Settings.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 5b42b4dcc..e458aabb1 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -468,6 +468,13 @@ class Settings(private val appContext: Context) : PreferencesHolder { true ) + /** + * Prefer to use a fixed top toolbar when: + * - a talkback service is enabled or + * - switch access is enabled. + * + * This is automatically inferred based on the current system status. Not a setting in our app. + */ val shouldUseFixedTopToolbar: Boolean get() { return touchExplorationIsEnabled || switchServiceIsEnabled From 8354d389c7921b66701814114abc31597d406012 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 23 Feb 2021 10:34:10 +0000 Subject: [PATCH 172/248] Update Android Components version to 73.0.20210222145717. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index fac632fa5..38d80495c 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210218143118" + const val VERSION = "73.0.20210222145717" } From 0eefce52d8cd9256f9440ef80f2427aee571e30b Mon Sep 17 00:00:00 2001 From: Mozilla L10n Automation Bot Date: Tue, 23 Feb 2021 00:06:05 +0000 Subject: [PATCH 173/248] Import l10n. --- app/src/main/res/values-cs/strings.xml | 12 ++++++-- app/src/main/res/values-da/strings.xml | 18 ++++++++++-- app/src/main/res/values-en-rGB/strings.xml | 12 ++++++-- app/src/main/res/values-es-rES/strings.xml | 12 ++++++-- app/src/main/res/values-fy-rNL/strings.xml | 12 ++++++-- app/src/main/res/values-gd/strings.xml | 23 +++++++++++---- app/src/main/res/values-gl/strings.xml | 12 ++++++-- app/src/main/res/values-gn/strings.xml | 12 ++++++-- app/src/main/res/values-iw/strings.xml | 12 ++++++-- app/src/main/res/values-nl/strings.xml | 12 ++++++-- app/src/main/res/values-pt-rPT/strings.xml | 12 ++++++-- app/src/main/res/values-rm/strings.xml | 12 ++++++-- app/src/main/res/values-ru/strings.xml | 12 ++++++-- app/src/main/res/values-sr/strings.xml | 12 ++++++-- app/src/main/res/values-tg/strings.xml | 12 ++++++-- app/src/main/res/values-tl/strings.xml | 34 +++++++++++----------- 16 files changed, 167 insertions(+), 64 deletions(-) diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 5d3a4477e..77facf933 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -905,16 +905,22 @@ Vypnuta - + Povolit zvuk i video + + Povolit zvuk i video Blokovat automatické přehrávání zvuků i videí při připojení přes mobilní data Na Wi-Fi připojení se zvuky i videa automaticky přehrávat budou - + Blokovat automatické přehrávání zvuků - + + Blokovat automatické přehrávání zvuků + Blokovat automatické přehrávání zvuků i videí + + Blokovat automatické přehrávání zvuků i videí Zapnuto diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 838fe1f53..b662bf04c 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -130,6 +130,8 @@ Rediger bogmærke Tilføjelser + + Udvidelser Her er ingen tilføjelser @@ -523,6 +525,10 @@ Andre bogmærker Historik + + Nyt faneblad + + Find på siden Synkroniserede faneblade @@ -873,16 +879,22 @@ Til Fra - + Tillad lyd og video + + Tillad lyd og video Bloker kun lyd og video via mobildata Lyd og video afspilles kun via wi-fi - + Bloker kun lyd - + + Bloker kun lyd + Bloker lyd og video + + Bloker lyd og video Til diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 9cc34c0cd..9ea65be1e 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -881,16 +881,22 @@ On Off - + Allow audio and video + + Allow audio and video Block audio and video on mobile data only Audio and video will play on Wi-Fi - + Block audio only - + + Block audio only + Block audio and video + + Block audio and video On diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 824db4a5d..227f8c447 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -900,16 +900,22 @@ Desactivada - + Permitir audio y vídeo + + Permitir audio y vídeo Bloquear audio y vídeo solo con datos móviles El audio y el vídeo se reproducirán con Wi-Fi - + Bloquear solo audio - + + Bloquear solo audio + Bloquear audio y vídeo + + Bloquear audio y vídeo Activado diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 2bfaa8d9f..9aa79e081 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -884,16 +884,22 @@ Oan Ut - + Audio en fideo tastean + + Audio en fideo tastean Audio en fideo allinnich op mobile data blokkearje Audio en fideo wurde fia wifi ôfspile - + Allinnich audio blokkearje - + + Allinnich audio blokkearje + Audio en fideo blokkearje + + Audio en fideo blokkearje Oan diff --git a/app/src/main/res/values-gd/strings.xml b/app/src/main/res/values-gd/strings.xml index 6cf7846f2..1d2e1c835 100644 --- a/app/src/main/res/values-gd/strings.xml +++ b/app/src/main/res/values-gd/strings.xml @@ -127,6 +127,8 @@ Deasaich an comharra-lìn Tuilleadain + + Leudachain Chan eil tuilleadan sam bith an-seo @@ -522,6 +524,10 @@ Comharran-lìn eile An eachdraidh + + Taba ùr + + Lorg san duilleag Tabaichean sioncronaichte @@ -871,16 +877,22 @@ Air Dheth - + Ceadaich fuaim is video + + Ceadaich fuaim is video Bac an fhuaim agus video air ceangal dàta mobile a-mhàin Gabhaidh fuaim agus video a chluich air WiFi - + Na bac ach an fhuaim - + + Na bac ach an fhuaim + Bach an fhuaim agus a’ video + + Bach an fhuaim agus a’ video Air @@ -1078,6 +1090,8 @@ Saoraidh seo stòras Ceadan nan làrach + + Luchdaidhean a-nuas Sguab an dàta brabhsaidh às @@ -1202,8 +1216,7 @@ Do phrìobhaideachd - Dhealbh sinn %s airson ’s gum bi smachd agad-sa air na cho-roinneas - tu air loidhne agus na cho-roinneas tu leinne. + Dhealbh sinn %s airson ’s gum bi smachd agad-sa air na cho-roinneas tu air loidhne agus na cho-roinneas tu leinn. Leugh sanas na prìobhaideachd againn diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 816bbd5c4..875f0fe2a 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -872,17 +872,23 @@ Activado Desactivado - + Permitir son e vídeo + + Permitir son e vídeo Bloquear son e vídeo só en datos móbiles O son e o vídeo reproduciranse habendo wifi - + Bloquear só o son - + + Bloquear só o son + Bloquear son e vídeo + + Bloquear son e vídeo Activado diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index c36665e03..c2d074cb6 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -900,16 +900,22 @@ Hendypyre Mboguepyre - + Emoneĩ mba’epu ha ta’ãngamýi + + Emoneĩ mba’epu ha ta’ãngamýi Ejoko mba’epu ha ta’ãngamýi pumbyry mba’ekuaarãme año Mba’epu ha ta’ãngamýi oñembohetáta Wi-Fi ndive - + Ejoko mba’epu año - + + Ejoko mba’epu año + Ejoko mba’epu ha ta’ãngamýi año + + Ejoko mba’epu ha ta’ãngamýi Hendypyre diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 937e2f0f4..a7645af5f 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -883,16 +883,22 @@ כבויה - + לאפשר שמע ווידאו + + לאפשר שמע ווידאו לחסום שמע ווידאו בחיבור סלולרי בלבד שמע ווידאו יופעלו על גבי Wi-Fi - + לחסום שמע בלבד - + + לחסום שמע בלבד + לחסום שמע ווידאו + + לחסום שמע ווידאו פעיל diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 4b6326bee..bb414308c 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -894,16 +894,22 @@ Uit - + Audio en video toestaan + + Audio en video toestaan Audio en video alleen op mobiele data blokkeren Audio en video worden via wifi afgespeeld - + Alleen audio blokkeren - + + Alleen audio blokkeren + Audio en video blokkeren + + Audio en video blokkeren Aan diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 909deec7d..1cfd4a089 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -889,16 +889,22 @@ Ativada Desativada - + Permitir áudio e vídeo + + Permitir áudio e vídeo Bloquear áudio e vídeo apenas em dados móveis Áudio e vídeo serão reproduzidos em Wi-Fi - + Bloquear apenas o áudio - + + Bloquear apenas o áudio + Bloquear o áudio e vídeo + + Bloquear o áudio e vídeo Ativado diff --git a/app/src/main/res/values-rm/strings.xml b/app/src/main/res/values-rm/strings.xml index 25257d506..2a50264e3 100644 --- a/app/src/main/res/values-rm/strings.xml +++ b/app/src/main/res/values-rm/strings.xml @@ -879,16 +879,22 @@ Activà Deactivà - + Permetter audio e video + + Permetter audio e video Bloccar audio e video mo en la rait mobila Audio e video vegn reproducì en cas dad ina connexiun WLAN - + Bloccar mo l\'audio - + + Bloccar mo l\'audio + Bloccar audio e video + + Bloccar audio e video Activà diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 2d9349101..5f8843eab 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -903,16 +903,22 @@ Отключена - + Разрешить аудио и видео + + Разрешить аудио и видео Блокировать аудио и видео только при использовании мобильных данных Аудио и видео будут проигрываться при использовании Wi-Fi - + Блокировать только аудио - + + Блокировать только аудио + Блокировать аудио и видео + + Блокировать аудио и видео Включено diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 491094655..b77fdd693 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -886,16 +886,22 @@ Укључено Искључено - + Дозволи звук и видео + + Дозволи звук и видео Блокирај звук и видео само на мобилној мрежи Звук и видео биће пуштани на бежичној мрежи - + Блокирај само звук - + + Блокирај само звук + Блокирај звук и видео + + Блокирај звук и видео Укључено diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index 7e3488988..4581b3f7b 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -886,16 +886,22 @@ Ғайрифаъол - + Иҷозат додани аудио ва видео + + Иҷозат додани аудио ва видео Бастани аудио ва видео танҳо дар шабакаи маълумоти мобилӣ Аудио ва видео дар шабакаи Wi-Fi пахш мешаванд - + Бастани танҳои аудио - + + Бастани танҳои аудио + Бастани аудио ва видео + + Бастани аудио ва видео Фаъол diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index 2439c1c5f..4ddbbb0ed 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -58,7 +58,7 @@ - Inaalis ng %1$s ang iyong bakas sa paghahanap at pag-browse sa mga pribadong tab kapag isinara mo sila o umalis sa app. Bagaman makikilala ka pa rin ng mga website o internet service provider mo, nakatutulong pa rin ito para mapanatiling pribado ang mga gawain mo online sa ibang gagamit ng device na ito. + Inaalis ng %1$s ang iyong bakas sa paghahanap at pag-browse sa mga pribadong tab kapag isinara mo sila o umalis sa app. Bagaman makikilala ka pa rin ng mga website o internet service provider mo, nakatutulong pa rin ito para mapanatiling pribado ang mga gawain mo online mula sa ibang gagamit ng device na ito. Mga karaniwang pamahiin tungkol sa pribadong pag-browse @@ -165,10 +165,10 @@ Buksan sa %1$s - POWERED BY %1$s + PINATATAKBO NG %1$s - Powered by %1$s + Pinatatakbo ng %1$s Reader view @@ -299,7 +299,7 @@ Mga gesture - Customize + Ipasadya Mag-sync ng mga bookmark, kasaysayan, at iba pa gamit ang iyong Firefox Account @@ -386,16 +386,16 @@ Mga Login - Open tabs + Mga nakabukas na tab - mag-Sign out + Mag-sign out Ngalan ng device Hindi maaaring blangko ang pangalan ng device. - Syncing… + Nagsi-Sync… Bigong pag-sync. Huling matagumpay na pag-sync: %s @@ -407,7 +407,7 @@ - %1$s ng %2$s %3$s + %1$s sa %2$s %3$s @@ -475,11 +475,11 @@ Scan pairing code in desktop Firefox - Sign in + Mag-sign in - Sign in to reconnect + Mag-sign in para mag-reconnect - Remove account + Tanggalin ang account @@ -715,7 +715,7 @@ Burahin - Napili na ang %1$d + May %1$d napili Burahin ang %1$d item @@ -748,7 +748,7 @@ Walang mga naka-download na file - Napili na ang %1$d + May %1$d napili Buksan @@ -815,7 +815,7 @@ i-Save - Napili na ang %1$d + May %1$d napili i-Edit ang bookmark @@ -903,7 +903,7 @@ Harangin ang audio at video kapag naka-cellular data lamang - Aandar ang audio at video sa Wi-Fi + Aandar ang audio at video kapag naka-Wi-Fi Harangin ang audio lamang @@ -913,9 +913,9 @@ Harangin ang audio at video - On + Nakabukas - Off + Nakasara From 2ead66f5c243c8c477aa57723c29a0fb0b51e934 Mon Sep 17 00:00:00 2001 From: mcarare Date: Tue, 23 Feb 2021 13:10:07 +0200 Subject: [PATCH 174/248] For #18102: Temporary ignore failing test. --- app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt b/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt index c3f21d59a..a82099258 100644 --- a/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt +++ b/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt @@ -8,6 +8,7 @@ import androidx.test.core.app.ApplicationProvider import mozilla.components.service.glean.testing.GleanTestRule import org.junit.Assert.assertTrue import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -26,6 +27,7 @@ class FenixApplicationTest { application = ApplicationProvider.getApplicationContext() } + @Ignore("See https://github.com/mozilla-mobile/fenix/issues/18102") @Test fun `GIVEN onCreate is called THEN the duration is measured`() { // application.onCreate is called before the test as part of test set up: From 40da3ecb675b4f5a19b15b42af254360bff5c802 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 23 Feb 2021 15:37:19 +0000 Subject: [PATCH 175/248] Update Android Components version to 73.0.20210223143117. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 38d80495c..1f3e0dba9 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210222145717" + const val VERSION = "73.0.20210223143117" } From fc312b0616b44e48d95a859747428f95f950fb4f Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Tue, 23 Feb 2021 23:45:49 +0400 Subject: [PATCH 176/248] Update AC version to 73.0.0 --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 1f3e0dba9..1cfef784e 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.20210223143117" + const val VERSION = "73.0.0" } From 1672243b6d72bddbf4f37d054d06811883e08cf1 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 23 Feb 2021 18:16:12 -0500 Subject: [PATCH 177/248] Change version to 87.0.0-beta.1 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index af2d9c332..6ec10b302 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -84.0.0-beta.1 +87.0.0-beta.1 From b3869e4a1a73e52519b933527d047a15ae33beb0 Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Wed, 24 Feb 2021 00:03:29 +0000 Subject: [PATCH 178/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 6ec10b302..61d34bd00 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.1 +87.0.0-beta.2 From e0f41bbead58d6ca9a3afe280871e3d28346819d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Delphine=20Leb=C3=A9del?= Date: Wed, 24 Feb 2021 06:14:13 -0800 Subject: [PATCH 179/248] Update l10n-release.toml with kmr and tl locales (#18134) --- l10n-release.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/l10n-release.toml b/l10n-release.toml index 8bc678f7f..acce5ec89 100644 --- a/l10n-release.toml +++ b/l10n-release.toml @@ -52,6 +52,7 @@ locales = [ "ka", "kab", "kk", + "kmr", "kn", "ko", "lij", @@ -82,6 +83,7 @@ locales = [ "te", "tg", "th", + "tl", "tr", "trs", "uk", From 6ec0e1bf104dcd751ba8d631cf891ec767fcc2ae Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 25 Feb 2021 18:34:40 +0000 Subject: [PATCH 180/248] Update to Android-Components 73.0.1. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 1cfef784e..95d641c05 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.0" + const val VERSION = "73.0.1" } From 8a2bfb45c57d1f55d44f6b08114b89ed7187b522 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 25 Feb 2021 23:22:08 +0000 Subject: [PATCH 181/248] Update to Android-Components 73.0.2. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 95d641c05..e872bad28 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.1" + const val VERSION = "73.0.2" } From c9fc1f253e1187a88f9c36d0b584192a4de4b228 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Sun, 28 Feb 2021 22:52:37 +0000 Subject: [PATCH 182/248] Update to Android-Components 73.0.3. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index e872bad28..b5f1db18d 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.2" + const val VERSION = "73.0.3" } From 6548730db7af5688f542f5fdc8d5091b1e350b67 Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Mon, 1 Mar 2021 00:41:35 +0000 Subject: [PATCH 183/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 61d34bd00..d17a898f9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.2 +87.0.0-beta.3 From 5b90c4651034886ed2da5829611d93a7335c44fe Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Tue, 2 Mar 2021 22:37:01 -0500 Subject: [PATCH 184/248] String sync for Fenix v87 (#18212) * Strings update - app/src/main/res/values-be/strings.xml * Strings update - app/src/main/res/values-co/strings.xml * Strings update - app/src/main/res/values-cs/strings.xml * Strings update - app/src/main/res/values-cy/strings.xml * Strings update - app/src/main/res/values-de/strings.xml * Strings update - app/src/main/res/values-dsb/strings.xml * Strings update - app/src/main/res/values-en-rCA/strings.xml * Strings update - app/src/main/res/values-es-rAR/strings.xml * Strings update - app/src/main/res/values-es-rCL/strings.xml * Strings update - app/src/main/res/values-fa/strings.xml * Strings update - app/src/main/res/values-fr/strings.xml * Strings update - app/src/main/res/values-fy-rNL/strings.xml * Strings update - app/src/main/res/values-gn/strings.xml * Strings update - app/src/main/res/values-iw/strings.xml * Strings update - app/src/main/res/values-hr/strings.xml * Strings update - app/src/main/res/values-hsb/strings.xml * Strings update - app/src/main/res/values-hu/strings.xml * Strings update - app/src/main/res/values-in/strings.xml * Strings update - app/src/main/res/values-it/strings.xml * Strings update - app/src/main/res/values-ka/strings.xml * Strings update - app/src/main/res/values-kab/strings.xml * Strings update - app/src/main/res/values-kk/strings.xml * Strings update - app/src/main/res/values-ko/strings.xml * Strings update - app/src/main/res/values-lt/strings.xml * Strings update - app/src/main/res/values-nb-rNO/strings.xml * Strings update - app/src/main/res/values-nl/strings.xml * Strings update - app/src/main/res/values-nn-rNO/strings.xml * Strings update - app/src/main/res/values-pl/strings.xml * Strings update - app/src/main/res/values-pt-rBR/strings.xml * Strings update - app/src/main/res/values-rm/strings.xml * Strings update - app/src/main/res/values-ru/strings.xml * Strings update - app/src/main/res/values-sk/strings.xml * Strings update - app/src/main/res/values-sl/strings.xml * Strings update - app/src/main/res/values-sr/strings.xml * Strings update - app/src/main/res/values-su/strings.xml * Strings update - app/src/main/res/values-sv-rSE/strings.xml * Strings update - app/src/main/res/values-tg/strings.xml * Strings update - app/src/main/res/values-tl/strings.xml * Strings update - app/src/main/res/values-tr/strings.xml * Strings update - app/src/main/res/values-uk/strings.xml * Strings update - app/src/main/res/values-ur/strings.xml * Strings update - app/src/main/res/values-vi/strings.xml * Strings update - app/src/main/res/values-zh-rCN/strings.xml * Strings update - app/src/main/res/values-zh-rTW/strings.xml --- app/src/main/res/values-be/strings.xml | 5 +++ app/src/main/res/values-co/strings.xml | 12 ++++-- app/src/main/res/values-cs/strings.xml | 7 ++++ app/src/main/res/values-cy/strings.xml | 17 ++++++-- app/src/main/res/values-de/strings.xml | 5 +++ app/src/main/res/values-dsb/strings.xml | 17 ++++++-- app/src/main/res/values-en-rCA/strings.xml | 5 +++ app/src/main/res/values-es-rAR/strings.xml | 5 +++ app/src/main/res/values-es-rCL/strings.xml | 5 +++ app/src/main/res/values-fa/strings.xml | 23 +++++++++-- app/src/main/res/values-fr/strings.xml | 5 +++ app/src/main/res/values-fy-rNL/strings.xml | 6 +++ app/src/main/res/values-gn/strings.xml | 6 +++ app/src/main/res/values-hr/strings.xml | 21 +++++++--- app/src/main/res/values-hsb/strings.xml | 5 +++ app/src/main/res/values-hu/strings.xml | 17 ++++++-- app/src/main/res/values-in/strings.xml | 12 ++++-- app/src/main/res/values-it/strings.xml | 5 +++ app/src/main/res/values-iw/strings.xml | 5 +++ app/src/main/res/values-ka/strings.xml | 7 +++- app/src/main/res/values-kab/strings.xml | 5 +++ app/src/main/res/values-kk/strings.xml | 23 +++++++++-- app/src/main/res/values-ko/strings.xml | 5 +++ app/src/main/res/values-lt/strings.xml | 5 +++ app/src/main/res/values-nb-rNO/strings.xml | 5 +++ app/src/main/res/values-nl/strings.xml | 5 +++ app/src/main/res/values-nn-rNO/strings.xml | 17 ++++++-- app/src/main/res/values-pl/strings.xml | 5 +++ app/src/main/res/values-pt-rBR/strings.xml | 5 +++ app/src/main/res/values-rm/strings.xml | 5 +++ app/src/main/res/values-ru/strings.xml | 5 +++ app/src/main/res/values-sk/strings.xml | 17 ++++++-- app/src/main/res/values-sl/strings.xml | 3 ++ app/src/main/res/values-sr/strings.xml | 5 +++ app/src/main/res/values-su/strings.xml | 17 ++++++-- app/src/main/res/values-sv-rSE/strings.xml | 5 +++ app/src/main/res/values-tg/strings.xml | 5 +++ app/src/main/res/values-tl/strings.xml | 5 +++ app/src/main/res/values-tr/strings.xml | 5 +++ app/src/main/res/values-uk/strings.xml | 9 +++- app/src/main/res/values-ur/strings.xml | 48 ++++++++++++++++++++-- app/src/main/res/values-vi/strings.xml | 5 +++ app/src/main/res/values-zh-rCN/strings.xml | 6 +++ app/src/main/res/values-zh-rTW/strings.xml | 5 +++ 44 files changed, 369 insertions(+), 41 deletions(-) diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 10f6219ff..df41cc5be 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -216,6 +216,11 @@ Даведацца больш + + Пошук у %s + + Пошук наўпрост з адраснага радка + Адкрыць новую картку Firefox diff --git a/app/src/main/res/values-co/strings.xml b/app/src/main/res/values-co/strings.xml index c42c30624..c8b6b8817 100644 --- a/app/src/main/res/values-co/strings.xml +++ b/app/src/main/res/values-co/strings.xml @@ -897,16 +897,22 @@ Attivata Disattivata - + Permette l’audio è a video + + Permette l’audio è a video Bluccà l’audio è a video da i dati mubili solu Audio è video seranu letti cù una cunnessione Wi-Fi - + Bluccà solu l’audio - + + Bluccà solu l’audio + Bluccà l’audio è a video + + Bluccà l’audio è a video Attivata diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 77facf933..6b80e461f 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -222,6 +222,11 @@ Zjistit více + + Hledat na %s + + Vyhledat na webu přímo z adresního řádku + Otevřít nový panel Firefoxu @@ -1120,6 +1125,8 @@ Uvolní využitý prostor na zařízení Oprávnění serverů + + Stažené soubory Smazat soukromá data diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index f96d976c2..a358c83fa 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -216,6 +216,11 @@ Dysgu rhagor + + Chwilio %s + + Chwilio’n uniongyrchol o’r bar cyfeiriad + Agorwch tab Firefox newydd @@ -886,16 +891,22 @@ Ymlaen Diffodd - + Caniatáu sain a fideo + + Caniatáu sain a fideo Rhwystro sain a fideo ar ddata cellol yn unig Bydd sain a fideo yn chwarae ar ddiwifr - + Rhwystro sain yn unig - + + Rhwystro sain yn unig + Rhwystro sain a fideo + + Rhwystro sain a fideo Ymlaen diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4022803bc..ab688e3f9 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -222,6 +222,11 @@ Weitere Informationen + + Suchen mit %s + + Direkt aus der Adressleiste suchen + In einem neuen Firefox-Tab öffnen diff --git a/app/src/main/res/values-dsb/strings.xml b/app/src/main/res/values-dsb/strings.xml index e9c24bd68..152f297cb 100644 --- a/app/src/main/res/values-dsb/strings.xml +++ b/app/src/main/res/values-dsb/strings.xml @@ -216,6 +216,11 @@ Dalšne informacije + + Z %s pytaś + + Direktnje z adresowego póla pytaś + Nowy rejtarik Firefox wócyniś @@ -886,16 +891,22 @@ Zašaltowany Wušaltowany - + Awdio a wideo dowóliś + + Awdio a wideo dowóliś Awdio a wideo jano za mobilny zwisk blokěrowaś Awdio a wideo se pśez WLAN wótgrawatej - + Jano awdio blokěrowaś - + + Jano awdio blokěrowaś + Awdio a wideo blokěrowaś + + Awdio a wideo blokěrowaś Zašaltowany diff --git a/app/src/main/res/values-en-rCA/strings.xml b/app/src/main/res/values-en-rCA/strings.xml index be3b6e3c0..38d70c102 100644 --- a/app/src/main/res/values-en-rCA/strings.xml +++ b/app/src/main/res/values-en-rCA/strings.xml @@ -216,6 +216,11 @@ Learn more + + Search %s + + Search directly from the address bar + Open a new Firefox tab diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index 4359cce87..77605f963 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -222,6 +222,11 @@ Conocer más + + Buscar %s + + Buscar directamente desde la barra de direcciones + Abrir una nueva pestaña de Firefox diff --git a/app/src/main/res/values-es-rCL/strings.xml b/app/src/main/res/values-es-rCL/strings.xml index 8479fbabf..4eb72f3c6 100644 --- a/app/src/main/res/values-es-rCL/strings.xml +++ b/app/src/main/res/values-es-rCL/strings.xml @@ -215,6 +215,11 @@ Aprender más + + Buscar %s + + Buscar directamente desde la barra de direcciones + Abrir una nueva pestaña de Firefox diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index b0fb3425e..59b9d908c 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -128,6 +128,8 @@ ویرایش نشانک افزونه‌ها + + افزونه‌ها هیچ افزودنی در اینجا وجود ندارد @@ -212,6 +214,11 @@ بیشتر بدانید + + جست‌وجو در %s + + مستقیماً از نوار آدرس جستجو کنید + بازکردن یک زبانه فایرفاکس جدید @@ -522,6 +529,10 @@ نشانک‌‌های دیگر تاریخچه + + زبانهٔ جدید + + پیدا کردن در صفحه زبانه‌های همگام‌سازی شده @@ -874,16 +885,22 @@ روشن خاموش - + اجازه دادن صوت و ویدئو + + اجازه دادن به صدا و ویدئو مسدود کردن صدا و تصویر فقط بر روی حالت داده صدا و تصویر بر روی حالت Wi-Fi پخش خواهد شد - + مسدود کردن فقط صدا - + + فقط مسدود کردن صدا + مسدود کردن صوت و ویدئو + + مسدود کردن صوت و ویدئو روشن diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 342192fed..165b91236 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -220,6 +220,11 @@ En savoir plus + + Recherche %s + + Recherchez directement depuis la barre d’adresse + Ouvrir un nouvel onglet dans Firefox diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 9aa79e081..415363eab 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -219,6 +219,12 @@ Mear ynfo + + %s trochsykje + + + Streekrjocht fan de adresbalke út sykje + In nij Firefox-ljepblêd iepenje diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index c2d074cb6..f018f67b1 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -220,6 +220,12 @@ Kuaave + + Eheka %s + + + Eheka kundaharape renda guive + Embojuruja Firefox rendayke pyahu diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 9cd85a0f9..efec04f2a 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -216,6 +216,11 @@ Saznaj više + + Pretraži %s + + Pretraži izravno iz adresne trake + Otvori novu karticu u Firefoxu @@ -493,9 +498,9 @@ - Svijetli + Svijetla - Tamni + Tamna Postavljeno u postavkama za štednju baterije @@ -892,16 +897,22 @@ Uključeno Isključeno - + Dopusti zvuk i video + + Dopusti zvuk i video Blokiraj zvuk i video samo na mobilnoj vezi Zvuk i video reproducirat će se na Wi-Fi-ju - + Blokiraj samo zvuk - + + Blokiraj samo zvuk + Blokiraj zvuk i video + + Blokiraj zvuk i video Uključeno diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index a6082b0aa..e1174d2cf 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -217,6 +217,11 @@ Dalše informacije + + Z %s pytać + + Direktnje z adresoweho pola pytać + Nowy rajtark Firefox wočinić diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index d0876285c..2762a89b0 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -219,6 +219,11 @@ További tudnivalók + + %s keresés + + Keresés közvetlenül a címsávból + Új Firefox-lap megnyitása @@ -891,16 +896,22 @@ Ki - + Hang és videó engedélyezése + + Hang és videó engedélyezése Hang és videó blokkolása csak mobil-adatkapcsolaton A hang és videó Wi-Fi-n lesz lejátszva - + Csak a hang blokkolása - + + Csak a hang blokkolása + Hang és videó blokkolása + + Hang és videó blokkolása Be diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 51fe05685..3869d747a 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -901,16 +901,22 @@ Nonaktif - + Izinkan audio dan video + + Izinkan audio dan video Blokir suara dan video hanya pada mode data seluler Suara dan video akan diputar dalam mode Wi-Fi - + Blokir suara saja - + + Blokir audio saja + Blokir suara dan video + + Blokir audio dan video Aktif diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 38a0bb45b..8b8596d9e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -220,6 +220,11 @@ Ulteriori informazioni + + Cerca in %s + + Cerca direttamente dalla barra degli indirizzi + Apri una nuova scheda in Firefox diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index a7645af5f..1c3d58571 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -216,6 +216,11 @@ מידע נוסף + + חיפוש ב־%s + + חיפוש ישירות משורת הכתובת + פתיחת לשונית חדשה ב־Firefox diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index a8f0fd919..fd46c0b37 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -213,6 +213,11 @@ ვრცლად + + საძიებოდ %s + + მოიძიეთ პირდაპირ მისამართების ველიდან + ახალი Firefox-ჩანართის გახსნა @@ -967,7 +972,7 @@ ბოლოს გამოყენებული - Sync შესვლა + დასინქრონებაში შესვლა ყველა მოწყობილობაზე გაგზავნა diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index 1da682bfa..ba2a92665 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -219,6 +219,11 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Issin ugar + + Nadi %s + + Nadi srid seg ufeggag n tansiwin + Ldi iccer amaynut n Firefox diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index 94477b126..3ea3ac89c 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -127,6 +127,8 @@ Бетбелгіні түзету Қосымшалар + + Кеңейтулер Осында қосымшалар жоқ @@ -211,6 +213,11 @@ Көбірек білу + + %s ішінен іздеу + + Адрестік жолақтан тікелей іздеу + Жаңа Firefox бетін ашу @@ -520,6 +527,10 @@ Басқа бетбелгілер Шолу тарихы + + Жаңа бет + + Беттен табу Синхрондалған беттер @@ -870,16 +881,22 @@ Іске қосулы Сөндірулі - + Аудио мен видеоны рұқсат ету + + Аудио мен видеоны рұқсат ету Аудио мен видеоны тек ұялы деректерде бұғаттау Аудио және видео Wi-Fi арқылы ойнатылады - + Тек аудионы бұғаттау - + + Тек аудионы бұғаттау + Аудио мен видеоны бұғаттау + + Аудио мен видеоны бұғаттау Іске қосулы diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index d9bc1aaeb..c504b7155 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -227,6 +227,11 @@ 더 알아보기 + + %s 검색 + + 주소 표시줄에서 직접 검색 + 새 Firefox 탭 열기 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index cba115244..9b5172f10 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -216,6 +216,11 @@ Sužinoti daugiau + + Ieškoti „%s“ + + Ieškokite tiesiai iš adreso lauko + Atverti naują „Firefox“ kortelę diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 1e016c1d7..aee06e372 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -220,6 +220,11 @@ Les mer + + Søk %s + + Søk direkte fra adresselinjen + Åpne en ny Firefox-fane diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index bb414308c..5c07dd030 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -224,6 +224,11 @@ Meer info + + %s doorzoeken + + Rechtstreeks vanuit de adresbalk zoeken + Een nieuw Firefox-tabblad openen diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index 0c50a0747..dce476b44 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -219,6 +219,11 @@ Les meir + + Søk med %s + + Søk direkte frå adresselinja + Opne ei ny Firefox-fane @@ -897,16 +902,22 @@ Av - + Tillat lyd og video + + Tillat lyd og video Blokker lyd og video berre på mobildata Lyd og video vert spela av på Wi-Fi - + Blokker berre lyd - + + Blokker berre lyd + Blokker lyd og video + + Blokker lyd og video diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 7bb5a4f72..1818b0a44 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -220,6 +220,11 @@ Więcej informacji + + Szukaj w %s + + Szukaj prosto z paska adresu + Otwórz nową kartę w Firefoksie diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index b69673ddb..68aa5db1b 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -218,6 +218,11 @@ Saiba mais + + Pesquisar com %s + + Pesquisar diretamente na barra de endereços + Abrir uma nova aba no Firefox diff --git a/app/src/main/res/values-rm/strings.xml b/app/src/main/res/values-rm/strings.xml index 2a50264e3..03637f965 100644 --- a/app/src/main/res/values-rm/strings.xml +++ b/app/src/main/res/values-rm/strings.xml @@ -214,6 +214,11 @@ Ulteriuras infurmaziuns + + Tschertgar cun %s + + Tschertgar direct en la trav d\'adressas + Avrir in nov tab da Firefox diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5f8843eab..648ba5d36 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -227,6 +227,11 @@ Узнать больше + + Поиск в %s + + Поиск прямо из адресной строки + Открыть новую вкладку Firefox diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 81e5a7464..9c6288eb9 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -220,6 +220,11 @@ Ďalšie informácie + + Hľadať cez %s + + Vyhľadať na webe priamo z panela s adresou + Otvoriť novú kartu vo Firefoxe @@ -894,16 +899,22 @@ Vypnutá - + Povoliť zvuk a video + + Povoliť zvuk a video Blokovať automatické prehrávanie zvuku a videí pri pripojení cez mobilné dáta Zvuk a video sa bude automaticky prehrávať len na Wi-Fi - + Blokovať len zvuk - + + Blokovať len zvuk + Blokovať zvuk a video + + Blokovať zvuk a video Zapnuté diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 96d8b30f2..8b70a43d7 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -217,6 +217,9 @@ Več o tem + + Iščite neposredno iz naslovne vrstice + Odpri nov zavihek v Firefoxu diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index b77fdd693..e9299775e 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -215,6 +215,11 @@ Сазнајте више + + Претражи %s + + Претражи директно из адресне траке + Отворите нови Firefox језичак diff --git a/app/src/main/res/values-su/strings.xml b/app/src/main/res/values-su/strings.xml index 18bae542f..4dc5c7319 100644 --- a/app/src/main/res/values-su/strings.xml +++ b/app/src/main/res/values-su/strings.xml @@ -216,6 +216,11 @@ Lenyepan + + Paluruh %s + + Paluruh langsung tina bilah alamat + Buka tab Firefox anyar @@ -893,16 +898,22 @@ Hurung Pareum - + Ngidinan sora jeung pidéo + + Idinan audio jeung pidéo Blokir sora jeung pidéo dina data sélulér wungkul Sora jeung pidéo bakal dimaénkeun dina Wi-Fi - + Blokir sora hungkul - + + Peungpeuk audio hungkul + Blokir sora jueng pidéo + + Peungpeuk audio jeung pidéo Hurung diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 33703b47f..5854f08e8 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -222,6 +222,11 @@ Läs mer + + Sök med %s + + Sök direkt från adressfältet + Öppna en ny Firefox-flik diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index 4581b3f7b..8761b6132 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -217,6 +217,11 @@ Маълумоти бештар + + Ҷустуҷӯ дар %s + + Ҷустуҷӯи бевосита аз навори нишонӣ + Кушодани варақаи нави Firefox diff --git a/app/src/main/res/values-tl/strings.xml b/app/src/main/res/values-tl/strings.xml index 4ddbbb0ed..17ede797b 100644 --- a/app/src/main/res/values-tl/strings.xml +++ b/app/src/main/res/values-tl/strings.xml @@ -217,6 +217,11 @@ Alamin + + Hanapin sa %s + + Maghanap direkta mula sa address bar + Magbukas ng bagong Firefox tab diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 7e87abc75..186ec3703 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -218,6 +218,11 @@ Daha fazla bilgi al + + %s ile ara + + Doğrudan adres çubuğundan arama yapın + Yeni Firefox sekmesi aç diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 9e242df11..9dd9736c7 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -69,7 +69,7 @@ - Додайте ярлик для відкриття приватних вкладок з головного екрану. + Додайте ярлик для відкриття приватних вкладок з головного екрана. Додати ярлик @@ -219,6 +219,11 @@ Докладніше + + Пошук в %s + + Пошук безпосередньо з панелі адреси + Відкрити нову вкладку Firefox @@ -522,7 +527,7 @@ Сеанси - Знімки екрану + Знімки екрана Завантаження diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index 0fb24449b..a3f03dd74 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -77,6 +77,8 @@ برخاست کریں + + کیمرے تک رسائی کی ضرورت ہے۔ Android کی ترتیبات پر جائیں ، اجازتیں ٹیپ کریں ، اور اجازت پر ٹیپ کریں۔ سیٹنگز پر جائیں @@ -118,6 +120,8 @@ بُک مارک کی تدوین کریں ایڈ اون + + ایکسٹینشنز یہاں کوئی ایڈونس نہیں ہے @@ -205,6 +209,9 @@ مزید سیکھیں + + %s تلاش کریں + ایک نیا Firefox ٹیب کھولیں @@ -262,6 +269,8 @@ لنکس نجی ٹیب میں کھولیں نجی براؤزنگ میں اسکرین شاٹس کی اجازت دیں + + اگر اجازت دی جائے تو ، جب ایک سے زیادہ اطلاقات کھلے ہیں تو نجی ٹیبز بھی نظر آئیں گے نجی براؤزنگ شارٹکٹ شامل کریں @@ -345,6 +354,12 @@ مجموعہ کرنے والا مالک (صارف شناخت) + + + ایڈ آن کی معاونت نہیں ہے + + ایڈ آن پہلے ہی نصب ہے + ابھی sync کریں @@ -478,6 +493,11 @@ آلہ کے تھیم پر عمل کریں + + + تازہ کرنے کے لیے کھینچیں + + ٹول بار کو چھپانے کے لئے اسکرول کریں ٹیبز کو کھولنے کے لئے ٹول بار کو سوائپ کریں @@ -500,6 +520,10 @@ دیگر نشانیاں سابقات + + نیا ٹیب + + صفحے میں تلاش کریں سینک ہو چکے ٹیبز @@ -530,6 +554,8 @@ ٹیبس + + ٹیب ویو فہرست @@ -595,6 +621,8 @@ بند كریں منتخب شدہ ٹیبز کا اشتراک کریں + + منتخب کردہ ٹیبز مینو مجموعہ سے ٹیب کو ہٹا دیں @@ -693,10 +721,14 @@ ڈاؤن لوڈ حذف کریں + + کیا آپ واقعی اپنے ڈاؤن لوڈ صاف کرنا چاہتے ہیں؟ ڈاؤن لوڈز کو ہٹا دیا گیا %1$s ہٹائیں + + ڈاؤن لوڈ فائلیں نہیں ہیں %1$d منتخب کیا گیا @@ -829,6 +861,8 @@ مقام اعلانات + + مستقل اسٹوریج DRM کے زیرانتظام مواد @@ -846,16 +880,22 @@ چالو بند - + آڈیو اور ویڈیو کی اجازت دیں + + آڈیو اور ویڈیو کی اجازت دیں صرف سیلولر ڈیٹا پر آڈیو اور ویڈیو بلاک کریں Wi-Fi پر آڈیو اور ویڈیو چلے گی - + صرف آڈیو بلاک کریں - + + صرف آڈیو کو مسدود کریں + آڈیو اور ویڈیو بلاک کریں + + آڈیو اور ویڈیو کو مسدود کریں چالو @@ -1050,6 +1090,8 @@ ذخیرہ کار جگہ کو خالی کرتا ہے سائٹ کی اجازت + + ڈاؤن لوڈز براؤزنگ کا ڈیٹا مٹائیں diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index d56306626..00825b2dc 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -217,6 +217,11 @@ Tìm hiểu thêm + + Tìm kiếm %s + + Tìm kiếm trực tiếp từ thanh địa chỉ + Mở một thẻ Firefox mới diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index cb934be6f..97c3776fe 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -226,6 +226,12 @@ 详细了解 + + %s 上搜索 + + + 直接从地址栏搜索 + 新建 Firefox 标签页 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 7f9b0a1c9..257d79220 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -221,6 +221,11 @@ 了解更多 + + 搜尋 %s + + 從網址列直接搜尋 + 開新 Firefox 分頁 From 0c3b29520100a1280858045311e5e934976168ce Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 4 Mar 2021 22:40:55 +0000 Subject: [PATCH 185/248] Update to Android-Components 73.0.5. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index b5f1db18d..341eb1f59 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.3" + const val VERSION = "73.0.5" } From 8270808b1a425bd3e038323d8361c53d03045c42 Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Fri, 5 Mar 2021 00:20:20 +0000 Subject: [PATCH 186/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index d17a898f9..8ee1a5294 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.3 +87.0.0-beta.4 From 82c8a64ca0b8bd5e6ea88395cba41c0db68d0a36 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Mon, 8 Mar 2021 11:44:52 +0000 Subject: [PATCH 187/248] Update to Android-Components 73.0.6. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 341eb1f59..dd23551f8 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.5" + const val VERSION = "73.0.6" } From c04409fa21daae0983b9c3df171140ce05e3667f Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Mon, 8 Mar 2021 18:05:33 +0000 Subject: [PATCH 188/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 8ee1a5294..39d37b2bf 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.4 +87.0.0-beta.5 From 9ec17d4eb2a5b5b2ddc5c2636ef5be23f46bb75c Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 9 Mar 2021 23:54:41 +0000 Subject: [PATCH 189/248] Update to Android-Components 73.0.7. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index dd23551f8..0ade998f5 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.6" + const val VERSION = "73.0.7" } From 296b6b818bdb51386735dbe6f74cdad23cb0ecf8 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 11 Mar 2021 00:13:41 +0000 Subject: [PATCH 190/248] Update to Android-Components 73.0.8. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 0ade998f5..4ccf4d213 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.7" + const val VERSION = "73.0.8" } From 61083e10e2a9020a3996bccf6e9559994acb64a9 Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Thu, 11 Mar 2021 23:54:55 +0000 Subject: [PATCH 191/248] Update to Android-Components 73.0.9. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 4ccf4d213..4b503a587 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.8" + const val VERSION = "73.0.9" } From 1d6d6984690a7e08b70bc4dc102af769a82507eb Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Fri, 12 Mar 2021 01:38:49 +0000 Subject: [PATCH 192/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 39d37b2bf..55c095e8a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.5 +87.0.0-beta.6 From dbe1f9a879df6bb1fcaa3f54a4bb2509bd15c5fc Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:31:58 -0400 Subject: [PATCH 193/248] Strings update - app/src/main/res/values-br/strings.xml --- app/src/main/res/values-br/strings.xml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml index 1a141ea80..5dbe8b20e 100644 --- a/app/src/main/res/values-br/strings.xml +++ b/app/src/main/res/values-br/strings.xml @@ -128,6 +128,8 @@ Embann ar sined Askouezhioù + + Askouezhioù Nʼeus tamm askouezh ebet amañ @@ -212,6 +214,11 @@ Gouzout hirocʼh + + Klask %s + + Klask war-eeun eus ar varrenn chomlec’h + Digeriñ un ivinell Firefox nevez @@ -523,6 +530,10 @@ Sinedoù all Roll istor + + Ivinell nevez + + Kavout er bajenn Ivinelloù goubredet @@ -873,17 +884,23 @@ Gweredekaet Diweredekaet - + Aotren an aodio ha video + + Aotren an aodio ha video Stankañ an aodio hag ar video pa vez war ar roadennoù hezoug nemetken An aodio hag ar video a vo lennet war ar Wi-Fi - + Stankañ an aodio nemetken - + + Stankañ an aodio nemetken + Stankañ an aodio hag ar video + + Stankañ an aodio hag ar video Gweredekaet From bd68ead370bce28629a1b6ec19531550049680b7 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:31:58 -0400 Subject: [PATCH 194/248] Strings update - app/src/main/res/values-ca/strings.xml --- app/src/main/res/values-ca/strings.xml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index dbff35f4c..aa6013a6b 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -218,6 +218,11 @@ Més informació + + Cerca amb %s + + Cerca directament des de la barra d’adreces + Obre una pestanya nova del Firefox @@ -889,16 +894,22 @@ Activada Desactivada - + Permet àudio i vídeo + + Permet àudio i vídeo Bloca àudio i vídeo només amb dades mòbils L’àudio i el vídeo es reproduiran amb Wi-Fi - + Bloca només àudio - + + Bloca només àudio + Bloca àudio i vídeo + + Bloca àudio i vídeo Activat From b19c05ef481172a3cab84f9cd0c90b419850388f Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:31:58 -0400 Subject: [PATCH 195/248] Strings update - app/src/main/res/values-cak/strings.xml --- app/src/main/res/values-cak/strings.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/main/res/values-cak/strings.xml b/app/src/main/res/values-cak/strings.xml index b2f1ce800..b5a773855 100644 --- a/app/src/main/res/values-cak/strings.xml +++ b/app/src/main/res/values-cak/strings.xml @@ -187,6 +187,8 @@ Rutzub\'al + + Ke\'ichinäx rutz\'etoj sik\'inem Man nok ta. Man netamäx ta ruwa ruch\'akulal URL. @@ -224,6 +226,12 @@ Tetamäx ch\'aqa\' chik + + Tikanöx %s + + + Tikanöx pa kikajtz\'ik ochochib\'äl + Tijaq jun k\'ak\'a\' ruwi\' Firefox From 78c4664b40e882cdcdcee31a301595df572722cf Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:31:59 -0400 Subject: [PATCH 196/248] Strings update - app/src/main/res/values-co/strings.xml --- app/src/main/res/values-co/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-co/strings.xml b/app/src/main/res/values-co/strings.xml index c8b6b8817..a8b76440e 100644 --- a/app/src/main/res/values-co/strings.xml +++ b/app/src/main/res/values-co/strings.xml @@ -185,6 +185,8 @@ Aspettu + + Persunalizà u modu di lettura Impussibule di cunnettassi. Schema d’URL scunnisciutu. @@ -221,6 +223,11 @@ Sapene di più + + Ricercà in %s + + Ricercà direttamente da a barra d’indirizzu + Apre una nova unghjetta in Firefox From a21a688b20dae2e4c3d8bcf57a42d36ca09ce98d Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:31:59 -0400 Subject: [PATCH 197/248] Strings update - app/src/main/res/values-cy/strings.xml --- app/src/main/res/values-cy/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index a358c83fa..c1e50db54 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -180,6 +180,8 @@ Gwedd + + Cyfaddasu’r golwg defnyddiwr Methu cysylltu. Cynllun URL anadnabyddadwy. From acd3acd398266da20a2073ee0a802939bef0ca1e Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:00 -0400 Subject: [PATCH 198/248] Strings update - app/src/main/res/values-de/strings.xml --- app/src/main/res/values-de/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index ab688e3f9..69ab06941 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -185,6 +185,8 @@ Erscheinungsbild + + Leseansicht anpassen Verbindung nicht möglich. Nicht erkennbares URL-Schema. From a0c039b41c50594a61970f63ca57eed0a37b8b68 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:00 -0400 Subject: [PATCH 199/248] Strings update - app/src/main/res/values-dsb/strings.xml --- app/src/main/res/values-dsb/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-dsb/strings.xml b/app/src/main/res/values-dsb/strings.xml index 152f297cb..497fb3929 100644 --- a/app/src/main/res/values-dsb/strings.xml +++ b/app/src/main/res/values-dsb/strings.xml @@ -180,6 +180,8 @@ Wenkowny naglěd + + Cytański naglěd pśiměriś Zwisk njejo móžny. Njespóznawajobna URL-šema. From a4b2bb805841d999c34bc5e508b1f3ddd6a4f404 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:01 -0400 Subject: [PATCH 200/248] Strings update - app/src/main/res/values-el/strings.xml --- app/src/main/res/values-el/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 11643d358..4dbbd5d96 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -186,6 +186,8 @@ Εμφάνιση + + Προσαρμογή προβολής ανάγνωσης Αδυναμία σύνδεσης. Μη αναγνωρίσιμο σχήμα URL. @@ -223,6 +225,11 @@ Μάθετε περισσότερα + + Αναζήτηση %s + + Αναζήτηση απευθείας από τη γραμμή διευθύνσεων + Άνοιγμα νέας καρτέλας Firefox From ac96e81303f8275a6f17e387794a66d0549596b3 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:01 -0400 Subject: [PATCH 201/248] Strings update - app/src/main/res/values-en-rCA/strings.xml --- app/src/main/res/values-en-rCA/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-en-rCA/strings.xml b/app/src/main/res/values-en-rCA/strings.xml index 38d70c102..889ce76fc 100644 --- a/app/src/main/res/values-en-rCA/strings.xml +++ b/app/src/main/res/values-en-rCA/strings.xml @@ -180,6 +180,8 @@ Appearance + + Customize reader view Unable to connect. Unrecognizable URL scheme. From 645905bc2e3c7d32caae34af67ccc5ae8199bff4 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:02 -0400 Subject: [PATCH 202/248] Strings update - app/src/main/res/values-en-rGB/strings.xml --- app/src/main/res/values-en-rGB/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 9ea65be1e..326e6bf0f 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -179,6 +179,8 @@ Appearance + + Customise reader view Unable to connect. Unrecognisable URL scheme. @@ -215,6 +217,11 @@ Learn more + + Search %s + + Search directly from the address bar + Open a new Firefox tab From a9a43b78e4be35a7ac90e9674c3df479d4d77117 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:02 -0400 Subject: [PATCH 203/248] Strings update - app/src/main/res/values-eo/strings.xml --- app/src/main/res/values-eo/strings.xml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index fc99a3785..13986308f 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -890,16 +890,20 @@ Ŝaltita Malŝaltita - + Permesi sonon kaj videon Bloki sonon kaj videon nur dum konekto al poŝaparataj retoj Sono kaj video estos ludataj en sendrata konektoj (Wi-Fi) - + Nur bloki sonon - + + Nur bloki sonon + Bloki sonon kaj videon + + Bloki sonon kaj videon Ŝaltita From e0aa9ad60fc31a13e526b777806cc452e1f5c203 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:02 -0400 Subject: [PATCH 204/248] Strings update - app/src/main/res/values-es/strings.xml --- app/src/main/res/values-es/strings.xml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index ad65854cf..4529d97c8 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -136,6 +136,8 @@ Editar marcador Complementos + + Extensiones No hay complementos aquí @@ -222,6 +224,9 @@ Saber más + + Buscar %1$s + Abrir una nueva pestaña de Firefox @@ -537,6 +542,10 @@ Otros marcadores Historial + + Nueva pestaña + + Buscar en la página Pestañas sincronizadas @@ -894,16 +903,22 @@ Desactivado - + Permitir audio y vídeo + + Permitir audio y video Bloquear audio y vídeo solo con datos móviles El audio y el vídeo se reproducirán con Wi-Fi - + Bloquear solo audio - + + Bloquear solo audio + Bloquear audio y vídeo + + Bloquear audio y video Activado From 83275fa5990c955dab3810b21a3edebe3c21befb Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:03 -0400 Subject: [PATCH 205/248] Strings update - app/src/main/res/values-es-rAR/strings.xml --- app/src/main/res/values-es-rAR/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-es-rAR/strings.xml b/app/src/main/res/values-es-rAR/strings.xml index 77605f963..08d90f696 100644 --- a/app/src/main/res/values-es-rAR/strings.xml +++ b/app/src/main/res/values-es-rAR/strings.xml @@ -183,6 +183,8 @@ Apariencia + + Personalizar vista de lectura No se puede conectar. Esquema de URL irreconocible. From a435f74bbfde4ec3148078018e562d7457086320 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:03 -0400 Subject: [PATCH 206/248] Strings update - app/src/main/res/values-es-rES/strings.xml --- app/src/main/res/values-es-rES/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index 227f8c447..bdae70083 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -184,6 +184,8 @@ Apariencia + + Personalizar vista de lectura No se puede conectar. Esquema de URL irreconocible. @@ -221,6 +223,11 @@ Saber más + + Buscar %s + + Buscar directamente desde la barra de direcciones + Abrir una nueva pestaña de Firefox From 34272e469d42e7979ec6a4f0dba929f4e536b0f0 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:04 -0400 Subject: [PATCH 207/248] Strings update - app/src/main/res/values-eu/strings.xml --- app/src/main/res/values-eu/strings.xml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index d0a3ea701..720aaf8b0 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -132,6 +132,8 @@ Editatu laster-marka Gehigarriak + + Hedapenak Gehigarririk ez hemen @@ -183,6 +185,8 @@ Itxura + + Pertsonalizatu irakurtzeko ikuspegia Ezin da konektatu. URL eskema ezagutezina. @@ -220,6 +224,11 @@ Argibide gehiago + + Bilatu %s erabiliz + + Bilatu helbide-barratik zuzenean + Ireki Firefoxen fitxa berri bat @@ -538,6 +547,10 @@ Beste laster-markak Historia + + Fitxa berria + + Bilatu orrian Sinkronizatutako fitxak @@ -893,16 +906,22 @@ Desaktibatuta - + Baimendu audioa eta bideoa + + Baimendu audioa eta bideoa Blokeatu audioa eta bideoa datu mugikorretan soilik Audioa eta bideoa WiFi bidez erreproduzituko dira soilik - + Blokeatu audioa soilik - + + Blokeatu audioa soilik + Blokeatu audioa eta bideoa + + Blokeatu audioa eta bideoa Aktibatuta From 3c4991559d653e40eb1f710740a75f4b2c9c00b0 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:04 -0400 Subject: [PATCH 208/248] Strings update - app/src/main/res/values-fi/strings.xml --- app/src/main/res/values-fi/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index eaacce8de..cc0bc4852 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -183,6 +183,8 @@ Ulkoasu + + Mukauta lukunäkymää Yhteyden muodostaminen epäonnistui. URL-skeeman tunnistaminen ei onnistu. From fa628369d8a50b016e90523153183623adecf4de Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:05 -0400 Subject: [PATCH 209/248] Strings update - app/src/main/res/values-fr/strings.xml --- app/src/main/res/values-fr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 165b91236..c603eab71 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -183,6 +183,8 @@ Apparence + + Personnaliser le mode lecture Impossible de se connecter. Schéma d’URL inconnu. From 187f291468bc4e5c8992f80f0196b31e1e0ae5e5 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:05 -0400 Subject: [PATCH 210/248] Strings update - app/src/main/res/values-fy-rNL/strings.xml --- app/src/main/res/values-fy-rNL/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-fy-rNL/strings.xml b/app/src/main/res/values-fy-rNL/strings.xml index 415363eab..ad4446e3d 100644 --- a/app/src/main/res/values-fy-rNL/strings.xml +++ b/app/src/main/res/values-fy-rNL/strings.xml @@ -183,6 +183,8 @@ Uterlik + + Lêzerwerjefte oanpasse Net yn steat te ferbinen. Unkenbere URL-skema. From 27a146e573a155d95bdb3d7d5eca0db032e9aa6e Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:05 -0400 Subject: [PATCH 211/248] Strings update - app/src/main/res/values-gn/strings.xml --- app/src/main/res/values-gn/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-gn/strings.xml b/app/src/main/res/values-gn/strings.xml index f018f67b1..58e36d347 100644 --- a/app/src/main/res/values-gn/strings.xml +++ b/app/src/main/res/values-gn/strings.xml @@ -184,6 +184,8 @@ Mba’ejegua + + Emboava moñe’ẽhára rechaha Ndaikatúi eike. URL reko ojekuaa’ỹva. From 41881ddfc5507d2df28814c49b7e7fdd3071aa0b Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:06 -0400 Subject: [PATCH 212/248] Strings update - app/src/main/res/values-iw/strings.xml --- app/src/main/res/values-iw/strings.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 1c3d58571..17a06d7ed 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -180,6 +180,8 @@ תצוגה + + התאמה אישית של תצוגת קריאה לא ניתן להתחבר. מבנה הכתובת אינו ברור. @@ -500,6 +502,8 @@ בהיר כהה + + הוגדר על־ידי מצב חיסכון בסוללה שימוש בערכת הנושא של המכשיר @@ -621,6 +625,8 @@ סגירת כל הלשוניות לשונית חדשה + + הביתה החלפת מצב לשונית @@ -1478,6 +1484,8 @@ שם משתמש ססמה + + להכניס את הקוד שלך מחדש יש לבטל את הנעילה כדי להציג את הכניסות השמורות שלך @@ -1516,12 +1524,18 @@ יש לבטל את הנעילה כדי להציג את הכניסות השמורות שלך שמירה מאובטחת של הכניסות והססמאות שלך + + ניתן להגדיר תבנית נעילת מכשיר, קוד או ססמה כדי להגן על פרטי הגישה והססמאות שלך מפני גורמים בלתי מהימנים שמחזיקים במכשיר שלך. מאוחר יותר + + להגדיר כעת שחרור נעילת המכשיר שלך + + התמקדות על כל האתרים יש להפעיל כדי לאפשר צביטה והתקרבות, אפילו באתרים שמונעים את תנועות האצבעות האלו. From 145b882aba213b3872a88b5386d6cfd8af26e82a Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:06 -0400 Subject: [PATCH 213/248] Strings update - app/src/main/res/values-hr/strings.xml --- app/src/main/res/values-hr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index efec04f2a..366e6ded3 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -179,6 +179,8 @@ Izgled + + Prilagodi prikaz za čitanje Nije se moguće povezati. Neprepoznatljiva URL shema. From 7eb759e21d08877d0862188d9e5e5f830732a37d Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:07 -0400 Subject: [PATCH 214/248] Strings update - app/src/main/res/values-hsb/strings.xml --- app/src/main/res/values-hsb/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-hsb/strings.xml b/app/src/main/res/values-hsb/strings.xml index e1174d2cf..0ca8c236d 100644 --- a/app/src/main/res/values-hsb/strings.xml +++ b/app/src/main/res/values-hsb/strings.xml @@ -181,6 +181,8 @@ Zwonkowny napohlad + + Čitanski napohlad přiměrić Zwisk móžny njeje. Njespóznawajomna URL-šema. From e1f0d77388c5a7fd3f8364ea5f6a74c9928d93a1 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:07 -0400 Subject: [PATCH 215/248] Strings update - app/src/main/res/values-hu/strings.xml --- app/src/main/res/values-hu/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 2762a89b0..d6f8400a9 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -182,6 +182,8 @@ Megjelenés + + Olvasó nézet testreszabása Nem tud csatlakozni. Felismerhetetlen URL-séma. From 3ac168e2cecce2b45ff52a36d12ef701e61ae33c Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:08 -0400 Subject: [PATCH 216/248] Strings update - app/src/main/res/values-it/strings.xml --- app/src/main/res/values-it/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8b8596d9e..974aaf3d5 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -183,6 +183,8 @@ Aspetto + + Personalizza modalità lettura Connessione non riuscita. Schema URL non riconoscibile. From 06db44d4dea401fe3cef6878f7514b77e2aebac9 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:08 -0400 Subject: [PATCH 217/248] Strings update - app/src/main/res/values-ja/strings.xml --- app/src/main/res/values-ja/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c0a54e3bc..f17cbe157 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -185,6 +185,8 @@ 外観 + + リーダービューをカスタマイズ 接続できません。認識できない URL スキームです。 @@ -222,6 +224,11 @@ 詳細情報 + + %s で検索 + + アドレスバーから直接検索します + 新しい Firefox タブを開く From 81647d1da044054fe7b04ffdf50c302ec1d1c61e Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:08 -0400 Subject: [PATCH 218/248] Strings update - app/src/main/res/values-ka/strings.xml --- app/src/main/res/values-ka/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index fd46c0b37..202688eb8 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -177,6 +177,8 @@ იერსახე + + კითხვის რეჟიმის მორგება ვერ დაუკავშირდა. გაურკვეველი URL-სქემა. From 736b1d1d6a180835a65808c93264aff9ee1996b0 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:09 -0400 Subject: [PATCH 219/248] Strings update - app/src/main/res/values-kab/strings.xml --- app/src/main/res/values-kab/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml index ba2a92665..2481a2f4f 100644 --- a/app/src/main/res/values-kab/strings.xml +++ b/app/src/main/res/values-kab/strings.xml @@ -183,6 +183,8 @@ Tiktiwin tigejdanin yuzzlen ur nṣeḥḥi ara Arwes + + Sagen timeẓri n tɣuri Ur izmir ara ad yeqqen. Azenziɣ n tensa URL ur yettwassen ara. From c83b64f2a00de3e7281802751112b4a1503b8e48 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:09 -0400 Subject: [PATCH 220/248] Strings update - app/src/main/res/values-kk/strings.xml --- app/src/main/res/values-kk/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-kk/strings.xml b/app/src/main/res/values-kk/strings.xml index 3ea3ac89c..73e61f1cb 100644 --- a/app/src/main/res/values-kk/strings.xml +++ b/app/src/main/res/values-kk/strings.xml @@ -176,6 +176,8 @@ Қолданбада ашу Сыртқы түрі + + Оқу режимін баптау Байланысу мүмкін емес. URL схемасы белгісіз. From 535ef41154123e0d920bbb8ee49f752d861c50eb Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:10 -0400 Subject: [PATCH 221/248] Strings update - app/src/main/res/values-kmr/strings.xml --- app/src/main/res/values-kmr/strings.xml | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/src/main/res/values-kmr/strings.xml b/app/src/main/res/values-kmr/strings.xml index a06128ed7..d7908dd91 100644 --- a/app/src/main/res/values-kmr/strings.xml +++ b/app/src/main/res/values-kmr/strings.xml @@ -198,7 +198,7 @@ - Sken bike + Kodê bixwîne Motora lêgerînê @@ -293,7 +293,7 @@ Têkeve - Darika amûran + Darikê amûran Rûkar @@ -471,7 +471,7 @@ Sync’ê veke - Koda hevcotkirinê ya di Firefoxa Sermaseyê de sken bike + Koda hevcotkirinê ya di Firefoxa Sermaseyê de bide xwendin Têkeve @@ -481,7 +481,7 @@ - firefox.com/pair de xuya dibe sken bike]]> + firefox.com/pair de xuya dibe, bide xwendin]]> Kamerayê veke @@ -508,11 +508,11 @@ Ji bo nûkirinê bikişîne - Ji bo veşartina derika amûran, bişemitîne + Ji bo darikê amûran veşêrî, bişemitîne - Ji bo guhertina hilpekînê, darika amûran bi kêlekê ve biherikîne + Ji bo hilpekînê biguherînî, darikê amûran biherikîne kêlekê - Ji bo vekirina hilpekînan, darika amûran bi jorê ve biherikîne + Ji bo hilpekînan vekî, darikê amûran biherikîne jorê @@ -528,7 +528,7 @@ Menûya Favoriyan - Darika Amûran a Favoriyan + Darikê Amûran ê Favoriyan Favoriyên din @@ -1201,7 +1201,7 @@ Standard (jixweber) - Hindiktir şopîneran asteng dike. Rûpel dê bi awayê asayî bên barkirin. + Hindiktir şopîneran asteng dike. Rûpel ew ê bi awayê normal vebin. Tund (tê pêşniyarkirin) @@ -1213,7 +1213,7 @@ but it is ok to make this more literally about "choosing a position in a physical space --> Aliyê xwe hilbijêre - Darika amûran a jêrîn bi destekî biceribîne an jî wê bibe jorê tu bi kêfa xwe yî. + Darikê amûran ê jêrîn bi destekî biceribîne an jî wê bibe jorê tu bi kêfa xwe yî. Bi nihênî bigere DÎSA BICERIBÎNE - Kodê sken bike + Kodê bide xwendin https://firefox.com/pair]]> - Ji bo skenkirinê amade me + Aniha kodê bide xwendin Bi kameraya xwe têkeve @@ -1288,7 +1288,7 @@ Parastina ji şopandinê ya pêşketî - Bêyî ku tu bê şopandin bigere + Bêyî ku tu werî şopandin bigere Bila daneyên te ji te re bimînin. %s te ji gelek şopdarên dilxerab diparêze û nahêle tiştên ku tu li ser înternetê dikî ji aliyê wan ve bên dîtin. @@ -1296,7 +1296,7 @@ Standard (heyî) - Hindiktir şopîneran asteng bike. Rûpel dê asayî vebin. + Hindiktir şopîneran asteng dike. Rûpel ew ê bi awayê normal vebin. Bi parastina ji şopandinê ya standard çi tên astengkirin? @@ -1308,7 +1308,7 @@ Taybet - Hilbijêre ka kîjan şopîner û skrîpt bên astengkirin. + Hilbijêre ka kîjan şopdar û skrîpt ew ê bêne astengkirin. Bi parastina ji şopandinê ya taybet çi tên astengkirin? @@ -1596,7 +1596,7 @@ Destûr’ê bitikîne]]> - %1$s’ê bike VEKIRÎ]]> + %1$s’yê bike VEKIRÎ]]> Girêdana ewle From 515bdfad18d8a46ac8dcafe5d2ebaa5b7bbd9566 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:10 -0400 Subject: [PATCH 222/248] Strings update - app/src/main/res/values-ko/strings.xml --- app/src/main/res/values-ko/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index c504b7155..2f401a876 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -190,6 +190,8 @@ 모양 + + 리더뷰 사용자 지정 연결할 수 없음. 인식할 수 없는 URL 구성표. @@ -1491,7 +1493,7 @@ 저장 안 함 - 자동완성 + 자동 채우기 Sync 로그인 From 93bda3a8217e1cd74497c932eab8fa54da17ec15 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:10 -0400 Subject: [PATCH 223/248] Strings update - app/src/main/res/values-lt/strings.xml --- app/src/main/res/values-lt/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 9b5172f10..5b547d35e 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -180,6 +180,8 @@ Išvaizda + + Tinkinti skaitymo rodinį Nepavyko prisijungti. Neatpažįstama URL schema. From 63b8b3b8b30a9ae98ace7475b62640adab97fbc8 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:11 -0400 Subject: [PATCH 224/248] Strings update - app/src/main/res/values-nb-rNO/strings.xml --- app/src/main/res/values-nb-rNO/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index aee06e372..64bc8f359 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -183,6 +183,8 @@ Utseende + + Tilpass lesevisning Kan ikke koble til. Ugjenkjennelig URL-skjema. From 215b3fea9448822d97a86c1a1cc79eebec145a23 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:11 -0400 Subject: [PATCH 225/248] Strings update - app/src/main/res/values-nl/strings.xml --- app/src/main/res/values-nl/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 5c07dd030..f12b21d5d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -187,6 +187,8 @@ Vormgeving + + Lezerweergave aanpassen Kan niet verbinden. Onherkenbaar URL-schema. From 926cb9e3581e8e5f94ef9dd438fa4b321d689251 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:12 -0400 Subject: [PATCH 226/248] Strings update - app/src/main/res/values-nn-rNO/strings.xml --- app/src/main/res/values-nn-rNO/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-nn-rNO/strings.xml b/app/src/main/res/values-nn-rNO/strings.xml index dce476b44..c5f993168 100644 --- a/app/src/main/res/values-nn-rNO/strings.xml +++ b/app/src/main/res/values-nn-rNO/strings.xml @@ -183,6 +183,8 @@ Utsjånad + + Tilpass lesevising Klarte ikkje å kople til. Ukjenneleg URL-skjema. From d014acda0a63b81f93f5549f764244e88da49910 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:12 -0400 Subject: [PATCH 227/248] Strings update - app/src/main/res/values-pa-rIN/strings.xml --- app/src/main/res/values-pa-rIN/strings.xml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values-pa-rIN/strings.xml b/app/src/main/res/values-pa-rIN/strings.xml index e65606abf..2c8bebf6a 100644 --- a/app/src/main/res/values-pa-rIN/strings.xml +++ b/app/src/main/res/values-pa-rIN/strings.xml @@ -187,6 +187,8 @@ ਦਿੱਖ + + ਪੜ੍ਹਨ ਝਲਕ ਨੂੰ ਕਸਟਮਾਈਜ਼ ਕਰੋ ਕਨੈਕਟ ਕਰਨ ਲਈ ਅਸਮਰੱਥ। ਬੇਪਛਾਣ URL ਸਕੀਮ। @@ -224,6 +226,11 @@ ਹੋਰ ਜਾਣੋ + + %s ਖੋਜ + + ਸਿਰਨਾਵਾਂ ਪੱਟੀ ਵਿੱਚੋਂ ਸਿ਼ੱਧਾ ਖੋਜੋ + ਨਵੀਂ Firefox ਟੈਬ ਖੋਲ੍ਹੋ @@ -902,16 +909,22 @@ ਬੰਦ - + ਆਡੀਓ ਅਤੇ ਵੀਡਿਓ ਦੀ ਇਜਾਜ਼ਤ ਦਿਓ + + ਆਡੀਓ ਤੇ ਵੀਡੀਓ ਦੀ ਮਨਜ਼ੂਰੀ ਦਿਓ ਸਿਰਫ਼ ਸੈਲੂਲਰ ਡਾਟਾ ਤੋਂ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਉੱਤੇ ਰੋਕ ਲਾਓ Wi-Fi ਉੱਤੇ ਆਡੀਓ ਤੇ ਵੀਡੀਓ ਚਲਾਏ ਜਾਣਗੇ - + ਸਿਰਫ਼ ਆਡੀਓ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ - + + ਸਿਰਫ਼ ਆਡੀਓ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ + ਆਡੀਓ ਅਤੇ ਵੀਡਿਓ ਤੇ ਪਾਬੰਦੀ ਲਾਓ + + ਆਡੀਓ ਅਤੇ ਵੀਡਿਓ \'ਤੇ ਪਾਬੰਦੀ ਲਾਓ ਚਾਲੂ From 5352c775defb2252381d68937a6a24ded6cd04ca Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:13 -0400 Subject: [PATCH 228/248] Strings update - app/src/main/res/values-pl/strings.xml --- app/src/main/res/values-pl/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 1818b0a44..5fe83ac0e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -183,6 +183,8 @@ Wygląd + + Dostosuj widok poprawionej czytelności Nie można się połączyć. Nieznany protokół adresu URL. From de2c91bf075db94cd2404dd5e71e483beb12fd45 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:13 -0400 Subject: [PATCH 229/248] Strings update - app/src/main/res/values-pt-rBR/strings.xml --- app/src/main/res/values-pt-rBR/strings.xml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 68aa5db1b..d6cb5c754 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -14,7 +14,7 @@ Pesquise ou digite um endereço - Suas abas abertas serão mostradas aqui. + Suas abas abertas são mostradas aqui. Suas abas privativas são mostradas aqui. @@ -181,6 +181,8 @@ Aparência + + Personalizar leitor Não foi possível conectar. Esquema de URL não reconhecível. @@ -1054,7 +1056,7 @@ Tem certeza que quer excluir %1$s? - Excluir esta aba também excluirá toda a coleção. Você pode criar novas coleções quando quiser. + Excluir esta aba também exclui toda a coleção. Você pode criar novas coleções quando quiser. Excluir %1$s? @@ -1200,7 +1202,7 @@ The first parameter is the name of the app (e.g. Firefox Preview) --> As configurações de privacidade e segurança bloqueiam rastreadores, código malicioso (malware) e empresas que seguem você. - Padrão (predefinido) + Normal (padrão) Bloqueia menos rastreadores. As páginas são carregadas normalmente. @@ -1300,11 +1302,11 @@ Saiba mais - Padrão (predefinido) + Normal (padrão) Bloqueia menos rastreadores. As páginas são carregadas normalmente. - O que é bloqueado pela proteção padrão contra rastreamento + O que é bloqueado pela proteção normal contra rastreamento Rigoroso From 3701c67b5971bc8810192ee1b861339b97dab4c6 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:14 -0400 Subject: [PATCH 230/248] Strings update - app/src/main/res/values-pt-rPT/strings.xml --- app/src/main/res/values-pt-rPT/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 1cfd4a089..882fd490d 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -181,6 +181,8 @@ Aparência + + Personalizar a vista de leitura Não foi possível ligar. Esquema do endereço não reconhecido. @@ -218,6 +220,11 @@ Saber mais + + Pesquisar %s + + Pesquisar diretamente a partir da barra de endereço + Abrir um novo separador Firefox From 8aa97e8c04ca78a280df6d400473545124d02439 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:14 -0400 Subject: [PATCH 231/248] Strings update - app/src/main/res/values-rm/strings.xml --- app/src/main/res/values-rm/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-rm/strings.xml b/app/src/main/res/values-rm/strings.xml index 03637f965..8efee5c6f 100644 --- a/app/src/main/res/values-rm/strings.xml +++ b/app/src/main/res/values-rm/strings.xml @@ -178,6 +178,8 @@ Apparientscha + + Persunalisar la vista da lectura Impussibel da connectar. Schema dad URL nunenconuschent. From 45d19dcfc36e88ce76b392306194b9c9173fcfef Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:14 -0400 Subject: [PATCH 232/248] Strings update - app/src/main/res/values-ru/strings.xml --- app/src/main/res/values-ru/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 648ba5d36..6de51053d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -190,6 +190,8 @@ Оформление + + Настроить вид для чтения Ошибка подключения. Не удалось распознать схему URL. @@ -1233,7 +1235,7 @@ Автоматическая приватность - Настройки конфиденциальности и безопасности блокируют трекеры, вредоносные программы, и компании, которые вас отслеживают. + Настройки приватности и безопасности блокируют трекеры, вредоносные программы, и компании, которые вас отслеживают. Стандартная (по умолчанию) From df386933a6e47e6fcd63d3b5edd9e1eb2918f6c3 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:15 -0400 Subject: [PATCH 233/248] Strings update - app/src/main/res/values-sl/strings.xml --- app/src/main/res/values-sl/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 8b70a43d7..7bcfaa4dc 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -181,6 +181,8 @@ Videz + + Prilagodi bralni pogled Povezava ni mogoča. Neprepoznavna URL shema. @@ -217,6 +219,8 @@ Več o tem + + Išči z %s Iščite neposredno iz naslovne vrstice From c4a1b7b230daba60978b2e912cab08bce39543c7 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:15 -0400 Subject: [PATCH 234/248] Strings update - app/src/main/res/values-sv-rSE/strings.xml --- app/src/main/res/values-sv-rSE/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 5854f08e8..c14538eaa 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -185,6 +185,8 @@ Utseende + + Anpassa läsvyn Kan inte ansluta. Oigenkännligt URL-schema. From 0452d67fd2cdb8adfe8310e794dd9893a8e70f3b Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:16 -0400 Subject: [PATCH 235/248] Strings update - app/src/main/res/values-tg/strings.xml --- app/src/main/res/values-tg/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-tg/strings.xml b/app/src/main/res/values-tg/strings.xml index 8761b6132..af1b29dbe 100644 --- a/app/src/main/res/values-tg/strings.xml +++ b/app/src/main/res/values-tg/strings.xml @@ -181,6 +181,8 @@ Намуди зоҳирӣ + + Фармоишдиҳии намоиши хониш Пайваст нашуд. Нақшаи URL шинохтанашаванда аст. From c3f428d28422c6e7d123d71db3c78f52fe47ea24 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:16 -0400 Subject: [PATCH 236/248] Strings update - app/src/main/res/values-th/strings.xml --- app/src/main/res/values-th/strings.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index a2b32e0c9..1cf481e48 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -216,6 +216,11 @@ เรียนรู้เพิ่มเติม + + ค้นหา %s + + ค้นหาโดยตรงจากแถบที่อยู่ + เปิดแท็บ Firefox ใหม่ From 39bd4e76238a7110fc12f040383d34735a0cb419 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:17 -0400 Subject: [PATCH 237/248] Strings update - app/src/main/res/values-tr/strings.xml --- app/src/main/res/values-tr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 186ec3703..9f7f5c592 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -181,6 +181,8 @@ Görünüm + + Okuyucu görünümünü özelleştir Bağlanılamıyor. Tanınmayan URL şeması. From 69385bd540b403594eb86f416143cfaa6340ff8e Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:17 -0400 Subject: [PATCH 238/248] Strings update - app/src/main/res/values-uk/strings.xml --- app/src/main/res/values-uk/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 9dd9736c7..fba695ca0 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -182,6 +182,8 @@ Вигляд + + Налаштувати режим читача Неможливо з’єднатися. Невідома схема URL-адреси. @@ -1090,7 +1092,7 @@ Видалити дані перегляду - Відкрити вкладки + Відкриті вкладки Вкладок: %d From 23a250ee10e21b9373755d383892be5ebff16b66 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:17 -0400 Subject: [PATCH 239/248] Strings update - app/src/main/res/values-vi/strings.xml --- app/src/main/res/values-vi/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 00825b2dc..be218f2f4 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -181,6 +181,8 @@ Giao diện + + Tùy chỉnh chế độ đọc Không thể kết nối. Không thể nhận dạng URL. From 215e60e50d0990d686e1ece9da70303d54c28864 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:18 -0400 Subject: [PATCH 240/248] Strings update - app/src/main/res/values-zh-rCN/strings.xml --- app/src/main/res/values-zh-rCN/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 97c3776fe..fe6bc4d34 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -188,6 +188,8 @@ 字型调控 + + 定制阅读器视图 未知的 URL 规范,无法连接。 From cd1b41381c067b5f0225115bc863a9dca2d21c3d Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Mon, 15 Mar 2021 11:32:18 -0400 Subject: [PATCH 241/248] Strings update - app/src/main/res/values-zh-rTW/strings.xml --- app/src/main/res/values-zh-rTW/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 257d79220..a61628838 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -184,6 +184,8 @@ 外觀設定 + + 自訂閱讀模式 不認識的通訊協定,無法連線。 From 23809d2bb52781bb6cc8a9e7bf2a2a800e3b670f Mon Sep 17 00:00:00 2001 From: mcarare Date: Thu, 4 Mar 2021 14:12:16 +0200 Subject: [PATCH 242/248] For #18312: Do not update secure flag on pausing logins fragments. The flags are already properly set for activity and thus for other fragments. (cherry picked from commit 8c519994f0a42e9b59a88ae30096ac02881ead4e) --- app/src/main/java/org/mozilla/fenix/ext/Fragment.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt index 4275dd801..1eb2cb27b 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -13,7 +13,6 @@ import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment.findNavController import androidx.navigation.fragment.findNavController import mozilla.components.concept.base.crash.Breadcrumb -import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.Components @@ -66,7 +65,6 @@ fun Fragment.hideToolbar() { * */ fun Fragment.redirectToReAuth(destinations: List, currentDestination: Int?) { - (activity as? HomeActivity)?.updateSecureWindowFlags() if (currentDestination !in destinations) { findNavController().popBackStack(R.id.savedLoginsAuthFragment, false) } From 361927210ceaf4f35950bd52e19195fe5d201538 Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Mon, 15 Mar 2021 15:13:39 -0700 Subject: [PATCH 243/248] Bump A-C version to 73.0.10 --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 4b503a587..6a478db98 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.9" + const val VERSION = "73.0.10" } From 104455abc13541bfa7311713a6f7df9cfa1a1e43 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 4 Mar 2021 21:28:35 +0200 Subject: [PATCH 244/248] For #17869 - Start the Android Keystore experiment Only on API 23+ (minimum Android version needed for SecureAbove22Preferences) and only if enabled by a Nimbus experiment. The Nimbus experiment will have the key `fenix-android-keystore` and use the default branches - "control" and "treatment". --- .../org/mozilla/fenix/FenixApplication.kt | 3 ++ .../metrics/SecurePrefsTelemetry.kt | 35 +++++++++++++++++++ .../mozilla/fenix/experiments/Experiments.kt | 1 + 3 files changed, 39 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/components/metrics/SecurePrefsTelemetry.kt diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index d3ddf601b..850e32140 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -42,6 +42,7 @@ import mozilla.components.support.webextensions.WebExtensionSupport import org.mozilla.fenix.GleanMetrics.PerfStartup import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.metrics.MetricServiceType +import org.mozilla.fenix.components.metrics.SecurePrefsTelemetry import org.mozilla.fenix.ext.settings import org.mozilla.fenix.perf.ProfilerMarkerFactProcessor import org.mozilla.fenix.perf.StartupTimeline @@ -203,6 +204,8 @@ open class FenixApplication : LocaleAwareApplication(), Provider { components.core.bookmarksStorage.warmUp() components.core.passwordsStorage.warmUp() } + + SecurePrefsTelemetry(this@FenixApplication, components.analytics.experiments).startTests() } // Account manager initialization needs to happen on the main thread. GlobalScope.launch(Dispatchers.Main) { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/SecurePrefsTelemetry.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/SecurePrefsTelemetry.kt new file mode 100644 index 000000000..47a34497a --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/SecurePrefsTelemetry.kt @@ -0,0 +1,35 @@ +/* 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 org.mozilla.fenix.components.metrics + +import android.content.Context +import android.os.Build +import mozilla.components.lib.dataprotect.SecurePrefsReliabilityExperiment +import mozilla.components.service.nimbus.NimbusApi +import org.mozilla.fenix.experiments.ExperimentBranch +import org.mozilla.fenix.experiments.Experiments +import org.mozilla.fenix.ext.withExperiment + +/** + * Allows starting a quick test of ACs SecureAbove22Preferences that will emit Facts + * for the basic operations and allow us to log them for later evaluation of APIs stability. + */ +class SecurePrefsTelemetry( + private val appContext: Context, + private val experiments: NimbusApi +) { + suspend fun startTests() { + // The Android Keystore is used to secure the shared prefs only on API 23+ + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + // These tests should run only if the experiment is live + experiments.withExperiment(Experiments.ANDROID_KEYSTORE) { experimentBranch -> + // .. and this device is not in the control group. + if (experimentBranch == ExperimentBranch.TREATMENT) { + SecurePrefsReliabilityExperiment(appContext)() + } + } + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt index baa800910..9a9a39036 100644 --- a/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt +++ b/app/src/main/java/org/mozilla/fenix/experiments/Experiments.kt @@ -8,6 +8,7 @@ class Experiments { companion object { const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation-v3" const val BOOKMARK_ICON = "fenix-bookmark-list-icon" + const val ANDROID_KEYSTORE = "fenix-android-keystore" } } From ad4f29474e199ee73ce783cc78a4f7b3e8181544 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 4 Mar 2021 21:29:19 +0200 Subject: [PATCH 245/248] For #17869 - New AndroidKeystoreExperiment telemetry --- app/metrics.yaml | 101 ++++++++++++++++++ .../mozilla/fenix/components/metrics/Event.kt | 20 ++++ .../components/metrics/GleanMetricsService.kt | 24 +++++ .../components/metrics/MetricController.kt | 22 ++++ docs/metrics.md | 10 +- 5 files changed, 175 insertions(+), 2 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 53e09d98e..d2c763aca 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -4533,3 +4533,104 @@ engine: - fenix-core@mozilla.com - skaspari@mozilla.com expires: "2021-12-31" + +android_keystore_experiment: + experiment_failure: + type: event + description: | + Records an instance of an unexpected failure during the experiment + extra_keys: + failure_exception: + description: | + Exception class associated with an unexpected failure of this + experiment, not caught by the other failure handlers. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" + get_failure: + type: event + description: | + Unexpected failure when trying to read from secure prefs. + extra_keys: + failure_exception: + description: | + Exception class associated with an unexpected failure of this + experiment. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" + get_result: + type: event + description: | + Success when trying to read from secure prefs. + extra_keys: + result: + description: | + Result code identifying whether the read operation returned the + expected value or not. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" + write_failure: + type: event + description: | + Unexpected failure when trying to write to secure prefs. + extra_keys: + failure_exception: + description: | + Exception class associated with an unexpected failure of this + experiment. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" + write_success: + type: event + description: | + Success in writing to secure prefs. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" + reset: + type: event + description: | + An experiment failed, and was reset to run again in the future from a + blank state. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/17869 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395 + data_sensitivity: + - technical + notification_emails: + - fenix-core@mozilla.com + expires: "2021-09-01" diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index c7e2431ea..1f0b41d4c 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -9,6 +9,7 @@ import mozilla.components.browser.errorpages.ErrorType import mozilla.components.browser.state.search.SearchEngine import mozilla.components.feature.top.sites.TopSite import org.mozilla.fenix.GleanMetrics.Addons +import org.mozilla.fenix.GleanMetrics.AndroidKeystoreExperiment import org.mozilla.fenix.GleanMetrics.AppTheme import org.mozilla.fenix.GleanMetrics.Autoplay import org.mozilla.fenix.GleanMetrics.Collections @@ -221,6 +222,25 @@ sealed class Event { get() = hashMapOf(TopSites.swipeCarouselKeys.page to page.toString()) } + data class SecurePrefsExperimentFailure(val failureException: String) : Event() { + override val extras = + mapOf(AndroidKeystoreExperiment.experimentFailureKeys.failureException to failureException) + } + data class SecurePrefsGetFailure(val failureException: String) : Event() { + override val extras = + mapOf(AndroidKeystoreExperiment.getFailureKeys.failureException to failureException) + } + data class SecurePrefsGetSuccess(val successCode: String) : Event() { + override val extras = + mapOf(AndroidKeystoreExperiment.getResultKeys.result to successCode) + } + data class SecurePrefsWriteFailure(val failureException: String) : Event() { + override val extras = + mapOf(AndroidKeystoreExperiment.writeFailureKeys.failureException to failureException) + } + object SecurePrefsWriteSuccess : Event() + object SecurePrefsReset : Event() + data class TopSiteLongPress(val type: TopSite.Type) : Event() { override val extras: Map? get() = hashMapOf(TopSites.longPressKeys.type to type.name) diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index d122d34a7..d28e40d21 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -15,6 +15,7 @@ import mozilla.components.support.base.log.logger.Logger import org.mozilla.fenix.Config import org.mozilla.fenix.GleanMetrics.AboutPage import org.mozilla.fenix.GleanMetrics.Addons +import org.mozilla.fenix.GleanMetrics.AndroidKeystoreExperiment import org.mozilla.fenix.GleanMetrics.AppTheme import org.mozilla.fenix.GleanMetrics.Autoplay import org.mozilla.fenix.GleanMetrics.BannerOpenInApp @@ -750,6 +751,29 @@ private val Event.wrapper: EventWrapper<*>? { BannerOpenInApp.goToSettings.record(it) } ) + is Event.SecurePrefsExperimentFailure -> EventWrapper( + { AndroidKeystoreExperiment.experimentFailure.record(it) }, + { AndroidKeystoreExperiment.experimentFailureKeys.valueOf(it) } + ) + is Event.SecurePrefsGetFailure -> EventWrapper( + { AndroidKeystoreExperiment.getFailure.record(it) }, + { AndroidKeystoreExperiment.getFailureKeys.valueOf(it) } + ) + is Event.SecurePrefsGetSuccess -> EventWrapper( + { AndroidKeystoreExperiment.getResult.record(it) }, + { AndroidKeystoreExperiment.getResultKeys.valueOf(it) } + ) + is Event.SecurePrefsWriteFailure -> EventWrapper( + { AndroidKeystoreExperiment.writeFailure.record(it) }, + { AndroidKeystoreExperiment.writeFailureKeys.valueOf(it) } + ) + is Event.SecurePrefsWriteSuccess -> EventWrapper( + { AndroidKeystoreExperiment.writeSuccess.record(it) } + ) + is Event.SecurePrefsReset -> EventWrapper( + { AndroidKeystoreExperiment.reset.record(it) } + ) + // Don't record other events in Glean: is Event.AddBookmark -> null is Event.OpenedBookmark -> null diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt index 013fd2422..7f9aed10a 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/MetricController.kt @@ -23,6 +23,7 @@ import mozilla.components.feature.media.facts.MediaFacts import mozilla.components.feature.prompts.dialog.LoginDialogFacts import mozilla.components.feature.pwa.ProgressiveWebAppFacts import mozilla.components.feature.top.sites.facts.TopSitesFacts +import mozilla.components.lib.dataprotect.SecurePrefsReliabilityExperiment import mozilla.components.support.base.Component import mozilla.components.support.base.facts.Action import mozilla.components.support.base.facts.Fact @@ -76,6 +77,7 @@ internal class DebugMetricController( } @VisibleForTesting +@Suppress("LargeClass") internal class ReleaseMetricController( private val services: List, private val isDataTelemetryEnabled: () -> Boolean, @@ -267,6 +269,26 @@ internal class ReleaseMetricController( } null } + Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.EXPERIMENT -> { + Event.SecurePrefsExperimentFailure(metadata?.get("javaClass") as String? ?: "null") + } + Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.GET -> { + if (SecurePrefsReliabilityExperiment.Companion.Values.FAIL.v == value?.toInt()) { + Event.SecurePrefsGetFailure(metadata?.get("javaClass") as String? ?: "null") + } else { + Event.SecurePrefsGetSuccess(value ?: "") + } + } + Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.WRITE -> { + if (SecurePrefsReliabilityExperiment.Companion.Values.FAIL.v == value?.toInt()) { + Event.SecurePrefsWriteFailure(metadata?.get("javaClass") as String? ?: "null") + } else { + Event.SecurePrefsWriteSuccess + } + } + Component.LIB_DATAPROTECT to SecurePrefsReliabilityExperiment.Companion.Actions.RESET -> { + Event.SecurePrefsReset + } else -> null } diff --git a/docs/metrics.md b/docs/metrics.md index 4412b58ab..0c988a1d7 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -52,6 +52,12 @@ The following metrics are added to the ping: | about_page.support_tapped |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user tapped on "Support" item from About page |[1](https://github.com/mozilla-mobile/fenix/pull/8047), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | | addons.open_addon_in_toolbar_menu |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user interacted with an installed add-on in the toolbar menu |[1](https://github.com/mozilla-mobile/fenix/pull/8318), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)|
  • addon_id: The id of the add-on that was interacted with in the toolbar menu
|2021-04-01 |2 | | addons.open_addons_in_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user accessed "Add-ons" from the Settings |[1](https://github.com/mozilla-mobile/fenix/pull/8318), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)||2021-04-01 |2 | +| android_keystore_experiment.experiment_failure |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Records an instance of an unexpected failure during the experiment |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)|
  • failure_exception: Exception class associated with an unexpected failure of this experiment, not caught by the other failure handlers.
|2021-09-01 |1 | +| android_keystore_experiment.get_failure |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Unexpected failure when trying to read from secure prefs. |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)|
  • failure_exception: Exception class associated with an unexpected failure of this experiment.
|2021-09-01 |1 | +| android_keystore_experiment.get_result |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Success when trying to read from secure prefs. |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)|
  • result: Result code identifying whether the read operation returned the expected value or not.
|2021-09-01 |1 | +| android_keystore_experiment.reset |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |An experiment failed, and was reset to run again in the future from a blank state. |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)||2021-09-01 |1 | +| android_keystore_experiment.write_failure |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Unexpected failure when trying to write to secure prefs. |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)|
  • failure_exception: Exception class associated with an unexpected failure of this experiment.
|2021-09-01 |1 | +| android_keystore_experiment.write_success |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |Success in writing to secure prefs. |[1](https://github.com/mozilla-mobile/fenix/pull/18333#pullrequestreview-612447395)||2021-09-01 |1 | | app_theme.dark_theme_selected |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user selected Dark Theme |[1](https://github.com/mozilla-mobile/fenix/pull/7968), [2](https://github.com/mozilla-mobile/fenix/pull/13958#issuecomment-676857877)|
  • source: The source from where dark theme was selected. The source can be 'SETTINGS' or 'ONBOARDING'
|2021-04-01 |2 | | autoplay.setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their autoplay setting to either block_cellular, block_audio, or block_all. |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)|
  • autoplay_setting: The new setting for autoplay: block_cellular, block_audio, or block_all.
|2021-08-01 |2 | | autoplay.visited_setting |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user visited the autoplay settings screen |[1](https://github.com/mozilla-mobile/fenix/pull/13041#issuecomment-665777411)||2021-08-01 |2 | @@ -315,8 +321,8 @@ The following metrics are added to the ping: | perf.awesomebar.session_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a session awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | | perf.awesomebar.shortcuts_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a shortcuts awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | | perf.awesomebar.synced_tabs_suggestions |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |Duration of a synced tabs awesomebar suggestion query. |[1](https://github.com/mozilla-mobile/fenix/pull/10276#pullrequestreview-411101979)||2020-11-15 |1, 2 | -| perf.startup.application_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `FenixApplication.onCreate` in the main process. |[1](todo)||2021-08-11 |1 | -| perf.startup.home_activity_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `HomeActivity.onCreate`. |[1](todo)||2021-08-11 |1 | +| perf.startup.application_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `FenixApplication.onCreate` in the main process. |[1](https://github.com/mozilla-mobile/fenix/pull/17973#issue-572183889)||2021-08-11 |1 | +| perf.startup.home_activity_on_create |[timing_distribution](https://mozilla.github.io/glean/book/user/metrics/timing_distribution.html) |The duration of `HomeActivity.onCreate`. |[1](https://github.com/mozilla-mobile/fenix/pull/17973#issue-572183889)||2021-08-11 |1 | | preferences.accessibility_services |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has touch exploration or switch services enabled. These are built into the Android OS, not Fenix prefs. default: "" |[1](https://github.com/mozilla-mobile/fenix/pull/11211), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | preferences.open_links_in_a_private_tab |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has enabled open links in a private tab. default: false |[1](https://github.com/mozilla-mobile/fenix/pull/11211), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | | preferences.open_links_in_app |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |Whether or not the user has the open links in apps feature enabled. default: false |[1](https://github.com/mozilla-mobile/fenix/pull/11446), [2](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 | From e5b7e41e371ea6221880afcc2e23ea278c412bd3 Mon Sep 17 00:00:00 2001 From: Mozilla Releng Treescript Date: Tue, 16 Mar 2021 01:50:20 +0000 Subject: [PATCH 246/248] Automatic version bump CLOSED TREE NO BUG a=release --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 55c095e8a..0c220ee14 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.6 +87.0.0-beta.7 From 89fd1009b6379c0798bfb92889952297f2ad41fd Mon Sep 17 00:00:00 2001 From: MickeyMoz Date: Tue, 16 Mar 2021 20:46:51 +0000 Subject: [PATCH 247/248] Update to Android-Components 73.0.11. --- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 6a478db98..5899e75df 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "73.0.10" + const val VERSION = "73.0.11" } From 9d91b8eeb9d287ee95937b5edfffde383982267a Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Tue, 16 Mar 2021 17:04:24 -0400 Subject: [PATCH 248/248] Set version to 87.0.0-rc.1 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 0c220ee14..275710fc9 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -87.0.0-beta.7 +87.0.0-rc.1