parent
5d8a9bb4be
commit
35a132d7ff
|
@ -3,6 +3,7 @@ package org.mozilla.fenix.ui
|
||||||
import okhttp3.mockwebserver.MockWebServer
|
import okhttp3.mockwebserver.MockWebServer
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Ignore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
|
||||||
|
@ -36,6 +37,7 @@ class LibraryMenuTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("Intermittently failing. See https://github.com/mozilla-mobile/fenix/issues/9287")
|
||||||
fun libraryMenuItemsTest() {
|
fun libraryMenuItemsTest() {
|
||||||
navigationToolbar {
|
navigationToolbar {
|
||||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||||
|
@ -50,6 +52,7 @@ class LibraryMenuTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Ignore("Intermittent failure. See https://github.com/mozilla-mobile/fenix/issues/9232")
|
||||||
fun backButtonTest() {
|
fun backButtonTest() {
|
||||||
navigationToolbar {
|
navigationToolbar {
|
||||||
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
}.enterURLAndEnterToBrowser(defaultWebPage.url) {
|
||||||
|
|
|
@ -391,6 +391,13 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
view = view
|
view = view
|
||||||
)
|
)
|
||||||
|
|
||||||
|
context.settings().setSitePermissionSettingListener(viewLifecycleOwner) {
|
||||||
|
// If the user connects to WIFI while on the BrowserFragment, this will update the
|
||||||
|
// SitePermissionsRules (specifically autoplay) accordingly
|
||||||
|
this.context?.let { assignSitePermissionsRules(it) }
|
||||||
|
}
|
||||||
|
assignSitePermissionsRules(context)
|
||||||
|
|
||||||
fullScreenFeature.set(
|
fullScreenFeature.set(
|
||||||
feature = FullScreenFeature(
|
feature = FullScreenFeature(
|
||||||
sessionManager,
|
sessionManager,
|
||||||
|
@ -541,8 +548,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
components.useCases.sessionUseCases.reload()
|
components.useCases.sessionUseCases.reload()
|
||||||
}
|
}
|
||||||
hideToolbar()
|
hideToolbar()
|
||||||
|
|
||||||
assignSitePermissionsRules()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
|
@ -673,8 +678,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
||||||
/**
|
/**
|
||||||
* Updates the site permissions rules based on user settings.
|
* Updates the site permissions rules based on user settings.
|
||||||
*/
|
*/
|
||||||
private fun assignSitePermissionsRules() {
|
private fun assignSitePermissionsRules(context: Context) {
|
||||||
val settings = requireContext().settings()
|
val settings = context.settings()
|
||||||
|
|
||||||
val rules: SitePermissionsRules = settings.getSitePermissionsCustomSettingsRules()
|
val rules: SitePermissionsRules = settings.getSitePermissionsCustomSettingsRules()
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.components
|
package org.mozilla.fenix.components
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
@ -17,8 +18,11 @@ import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
|
import mozilla.components.lib.publicsuffixlist.PublicSuffixList
|
||||||
import mozilla.components.support.migration.state.MigrationStore
|
import mozilla.components.support.migration.state.MigrationStore
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.test.Mockable
|
import org.mozilla.fenix.test.Mockable
|
||||||
import org.mozilla.fenix.utils.ClipboardHandler
|
import org.mozilla.fenix.utils.ClipboardHandler
|
||||||
|
import org.mozilla.fenix.wifi.WifiConnectionMonitor
|
||||||
|
import org.mozilla.fenix.wifi.WifiIntegration
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
private const val DAY_IN_MINUTES = 24 * 60L
|
private const val DAY_IN_MINUTES = 24 * 60L
|
||||||
|
@ -96,4 +100,12 @@ class Components(private val context: Context) {
|
||||||
val migrationStore by lazy { MigrationStore() }
|
val migrationStore by lazy { MigrationStore() }
|
||||||
val performance by lazy { PerformanceComponent() }
|
val performance by lazy { PerformanceComponent() }
|
||||||
val push by lazy { Push(context, analytics.crashReporter) }
|
val push by lazy { Push(context, analytics.crashReporter) }
|
||||||
|
val wifiIntegration by lazy {
|
||||||
|
WifiIntegration(
|
||||||
|
settings = context.settings(),
|
||||||
|
wifiConnectionMonitor = WifiConnectionMonitor(
|
||||||
|
context as Application
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
import mozilla.components.support.ktx.android.content.isPermissionGranted
|
import mozilla.components.support.ktx.android.content.isPermissionGranted
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
|
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_ALLOW_ALL
|
||||||
|
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_ALLOW_ON_WIFI
|
||||||
|
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL
|
||||||
|
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_AUDIBLE
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
import android.Manifest.permission.CAMERA as CAMERA_PERMISSION
|
import android.Manifest.permission.CAMERA as CAMERA_PERMISSION
|
||||||
|
|
||||||
|
@ -49,11 +53,13 @@ enum class PhoneFeature(val id: Int, val androidPermissionsList: Array<String>)
|
||||||
when (isAndroidPermissionGranted(context)) {
|
when (isAndroidPermissionGranted(context)) {
|
||||||
false -> R.string.phone_feature_blocked_by_android
|
false -> R.string.phone_feature_blocked_by_android
|
||||||
else -> when (this) {
|
else -> when (this) {
|
||||||
AUTOPLAY_AUDIBLE, AUTOPLAY_INAUDIBLE -> {
|
AUTOPLAY_AUDIBLE -> {
|
||||||
when (getStatus(sitePermissions, settings)) {
|
when (settings?.getAutoplayUserSetting(default = AUTOPLAY_BLOCK_ALL) ?: AUTOPLAY_BLOCK_ALL) {
|
||||||
SitePermissions.Status.BLOCKED -> R.string.preference_option_autoplay_blocked
|
AUTOPLAY_ALLOW_ALL -> R.string.preference_option_autoplay_allowed2
|
||||||
SitePermissions.Status.ALLOWED -> R.string.preference_option_autoplay_allowed
|
AUTOPLAY_ALLOW_ON_WIFI -> R.string.preference_option_autoplay_allowed_wifi_only2
|
||||||
else -> R.string.preference_option_autoplay_allowed
|
AUTOPLAY_BLOCK_AUDIBLE -> R.string.preference_option_autoplay_block_audio2
|
||||||
|
AUTOPLAY_BLOCK_ALL -> R.string.preference_option_autoplay_blocked3
|
||||||
|
else -> R.string.preference_option_autoplay_blocked3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|
|
@ -61,10 +61,17 @@ class SitePermissionsFragment : PreferenceFragmentCompat() {
|
||||||
val settings = context.settings()
|
val settings = context.settings()
|
||||||
|
|
||||||
val summary = phoneFeature.getActionLabel(context, settings = 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 preferenceKey = phoneFeature.getPreferenceKey(context)
|
val preferenceKey = phoneFeature.getPreferenceKey(context)
|
||||||
|
|
||||||
val cameraPhoneFeatures: Preference = requireNotNull(findPreference(preferenceKey))
|
val cameraPhoneFeatures: Preference = requireNotNull(findPreference(preferenceKey))
|
||||||
cameraPhoneFeatures.summary = summary
|
cameraPhoneFeatures.summary = autoplaySummary ?: summary
|
||||||
|
|
||||||
cameraPhoneFeatures.onPreferenceClickListener = OnPreferenceClickListener {
|
cameraPhoneFeatures.onPreferenceClickListener = OnPreferenceClickListener {
|
||||||
navigateToPhoneFeature(phoneFeature)
|
navigateToPhoneFeature(phoneFeature)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.settings.sitepermissions
|
package org.mozilla.fenix.settings.sitepermissions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -20,18 +21,30 @@ import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.RadioButton
|
import android.widget.RadioButton
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import kotlinx.android.synthetic.main.fragment_manage_site_permissions_feature_phone.view.ask_to_allow_radio
|
||||||
|
import kotlinx.android.synthetic.main.fragment_manage_site_permissions_feature_phone.view.block_radio
|
||||||
|
import kotlinx.android.synthetic.main.fragment_manage_site_permissions_feature_phone.view.fourth_radio
|
||||||
|
import kotlinx.android.synthetic.main.fragment_manage_site_permissions_feature_phone.view.third_radio
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ALLOWED
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
|
import org.mozilla.fenix.settings.PhoneFeature.AUTOPLAY_AUDIBLE
|
||||||
|
import org.mozilla.fenix.settings.PhoneFeature.AUTOPLAY_INAUDIBLE
|
||||||
import org.mozilla.fenix.settings.initBlockedByAndroidView
|
import org.mozilla.fenix.settings.initBlockedByAndroidView
|
||||||
import org.mozilla.fenix.settings.setStartCheckedIndicator
|
import org.mozilla.fenix.settings.setStartCheckedIndicator
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
const val AUTOPLAY_BLOCK_ALL = 0
|
||||||
|
const val AUTOPLAY_BLOCK_AUDIBLE = 1
|
||||||
|
const val AUTOPLAY_ALLOW_ON_WIFI = 2
|
||||||
|
const val AUTOPLAY_ALLOW_ALL = 3
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions")
|
@SuppressWarnings("TooManyFunctions")
|
||||||
class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
||||||
private lateinit var phoneFeature: PhoneFeature
|
private lateinit var phoneFeature: PhoneFeature
|
||||||
|
@ -62,6 +75,8 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
||||||
|
|
||||||
initFirstRadio(rootView)
|
initFirstRadio(rootView)
|
||||||
initSecondRadio(rootView)
|
initSecondRadio(rootView)
|
||||||
|
initThirdRadio(rootView)
|
||||||
|
initFourthRadio(rootView)
|
||||||
bindBlockedByAndroidContainer(rootView)
|
bindBlockedByAndroidContainer(rootView)
|
||||||
|
|
||||||
return rootView
|
return rootView
|
||||||
|
@ -73,66 +88,133 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initFirstRadio(rootView: View) {
|
private fun initFirstRadio(rootView: View) {
|
||||||
val radio = rootView.findViewById<RadioButton>(R.id.ask_to_allow_radio)
|
with(rootView.ask_to_allow_radio) {
|
||||||
val askToAllowText = when (phoneFeature) {
|
if (phoneFeature == AUTOPLAY_AUDIBLE) {
|
||||||
PhoneFeature.AUTOPLAY_AUDIBLE ->
|
// Disabled because GV does not allow this setting. TODO Reenable after
|
||||||
getString(R.string.preference_option_autoplay_blocked)
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1621825 is fixed
|
||||||
else -> getString(R.string.preference_option_phone_feature_ask_to_allow)
|
// text = getString(R.string.preference_option_autoplay_allowed2)
|
||||||
|
// setOnClickListener {
|
||||||
|
// saveActionInSettings(it.context, AUTOPLAY_ALLOW_ALL)
|
||||||
|
// }
|
||||||
|
// restoreState(AUTOPLAY_ALLOW_ALL)
|
||||||
|
visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
text = getCombinedLabel(
|
||||||
|
getString(R.string.preference_option_phone_feature_ask_to_allow),
|
||||||
|
getString(R.string.phone_feature_recommended)
|
||||||
|
)
|
||||||
|
setOnClickListener {
|
||||||
|
saveActionInSettings(ASK_TO_ALLOW)
|
||||||
|
}
|
||||||
|
restoreState(ASK_TO_ALLOW)
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val recommendedText = getString(R.string.phone_feature_recommended)
|
|
||||||
val recommendedTextSize =
|
|
||||||
resources.getDimensionPixelSize(R.dimen.phone_feature_label_recommended_text_size)
|
|
||||||
val recommendedSpannable = SpannableString(recommendedText)
|
|
||||||
|
|
||||||
recommendedSpannable.setSpan(
|
|
||||||
ForegroundColorSpan(Color.GRAY),
|
|
||||||
0,
|
|
||||||
recommendedSpannable.length,
|
|
||||||
SPAN_EXCLUSIVE_INCLUSIVE
|
|
||||||
)
|
|
||||||
|
|
||||||
recommendedSpannable.setSpan(
|
|
||||||
AbsoluteSizeSpan(recommendedTextSize), 0,
|
|
||||||
recommendedSpannable.length,
|
|
||||||
SPAN_EXCLUSIVE_INCLUSIVE
|
|
||||||
)
|
|
||||||
|
|
||||||
radio.text = with(SpannableStringBuilder()) {
|
|
||||||
append(askToAllowText)
|
|
||||||
append("\n")
|
|
||||||
append(recommendedSpannable)
|
|
||||||
this
|
|
||||||
}
|
|
||||||
val expectedAction = if (phoneFeature == PhoneFeature.AUTOPLAY_AUDIBLE) BLOCKED else ASK_TO_ALLOW
|
|
||||||
radio.setOnClickListener {
|
|
||||||
saveActionInSettings(expectedAction)
|
|
||||||
}
|
|
||||||
radio.restoreState(expectedAction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun RadioButton.restoreState(action: SitePermissionsRules.Action) {
|
private fun initSecondRadio(rootView: View) {
|
||||||
if (phoneFeature.getAction(settings) == action) {
|
with(rootView.block_radio) {
|
||||||
|
if (phoneFeature == AUTOPLAY_AUDIBLE) {
|
||||||
|
text = getCombinedLabel(
|
||||||
|
getString(R.string.preference_option_autoplay_allowed_wifi_only2),
|
||||||
|
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(it.context, AUTOPLAY_ALLOW_ALL)
|
||||||
|
}
|
||||||
|
// 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
|
||||||
|
restoreState(AUTOPLAY_ALLOW_ALL)
|
||||||
|
} else {
|
||||||
|
text = getString(R.string.preference_option_phone_feature_blocked)
|
||||||
|
setOnClickListener {
|
||||||
|
saveActionInSettings(BLOCKED)
|
||||||
|
}
|
||||||
|
restoreState(BLOCKED)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initThirdRadio(rootView: View) {
|
||||||
|
with(rootView.third_radio) {
|
||||||
|
if (phoneFeature == AUTOPLAY_AUDIBLE) {
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
text = getString(R.string.preference_option_autoplay_block_audio2)
|
||||||
|
setOnClickListener {
|
||||||
|
saveActionInSettings(it.context, AUTOPLAY_BLOCK_AUDIBLE)
|
||||||
|
}
|
||||||
|
restoreState(AUTOPLAY_BLOCK_AUDIBLE)
|
||||||
|
} else {
|
||||||
|
visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initFourthRadio(rootView: View) {
|
||||||
|
with(rootView.fourth_radio) {
|
||||||
|
if (phoneFeature == AUTOPLAY_AUDIBLE) {
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
text = getCombinedLabel(
|
||||||
|
getString(R.string.preference_option_autoplay_blocked3),
|
||||||
|
getString(R.string.phone_feature_recommended)
|
||||||
|
)
|
||||||
|
setOnClickListener {
|
||||||
|
saveActionInSettings(it.context, AUTOPLAY_BLOCK_ALL)
|
||||||
|
}
|
||||||
|
restoreState(AUTOPLAY_BLOCK_ALL)
|
||||||
|
} else {
|
||||||
|
visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun RadioButton.restoreState(buttonAction: SitePermissionsRules.Action) {
|
||||||
|
if (phoneFeature.getAction(settings) == buttonAction) {
|
||||||
this.isChecked = true
|
this.isChecked = true
|
||||||
this.setStartCheckedIndicator()
|
this.setStartCheckedIndicator()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initSecondRadio(rootView: View) {
|
private fun RadioButton.restoreState(buttonAutoplaySetting: Int) {
|
||||||
val radio = rootView.findViewById<RadioButton>(R.id.block_radio)
|
if (settings.getAutoplayUserSetting(AUTOPLAY_BLOCK_ALL) == buttonAutoplaySetting) {
|
||||||
radio.text = when (phoneFeature) {
|
this.isChecked = true
|
||||||
PhoneFeature.AUTOPLAY_AUDIBLE, PhoneFeature.AUTOPLAY_INAUDIBLE ->
|
this.setStartCheckedIndicator()
|
||||||
getString(R.string.preference_option_autoplay_allowed)
|
|
||||||
else -> getString(R.string.preference_option_phone_feature_blocked)
|
|
||||||
}
|
}
|
||||||
val expectedAction = if (phoneFeature == PhoneFeature.AUTOPLAY_AUDIBLE) ALLOWED else BLOCKED
|
}
|
||||||
radio.setOnClickListener {
|
|
||||||
saveActionInSettings(expectedAction)
|
private fun saveActionInSettings(action: SitePermissionsRules.Action) {
|
||||||
|
settings.setSitePermissionsPhoneFeatureAction(phoneFeature, action)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the user selected autoplay setting.
|
||||||
|
*
|
||||||
|
* See [Settings.setAutoplayUserSetting] kdoc for an explanation of why this cannot follow the
|
||||||
|
* same code path as other permissions.
|
||||||
|
*/
|
||||||
|
private fun saveActionInSettings(context: Context, autoplaySetting: Int) {
|
||||||
|
settings.setAutoplayUserSetting(autoplaySetting)
|
||||||
|
val (audible, inaudible) = when (autoplaySetting) {
|
||||||
|
AUTOPLAY_ALLOW_ALL -> ALLOWED to ALLOWED
|
||||||
|
AUTOPLAY_ALLOW_ON_WIFI -> {
|
||||||
|
context.components.wifiIntegration.addWifiConnectedListener()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
AUTOPLAY_BLOCK_AUDIBLE -> BLOCKED to ALLOWED
|
||||||
|
AUTOPLAY_BLOCK_ALL -> BLOCKED to BLOCKED
|
||||||
|
else -> return
|
||||||
}
|
}
|
||||||
radio.restoreState(expectedAction)
|
context.components.wifiIntegration.removeWifiConnectedListener()
|
||||||
|
settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_AUDIBLE, audible)
|
||||||
|
settings.setSitePermissionsPhoneFeatureAction(AUTOPLAY_INAUDIBLE, inaudible)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindBlockedByAndroidContainer(rootView: View) {
|
private fun bindBlockedByAndroidContainer(rootView: View) {
|
||||||
blockedByAndroidView = rootView.findViewById<View>(R.id.permissions_blocked_container)
|
blockedByAndroidView = rootView.findViewById(R.id.permissions_blocked_container)
|
||||||
initSettingsButton(blockedByAndroidView)
|
initSettingsButton(blockedByAndroidView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +240,32 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveActionInSettings(action: SitePermissionsRules.Action) {
|
/**
|
||||||
settings.setSitePermissionsPhoneFeatureAction(phoneFeature, action)
|
* Returns a [CharSequence] that arranges and styles [mainText], a line break, and then [subText]
|
||||||
|
*/
|
||||||
|
private fun getCombinedLabel(mainText: CharSequence, subText: CharSequence): CharSequence {
|
||||||
|
val subTextSize =
|
||||||
|
resources.getDimensionPixelSize(R.dimen.phone_feature_label_recommended_text_size)
|
||||||
|
val recommendedSpannable = SpannableString(subText)
|
||||||
|
|
||||||
|
recommendedSpannable.setSpan(
|
||||||
|
ForegroundColorSpan(Color.GRAY),
|
||||||
|
0,
|
||||||
|
recommendedSpannable.length,
|
||||||
|
SPAN_EXCLUSIVE_INCLUSIVE
|
||||||
|
)
|
||||||
|
|
||||||
|
recommendedSpannable.setSpan(
|
||||||
|
AbsoluteSizeSpan(subTextSize), 0,
|
||||||
|
recommendedSpannable.length,
|
||||||
|
SPAN_EXCLUSIVE_INCLUSIVE
|
||||||
|
)
|
||||||
|
|
||||||
|
return with(SpannableStringBuilder()) {
|
||||||
|
append(mainText)
|
||||||
|
append("\n")
|
||||||
|
append(recommendedSpannable)
|
||||||
|
this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.mozilla.fenix.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functional interface for listening to when wifi is/is not connected.
|
||||||
|
*
|
||||||
|
* This is not a () -> Boolean so that method parameters can be more clearly typed.
|
||||||
|
*
|
||||||
|
* This file is in Java because of the SAM conversion problem in Kotlin.
|
||||||
|
* See https://youtrack.jetbrains.com/issue/KT-7770.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OnWifiChanged {
|
||||||
|
void invoke(boolean Connected);
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import android.content.SharedPreferences
|
||||||
import android.view.accessibility.AccessibilityManager
|
import android.view.accessibility.AccessibilityManager
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction
|
import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction
|
||||||
|
@ -29,8 +30,11 @@ import org.mozilla.fenix.components.metrics.MozillaProductDetector
|
||||||
import org.mozilla.fenix.ext.getPreferenceKey
|
import org.mozilla.fenix.ext.getPreferenceKey
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
|
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
|
||||||
|
import org.mozilla.fenix.settings.registerOnSharedPreferenceChangeListener
|
||||||
import java.security.InvalidParameterException
|
import java.security.InvalidParameterException
|
||||||
|
|
||||||
|
private const val AUTOPLAY_USER_SETTING = "AUTOPLAY_USER_SETTING"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple wrapper for SharedPreferences that makes reading preference a little bit easier.
|
* A simple wrapper for SharedPreferences that makes reading preference a little bit easier.
|
||||||
*/
|
*/
|
||||||
|
@ -175,10 +179,6 @@ class Settings private constructor(
|
||||||
default = true
|
default = true
|
||||||
)
|
)
|
||||||
|
|
||||||
val isAutoPlayEnabled = getSitePermissionsPhoneFeatureAction(
|
|
||||||
PhoneFeature.AUTOPLAY_AUDIBLE, Action.BLOCKED
|
|
||||||
) != Action.BLOCKED
|
|
||||||
|
|
||||||
private var trackingProtectionOnboardingShownThisSession = false
|
private var trackingProtectionOnboardingShownThisSession = false
|
||||||
var isOverrideTPPopupsForPerformanceTest = false
|
var isOverrideTPPopupsForPerformanceTest = false
|
||||||
|
|
||||||
|
@ -452,6 +452,34 @@ class Settings private constructor(
|
||||||
) =
|
) =
|
||||||
preferences.getInt(feature.getPreferenceKey(appContext), default.toInt()).toAction()
|
preferences.getInt(feature.getPreferenceKey(appContext), default.toInt()).toAction()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the user selected autoplay setting.
|
||||||
|
*
|
||||||
|
* Under the hood, autoplay is represented by two settings, [AUTOPLAY_AUDIBLE] and
|
||||||
|
* [AUTOPLAY_INAUDIBLE]. The user selection cannot be inferred from the combination of these
|
||||||
|
* settings because, while on [AUTOPLAY_ALLOW_ON_WIFI], they will be indistinguishable from
|
||||||
|
* either [AUTOPLAY_ALLOW_ALL] or [AUTOPLAY_BLOCK_ALL]. Because of this, we are forced to save
|
||||||
|
* the user selected setting as well.
|
||||||
|
*/
|
||||||
|
fun setAutoplayUserSetting(
|
||||||
|
autoplaySetting: Int
|
||||||
|
) {
|
||||||
|
preferences.edit().putInt(AUTOPLAY_USER_SETTING, autoplaySetting).apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user selected autoplay setting.
|
||||||
|
*
|
||||||
|
* Under the hood, autoplay is represented by two settings, [AUTOPLAY_AUDIBLE] and
|
||||||
|
* [AUTOPLAY_INAUDIBLE]. The user selection cannot be inferred from the combination of these
|
||||||
|
* settings because, while on [AUTOPLAY_ALLOW_ON_WIFI], they will be indistinguishable from
|
||||||
|
* 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 getSitePermissionsPhoneFeatureAutoplayAction(
|
fun getSitePermissionsPhoneFeatureAutoplayAction(
|
||||||
feature: PhoneFeature,
|
feature: PhoneFeature,
|
||||||
default: AutoplayAction = AutoplayAction.BLOCKED
|
default: AutoplayAction = AutoplayAction.BLOCKED
|
||||||
|
@ -471,11 +499,25 @@ class Settings private constructor(
|
||||||
location = getSitePermissionsPhoneFeatureAction(PhoneFeature.LOCATION),
|
location = getSitePermissionsPhoneFeatureAction(PhoneFeature.LOCATION),
|
||||||
camera = getSitePermissionsPhoneFeatureAction(PhoneFeature.CAMERA),
|
camera = getSitePermissionsPhoneFeatureAction(PhoneFeature.CAMERA),
|
||||||
autoplayAudible = getSitePermissionsPhoneFeatureAutoplayAction(PhoneFeature.AUTOPLAY_AUDIBLE),
|
autoplayAudible = getSitePermissionsPhoneFeatureAutoplayAction(PhoneFeature.AUTOPLAY_AUDIBLE),
|
||||||
// TODO autoplayInaudible will be hardcoded until additional options are added in #8017
|
autoplayInaudible = getSitePermissionsPhoneFeatureAutoplayAction(PhoneFeature.AUTOPLAY_INAUDIBLE)
|
||||||
autoplayInaudible = AutoplayAction.ALLOWED
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setSitePermissionSettingListener(lifecycleOwner: LifecycleOwner, listener: () -> Unit) {
|
||||||
|
val sitePermissionKeys = listOf(
|
||||||
|
PhoneFeature.NOTIFICATION,
|
||||||
|
PhoneFeature.MICROPHONE,
|
||||||
|
PhoneFeature.LOCATION,
|
||||||
|
PhoneFeature.CAMERA,
|
||||||
|
PhoneFeature.AUTOPLAY_AUDIBLE,
|
||||||
|
PhoneFeature.AUTOPLAY_INAUDIBLE
|
||||||
|
).map { it.getPreferenceKey(appContext) }
|
||||||
|
|
||||||
|
preferences.registerOnSharedPreferenceChangeListener(lifecycleOwner) { _, key ->
|
||||||
|
if (key in sitePermissionKeys) listener.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var shouldPromptToSaveLogins by booleanPreference(
|
var shouldPromptToSaveLogins by booleanPreference(
|
||||||
appContext.getPreferenceKey(R.string.pref_key_save_logins),
|
appContext.getPreferenceKey(R.string.pref_key_save_logins),
|
||||||
default = true
|
default = true
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
/* 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.content.Context
|
||||||
|
import android.net.ConnectivityManager
|
||||||
|
import android.net.Network
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.NetworkRequest
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches itself to the [Application] and listens for WIFI available/not available events. This
|
||||||
|
* allows calling code to set simpler listeners.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ```kotlin
|
||||||
|
* app.components.wifiConnectionListener.addOnWifiConnectedChangedListener { isConnected ->
|
||||||
|
* if (isConnected) {
|
||||||
|
* downloadThing()
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* app.components.wifiConnectionListener.start()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
class WifiConnectionMonitor(app: Application) {
|
||||||
|
private val callbacks = mutableSetOf<(Boolean) -> Unit>()
|
||||||
|
private val connectivityManager = app.getSystemService(Context.CONNECTIVITY_SERVICE) as
|
||||||
|
ConnectivityManager
|
||||||
|
|
||||||
|
private var lastKnownStateWasAvailable: Boolean? = null
|
||||||
|
private var isRegistered = false
|
||||||
|
|
||||||
|
private val frameworkListener = object : ConnectivityManager.NetworkCallback() {
|
||||||
|
override fun onLost(network: Network?) {
|
||||||
|
callbacks.forEach { it(false) }
|
||||||
|
lastKnownStateWasAvailable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAvailable(network: Network?) {
|
||||||
|
callbacks.forEach { it(true) }
|
||||||
|
lastKnownStateWasAvailable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the [WifiConnectionMonitor] to the application. After this has been called, callbacks
|
||||||
|
* added via [addOnWifiConnectedChangedListener] will be called until either the app exits, or
|
||||||
|
* [stop] is called.
|
||||||
|
*
|
||||||
|
* Any existing callbacks will be called with the current state when this is called.
|
||||||
|
*/
|
||||||
|
fun start() {
|
||||||
|
// Framework code throws if a listener is registered twice without unregistering.
|
||||||
|
if (isRegistered) return
|
||||||
|
val request = NetworkRequest.Builder()
|
||||||
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
// AFAICT, the framework does not send an event when a new NetworkCallback is registered
|
||||||
|
// while the WIFI is not connected, so we push this manually. If the WIFI is on, it will send
|
||||||
|
// a follow up event shortly
|
||||||
|
val noCallbacksReceivedYet = lastKnownStateWasAvailable == null
|
||||||
|
if (noCallbacksReceivedYet) {
|
||||||
|
lastKnownStateWasAvailable = false
|
||||||
|
callbacks.forEach { it(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
connectivityManager.registerNetworkCallback(request, frameworkListener)
|
||||||
|
isRegistered = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detatches the [WifiConnectionMonitor] from the app. No callbacks added via
|
||||||
|
* [addOnWifiConnectedChangedListener] will be called after this has been called.
|
||||||
|
*/
|
||||||
|
fun stop() {
|
||||||
|
// Framework code will throw if an unregistered listener attempts to unregister.
|
||||||
|
if (!isRegistered) return
|
||||||
|
connectivityManager.unregisterNetworkCallback(frameworkListener)
|
||||||
|
isRegistered = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds [onWifiChanged] to a list of listeners that will be called whenever WIFI connects or
|
||||||
|
* disconnects.
|
||||||
|
*
|
||||||
|
* If [onWifiChanged] is successfully added (i.e., it is a new listener), it will be immediately
|
||||||
|
* called with the last known state.
|
||||||
|
*/
|
||||||
|
fun addOnWifiConnectedChangedListener(onWifiChanged: (Boolean) -> Unit) {
|
||||||
|
val lastKnownState = lastKnownStateWasAvailable
|
||||||
|
if (callbacks.add(onWifiChanged) && lastKnownState != null) {
|
||||||
|
onWifiChanged(lastKnownState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes [onWifiChanged] from the list of listeners to be called whenever WIFI connects or
|
||||||
|
* disconnects.
|
||||||
|
*/
|
||||||
|
fun removeOnWifiConnectedChangedListener(onWifiChanged: (Boolean) -> Unit) {
|
||||||
|
callbacks.remove(onWifiChanged)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* 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 mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||||
|
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
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles implementation details of only setting up a WIFI connectivity listener if the current
|
||||||
|
* user settings require it.
|
||||||
|
*/
|
||||||
|
class WifiIntegration(private val settings: Settings, private val wifiConnectionMonitor: WifiConnectionMonitor) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds listener for autplay setting [AUTOPLAY_ALLOW_ON_WIFI]. Sets all autoplay to allowed when
|
||||||
|
* WIFI is connected, blocked otherwise.
|
||||||
|
*/
|
||||||
|
private val wifiConnectedListener: ((Boolean) -> Unit) by lazy {
|
||||||
|
{ connected: Boolean ->
|
||||||
|
val setting =
|
||||||
|
if (connected) SitePermissionsRules.Action.ALLOWED else SitePermissionsRules.Action.BLOCKED
|
||||||
|
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_AUDIBLE, setting)
|
||||||
|
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_INAUDIBLE, setting)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeWifiConnectedListener() {
|
||||||
|
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.
|
||||||
|
fun start() { wifiConnectionMonitor.start() }
|
||||||
|
|
||||||
|
fun stop() { wifiConnectionMonitor.stop() }
|
||||||
|
}
|
|
@ -3,11 +3,11 @@
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- 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/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_height="fill_parent" >
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
@ -21,31 +21,59 @@
|
||||||
android:id="@+id/ask_to_allow_radio"
|
android:id="@+id/ask_to_allow_radio"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/preference_option_phone_feature_ask_to_allow"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:button="@null"
|
android:button="@null"
|
||||||
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
|
||||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
|
||||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||||
android:paddingBottom="@dimen/radio_button_preference_vertical"/>
|
android:paddingBottom="@dimen/radio_button_preference_vertical"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
||||||
|
tools:text="@string/preference_option_phone_feature_ask_to_allow" />
|
||||||
|
|
||||||
<RadioButton
|
<RadioButton
|
||||||
android:id="@+id/block_radio"
|
android:id="@+id/block_radio"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/radio_button_preference_height"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/preference_option_phone_feature_blocked"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
|
||||||
android:background="?android:attr/selectableItemBackground"
|
android:background="?android:attr/selectableItemBackground"
|
||||||
android:button="@null"
|
android:button="@null"
|
||||||
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
|
||||||
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||||
android:paddingTop="@dimen/radio_button_preference_vertical"
|
|
||||||
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||||
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||||
android:paddingBottom="@dimen/radio_button_preference_vertical"/>
|
android:paddingBottom="@dimen/radio_button_preference_vertical"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle"
|
||||||
|
tools:text="@string/preference_option_phone_feature_blocked" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/third_radio"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:button="@null"
|
||||||
|
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||||
|
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||||
|
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingBottom="@dimen/radio_button_preference_vertical"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/fourth_radio"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:button="@null"
|
||||||
|
android:drawablePadding="@dimen/radio_button_preference_drawable_padding"
|
||||||
|
android:paddingStart="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingTop="@dimen/radio_button_preference_vertical"
|
||||||
|
android:paddingEnd="@dimen/radio_button_preference_horizontal"
|
||||||
|
android:paddingBottom="@dimen/radio_button_preference_vertical"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||||
|
app:drawableStartCompat="?android:attr/listChoiceIndicatorSingle" />
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
<include layout="@layout/component_permissions_blocked_by_android"/>
|
<include layout="@layout/component_permissions_blocked_by_android"/>
|
||||||
|
|
|
@ -596,18 +596,16 @@
|
||||||
<string name="tracking_protection_on">On</string>
|
<string name="tracking_protection_on">On</string>
|
||||||
<!-- Summary of tracking protection preference if tracking protection is set to off -->
|
<!-- Summary of tracking protection preference if tracking protection is set to off -->
|
||||||
<string name="tracking_protection_off">Off</string>
|
<string name="tracking_protection_off">Off</string>
|
||||||
<!-- DEPRECATED: Label that indicates video and audio autoplay is blocked -->
|
|
||||||
<string name="preference_option_autoplay_blocked">Video and audio blocked</string>
|
|
||||||
<!-- DEPRECATED: Label that indicates video and audio autoplay is allowed -->
|
|
||||||
<string name="preference_option_autoplay_allowed">Video and audio allowed</string>
|
|
||||||
<!-- Label that indicates that all video and audio autoplay is allowed -->
|
<!-- Label that indicates that all video and audio autoplay is allowed -->
|
||||||
<string name="preference_option_autoplay_allowed2">Allow audio and video</string>
|
<string name="preference_option_autoplay_allowed2">Allow audio and video</string>
|
||||||
<!-- Label that indicates that video and audio autoplay is only allowed over WIFI -->
|
<!-- Label that indicates that video and audio autoplay is only allowed over Wi-Fi -->
|
||||||
<string name="preference_option_autoplay_allowed_wifi_only">Allow audio and video on Wi-Fi only</string>
|
<string name="preference_option_autoplay_allowed_wifi_only2">Block audio and video on cellular data only</string>
|
||||||
|
<!-- Subtext that explains 'autoplay on Wi-Fi only' option -->
|
||||||
|
<string name="preference_option_autoplay_allowed_wifi_subtext">Audio and video will play on Wi-Fi</string>
|
||||||
<!-- Label that indicates that video autoplay is allowed, but audio autoplay is blocked -->
|
<!-- Label that indicates that video autoplay is allowed, but audio autoplay is blocked -->
|
||||||
<string name="preference_option_autoplay_block_audio">Block audio</string>
|
<string name="preference_option_autoplay_block_audio2">Block audio only</string>
|
||||||
<!-- Label that indicates that all video and audio autoplay is blocked -->
|
<!-- Label that indicates that all video and audio autoplay is blocked -->
|
||||||
<string name="preference_option_autoplay_blocked2">Block video and audio</string>
|
<string name="preference_option_autoplay_blocked3">Block audio and video</string>
|
||||||
<!-- Summary of delete browsing data on quit preference if it is set to on -->
|
<!-- Summary of delete browsing data on quit preference if it is set to on -->
|
||||||
<string name="delete_browsing_data_quit_on">On</string>
|
<string name="delete_browsing_data_quit_on">On</string>
|
||||||
<!-- Summary of delete browsing data on quit preference if it is set to off -->
|
<!-- Summary of delete browsing data on quit preference if it is set to off -->
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
android:icon="@drawable/ic_autoplay_enabled"
|
android:icon="@drawable/ic_autoplay_enabled"
|
||||||
android:key="@string/pref_key_browser_feature_autoplay_audible"
|
android:key="@string/pref_key_browser_feature_autoplay_audible"
|
||||||
android:title="@string/preference_browser_feature_autoplay"
|
android:title="@string/preference_browser_feature_autoplay"
|
||||||
android:summary="@string/preference_option_autoplay_blocked"/>
|
android:summary="@string/preference_option_autoplay_blocked3"/>
|
||||||
|
|
||||||
<androidx.preference.Preference
|
<androidx.preference.Preference
|
||||||
android:icon="@drawable/ic_camera_enabled"
|
android:icon="@drawable/ic_camera_enabled"
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.TestApplication
|
import org.mozilla.fenix.TestApplication
|
||||||
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getInsecureWebsiteUiValues
|
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getInsecureWebsiteUiValues
|
||||||
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getPermissionStatus
|
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getPermissionStatus
|
||||||
|
@ -33,6 +34,7 @@ import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Compa
|
||||||
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.toWebsitePermission
|
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.toWebsitePermission
|
||||||
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
||||||
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeVisible
|
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeVisible
|
||||||
|
import org.mozilla.fenix.settings.sitepermissions.AUTOPLAY_BLOCK_ALL
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
import org.robolectric.RobolectricTestRunner
|
import org.robolectric.RobolectricTestRunner
|
||||||
import org.robolectric.annotation.Config
|
import org.robolectric.annotation.Config
|
||||||
|
@ -120,6 +122,7 @@ class QuickSettingsFragmentStoreTest {
|
||||||
every { permissions.location } returns SitePermissions.Status.ALLOWED
|
every { permissions.location } returns SitePermissions.Status.ALLOWED
|
||||||
every { permissions.autoplayAudible } returns SitePermissions.Status.BLOCKED
|
every { permissions.autoplayAudible } returns SitePermissions.Status.BLOCKED
|
||||||
every { permissions.autoplayInaudible } returns SitePermissions.Status.BLOCKED
|
every { permissions.autoplayInaudible } returns SitePermissions.Status.BLOCKED
|
||||||
|
every { appSettings.getAutoplayUserSetting(any()) } returns AUTOPLAY_BLOCK_ALL
|
||||||
|
|
||||||
val state = QuickSettingsFragmentStore.createWebsitePermissionState(
|
val state = QuickSettingsFragmentStore.createWebsitePermissionState(
|
||||||
context, permissions, appSettings
|
context, permissions, appSettings
|
||||||
|
|
|
@ -497,14 +497,7 @@ class SettingsTest {
|
||||||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_INAUDIBLE, ALLOWED)
|
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_INAUDIBLE, ALLOWED)
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
defaultPermissions(),
|
defaultPermissions().copy(autoplayInaudible = ALLOWED),
|
||||||
settings.getSitePermissionsCustomSettingsRules()
|
|
||||||
)
|
|
||||||
|
|
||||||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY_INAUDIBLE, BLOCKED)
|
|
||||||
|
|
||||||
assertEquals(
|
|
||||||
defaultPermissions(),
|
|
||||||
settings.getSitePermissionsCustomSettingsRules()
|
settings.getSitePermissionsCustomSettingsRules()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -524,5 +517,5 @@ private fun defaultPermissions() = SitePermissionsRules(
|
||||||
microphone = ASK_TO_ALLOW,
|
microphone = ASK_TO_ALLOW,
|
||||||
notification = ASK_TO_ALLOW,
|
notification = ASK_TO_ALLOW,
|
||||||
autoplayAudible = AutoplayAction.BLOCKED,
|
autoplayAudible = AutoplayAction.BLOCKED,
|
||||||
autoplayInaudible = AutoplayAction.ALLOWED
|
autoplayInaudible = AutoplayAction.BLOCKED
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue