diff --git a/app/build.gradle b/app/build.gradle index 4f29b5e47..6418535f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -32,7 +32,7 @@ android { testInstrumentationRunnerArguments clearPackageData: 'true' resValue "bool", "IS_DEBUG", "false" buildConfigField "boolean", "USE_RELEASE_VERSIONING", "false" - buildConfigField "String", "AMO_COLLECTION", "\"16f6e5d9a40448b8955db57ced6d75\"" + buildConfigField "String", "AMO_COLLECTION", "\"3204bb44a6ef44d39ee34917f28055\"" def deepLinkSchemeValue = "fenix-dev" buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" manifestPlaceholders = [ @@ -53,7 +53,6 @@ android { shrinkResources false minifyEnabled false applicationIdSuffix ".fenix.debug" - buildConfigField "String", "AMO_COLLECTION", "\"3204bb44a6ef44d39ee34917f28055\"" manifestPlaceholders.isRaptorEnabled = "true" resValue "bool", "IS_DEBUG", "true" pseudoLocalesEnabled true @@ -73,7 +72,6 @@ android { fenixNightly releaseTemplate >> { applicationIdSuffix ".fenix.nightly" buildConfigField "boolean", "USE_RELEASE_VERSIONING", "true" - buildConfigField "String", "AMO_COLLECTION", "\"3204bb44a6ef44d39ee34917f28055\"" def deepLinkSchemeValue = "fenix-nightly" buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" manifestPlaceholders = ["deepLinkScheme": deepLinkSchemeValue] @@ -131,7 +129,6 @@ android { applicationIdSuffix ".fennec_aurora" def deepLinkSchemeValue = "fenix-nightly" buildConfigField "String", "DEEP_LINK_SCHEME", "\"$deepLinkSchemeValue\"" - buildConfigField "String", "AMO_COLLECTION", "\"3204bb44a6ef44d39ee34917f28055\"" manifestPlaceholders = [ // This release type is meant to replace Firefox (Release channel) and therefore needs to inherit // its sharedUserId for all eternity. See: diff --git a/app/src/main/java/org/mozilla/fenix/StrictModeManager.kt b/app/src/main/java/org/mozilla/fenix/StrictModeManager.kt index 16f788679..5ff1932bb 100644 --- a/app/src/main/java/org/mozilla/fenix/StrictModeManager.kt +++ b/app/src/main/java/org/mozilla/fenix/StrictModeManager.kt @@ -1,6 +1,6 @@ -/* 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/. */ +/* 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 @@ -8,7 +8,6 @@ import android.os.Build import android.os.StrictMode import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager -import kotlin.collections.HashSet /** * Manages strict mode settings for the application. @@ -16,38 +15,39 @@ import kotlin.collections.HashSet object StrictModeManager { /*** - * Enables strict mode for debug purposes. meant to be run only in the main process. - * @param setPenaltyDialog boolean value to decide setting the dialog box as a penalty. - */ - fun enableStrictMode(setPenaltyDialog: Boolean) { - if (Config.channel.isDebug) { - val threadPolicy = StrictMode.ThreadPolicy.Builder() - .detectAll() - .penaltyLog() - if (setPenaltyDialog && - !strictModeExceptionList.contains(Build.MANUFACTURER)) { - threadPolicy.penaltyDialog() - } - StrictMode.setThreadPolicy(threadPolicy.build()) - var builder = StrictMode.VmPolicy.Builder() - .detectLeakedSqlLiteObjects() - .detectLeakedClosableObjects() - .detectLeakedRegistrationObjects() - .detectActivityLeaks() - .detectFileUriExposure() - .penaltyLog() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) builder = - builder.detectContentUriWithoutPermission() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - if (setPenaltyDialog) { - builder.permitNonSdkApiUsage() - } else { - builder.detectNonSdkApiUsage() - } - } - StrictMode.setVmPolicy(builder.build()) + * Enables strict mode for debug purposes. meant to be run only in the main process. + * @param setPenaltyDialog boolean value to decide setting the dialog box as a penalty. + */ + fun enableStrictMode(setPenaltyDialog: Boolean) { + if (Config.channel.isDebug) { + val threadPolicy = StrictMode.ThreadPolicy.Builder() + .detectAll() + .penaltyLog() + if (setPenaltyDialog && Build.MANUFACTURER !in strictModeExceptionList) { + threadPolicy.penaltyDialog() } + StrictMode.setThreadPolicy(threadPolicy.build()) + + val builder = StrictMode.VmPolicy.Builder() + .detectLeakedSqlLiteObjects() + .detectLeakedClosableObjects() + .detectLeakedRegistrationObjects() + .detectActivityLeaks() + .detectFileUriExposure() + .penaltyLog() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + builder.detectContentUriWithoutPermission() + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (setPenaltyDialog) { + builder.permitNonSdkApiUsage() + } else { + builder.detectNonSdkApiUsage() + } + } + StrictMode.setVmPolicy(builder.build()) } + } /** * Revert strict mode to disable penalty dialog. Tied to fragment lifecycle since strict mode @@ -55,8 +55,7 @@ object StrictModeManager { * specific fragment. */ fun changeStrictModePolicies(fragmentManager: FragmentManager) { - fragmentManager.registerFragmentLifecycleCallbacks(object : - FragmentManager.FragmentLifecycleCallbacks() { + fragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { enableStrictMode(false) fm.unregisterFragmentLifecycleCallbacks(this) @@ -64,6 +63,9 @@ object StrictModeManager { }, false) } + private const val MANUFACTURE_HUAWEI: String = "HUAWEI" + private const val MANUFACTURE_ONE_PLUS: String = "OnePlus" + /** * 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 @@ -71,11 +73,5 @@ object 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 = HashSet().also { - it.add(MANUFACTURE_HUAWEI) - it.add(MANUFACTURE_ONE_PLUS) - } - - private const val MANUFACTURE_HUAWEI: String = "HUAWEI" - private const val MANUFACTURE_ONE_PLUS: String = "OnePlus" + private val strictModeExceptionList = setOf(MANUFACTURE_HUAWEI, MANUFACTURE_ONE_PLUS) } diff --git a/app/src/main/java/org/mozilla/fenix/ext/StrictMode.kt b/app/src/main/java/org/mozilla/fenix/ext/StrictMode.kt index daf344933..ecb73dc39 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/StrictMode.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/StrictMode.kt @@ -1,6 +1,7 @@ /* 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 android.os.StrictMode 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 76c463054..f2993aa86 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -30,6 +30,7 @@ import androidx.constraintlayout.widget.ConstraintSet.TOP import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.ContextCompat import androidx.core.view.doOnLayout +import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels @@ -223,22 +224,6 @@ class HomeFragment : Fragment() { updateSessionControlView(view) activity.themeManager.applyStatusBarTheme(activity) - - view.consumeFrom(requireComponents.core.store, viewLifecycleOwner) { - val tabCount = if (currentMode.getCurrentMode() == Mode.Normal) { - it.normalTabs.size - } else { - it.privateTabs.size - } - - view.tab_button.setCountWithAnimation(tabCount) - view.add_tabs_to_collections_button?.visibility = if (tabCount > 0) { - View.VISIBLE - } else { - View.GONE - } - } - return view } @@ -403,6 +388,17 @@ class HomeFragment : Fragment() { } else { requireActivity().window.clearFlags(FLAG_SECURE) } + + consumeFrom(requireComponents.core.store) { + val tabCount = if (browsingModeManager.mode.isPrivate) { + it.privateTabs.size + } else { + it.normalTabs.size + } + + view.tab_button?.setCountWithAnimation(tabCount) + view.add_tabs_to_collections_button?.isVisible = tabCount > 0 + } } override fun onDestroyView() { diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 4a6d43b59..a7c6c9f47 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -20,6 +20,11 @@ Тут будуць паказаны вашы прыватныя карткі. + + 1 адкрытая картка. Націсніце, каб пераключыць карткі. + + Адкрытых картак: %1$s. Націсніце, каб пераключыць карткі. + Вы ў прыватным сеансе @@ -324,9 +329,9 @@ - Зверху + Уверсе - Знізу + Унізе @@ -334,6 +339,8 @@ Цёмная + + Паводле рэжыму эканоміі зараду Тэма прылады @@ -403,6 +410,8 @@ Закрыць картку Закрыць картку %s + + Меню адкрытых картак Закрыць усе карткі @@ -505,6 +514,8 @@ Закладка створана. Закладка захавана! + + ЗМЯНІЦЬ Змяніць @@ -585,6 +596,8 @@ Абвестка Запытваць дазвол + + Дазволена Заблакавана Android @@ -625,6 +638,12 @@ Адмяніць выбар усіх Выберыце карткі для захавання + + Выбрана картак: %d + + Выбрана картка: %d Карткі захаваны! @@ -667,6 +686,8 @@ Па-за сеткай Падключыць іншую прыладу + + Каб адправіць картку, увайдзіце ў Firefox прынамсі на адной іншай прыладзе. Зразумела @@ -707,6 +728,8 @@ Карткі закрыты + + Дададзена да папулярных сайтаў Прыватная картка закрыта @@ -746,11 +769,16 @@ Адкрытыя карткі Карткі: %d + + Гісторыя аглядання і дадзеныя сайтаў Адрасы: %d Гісторыя + + Старонак: %d Кукі @@ -787,26 +815,56 @@ Вітаем у %s! Ужо маеце ўліковы запіс? + + Пазнаёмцеся з %s Паглядзіце, што новага + + Маеце пытанні па абноўленым выглядзе %s? Хочаце ведаць, што змянілася? + + Адказы тут + + Атрымайце максімум ад %s. Увайсці ў Firefox Няўдача ўваходу Аўтаматычная прыватнасць + + Налады прыватнасці і бяспекі блакуюць трэкеры, шкоднасныя праграмы і кампаніі, што ідуць за вамі. Стандартная (прадвызначана) + + Блакуе менш трэкераў. Старонкі загружаюцца нармальна. Строгая (рэкамендуецца) Строгая + + Блакуе больш трэкераў, рэкламы і выплыўных вокнаў. Старонкі загружаюцца хутчэй, але некаторыя функцыі могуць не працаваць. + + Выберыце становішча + + Паспрабуйце навігацыю адной рукой на паліцы прылад унізе або перамясціце яе ўверх. Аглядайце прыватна Адкрыць налады Ваша прыватнасць + + Мы распрацавалі %s, каб даць вам кантроль над тым, чым дзяліцца + ў Інтэрнэце і тым, чым вы падзеліцеся з намі. + + Паведамленне аб прыватнасці Закрыць @@ -866,12 +924,20 @@ Даведацца больш Стандартная (прадвызначана) + + Што блакуецца стандартнай аховай ад сачэння Строгая + + Блакуе больш трэкераў, рэкламы і выплыўных вокнаў. Старонкі загружаюцца хутчэй, але некаторыя функцыі могуць не працаваць. + + Што блакуецца строгай аховай ад сачэння Адмыслова Выберыце, якія трэкеры і скрыпты трэба заблакаваць. + + Што блакуецца адмысловай аховай ад сачэння Кукі @@ -889,6 +955,8 @@ Ва ўсіх картках Толькі ў прыватных картках + + Толькі ў адмысловых картках Майнеры крыптавалют @@ -914,6 +982,8 @@ Перайсці назад Вашы правы + + Выкарыстаныя бібліятэкі з адкрытым зыходным кодам Што новага ў %s @@ -982,6 +1052,12 @@ Выключэнні + + Шукаць лагіны + + Па алфавіце + + Нядаўна выкарыстаныя Сайт @@ -1035,6 +1111,8 @@ Выдаліць + + Іншы Назва @@ -1065,6 +1143,8 @@ Не бяспечнае злучэнне + + Няма выняткаў для сайта Дадаць да папулярных сайтаў Sitio de escritorio - Añadir a la pantalla de inicio + Añadir a pantalla de inicio Instalar @@ -884,8 +884,6 @@ Elimina automáticamente los datos de navegación cuando seleccionas "Salir" en el menú principal Elimina automáticamente los datos de navegación cuando seleccionas \"Salir\" en el menú principal - - Historial de navegación Salir @@ -1384,7 +1382,7 @@ ¿De verdad quieres eliminar este marcador? - Añadir a sitios frecuentes + Añadir sitio frecuente Verificado por: %1$s diff --git a/app/src/test/java/org/mozilla/fenix/StrictModeManagerTest.kt b/app/src/test/java/org/mozilla/fenix/StrictModeManagerTest.kt new file mode 100644 index 000000000..0ddd003d9 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/StrictModeManagerTest.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 + +import android.os.StrictMode +import androidx.fragment.app.FragmentManager +import io.mockk.MockKAnnotations +import io.mockk.confirmVerified +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.mockkStatic +import io.mockk.slot +import io.mockk.unmockkObject +import io.mockk.unmockkStatic +import io.mockk.verify +import org.junit.After +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class StrictModeManagerTest { + + @MockK(relaxUnitFun = true) private lateinit var fragmentManager: FragmentManager + + @Before + fun setup() { + MockKAnnotations.init(this) + mockkStatic(StrictMode::class) + mockkObject(Config) + } + + @After + fun teardown() { + unmockkStatic(StrictMode::class) + unmockkObject(Config) + } + + @Test + fun `test enableStrictMode in release`() { + every { Config.channel } returns ReleaseChannel.FenixProduction + StrictModeManager.enableStrictMode(false) + + verify(exactly = 0) { StrictMode.setThreadPolicy(any()) } + verify(exactly = 0) { StrictMode.setVmPolicy(any()) } + } + + @Test + fun `test enableStrictMode in debug`() { + every { Config.channel } returns ReleaseChannel.FenixDebug + StrictModeManager.enableStrictMode(false) + + verify { StrictMode.setThreadPolicy(any()) } + verify { StrictMode.setVmPolicy(any()) } + } + + @Test + fun `test changeStrictModePolicies`() { + val callbacks = slot() + + StrictModeManager.changeStrictModePolicies(fragmentManager) + verify { fragmentManager.registerFragmentLifecycleCallbacks(capture(callbacks), false) } + confirmVerified(fragmentManager) + + callbacks.captured.onFragmentResumed(fragmentManager, mockk()) + verify { fragmentManager.unregisterFragmentLifecycleCallbacks(callbacks.captured) } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/ext/StrictModeTest.kt b/app/src/test/java/org/mozilla/fenix/ext/StrictModeTest.kt new file mode 100644 index 000000000..515949d2a --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/ext/StrictModeTest.kt @@ -0,0 +1,79 @@ +/* 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 android.os.StrictMode +import io.mockk.Runs +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.mockkStatic +import io.mockk.unmockkObject +import io.mockk.unmockkStatic +import io.mockk.verify +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.Config +import org.mozilla.fenix.ReleaseChannel +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class StrictModeTest { + + private lateinit var threadPolicy: StrictMode.ThreadPolicy + private lateinit var functionBlock: () -> String + + @Before + fun setup() { + threadPolicy = StrictMode.ThreadPolicy.LAX + functionBlock = mockk() + mockkStatic(StrictMode::class) + mockkObject(Config) + + every { StrictMode.setThreadPolicy(threadPolicy) } just Runs + every { functionBlock() } returns "Hello world" + } + + @After + fun teardown() { + unmockkStatic(StrictMode::class) + unmockkObject(Config) + } + + @Test + fun `runs function block in release`() { + every { Config.channel } returns ReleaseChannel.FenixProduction + assertEquals("Hello world", threadPolicy.resetPoliciesAfter(functionBlock)) + verify(exactly = 0) { StrictMode.setThreadPolicy(any()) } + } + + @Test + fun `runs function block in debug`() { + every { Config.channel } returns ReleaseChannel.FenixDebug + assertEquals("Hello world", threadPolicy.resetPoliciesAfter(functionBlock)) + verify { StrictMode.setThreadPolicy(threadPolicy) } + } + + @Test + fun `sets thread policy even if function throws`() { + every { Config.channel } returns ReleaseChannel.FenixDebug + every { functionBlock() } throws IllegalStateException() + var exception: IllegalStateException? = null + + try { + threadPolicy.resetPoliciesAfter(functionBlock) + } catch (e: IllegalStateException) { + exception = e + } + + verify { StrictMode.setThreadPolicy(threadPolicy) } + assertNotNull(exception) + } +} diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 659a9d890..c1f92abc1 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 = "48.0.20200628130058" + const val VERSION = "48.0.20200629130051" } diff --git a/taskcluster/ci/raptor/kind.yml b/taskcluster/ci/raptor/kind.yml index 07315a15f..135a05b5c 100644 --- a/taskcluster/ci/raptor/kind.yml +++ b/taskcluster/ci/raptor/kind.yml @@ -80,6 +80,7 @@ job-defaults: - '--binary=org.mozilla.fenix.nightly' - '--activity=org.mozilla.fenix.IntentReceiverActivity' - '--download-symbols=ondemand' + - '--no-conditioned-profile' fetches: toolchain: - linux64-minidump-stackwalk