From b9bdc288cb84c61965f5cc86b5452796363dd773 Mon Sep 17 00:00:00 2001 From: Arturo Mejia Date: Wed, 13 Jan 2021 10:52:56 -0500 Subject: [PATCH] For issue: #16846 Add ui for controlling exceptions for auto play --- ...itePermissionsDetailsExceptionsFragment.kt | 63 +- ...onsManageExceptionsPhoneFeatureFragment.kt | 127 ++++- ...e_permissions_exceptions_feature_phone.xml | 16 + app/src/main/res/values/preference_keys.xml | 1 + ...issions_details_exceptions_preferences.xml | 6 + ...ermissionsDetailsExceptionsFragmentTest.kt | 106 ++++ ...anageExceptionsPhoneFeatureFragmentTest.kt | 538 ++++++++++++++++++ 7 files changed, 834 insertions(+), 23 deletions(-) create mode 100644 app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragmentTest.kt create mode 100644 app/src/test/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragmentTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt index 5b4d0aa99..399d46ca8 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt @@ -4,8 +4,10 @@ package org.mozilla.fenix.settings.sitepermissions +import android.content.Context import android.content.DialogInterface import android.os.Bundle +import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController @@ -19,6 +21,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions import org.mozilla.fenix.R import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.requireComponents +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.settings.PhoneFeature import org.mozilla.fenix.settings.PhoneFeature.CAMERA @@ -27,10 +30,15 @@ import org.mozilla.fenix.settings.PhoneFeature.MICROPHONE import org.mozilla.fenix.settings.PhoneFeature.NOTIFICATION import org.mozilla.fenix.settings.PhoneFeature.PERSISTENT_STORAGE import org.mozilla.fenix.settings.PhoneFeature.MEDIA_KEY_SYSTEM_ACCESS +import org.mozilla.fenix.settings.PhoneFeature.AUTOPLAY +import org.mozilla.fenix.settings.quicksettings.AutoplayValue import org.mozilla.fenix.settings.requirePreference +import org.mozilla.fenix.utils.Settings +@SuppressWarnings("TooManyFunctions") class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() { - private lateinit var sitePermissions: SitePermissions + @VisibleForTesting + internal lateinit var sitePermissions: SitePermissions override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -54,19 +62,22 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() { } } - private fun bindCategoryPhoneFeatures() { + @VisibleForTesting + internal fun bindCategoryPhoneFeatures() { initPhoneFeature(CAMERA) initPhoneFeature(LOCATION) initPhoneFeature(MICROPHONE) initPhoneFeature(NOTIFICATION) initPhoneFeature(PERSISTENT_STORAGE) initPhoneFeature(MEDIA_KEY_SYSTEM_ACCESS) + initAutoplayFeature() bindClearPermissionsButton() } - private fun initPhoneFeature(phoneFeature: PhoneFeature) { - val summary = phoneFeature.getActionLabel(requireContext(), sitePermissions) - val cameraPhoneFeatures = requirePreference(phoneFeature.getPreferenceId()) + @VisibleForTesting + internal fun initPhoneFeature(phoneFeature: PhoneFeature) { + val summary = phoneFeature.getActionLabel(provideContext(), sitePermissions) + val cameraPhoneFeatures = getPreference(phoneFeature) cameraPhoneFeatures.summary = summary cameraPhoneFeatures.onPreferenceClickListener = Preference.OnPreferenceClickListener { @@ -75,7 +86,44 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() { } } - private fun bindClearPermissionsButton() { + @VisibleForTesting + internal fun getPreference(phoneFeature: PhoneFeature): Preference = + requirePreference(phoneFeature.getPreferenceId()) + + @VisibleForTesting + internal fun provideContext(): Context = requireContext() + + @VisibleForTesting + internal fun provideSettings(): Settings = provideContext().settings() + + @VisibleForTesting + internal fun initAutoplayFeature() { + val phoneFeature = getPreference(AUTOPLAY) + phoneFeature.summary = getAutoplayLabel() + + phoneFeature.onPreferenceClickListener = Preference.OnPreferenceClickListener { + navigateToPhoneFeature(AUTOPLAY) + true + } + } + + @VisibleForTesting + internal fun getAutoplayLabel(): String { + val context = provideContext() + val settings = provideSettings() + val autoplayValues = AutoplayValue.values(context, settings, sitePermissions) + val selected = + autoplayValues.firstOrNull { it.isSelected() } ?: AutoplayValue.getFallbackValue( + context, + settings, + sitePermissions + ) + + return selected.label + } + + @VisibleForTesting + internal fun bindClearPermissionsButton() { val button: Preference = requirePreference(R.string.pref_key_exceptions_clear_site_permissions) button.onPreferenceClickListener = Preference.OnPreferenceClickListener { @@ -106,7 +154,8 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() { } } - private fun navigateToPhoneFeature(phoneFeature: PhoneFeature) { + @VisibleForTesting + internal fun navigateToPhoneFeature(phoneFeature: PhoneFeature) { val directions = SitePermissionsDetailsExceptionsFragmentDirections.actionSitePermissionsToExceptionsToManagePhoneFeature( phoneFeature = phoneFeature, diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt index 110fc2bda..dab4a76e8 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt @@ -14,7 +14,10 @@ import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.RadioButton +import androidx.annotation.IdRes +import androidx.annotation.VisibleForTesting import androidx.appcompat.app.AlertDialog +import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.navArgs @@ -27,8 +30,11 @@ import org.mozilla.fenix.R import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar +import org.mozilla.fenix.settings.PhoneFeature +import org.mozilla.fenix.settings.quicksettings.AutoplayValue import org.mozilla.fenix.settings.setStartCheckedIndicator import org.mozilla.fenix.settings.update +import org.mozilla.fenix.utils.Settings @SuppressWarnings("TooManyFunctions") class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { @@ -36,13 +42,14 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { private lateinit var radioAllow: RadioButton private lateinit var radioBlock: RadioButton private lateinit var blockedByAndroidView: View + @VisibleForTesting + internal lateinit var rootView: View private val args by navArgs() - val settings by lazy { requireContext().settings() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - showToolbar(args.phoneFeature.getLabel(requireContext())) + showToolbar(getFeature().getLabel(requireContext())) } override fun onCreateView( @@ -50,20 +57,62 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View? { - val rootView = + rootView = inflater.inflate(R.layout.fragment_manage_site_permissions_exceptions_feature_phone, container, false) - initAskToAllowRadio(rootView) - initBlockRadio(rootView) - bindBlockedByAndroidContainer(rootView) - initClearPermissionsButton(rootView) + if (getFeature() == PhoneFeature.AUTOPLAY) { + initAutoplay(getSitePermission()) + } else { + initNormalFeature() + } + bindBlockedByAndroidContainer() + initClearPermissionsButton() return rootView } + @VisibleForTesting + internal fun getFeature(): PhoneFeature = args.phoneFeature + + @VisibleForTesting + internal fun getSitePermission(): SitePermissions = args.sitePermissions + + @VisibleForTesting + internal fun getSettings(): Settings = requireContext().settings() + + fun initAutoplay(sitePermissions: SitePermissions? = null) { + val context = requireContext() + val autoplayValues = AutoplayValue.values(context, getSettings(), sitePermissions) + val allowAudioAndVideo = + requireNotNull(autoplayValues.find { it is AutoplayValue.AllowAll }) + val blockAll = requireNotNull(autoplayValues.find { it is AutoplayValue.BlockAll }) + val blockAudible = requireNotNull(autoplayValues.find { it is AutoplayValue.BlockAudible }) + + initAutoplayOption(R.id.ask_to_allow_radio, allowAudioAndVideo) + initAutoplayOption(R.id.block_radio, blockAll) + initAutoplayOption(R.id.optional_radio, blockAudible) + } + + fun initNormalFeature() { + initAskToAllowRadio(rootView) + initBlockRadio() + } + override fun onResume() { super.onResume() - initBlockedByAndroidView(args.phoneFeature, blockedByAndroidView) + initBlockedByAndroidView(getFeature(), blockedByAndroidView) + } + + @VisibleForTesting + internal fun initAutoplayOption(@IdRes viewId: Int, value: AutoplayValue) { + val radio = rootView.findViewById(viewId) + radio.isVisible = true + radio.text = value.label + + radio.setOnClickListener { + updatedSitePermissions(value) + } + radio.restoreState(value) } private fun initAskToAllowRadio(rootView: View) { @@ -79,13 +128,22 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { } private fun RadioButton.restoreState(status: SitePermissions.Status) { - if (args.phoneFeature.getStatus(args.sitePermissions) == status) { + val permissionsStatus = getFeature().getStatus(getSitePermission()) + if (permissionsStatus != SitePermissions.Status.NO_DECISION && permissionsStatus == status) { this.isChecked = true this.setStartCheckedIndicator() } } - private fun initBlockRadio(rootView: View) { + @VisibleForTesting + internal fun RadioButton.restoreState(autoplayValue: AutoplayValue) { + if (autoplayValue.isSelected()) { + this.isChecked = true + this.setStartCheckedIndicator() + } + } + + private fun initBlockRadio() { radioBlock = rootView.findViewById(R.id.block_radio) radioBlock.setOnClickListener { updatedSitePermissions(BLOCKED) @@ -93,7 +151,8 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { radioBlock.restoreState(BLOCKED) } - private fun initClearPermissionsButton(rootView: View) { + @VisibleForTesting + internal fun initClearPermissionsButton() { val button = rootView.findViewById