From 129d42ea9fff635362929e438e7904e137709bfd Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Wed, 18 Nov 2020 16:57:17 -0500 Subject: [PATCH] For issue #16557 set autoplay block audio only by default --- ...ttingsSubMenuSitePermissionsCommonRobot.kt | 7 + .../fenix/browser/BaseBrowserFragment.kt | 6 - .../mozilla/fenix/components/metrics/Event.kt | 2 +- .../mozilla/fenix/settings/PhoneFeature.kt | 2 +- .../SitePermissionsFragment.kt | 11 +- ...tePermissionsManagePhoneFeatureFragment.kt | 38 ++-- .../java/org/mozilla/fenix/utils/Settings.kt | 5 +- .../wifi/SitePermissionsWifiIntegration.kt | 35 ++-- .../fenix/wifi/WifiConnectionMonitor.kt | 20 +- .../QuickSettingsFragmentStoreTest.kt | 2 +- .../SitePermissionsWifiIntegrationTest.kt | 140 +++++++++++++ .../org/mozilla/fenix/utils/SettingsTest.kt | 15 ++ .../fenix/wifi/WifiConnectionMonitorTest.kt | 192 ++++++++++++++++++ 13 files changed, 406 insertions(+), 69 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsWifiIntegrationTest.kt create mode 100644 app/src/test/java/org/mozilla/fenix/wifi/WifiConnectionMonitorTest.kt diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt index e88b38ba022b..1ff42f0b3c55 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SettingsSubMenuSitePermissionsCommonRobot.kt @@ -107,12 +107,19 @@ private fun assertVideoAndAudioBlockedRecommended() = onView(withId(R.id.fourth_ private fun assertCheckAutoPayRadioButtonDefault() { + // Allow audio and video onView(withId(R.id.block_radio)) .assertIsChecked(isChecked = false) + // Block audio and video on cellular data only + onView(withId(R.id.block_radio)) + .assertIsChecked(isChecked = false) + + // Block audio only onView(withId(R.id.third_radio)) .assertIsChecked(isChecked = false) + // Block audio and video onView(withId(R.id.fourth_radio)) .assertIsChecked(isChecked = true) } 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 3fe1a59a82df..8772f880fc6f 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -799,12 +799,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, view: View ): List - @CallSuper - override fun onStart() { - super.onStart() - sitePermissionWifiIntegration.get()?.maybeAddWifiConnectedListener() - } - @VisibleForTesting internal fun observeRestoreComplete(store: BrowserStore, navController: NavController) { val activity = activity as HomeActivity 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 d25cf377072d..abfa9af080f3 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 @@ -535,7 +535,7 @@ sealed class Event { data class AutoPlaySettingChanged(val setting: AutoplaySetting) : Event() { enum class AutoplaySetting { - BLOCK_CELLULAR, BLOCK_AUDIO, BLOCK_ALL + BLOCK_CELLULAR, BLOCK_AUDIO, BLOCK_ALL, ALLOW_ALL } override val extras: Map? diff --git a/app/src/main/java/org/mozilla/fenix/settings/PhoneFeature.kt b/app/src/main/java/org/mozilla/fenix/settings/PhoneFeature.kt index 31ca24ecb08f..ac0dc1a3632f 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/PhoneFeature.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/PhoneFeature.kt @@ -46,7 +46,7 @@ enum class PhoneFeature(val androidPermissionsList: Array) : Parcelable @StringRes val stringRes = if (isAndroidPermissionGranted(context)) { when (this) { AUTOPLAY_AUDIBLE -> - when (settings?.getAutoplayUserSetting(default = AUTOPLAY_BLOCK_ALL) ?: AUTOPLAY_BLOCK_ALL) { + when (settings?.getAutoplayUserSetting() ?: AUTOPLAY_BLOCK_ALL) { AUTOPLAY_ALLOW_ALL -> R.string.preference_option_autoplay_allowed2 AUTOPLAY_ALLOW_ON_WIFI -> R.string.preference_option_autoplay_allowed_wifi_only2 AUTOPLAY_BLOCK_AUDIBLE -> R.string.preference_option_autoplay_block_audio2 diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsFragment.kt index a87f1041ea7c..ce03bf9782ac 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsFragment.kt @@ -59,17 +59,8 @@ class SitePermissionsFragment : PreferenceFragmentCompat() { val context = requireContext() val settings = context.settings() - val summary = phoneFeature.getActionLabel(context, settings = settings) - // Remove autoplaySummary after https://bugzilla.mozilla.org/show_bug.cgi?id=1621825 is fixed - val autoplaySummary = - if (summary == context.getString(R.string.preference_option_autoplay_allowed2)) { - context.getString(R.string.preference_option_autoplay_allowed_wifi_only2) - } else { - null - } - val cameraPhoneFeatures = requirePreference(phoneFeature.getPreferenceId()) - cameraPhoneFeatures.summary = autoplaySummary ?: summary + cameraPhoneFeatures.summary = phoneFeature.getActionLabel(context, settings = settings) cameraPhoneFeatures.onPreferenceClickListener = OnPreferenceClickListener { navigateToPhoneFeature(phoneFeature) diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManagePhoneFeatureFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManagePhoneFeatureFragment.kt index d96f44836e43..496a12a1d8e1 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManagePhoneFeatureFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManagePhoneFeatureFragment.kt @@ -77,14 +77,12 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { private fun initFirstRadio(rootView: View) { with(rootView.ask_to_allow_radio) { if (args.phoneFeature == AUTOPLAY_AUDIBLE) { - // Disabled because GV does not allow this setting. TODO Reenable after - // https://bugzilla.mozilla.org/show_bug.cgi?id=1621825 is fixed -// text = getString(R.string.preference_option_autoplay_allowed2) -// setOnClickListener { -// saveActionInSettings(it.context, AUTOPLAY_ALLOW_ALL) -// } -// restoreState(AUTOPLAY_ALLOW_ALL) - visibility = View.GONE + text = getString(R.string.preference_option_autoplay_allowed2) + setOnClickListener { + saveActionInSettings(AUTOPLAY_ALLOW_ALL) + } + restoreState(AUTOPLAY_ALLOW_ALL) + visibility = View.VISIBLE } else { text = getCombinedLabel( getString(R.string.preference_option_phone_feature_ask_to_allow), @@ -107,10 +105,7 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { getString(R.string.preference_option_autoplay_allowed_wifi_subtext) ) setOnClickListener { - // TODO replace with AUTOPLAY_ALLOW_ON_WIFI when - // https://bugzilla.mozilla.org/show_bug.cgi?id=1621825 is fixed. This GV bug - // makes ALLOW_ALL behave as ALLOW_ON_WIFI - saveActionInSettings(AUTOPLAY_ALLOW_ALL) + saveActionInSettings(AUTOPLAY_ALLOW_ON_WIFI) } restoreState(AUTOPLAY_ALLOW_ON_WIFI) } else { @@ -127,7 +122,10 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { with(rootView.third_radio) { if (args.phoneFeature == AUTOPLAY_AUDIBLE) { visibility = View.VISIBLE - text = getString(R.string.preference_option_autoplay_block_audio2) + text = getCombinedLabel( + getString(R.string.preference_option_autoplay_block_audio2), + getString(R.string.phone_feature_recommended) + ) setOnClickListener { saveActionInSettings(AUTOPLAY_BLOCK_AUDIBLE) } @@ -142,10 +140,8 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { with(rootView.fourth_radio) { if (args.phoneFeature == AUTOPLAY_AUDIBLE) { visibility = View.VISIBLE - text = getCombinedLabel( - getString(R.string.preference_option_autoplay_blocked3), - getString(R.string.phone_feature_recommended) - ) + text = getString(R.string.preference_option_autoplay_blocked3) + setOnClickListener { saveActionInSettings(AUTOPLAY_BLOCK_ALL) } @@ -164,7 +160,7 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { } private fun RadioButton.restoreState(buttonAutoplaySetting: Int) { - if (settings.getAutoplayUserSetting(AUTOPLAY_BLOCK_ALL) == buttonAutoplaySetting) { + if (settings.getAutoplayUserSetting() == buttonAutoplaySetting) { this.isChecked = true this.setStartCheckedIndicator() } @@ -185,9 +181,11 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() { val setting: Event.AutoPlaySettingChanged.AutoplaySetting val (audible, inaudible) = when (autoplaySetting) { - AUTOPLAY_ALLOW_ALL, + AUTOPLAY_ALLOW_ALL -> { + setting = Event.AutoPlaySettingChanged.AutoplaySetting.ALLOW_ALL + ALLOWED to ALLOWED + } AUTOPLAY_ALLOW_ON_WIFI -> { - settings.setAutoplayUserSetting(AUTOPLAY_ALLOW_ON_WIFI) setting = Event.AutoPlaySettingChanged.AutoplaySetting.BLOCK_CELLULAR BLOCKED to BLOCKED } 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 985572be6b5c..9815537a520b 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -40,6 +40,7 @@ import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitTyp import org.mozilla.fenix.settings.logins.SavedLoginsSortingStrategyMenu import org.mozilla.fenix.settings.logins.SortingStrategy import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener +import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL import java.security.InvalidParameterException private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING" @@ -722,9 +723,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { * either [AUTOPLAY_ALLOW_ALL] or [AUTOPLAY_BLOCK_ALL]. Because of this, we are forced to save * the user selected setting as well. */ - fun getAutoplayUserSetting( - default: Int - ) = preferences.getInt(AUTOPLAY_USER_SETTING, default) + fun getAutoplayUserSetting() = preferences.getInt(AUTOPLAY_USER_SETTING, AUTOPLAY_BLOCK_ALL) private fun getSitePermissionsPhoneFeatureAutoplayAction( feature: PhoneFeature, diff --git a/app/src/main/java/org/mozilla/fenix/wifi/SitePermissionsWifiIntegration.kt b/app/src/main/java/org/mozilla/fenix/wifi/SitePermissionsWifiIntegration.kt index eec7d25e6bd7..603c76bdc5a4 100644 --- a/app/src/main/java/org/mozilla/fenix/wifi/SitePermissionsWifiIntegration.kt +++ b/app/src/main/java/org/mozilla/fenix/wifi/SitePermissionsWifiIntegration.kt @@ -4,11 +4,12 @@ package org.mozilla.fenix.wifi -import mozilla.components.feature.sitepermissions.SitePermissionsRules +import androidx.annotation.VisibleForTesting +import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED +import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED import mozilla.components.support.base.feature.LifecycleAwareFeature import org.mozilla.fenix.settings.PhoneFeature import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_ALLOW_ON_WIFI -import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL import org.mozilla.fenix.utils.Settings /** @@ -24,11 +25,11 @@ class SitePermissionsWifiIntegration( * Adds listener for autoplay setting [AUTOPLAY_ALLOW_ON_WIFI]. Sets all autoplay to allowed when * WIFI is connected, blocked otherwise. */ - private val wifiConnectedListener: ((Boolean) -> Unit) by lazy { + @VisibleForTesting + internal val wifiConnectedListener: ((Boolean) -> Unit) by lazy { { connected: Boolean -> - val setting = - if (connected) SitePermissionsRules.Action.ALLOWED else SitePermissionsRules.Action.BLOCKED - if (settings.getAutoplayUserSetting(default = AUTOPLAY_BLOCK_ALL) == AUTOPLAY_ALLOW_ON_WIFI) { + if (settings.getAutoplayUserSetting() == AUTOPLAY_ALLOW_ON_WIFI) { + val setting = if (connected) ALLOWED else BLOCKED settings.setSitePermissionsPhoneFeatureAction( PhoneFeature.AUTOPLAY_AUDIBLE, setting @@ -39,21 +40,11 @@ class SitePermissionsWifiIntegration( ) } else { // The autoplay setting has changed, we can remove the listener - removeWifiConnectedListener() + stop() } } } - /** - * If autoplay is only enabled on WIFI, sets a WIFI listener to set them accordingly. Otherwise - * noop. - */ - fun maybeAddWifiConnectedListener() { - if (settings.getAutoplayUserSetting(default = AUTOPLAY_BLOCK_ALL) == AUTOPLAY_ALLOW_ON_WIFI) { - addWifiConnectedListener() - } - } - fun addWifiConnectedListener() { wifiConnectionMonitor.addOnWifiConnectedChangedListener(wifiConnectedListener) } @@ -62,15 +53,15 @@ class SitePermissionsWifiIntegration( wifiConnectionMonitor.removeOnWifiConnectedChangedListener(wifiConnectedListener) } - // Until https://bugzilla.mozilla.org/show_bug.cgi?id=1621825 is fixed, AUTOPLAY_ALLOW_ALL - // only works while WIFI is active, so we are not using AUTOPLAY_ALLOW_ON_WIFI (or this class). - // Once that is fixed, [start] and [maybeAddWifiConnectedListener] will need to be called on - // activity startup. override fun start() { - wifiConnectionMonitor.start() + if (settings.getAutoplayUserSetting() == AUTOPLAY_ALLOW_ON_WIFI) { + wifiConnectionMonitor.start() + addWifiConnectedListener() + } } override fun stop() { wifiConnectionMonitor.stop() + removeWifiConnectedListener() } } diff --git a/app/src/main/java/org/mozilla/fenix/wifi/WifiConnectionMonitor.kt b/app/src/main/java/org/mozilla/fenix/wifi/WifiConnectionMonitor.kt index 4db646e128aa..0818588109b3 100644 --- a/app/src/main/java/org/mozilla/fenix/wifi/WifiConnectionMonitor.kt +++ b/app/src/main/java/org/mozilla/fenix/wifi/WifiConnectionMonitor.kt @@ -10,6 +10,7 @@ import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest +import androidx.annotation.VisibleForTesting /** * Attaches itself to the [Application] and listens for WIFI available/not available events. This @@ -26,14 +27,21 @@ import android.net.NetworkRequest * ``` */ class WifiConnectionMonitor(app: Application) { - private val callbacks = mutableListOf<(Boolean) -> Unit>() - private val connectivityManager = app.getSystemService(Context.CONNECTIVITY_SERVICE) as + @VisibleForTesting + internal val callbacks = mutableListOf<(Boolean) -> Unit>() + + @VisibleForTesting + internal var connectivityManager = app.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - private var lastKnownStateWasAvailable: Boolean? = null - private var isRegistered = false + @VisibleForTesting + internal var lastKnownStateWasAvailable: Boolean? = null + + @VisibleForTesting + internal var isRegistered = false - private val frameworkListener = object : ConnectivityManager.NetworkCallback() { + @VisibleForTesting + internal val frameworkListener = object : ConnectivityManager.NetworkCallback() { override fun onLost(network: Network?) { notifyListeners(false) lastKnownStateWasAvailable = false @@ -86,6 +94,8 @@ class WifiConnectionMonitor(app: Application) { if (!isRegistered) return connectivityManager.unregisterNetworkCallback(frameworkListener) isRegistered = false + lastKnownStateWasAvailable = null + callbacks.clear() } /** diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentStoreTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentStoreTest.kt index 8b69a28c4b5a..26b1c1615946 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentStoreTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentStoreTest.kt @@ -97,7 +97,7 @@ class QuickSettingsFragmentStoreTest { every { permissions.localStorage } returns SitePermissions.Status.ALLOWED every { permissions.autoplayAudible } returns SitePermissions.Status.BLOCKED every { permissions.autoplayInaudible } returns SitePermissions.Status.BLOCKED - every { appSettings.getAutoplayUserSetting(any()) } returns AUTOPLAY_BLOCK_ALL + every { appSettings.getAutoplayUserSetting() } returns AUTOPLAY_BLOCK_ALL val state = QuickSettingsFragmentStore.createWebsitePermissionState( context, permissions, appSettings diff --git a/app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsWifiIntegrationTest.kt b/app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsWifiIntegrationTest.kt new file mode 100644 index 000000000000..b69940833522 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsWifiIntegrationTest.kt @@ -0,0 +1,140 @@ +/* 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.settings.sitepermissions + +import io.mockk.every +import io.mockk.verify +import io.mockk.mockk +import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED +import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.settings.PhoneFeature.AUTOPLAY_AUDIBLE +import org.mozilla.fenix.settings.PhoneFeature.AUTOPLAY_INAUDIBLE +import org.mozilla.fenix.utils.Settings +import org.mozilla.fenix.wifi.SitePermissionsWifiIntegration +import org.mozilla.fenix.wifi.WifiConnectionMonitor + +@RunWith(FenixRobolectricTestRunner::class) +class SitePermissionsWifiIntegrationTest { + lateinit var settings: Settings + lateinit var wifiIntegration: SitePermissionsWifiIntegration + lateinit var wifiConnectionMonitor: WifiConnectionMonitor + + @Before + fun setUp() { + settings = mockk(relaxed = true) + wifiConnectionMonitor = mockk(relaxed = true) + wifiIntegration = SitePermissionsWifiIntegration(settings, wifiConnectionMonitor) + } + + @Test + fun `start - SHOULD register wifiConnectionMonitor WHEN AUTOPLAY_ALLOW_ON_WIFI is set`() { + every { settings.getAutoplayUserSetting() } returns AUTOPLAY_ALLOW_ON_WIFI + + wifiIntegration.start() + + verify(exactly = 1) { + wifiConnectionMonitor.start() + wifiConnectionMonitor.addOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + } + + @Test + fun `start - SHOULD NOT register wifiConnectionMonitor WHEN AUTOPLAY_ALLOW_ON_WIFI is NOT set`() { + val autoPlaySettings = + listOf(AUTOPLAY_BLOCK_ALL, AUTOPLAY_BLOCK_AUDIBLE, AUTOPLAY_ALLOW_ALL) + + autoPlaySettings.forEach { autoPlaySetting -> + every { settings.getAutoplayUserSetting() } returns autoPlaySetting + + wifiIntegration.start() + + verify(exactly = 0) { + wifiConnectionMonitor.start() + wifiConnectionMonitor.addOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + } + } + + @Test + fun `stop - SHOULD unregister wifiConnectionMonitor`() { + wifiIntegration.stop() + + verify(exactly = 1) { + wifiConnectionMonitor.stop() + wifiConnectionMonitor.removeOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + } + + @Test + fun `removeWifiConnectedListener - SHOULD unregister wifiConnectionMonitor listeners`() { + wifiIntegration.removeWifiConnectedListener() + + verify(exactly = 1) { + wifiConnectionMonitor.removeOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + } + + @Test + fun `addWifiConnectedListener - SHOULD register wifiConnectionMonitor listeners`() { + wifiIntegration.addWifiConnectedListener() + + verify(exactly = 1) { + wifiConnectionMonitor.addOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + } + + @Test + fun `wifiConnectedListener true AND getAutoplayUserSetting equals to AUTOPLAY_ALLOW_ON_WIFI - SHOULD set autoplay settings to ALLOW`() { + every { settings.getAutoplayUserSetting() } returns AUTOPLAY_ALLOW_ON_WIFI + + wifiIntegration.wifiConnectedListener(true) + + verify(exactly = 1) { + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_AUDIBLE, ALLOWED) + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_INAUDIBLE, ALLOWED) + } + } + + @Test + fun `wifiConnectedListener false AND getAutoplayUserSetting equals to AUTOPLAY_ALLOW_ON_WIFI - SHOULD set autoplay settings to ALLOW`() { + every { settings.getAutoplayUserSetting() } returns AUTOPLAY_ALLOW_ON_WIFI + + wifiIntegration.wifiConnectedListener(false) + + verify(exactly = 1) { + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_AUDIBLE, BLOCKED) + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_INAUDIBLE, BLOCKED) + } + } + + @Test + fun `wifiConnectedListener true|false AND getAutoplayUserSetting different from AUTOPLAY_ALLOW_ON_WIFI - SHOULD stop`() { + val autoPlaySettings = listOf(AUTOPLAY_BLOCK_ALL, AUTOPLAY_BLOCK_AUDIBLE, AUTOPLAY_ALLOW_ALL) + + autoPlaySettings.forEach { autoPlaySetting -> + every { settings.getAutoplayUserSetting() } returns autoPlaySetting + + wifiIntegration.wifiConnectedListener(true) + wifiIntegration.wifiConnectedListener(false) + + verify(atLeast = 1) { + wifiConnectionMonitor.stop() + wifiConnectionMonitor.removeOnWifiConnectedChangedListener(wifiIntegration.wifiConnectedListener) + } + + verify(exactly = 0) { + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_AUDIBLE, ALLOWED) + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_INAUDIBLE, ALLOWED) + + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_AUDIBLE, BLOCKED) + settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_INAUDIBLE, BLOCKED) + } + } + } +} diff --git a/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt b/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt index 18ca08866dca..059fed573c4e 100644 --- a/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt +++ b/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt @@ -591,6 +591,21 @@ class SettingsTest { ) } + @Test + fun getSitePermissionsCustomSettingsRules_autoplay_defaults() { + val settings = Settings(testContext) + + assertEquals( + BLOCKED, + settings.getSitePermissionsCustomSettingsRules().autoplayAudible + ) + + assertEquals( + BLOCKED, + settings.getSitePermissionsCustomSettingsRules().autoplayInaudible + ) + } + @Test fun getSitePermissionsCustomSettingsRules_persistentStorage() { settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.PERSISTENT_STORAGE, ALLOWED) diff --git a/app/src/test/java/org/mozilla/fenix/wifi/WifiConnectionMonitorTest.kt b/app/src/test/java/org/mozilla/fenix/wifi/WifiConnectionMonitorTest.kt new file mode 100644 index 000000000000..72b11b304c44 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/wifi/WifiConnectionMonitorTest.kt @@ -0,0 +1,192 @@ +/* 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.wifi + +import android.app.Application +import android.net.ConnectivityManager +import io.mockk.mockk +import io.mockk.spyk +import io.mockk.verify +import mozilla.components.support.test.mock +import mozilla.components.support.test.robolectric.testContext +import org.junit.Assert.assertTrue +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner +import org.mozilla.fenix.utils.Settings + +@RunWith(FenixRobolectricTestRunner::class) +class WifiConnectionMonitorTest { + lateinit var settings: Settings + lateinit var connectivityManager: ConnectivityManager + lateinit var wifiConnectionMonitor: WifiConnectionMonitor + + @Before + fun setUp() { + settings = mockk(relaxed = true) + wifiConnectionMonitor = WifiConnectionMonitor(testContext as Application) + connectivityManager = spyk(wifiConnectionMonitor.connectivityManager) + wifiConnectionMonitor.connectivityManager = connectivityManager + } + + @Test + fun `start - SHOULD registerNetworkCallback`() { + val spyWifiConnectionMonitor = spyk(wifiConnectionMonitor) + + spyWifiConnectionMonitor.connectivityManager = connectivityManager + + spyWifiConnectionMonitor.start() + + verify(exactly = 1) { + connectivityManager.registerNetworkCallback( + any(), + wifiConnectionMonitor.frameworkListener + ) + } + + verify(exactly = 1) { + spyWifiConnectionMonitor.notifyListeners(false) + } + + assertTrue(spyWifiConnectionMonitor.isRegistered) + assertFalse(spyWifiConnectionMonitor.lastKnownStateWasAvailable!!) + } + + @Test + fun `multiple calls to start - SHOULD not registerNetworkCallback`() { + wifiConnectionMonitor.isRegistered = true + + wifiConnectionMonitor.start() + + verify(exactly = 0) { + connectivityManager.registerNetworkCallback( + any(), + wifiConnectionMonitor.frameworkListener + ) + } + } + + @Test + fun `stop - SHOULD unregisterNetworkCallback`() { + wifiConnectionMonitor.start() + wifiConnectionMonitor.stop() + + verify { + wifiConnectionMonitor.connectivityManager.unregisterNetworkCallback( + wifiConnectionMonitor.frameworkListener + ) + } + + assertFalse(wifiConnectionMonitor.isRegistered) + assertTrue(wifiConnectionMonitor.callbacks.isEmpty()) + assertNull(wifiConnectionMonitor.lastKnownStateWasAvailable) + } + + @Test + fun `multiple calls to stop - SHOULD do nothing`() { + wifiConnectionMonitor.isRegistered = false + + wifiConnectionMonitor.stop() + + verify(exactly = 0) { + connectivityManager.unregisterNetworkCallback(wifiConnectionMonitor.frameworkListener) + } + } + + @Test + fun `addOnWifiConnectedChangedListener - SHOULD register callback`() { + + wifiConnectionMonitor.addOnWifiConnectedChangedListener({}) + + assertFalse(wifiConnectionMonitor.callbacks.isEmpty()) + } + + @Test + fun `addOnWifiConnectedChangedListener AND lastKnownState different of NULL - SHOULD register callback and call it`() { + var wasNotified: Boolean? = null + wifiConnectionMonitor.lastKnownStateWasAvailable = false + + wifiConnectionMonitor.addOnWifiConnectedChangedListener { + wasNotified = it + } + + assertFalse(wasNotified!!) + assertFalse(wifiConnectionMonitor.callbacks.isEmpty()) + } + + @Test + fun `removeOnWifiConnectedChangedListener - SHOULD remove callback`() { + + assertTrue(wifiConnectionMonitor.callbacks.isEmpty()) + + val callback: (Boolean) -> Unit = {} + wifiConnectionMonitor.addOnWifiConnectedChangedListener(callback) + + assertFalse(wifiConnectionMonitor.callbacks.isEmpty()) + + wifiConnectionMonitor.removeOnWifiConnectedChangedListener(callback) + + assertTrue(wifiConnectionMonitor.callbacks.isEmpty()) + } + + @Test + fun `frameworkListener - SHOULD notify when connection lost`() { + var wasNotified: Boolean? = null + + val callback: (Boolean) -> Unit = { wasNotified = it } + + wifiConnectionMonitor.addOnWifiConnectedChangedListener(callback) + wifiConnectionMonitor.frameworkListener.onLost(mock()) + + assertFalse(wasNotified!!) + } + + @Test + fun `frameworkListener - SHOULD notify when connection available`() { + var wasNotified: Boolean? = null + + val callback: (Boolean) -> Unit = { wasNotified = it } + + wifiConnectionMonitor.addOnWifiConnectedChangedListener(callback) + wifiConnectionMonitor.frameworkListener.onAvailable(mock()) + + assertTrue(wasNotified!!) + } + + @Test + fun `notifyListeners - SHOULD notify listeners`() { + var wasNotified1: Boolean? = null + var wasNotified2: Boolean? = null + + val callback1: (Boolean) -> Unit = { wasNotified1 = it } + val callback2: (Boolean) -> Unit = { wasNotified2 = it } + + wifiConnectionMonitor.addOnWifiConnectedChangedListener(callback1) + wifiConnectionMonitor.addOnWifiConnectedChangedListener(callback2) + wifiConnectionMonitor.notifyListeners(true) + + assertTrue(wasNotified1!!) + assertTrue(wasNotified2!!) + } + + @Test + fun `notifyListeners - SHOULD NOT throw a ConcurrentModificationException`() { + repeat(100) { + + // Adding to callbacks. + wifiConnectionMonitor.addOnWifiConnectedChangedListener { + // Altering callbacks while looping. + if (wifiConnectionMonitor.callbacks.isNotEmpty()) + wifiConnectionMonitor.callbacks.removeFirst() + } + + // Looping over callbacks. + wifiConnectionMonitor.notifyListeners(true) + } + } +}