For #255: Toggle Media Autoplay
parent
a470b1c74c
commit
1aa4f5a519
|
@ -55,7 +55,8 @@ class Core(private val context: Context) {
|
|||
preferredColorScheme = getPreferredColorScheme(),
|
||||
automaticFontSizeAdjustment = context.settings.shouldUseAutoSize,
|
||||
fontInflationEnabled = context.settings.shouldUseAutoSize,
|
||||
suspendMediaWhenInactive = !FeatureFlags.mediaIntegration
|
||||
suspendMediaWhenInactive = !FeatureFlags.mediaIntegration,
|
||||
allowAutoplayMedia = context.settings.isAutoPlayEnabled
|
||||
)
|
||||
|
||||
GeckoEngine(context, defaultSettings, GeckoProvider.getOrCreateRuntime(context))
|
||||
|
|
|
@ -20,6 +20,7 @@ fun SitePermissions.toggle(featurePhone: PhoneFeature): SitePermissions {
|
|||
PhoneFeature.LOCATION -> copy(location = location.toggle())
|
||||
PhoneFeature.MICROPHONE -> copy(microphone = microphone.toggle())
|
||||
PhoneFeature.NOTIFICATION -> copy(notification = notification.toggle())
|
||||
PhoneFeature.AUTOPLAY -> copy() // not supported by GV or A-C yet
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,30 +21,51 @@ const val ID_CAMERA_PERMISSION = 0
|
|||
const val ID_LOCATION_PERMISSION = 1
|
||||
const val ID_MICROPHONE_PERMISSION = 2
|
||||
const val ID_NOTIFICATION_PERMISSION = 3
|
||||
const val ID_AUTOPLAY_PERMISSION = 4
|
||||
|
||||
enum class PhoneFeature(val id: Int, val androidPermissionsList: Array<String>) {
|
||||
CAMERA(ID_CAMERA_PERMISSION, arrayOf(CAMERA_PERMISSION)),
|
||||
LOCATION(ID_LOCATION_PERMISSION, arrayOf(ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION)),
|
||||
MICROPHONE(ID_MICROPHONE_PERMISSION, arrayOf(RECORD_AUDIO)),
|
||||
NOTIFICATION(ID_NOTIFICATION_PERMISSION, emptyArray());
|
||||
NOTIFICATION(ID_NOTIFICATION_PERMISSION, emptyArray()),
|
||||
AUTOPLAY(ID_AUTOPLAY_PERMISSION, emptyArray());
|
||||
|
||||
fun isAndroidPermissionGranted(context: Context): Boolean {
|
||||
return when (this) {
|
||||
CAMERA, LOCATION, MICROPHONE -> context.isPermissionGranted(androidPermissionsList.asIterable())
|
||||
NOTIFICATION -> true
|
||||
NOTIFICATION, AUTOPLAY -> true
|
||||
}
|
||||
}
|
||||
|
||||
fun getActionLabel(context: Context, sitePermissions: SitePermissions? = null, settings: Settings? = null): String {
|
||||
@StringRes val stringRes = when (getStatus(sitePermissions, settings)) {
|
||||
SitePermissions.Status.BLOCKED -> R.string.preference_option_phone_feature_blocked
|
||||
SitePermissions.Status.NO_DECISION -> R.string.preference_option_phone_feature_ask_to_allow
|
||||
SitePermissions.Status.ALLOWED -> R.string.preference_option_phone_feature_allowed
|
||||
}
|
||||
fun getActionLabel(
|
||||
context: Context,
|
||||
sitePermissions: SitePermissions? = null,
|
||||
settings: Settings? = null
|
||||
): String {
|
||||
@StringRes val stringRes =
|
||||
when (this) {
|
||||
AUTOPLAY -> {
|
||||
when (getStatus(sitePermissions, settings)) {
|
||||
SitePermissions.Status.BLOCKED -> R.string.preference_option_autoplay_blocked
|
||||
SitePermissions.Status.ALLOWED -> R.string.preference_option_autoplay_allowed
|
||||
else -> R.string.preference_option_autoplay_allowed
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
when (getStatus(sitePermissions, settings)) {
|
||||
SitePermissions.Status.BLOCKED -> R.string.preference_option_phone_feature_blocked
|
||||
SitePermissions.Status.NO_DECISION -> R.string.preference_option_phone_feature_ask_to_allow
|
||||
SitePermissions.Status.ALLOWED -> R.string.preference_option_phone_feature_allowed
|
||||
}
|
||||
}
|
||||
}
|
||||
return context.getString(stringRes)
|
||||
}
|
||||
|
||||
fun getStatus(sitePermissions: SitePermissions? = null, settings: Settings? = null): SitePermissions.Status {
|
||||
fun getStatus(
|
||||
sitePermissions: SitePermissions? = null,
|
||||
settings: Settings? = null
|
||||
): SitePermissions.Status {
|
||||
val status = getStatus(sitePermissions) ?: settings?.let(::getAction)?.toStatus()
|
||||
return requireNotNull(status)
|
||||
}
|
||||
|
@ -55,6 +76,7 @@ enum class PhoneFeature(val id: Int, val androidPermissionsList: Array<String>)
|
|||
LOCATION -> context.getString(R.string.preference_phone_feature_location)
|
||||
MICROPHONE -> context.getString(R.string.preference_phone_feature_microphone)
|
||||
NOTIFICATION -> context.getString(R.string.preference_phone_feature_notification)
|
||||
AUTOPLAY -> context.getString(R.string.preference_browser_feature_autoplay)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,11 +86,19 @@ enum class PhoneFeature(val id: Int, val androidPermissionsList: Array<String>)
|
|||
LOCATION -> context.getPreferenceKey(R.string.pref_key_phone_feature_location)
|
||||
MICROPHONE -> context.getPreferenceKey(R.string.pref_key_phone_feature_microphone)
|
||||
NOTIFICATION -> context.getPreferenceKey(R.string.pref_key_phone_feature_notification)
|
||||
AUTOPLAY -> context.getPreferenceKey(R.string.pref_key_browser_feature_autoplay)
|
||||
}
|
||||
}
|
||||
|
||||
fun getAction(settings: Settings): SitePermissionsRules.Action =
|
||||
settings.getSitePermissionsPhoneFeatureAction(this)
|
||||
settings.getSitePermissionsPhoneFeatureAction(this, getDefault())
|
||||
|
||||
fun getDefault(): SitePermissionsRules.Action {
|
||||
return when (this) {
|
||||
AUTOPLAY -> SitePermissionsRules.Action.BLOCKED
|
||||
else -> SitePermissionsRules.Action.ASK_TO_ALLOW
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStatus(sitePermissions: SitePermissions?): SitePermissions.Status? {
|
||||
sitePermissions ?: return null
|
||||
|
@ -77,12 +107,13 @@ enum class PhoneFeature(val id: Int, val androidPermissionsList: Array<String>)
|
|||
LOCATION -> sitePermissions.location
|
||||
MICROPHONE -> sitePermissions.microphone
|
||||
NOTIFICATION -> sitePermissions.notification
|
||||
AUTOPLAY -> SitePermissions.Status.NO_DECISION // No support from GV or A-C yet
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun findFeatureBy(permissions: Array<out String>): PhoneFeature? {
|
||||
return PhoneFeature.values().find { feature ->
|
||||
return values().find { feature ->
|
||||
feature.androidPermissionsList.any { permission ->
|
||||
permission == permissions.first()
|
||||
}
|
||||
|
|
|
@ -159,6 +159,7 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() {
|
|||
PhoneFeature.LOCATION -> sitePermissions.copy(location = status)
|
||||
PhoneFeature.MICROPHONE -> sitePermissions.copy(microphone = status)
|
||||
PhoneFeature.NOTIFICATION -> sitePermissions.copy(notification = status)
|
||||
PhoneFeature.AUTOPLAY -> sitePermissions.copy() // not supported by GV or A-C yet
|
||||
}
|
||||
lifecycleScope.launch(IO) {
|
||||
requireComponents.core.permissionStorage.updateSitePermissions(updatedSitePermissions)
|
||||
|
|
|
@ -25,6 +25,7 @@ import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
|||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.ASK_TO_ALLOW
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action.BLOCKED
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
|
@ -46,25 +47,38 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
|||
settings = requireContext().settings
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val rootView = inflater.inflate(R.layout.fragment_manage_site_permissions_feature_phone, container, false)
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val rootView = inflater.inflate(
|
||||
R.layout.fragment_manage_site_permissions_feature_phone,
|
||||
container,
|
||||
false
|
||||
)
|
||||
|
||||
initAskToAllowRadio(rootView)
|
||||
initBlockRadio(rootView)
|
||||
initFirstRadio(rootView)
|
||||
initSecondRadio(rootView)
|
||||
bindBlockedByAndroidContainer(rootView)
|
||||
|
||||
return rootView
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
initBlockedByAndroidView(phoneFeature, blockedByAndroidView)
|
||||
}
|
||||
|
||||
private fun initAskToAllowRadio(rootView: View) {
|
||||
private fun initFirstRadio(rootView: View) {
|
||||
val radio = rootView.findViewById<RadioButton>(R.id.ask_to_allow_radio)
|
||||
val askToAllowText = getString(R.string.preference_option_phone_feature_ask_to_allow)
|
||||
val askToAllowText = when (phoneFeature) {
|
||||
PhoneFeature.AUTOPLAY -> getString(R.string.preference_option_autoplay_blocked)
|
||||
else -> getString(R.string.preference_option_phone_feature_ask_to_allow)
|
||||
}
|
||||
val recommendedText = getString(R.string.phone_feature_recommended)
|
||||
val recommendedTextSize = resources.getDimensionPixelSize(R.dimen.phone_feature_label_recommended_text_size)
|
||||
val recommendedTextSize =
|
||||
resources.getDimensionPixelSize(R.dimen.phone_feature_label_recommended_text_size)
|
||||
val recommendedSpannable = SpannableString(recommendedText)
|
||||
|
||||
recommendedSpannable.setSpan(
|
||||
|
@ -86,10 +100,16 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
|||
append(recommendedSpannable)
|
||||
this
|
||||
}
|
||||
val expectedAction = if (phoneFeature == PhoneFeature.AUTOPLAY) BLOCKED else ASK_TO_ALLOW
|
||||
radio.setOnClickListener {
|
||||
saveActionInSettings(ASK_TO_ALLOW)
|
||||
if (phoneFeature == PhoneFeature.AUTOPLAY) {
|
||||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY, expectedAction)
|
||||
requireComponents.core.engine.settings.allowAutoplayMedia = false
|
||||
} else {
|
||||
saveActionInSettings(expectedAction)
|
||||
}
|
||||
}
|
||||
radio.restoreState(ASK_TO_ALLOW)
|
||||
radio.restoreState(expectedAction)
|
||||
}
|
||||
|
||||
private fun RadioButton.restoreState(action: SitePermissionsRules.Action) {
|
||||
|
@ -99,12 +119,22 @@ class SitePermissionsManagePhoneFeatureFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun initBlockRadio(rootView: View) {
|
||||
private fun initSecondRadio(rootView: View) {
|
||||
val radio = rootView.findViewById<RadioButton>(R.id.block_radio)
|
||||
radio.setOnClickListener {
|
||||
saveActionInSettings(BLOCKED)
|
||||
radio.text = when (phoneFeature) {
|
||||
PhoneFeature.AUTOPLAY -> getString(R.string.preference_option_autoplay_allowed)
|
||||
else -> getString(R.string.preference_option_phone_feature_blocked)
|
||||
}
|
||||
radio.restoreState(BLOCKED)
|
||||
val expectedAction = if (phoneFeature == PhoneFeature.AUTOPLAY) ASK_TO_ALLOW else BLOCKED
|
||||
radio.setOnClickListener {
|
||||
if (phoneFeature == PhoneFeature.AUTOPLAY) {
|
||||
settings.setSitePermissionsPhoneFeatureAction(PhoneFeature.AUTOPLAY, expectedAction)
|
||||
requireComponents.core.engine.settings.allowAutoplayMedia = true
|
||||
} else {
|
||||
saveActionInSettings(expectedAction)
|
||||
}
|
||||
}
|
||||
radio.restoreState(expectedAction)
|
||||
}
|
||||
|
||||
private fun bindBlockedByAndroidContainer(rootView: View) {
|
||||
|
|
|
@ -48,16 +48,22 @@ class QuickSettingsComponent(
|
|||
return if (sitePermissions == null) {
|
||||
val settings = context.settings
|
||||
val origin = requireNotNull(url.toUri().host)
|
||||
var location = settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.LOCATION).toStatus()
|
||||
var camera = settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.CAMERA).toStatus()
|
||||
var microphone = settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.MICROPHONE).toStatus()
|
||||
var notification = settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.NOTIFICATION).toStatus()
|
||||
var location =
|
||||
settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.LOCATION).toStatus()
|
||||
var camera =
|
||||
settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.CAMERA).toStatus()
|
||||
var microphone =
|
||||
settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.MICROPHONE).toStatus()
|
||||
var notification =
|
||||
settings.getSitePermissionsPhoneFeatureAction(PhoneFeature.NOTIFICATION).toStatus()
|
||||
|
||||
when (featurePhone) {
|
||||
PhoneFeature.CAMERA -> camera = camera.toggle()
|
||||
PhoneFeature.LOCATION -> location = location.toggle()
|
||||
PhoneFeature.MICROPHONE -> microphone = microphone.toggle()
|
||||
PhoneFeature.NOTIFICATION -> notification = notification.toggle()
|
||||
PhoneFeature.AUTOPLAY -> { // not supported by GV or A-C yet
|
||||
}
|
||||
}
|
||||
context.components.core.permissionStorage
|
||||
.addSitePermissionException(origin, location, notification, microphone, camera)
|
||||
|
@ -105,45 +111,58 @@ sealed class QuickSettingsChange : Change {
|
|||
val sitePermissions: SitePermissions?
|
||||
) : QuickSettingsChange()
|
||||
|
||||
data class PermissionGranted(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) :
|
||||
data class PermissionGranted(
|
||||
val phoneFeature: PhoneFeature,
|
||||
val sitePermissions: SitePermissions?
|
||||
) :
|
||||
QuickSettingsChange()
|
||||
|
||||
data class PromptRestarted(val sitePermissions: SitePermissions?) : QuickSettingsChange()
|
||||
data class Stored(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) : QuickSettingsChange()
|
||||
data class Stored(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) :
|
||||
QuickSettingsChange()
|
||||
}
|
||||
|
||||
class QuickSettingsViewModel(
|
||||
initialState: QuickSettingsState
|
||||
) : UIComponentViewModelBase<QuickSettingsState, QuickSettingsChange>(initialState, reducer) {
|
||||
companion object {
|
||||
val reducer: (QuickSettingsState, QuickSettingsChange) -> QuickSettingsState = { state, change ->
|
||||
when (change) {
|
||||
is QuickSettingsChange.Change -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.Normal(
|
||||
change.url,
|
||||
change.isSecured,
|
||||
change.isTrackingProtectionOn,
|
||||
change.sitePermissions
|
||||
val reducer: (QuickSettingsState, QuickSettingsChange) -> QuickSettingsState =
|
||||
{ state, change ->
|
||||
when (change) {
|
||||
is QuickSettingsChange.Change -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.Normal(
|
||||
change.url,
|
||||
change.isSecured,
|
||||
change.isTrackingProtectionOn,
|
||||
change.sitePermissions
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.PermissionGranted -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.ActionLabelUpdated(change.phoneFeature, change.sitePermissions)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.PromptRestarted -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.CheckPendingFeatureBlockedByAndroid(change.sitePermissions)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.Stored -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.ActionLabelUpdated(change.phoneFeature, change.sitePermissions)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.PermissionGranted -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.ActionLabelUpdated(
|
||||
change.phoneFeature,
|
||||
change.sitePermissions
|
||||
)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.PromptRestarted -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.CheckPendingFeatureBlockedByAndroid(
|
||||
change.sitePermissions
|
||||
)
|
||||
)
|
||||
}
|
||||
is QuickSettingsChange.Stored -> {
|
||||
state.copy(
|
||||
mode = QuickSettingsState.Mode.ActionLabelUpdated(
|
||||
change.phoneFeature,
|
||||
change.sitePermissions
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.content.SharedPreferences
|
|||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.annotation.VisibleForTesting.PRIVATE
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules
|
||||
import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action
|
||||
import mozilla.components.support.ktx.android.content.PreferencesHolder
|
||||
import mozilla.components.support.ktx.android.content.booleanPreference
|
||||
import mozilla.components.support.ktx.android.content.floatPreference
|
||||
|
@ -42,14 +43,14 @@ class Settings private constructor(
|
|||
private const val CFR_COUNT_CONDITION_FOCUS_INSTALLED = 1
|
||||
private const val CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED = 3
|
||||
|
||||
private fun actionToInt(action: SitePermissionsRules.Action) = when (action) {
|
||||
SitePermissionsRules.Action.BLOCKED -> BLOCKED_INT
|
||||
SitePermissionsRules.Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT
|
||||
private fun actionToInt(action: Action) = when (action) {
|
||||
Action.BLOCKED -> BLOCKED_INT
|
||||
Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT
|
||||
}
|
||||
|
||||
private fun intToAction(action: Int) = when (action) {
|
||||
BLOCKED_INT -> SitePermissionsRules.Action.BLOCKED
|
||||
ASK_TO_ALLOW_INT -> SitePermissionsRules.Action.ASK_TO_ALLOW
|
||||
BLOCKED_INT -> Action.BLOCKED
|
||||
ASK_TO_ALLOW_INT -> Action.ASK_TO_ALLOW
|
||||
else -> throw InvalidParameterException("$action is not a valid SitePermissionsRules.Action")
|
||||
}
|
||||
|
||||
|
@ -86,10 +87,10 @@ class Settings private constructor(
|
|||
|
||||
val isCrashReportingEnabled: Boolean
|
||||
get() = isCrashReportEnabledInBuild &&
|
||||
preferences.getBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
|
||||
true
|
||||
)
|
||||
preferences.getBoolean(
|
||||
appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
|
||||
true
|
||||
)
|
||||
|
||||
val isRemoteDebuggingEnabled by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_remote_debugging),
|
||||
|
@ -106,11 +107,15 @@ class Settings private constructor(
|
|||
default = true
|
||||
)
|
||||
|
||||
val isAutoPlayEnabled = getSitePermissionsPhoneFeatureAction(
|
||||
PhoneFeature.AUTOPLAY, Action.BLOCKED
|
||||
) != Action.BLOCKED
|
||||
|
||||
private var trackingProtectionOnboardingShownThisSession = false
|
||||
|
||||
val shouldShowTrackingProtectionOnboarding: Boolean
|
||||
get() = trackingProtectionOnboardingCount < trackingProtectionOnboardingMaximumCount &&
|
||||
!trackingProtectionOnboardingShownThisSession
|
||||
!trackingProtectionOnboardingShownThisSession
|
||||
|
||||
val shouldAutoBounceQuickActionSheet: Boolean
|
||||
get() = autoBounceQuickActionSheetCount < autoBounceMaximumCount
|
||||
|
@ -226,12 +231,15 @@ class Settings private constructor(
|
|||
).apply()
|
||||
}
|
||||
|
||||
fun getSitePermissionsPhoneFeatureAction(feature: PhoneFeature) =
|
||||
intToAction(preferences.getInt(feature.getPreferenceKey(appContext), ASK_TO_ALLOW_INT))
|
||||
fun getSitePermissionsPhoneFeatureAction(
|
||||
feature: PhoneFeature,
|
||||
default: Action = Action.ASK_TO_ALLOW
|
||||
) =
|
||||
intToAction(preferences.getInt(feature.getPreferenceKey(appContext), actionToInt(default)))
|
||||
|
||||
fun setSitePermissionsPhoneFeatureAction(
|
||||
feature: PhoneFeature,
|
||||
value: SitePermissionsRules.Action
|
||||
value: Action
|
||||
) {
|
||||
preferences.edit().putInt(feature.getPreferenceKey(appContext), actionToInt(value)).apply()
|
||||
}
|
||||
|
@ -295,7 +303,7 @@ class Settings private constructor(
|
|||
|
||||
val showCondition =
|
||||
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_INSTALLED && focusInstalled) ||
|
||||
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED && !focusInstalled)
|
||||
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED && !focusInstalled)
|
||||
|
||||
if (showCondition && !showedPrivateModeContextualFeatureRecommender) {
|
||||
showedPrivateModeContextualFeatureRecommender = true
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<vector android:autoMirrored="true" android:height="24dp"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M10.5,16.357l6.01,-3.492a1,1 0,0 0,0 -1.73L10.5,7.643A1,1 0,0 0,9 8.508v6.984a1,1 0,0 0,1.5 0.865zM15.33,2.569a1,1 0,1 0,-0.666 1.885A8.023,8.023 0,1 1,7 5.773L7,9.5a0.5,0.5 0,0 0,1 0v-6A0.5,0.5 0,0 0,7.5 3h-5a0.5,0.5 0,0 0,0 1h3.524a9.984,9.984 0,1 0,9.308 -1.431z"/>
|
||||
</vector>
|
|
@ -74,6 +74,7 @@
|
|||
<string name="pref_key_show_site_exceptions" translatable="false">pref_key_show_site_exceptions</string>
|
||||
<string name="pref_key_recommended_settings" translatable="false">pref_key_recommended_settings</string>
|
||||
<string name="pref_key_custom_settings" translatable="false">pref_key_custom_settings</string>
|
||||
<string name="pref_key_browser_feature_autoplay" translatable="false">pref_key_browser_feature_autoplay</string>
|
||||
<string name="pref_key_phone_feature_camera" translatable="false">pref_key_phone_feature_camera</string>
|
||||
<string name="pref_key_phone_feature_location" translatable="false">pref_key_phone_feature_location</string>
|
||||
<string name="pref_key_phone_feature_microphone" translatable="false">pref_key_phone_feature_microphone</string>
|
||||
|
|
|
@ -504,6 +504,8 @@
|
|||
<string name="clear_permission">Clear permission</string>
|
||||
<!-- Button label for clearing all the information on all sites-->
|
||||
<string name="clear_permissions_on_all_sites">Clear permissions on all sites</string>
|
||||
<!-- Preference for altering video and audio autoplay for all websites -->
|
||||
<string name="preference_browser_feature_autoplay">Autoplay</string>
|
||||
<!-- Preference for altering the camera access for all websites -->
|
||||
<string name="preference_phone_feature_camera">Camera</string>
|
||||
<!-- Preference for altering the microphone access for all websites -->
|
||||
|
@ -526,6 +528,10 @@
|
|||
<string name="tracking_protection_on">On</string>
|
||||
<!-- Summary of tracking protection preference if tracking protection is set to off -->
|
||||
<string name="tracking_protection_off">Off</string>
|
||||
<!-- Label that indicates video and audio autoplay is blocked -->
|
||||
<string name="preference_option_autoplay_blocked">Video and audio blocked</string>
|
||||
<!-- Label that indicates video and audio autoplay is allowed -->
|
||||
<string name="preference_option_autoplay_allowed">Video and audio allowed</string>
|
||||
|
||||
<!-- Collections -->
|
||||
<!-- Label to describe what collections are to a new user without any collections -->
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.preference.Preference
|
||||
android:icon="@drawable/ic_autoplay_enabled"
|
||||
android:key="@string/pref_key_browser_feature_autoplay"
|
||||
android:title="@string/preference_browser_feature_autoplay"
|
||||
android:summary="@string/preference_option_autoplay_blocked"/>
|
||||
|
||||
<androidx.preference.Preference
|
||||
android:icon="@drawable/ic_camera_enabled"
|
||||
android:key="@string/pref_key_phone_feature_camera"
|
||||
|
|
Loading…
Reference in New Issue