[fenix] Merge branch 'master' into manage_site_permissions_exceptions

pull/600/head
Colin Lee 6 years ago committed by GitHub
commit 40459d6ac4

@ -31,6 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #176 - Added a swipe to delete gesture on home screen - #176 - Added a swipe to delete gesture on home screen
- #1539 - Added bookmarks multi-select related features - #1539 - Added bookmarks multi-select related features
- #1603 - Remove deprecated success path for Firefox Accounts login - #1603 - Remove deprecated success path for Firefox Accounts login
- #619 - Sets toolbar behavior based on accessibility and if session is loading
- #1571 - Added a snackbar for undoing bookmark deletion
- #1079 - Managing site permissions exceptions - #1079 - Managing site permissions exceptions
### Changed ### Changed

@ -82,6 +82,7 @@ import kotlin.coroutines.CoroutineContext
class BrowserFragment : Fragment(), BackHandler, CoroutineScope { class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
private lateinit var toolbarComponent: ToolbarComponent private lateinit var toolbarComponent: ToolbarComponent
private var sessionObserver: Session.Observer? = null
private val sessionFeature = ViewBoundFeatureWrapper<SessionFeature>() private val sessionFeature = ViewBoundFeatureWrapper<SessionFeature>()
private val contextMenuFeature = ViewBoundFeatureWrapper<ContextMenuFeature>() private val contextMenuFeature = ViewBoundFeatureWrapper<ContextMenuFeature>()
private val downloadsFeature = ViewBoundFeatureWrapper<DownloadsFeature>() private val downloadsFeature = ViewBoundFeatureWrapper<DownloadsFeature>()
@ -130,14 +131,6 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
) )
(layoutParams as CoordinatorLayout.LayoutParams).apply { (layoutParams as CoordinatorLayout.LayoutParams).apply {
// Stop toolbar from collapsing if TalkBack is enabled
val accessibilityManager = context
?.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (!accessibilityManager.isTouchExplorationEnabled) {
behavior = BrowserToolbarBottomBehavior(view.context, null)
}
gravity = Gravity.BOTTOM gravity = Gravity.BOTTOM
height = (resources.displayMetrics.density * TOOLBAR_HEIGHT).toInt() height = (resources.displayMetrics.density * TOOLBAR_HEIGHT).toInt()
} }
@ -289,6 +282,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
@Suppress("ComplexMethod") @Suppress("ComplexMethod")
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
sessionObserver = subscribeToSession()
getAutoDisposeObservable<SearchAction>() getAutoDisposeObservable<SearchAction>()
.subscribe { .subscribe {
when (it) { when (it) {
@ -370,6 +364,13 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
assignSitePermissionsRules() assignSitePermissionsRules()
} }
override fun onStop() {
super.onStop()
sessionObserver?.let {
requireComponents.core.sessionManager.selectedSession?.unregister(it)
}
}
override fun onBackPressed(): Boolean { override fun onBackPressed(): Boolean {
return when { return when {
findInPageIntegration.onBackPressed() -> true findInPageIntegration.onBackPressed() -> true
@ -520,6 +521,34 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
clipBoard.primaryClip = ClipData.newRawUri("Uri", uri) clipBoard.primaryClip = ClipData.newRawUri("Uri", uri)
} }
private fun subscribeToSession(): Session.Observer {
val observer = object : Session.Observer {
override fun onLoadingStateChanged(session: Session, loading: Boolean) {
super.onLoadingStateChanged(session, loading)
setToolbarBehavior(loading)
}
}
requireComponents.core.sessionManager.selectedSession?.register(observer)
return observer
}
private fun setToolbarBehavior(loading: Boolean) {
val toolbarView = toolbarComponent.uiView.view
(toolbarView.layoutParams as CoordinatorLayout.LayoutParams).apply {
// Stop toolbar from collapsing if TalkBack is enabled or page is loading
val accessibilityManager = context
?.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (!accessibilityManager.isTouchExplorationEnabled) {
if (!loading) {
behavior = BrowserToolbarBottomBehavior(context, null)
} else {
(behavior as? BrowserToolbarBottomBehavior)?.forceExpand(toolbarView)
behavior = null
}
}
}
}
companion object { companion object {
private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1 private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2 private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2

@ -44,6 +44,10 @@ class BrowserToolbarBottomBehavior(
duration = SNAP_ANIMATION_DURATION duration = SNAP_ANIMATION_DURATION
} }
fun forceExpand(view: View) {
animateSnap(view, SnapDirection.UP)
}
override fun onStartNestedScroll( override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout, coordinatorLayout: CoordinatorLayout,
child: BrowserToolbar, child: BrowserToolbar,

@ -5,10 +5,8 @@
package org.mozilla.fenix.components package org.mozilla.fenix.components
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async import kotlinx.coroutines.async
@ -60,13 +58,11 @@ class Core(private val context: Context) {
* configuration (see build variants). * configuration (see build variants).
*/ */
val engine: Engine by lazy { val engine: Engine by lazy {
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val defaultSettings = DefaultSettings( val defaultSettings = DefaultSettings(
requestInterceptor = AppRequestInterceptor(context), requestInterceptor = AppRequestInterceptor(context),
remoteDebuggingEnabled = Settings.getInstance(context).isRemoteDebuggingEnabled, remoteDebuggingEnabled = Settings.getInstance(context).isRemoteDebuggingEnabled,
testingModeEnabled = false, testingModeEnabled = false,
trackingProtectionPolicy = createTrackingProtectionPolicy(prefs), trackingProtectionPolicy = createTrackingProtectionPolicy(),
historyTrackingDelegate = HistoryDelegate(historyStorage) historyTrackingDelegate = HistoryDelegate(historyStorage)
) )
@ -133,17 +129,14 @@ class Core(private val context: Context) {
/** /**
* Constructs a [TrackingProtectionPolicy] based on current preferences. * Constructs a [TrackingProtectionPolicy] based on current preferences.
* *
* @param prefs the shared preferences to use when reading tracking
* protection settings.
* @param normalMode whether or not tracking protection should be enabled * @param normalMode whether or not tracking protection should be enabled
* in normal browsing mode, defaults to the current preference value. * in normal browsing mode, defaults to the current preference value.
* @param privateMode whether or not tracking protection should be enabled * @param privateMode whether or not tracking protection should be enabled
* in private browsing mode, default to the current preference value. * in private browsing mode, default to the current preference value.
* @return the constructed tracking protection policy based on preferences. * @return the constructed tracking protection policy based on preferences.
*/ */
fun createTrackingProtectionPolicy( private fun createTrackingProtectionPolicy(
prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context), normalMode: Boolean = Settings.getInstance(context).shouldUseTrackingProtection,
normalMode: Boolean = true,
privateMode: Boolean = true privateMode: Boolean = true
): TrackingProtectionPolicy { ): TrackingProtectionPolicy {
val trackingProtectionPolicy = TrackingProtectionPolicy.select( val trackingProtectionPolicy = TrackingProtectionPolicy.select(
@ -160,6 +153,11 @@ class Core(private val context: Context) {
} }
} }
fun updateTrackingProtection(newValue: Boolean) {
engine.settings.trackingProtectionPolicy =
createTrackingProtectionPolicy(normalMode = newValue)
}
/** /**
* Sets Preferred Color scheme based on Dark/Light Theme Settings or Current Configuration * Sets Preferred Color scheme based on Dark/Light Theme Settings or Current Configuration
*/ */

@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ext
import android.view.View
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.mozilla.fenix.components.FenixSnackbar
fun CoroutineScope.allowUndo(view: View, message: String, undoActionTitle: String, operation: suspend () -> Unit) {
val undoJob = launch(Dispatchers.IO) {
delay(UNDO_DELAY)
operation.invoke()
}
FenixSnackbar.make(view, FenixSnackbar.LENGTH_LONG)
.setText(message)
.setAction(undoActionTitle) {
undoJob.cancel()
}.show()
}
internal const val UNDO_DELAY = 3000L

@ -6,6 +6,9 @@
package org.mozilla.fenix.ext package org.mozilla.fenix.ext
import java.net.MalformedURLException
import java.net.URL
/** /**
* Replaces the keys with the values with the map provided. * Replaces the keys with the values with the map provided.
*/ */
@ -14,3 +17,12 @@ fun String.replace(pairs: Map<String, String>): String {
pairs.forEach { (l, r) -> result = result.replace(l, r) } pairs.forEach { (l, r) -> result = result.replace(l, r) }
return result return result
} }
fun String?.urlToHost(): String {
return try {
val url = URL(this)
url.host
} catch (e: MalformedURLException) {
""
}
}

@ -31,7 +31,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot import mozilla.appservices.places.BookmarkRoot
import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNode
@ -45,9 +44,11 @@ import org.mozilla.fenix.BrowsingModeManager
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.allowUndo
import org.mozilla.fenix.ext.getColorFromAttr import org.mozilla.fenix.ext.getColorFromAttr
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.share import org.mozilla.fenix.ext.share
import org.mozilla.fenix.ext.urlToHost
import org.mozilla.fenix.mvi.ActionBusFactory import org.mozilla.fenix.mvi.ActionBusFactory
import org.mozilla.fenix.mvi.getAutoDisposeObservable import org.mozilla.fenix.mvi.getAutoDisposeObservable
import org.mozilla.fenix.mvi.getManagedEmitter import org.mozilla.fenix.mvi.getManagedEmitter
@ -216,7 +217,10 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
} }
} }
is BookmarkAction.Delete -> { is BookmarkAction.Delete -> {
launch(IO) { allowUndo(
view!!, getString(R.string.bookmark_deletion_snackbar_message, it.item.url.urlToHost()),
getString(R.string.bookmark_undo_deletion)
) {
requireComponents.core.bookmarksStorage.deleteNode(it.item.guid) requireComponents.core.bookmarksStorage.deleteNode(it.item.guid)
refreshBookmarks() refreshBookmarks()
} }
@ -277,16 +281,13 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
true true
} }
R.id.delete_bookmarks_multi_select -> { R.id.delete_bookmarks_multi_select -> {
val deleteJob = launch(IO) { allowUndo(
delay(bookmarkDeletionDelay) view!!, getString(R.string.bookmark_deletion_multiple_snackbar_message),
getString(R.string.bookmark_undo_deletion)
) {
deleteSelectedBookmarks() deleteSelectedBookmarks()
refreshBookmarks() refreshBookmarks()
} }
FenixSnackbar.make(view!!, FenixSnackbar.LENGTH_LONG)
.setText(getString(R.string.bookmark_deletion_multiple_snackbar_message))
.setAction(getString(R.string.bookmark_undo_deletion)) {
deleteJob.cancel()
}.show()
true true
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)
@ -344,8 +345,4 @@ class BookmarkFragment : Fragment(), CoroutineScope, BackHandler, AccountObserve
val uri = Uri.parse(url) val uri = Uri.parse(url)
clipBoard.primaryClip = ClipData.newRawUri("Uri", uri) clipBoard.primaryClip = ClipData.newRawUri("Uri", uri)
} }
companion object {
private const val bookmarkDeletionDelay = 3000L
}
} }

@ -47,6 +47,7 @@ import org.mozilla.fenix.R.string.pref_key_theme
import org.mozilla.fenix.R.string.pref_key_account import org.mozilla.fenix.R.string.pref_key_account
import org.mozilla.fenix.R.string.pref_key_account_category import org.mozilla.fenix.R.string.pref_key_account_category
import org.mozilla.fenix.R.string.pref_key_search_engine_settings import org.mozilla.fenix.R.string.pref_key_search_engine_settings
import org.mozilla.fenix.R.string.pref_key_tracking_protection_settings
import org.mozilla.fenix.utils.ItsNotBrokenSnack import org.mozilla.fenix.utils.ItsNotBrokenSnack
@SuppressWarnings("TooManyFunctions") @SuppressWarnings("TooManyFunctions")
@ -99,6 +100,9 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse
resources.getString(pref_key_search_engine_settings) -> { resources.getString(pref_key_search_engine_settings) -> {
navigateToSearchEngineSettings() navigateToSearchEngineSettings()
} }
resources.getString(pref_key_tracking_protection_settings) -> {
navigateToTrackingProtectionSettings()
}
resources.getString(pref_key_site_permissions) -> { resources.getString(pref_key_site_permissions) -> {
navigateToSitePermissions() navigateToSitePermissions()
} }
@ -221,6 +225,11 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse
Navigation.findNavController(view!!).navigate(directions) Navigation.findNavController(view!!).navigate(directions)
} }
private fun navigateToTrackingProtectionSettings() {
val directions = SettingsFragmentDirections.actionSettingsFragmentToTrackingProtectionFragment()
Navigation.findNavController(view!!).navigate(directions)
}
private fun navigateToThemeSettings() { private fun navigateToThemeSettings() {
val directions = SettingsFragmentDirections.actionSettingsFragmentToThemeFragment() val directions = SettingsFragmentDirections.actionSettingsFragmentToThemeFragment()
Navigation.findNavController(view!!).navigate(directions) Navigation.findNavController(view!!).navigate(directions)

@ -0,0 +1,51 @@
/* 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
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.requireComponents
class TrackingProtectionFragment : PreferenceFragmentCompat() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(activity as AppCompatActivity).title = getString(R.string.preferences_tracking_protection)
(activity as AppCompatActivity).supportActionBar?.show()
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.tracking_protection_preferences, rootKey)
}
override fun onResume() {
super.onResume()
// Tracking Protection Switch
val trackingProtectionKey =
context!!.getPreferenceKey(R.string.pref_key_tracking_protection)
val preferenceTP = findPreference<Preference>(trackingProtectionKey)
preferenceTP?.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
requireComponents.core.updateTrackingProtection(newValue as Boolean)
true
}
// Exceptions
val exceptions =
context!!.getPreferenceKey(R.string.pref_key_tracking_protection_exceptions)
val preferenceExceptions = findPreference<Preference>(exceptions)
preferenceExceptions?.onPreferenceClickListener = getClickListenerForSignOut()
}
private fun getClickListenerForSignOut(): Preference.OnPreferenceClickListener {
return Preference.OnPreferenceClickListener {
// TODO go to Exceptions Fragment
true
}
}
}

@ -79,6 +79,12 @@ class Settings private constructor(context: Context) {
false false
) )
val shouldUseTrackingProtection: Boolean
get() = preferences.getBoolean(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection),
true
)
val shouldUseAutoBatteryTheme: Boolean val shouldUseAutoBatteryTheme: Boolean
get() = preferences.getBoolean( get() = preferences.getBoolean(
appContext.getPreferenceKey(R.string.pref_key_auto_battery_theme), appContext.getPreferenceKey(R.string.pref_key_auto_battery_theme),

@ -0,0 +1,14 @@
<?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 xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/primaryTextColor"
android:fillType="evenOdd"
android:pathData="M20,6.047C19.9965,4.9927 19.2276,4.0971 18.186,3.934L12,2.912L5.816,3.933C4.7741,4.0968 4.0049,4.9923 4,6.047C4,7.729 4.012,9.954 4.111,11.005C4.411,14.205 5.033,15.96 6.56,17.954C7.8759,19.6329 9.7831,20.746 11.892,21.066L12,21.078L12.107,21.066C14.2159,20.746 16.1231,19.6329 17.439,17.954C18.967,15.96 19.584,14.206 19.888,11.005L19.888,11.005C19.993,9.891 20,7.421 20,6.047ZM17.9,10.815C17.63,13.659 17.152,15.043 15.855,16.739C14.8897,17.9499 13.5217,18.7739 12,19.061C10.4792,18.7737 9.1122,17.9496 8.148,16.739C6.848,15.039 6.372,13.659 6.103,10.816C6.031,10.059 6,8.367 6,6.054C6.0036,5.9768 6.0631,5.9138 6.14,5.906L12,4.939L17.861,5.907C17.9376,5.9135 17.9972,5.9762 18,6.053C18.005,8.328 17.968,10.064 17.9,10.815ZM8,7.626C8.015,9.593 8.066,10.365 8.091,10.626C8.347,13.326 8.785,14.282 9.733,15.526C10.3122,16.2484 11.1061,16.7677 12,17.009L12,6.967L8,7.626Z" />
</vector>

@ -232,6 +232,9 @@
<action <action
android:id="@+id/action_settingsFragment_to_themeFragment" android:id="@+id/action_settingsFragment_to_themeFragment"
app:destination="@id/themeFragment" /> app:destination="@id/themeFragment" />
<action
android:id="@+id/action_settingsFragment_to_trackingProtectionFragment"
app:destination="@id/trackingProtectionFragment" />
</fragment> </fragment>
<fragment android:id="@+id/dataChoicesFragment" android:name="org.mozilla.fenix.settings.DataChoicesFragment" <fragment android:id="@+id/dataChoicesFragment" android:name="org.mozilla.fenix.settings.DataChoicesFragment"
android:label="DataChoicesFragment"/> android:label="DataChoicesFragment"/>
@ -277,4 +280,8 @@
android:id="@+id/themeFragment" android:id="@+id/themeFragment"
android:name="org.mozilla.fenix.settings.ThemeFragment" android:name="org.mozilla.fenix.settings.ThemeFragment"
android:label="ThemeFragment" /> android:label="ThemeFragment" />
<fragment
android:id="@+id/trackingProtectionFragment"
android:name="org.mozilla.fenix.settings.TrackingProtectionFragment"
android:label="TrackingProtectionFragment" />
</navigation> </navigation>

@ -56,4 +56,9 @@
<string name="pref_key_dark_theme" translatable="false">pref_key_dark_theme</string> <string name="pref_key_dark_theme" translatable="false">pref_key_dark_theme</string>
<string name="pref_key_auto_battery_theme" translatable="false">pref_key_auto_battery_theme</string> <string name="pref_key_auto_battery_theme" translatable="false">pref_key_auto_battery_theme</string>
<string name="pref_key_follow_device_theme" translatable="false">pref_key_follow_device_theme</string> <string name="pref_key_follow_device_theme" translatable="false">pref_key_follow_device_theme</string>
<!-- Tracking Protection Settings -->
<string name="pref_key_tracking_protection_settings" translatable="false">pref_key_tracking_protection_settings</string>
<string name="pref_key_tracking_protection" translatable="false">pref_key_tracking_protection</string>
<string name="pref_key_tracking_protection_exceptions" translatable="false">pref_key_tracking_protection_exceptions</string>
</resources> </resources>

@ -156,6 +156,15 @@
<string name="sync_never_synced_summary">Last synced: never</string> <string name="sync_never_synced_summary">Last synced: never</string>
<!-- Advanced Preferences --> <!-- Advanced Preferences -->
<!-- Preference for tracking protection settings -->
<string name="preferences_tracking_protection_settings">Tracking Protection</string>
<!-- Preference switch for tracking protection -->
<string name="preferences_tracking_protection">Tracking Protection</string>
<!-- Preference switch description for tracking protection -->
<string name="preferences_tracking_protection_description">Block content and scripts that track you online</string>
<!-- Preference for tracking protection exceptions -->
<string name="preferences_tracking_protection_exceptions">Exceptions</string>
<!-- Preference switch for Telemetry --> <!-- Preference switch for Telemetry -->
<string name="preferences_telemetry">Telemetry</string> <string name="preferences_telemetry">Telemetry</string>
<!-- Preference switch for crash reporter --> <!-- Preference switch for crash reporter -->
@ -327,7 +336,8 @@
<string name="bookmark_invalid_url_error">Invalid URL</string> <string name="bookmark_invalid_url_error">Invalid URL</string>
<!-- Bookmark screen message for empty bookmarks folder --> <!-- Bookmark screen message for empty bookmarks folder -->
<string name="bookmarks_empty_message">No bookmarks here</string> <string name="bookmarks_empty_message">No bookmarks here</string>
<!-- Bookmark snackbar message on deletion --> <!-- Bookmark snackbar message on deletion
The first parameter is the host part of the URL of the bookmark deleted, if any -->
<string name="bookmark_deletion_snackbar_message">Deleted %1$s</string> <string name="bookmark_deletion_snackbar_message">Deleted %1$s</string>
<!-- Bookmark snackbar message on deleting multiple bookmarks --> <!-- Bookmark snackbar message on deleting multiple bookmarks -->
<string name="bookmark_deletion_multiple_snackbar_message">Deleting selected bookmarks</string> <string name="bookmark_deletion_multiple_snackbar_message">Deleting selected bookmarks</string>

@ -55,6 +55,10 @@
<androidx.preference.PreferenceCategory <androidx.preference.PreferenceCategory
android:title="@string/preferences_category_advanced" android:title="@string/preferences_category_advanced"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<androidx.preference.Preference
android:icon="@drawable/ic_tracking_protection"
android:key="@string/pref_key_tracking_protection_settings"
android:title="@string/preferences_tracking_protection" />
<androidx.preference.Preference <androidx.preference.Preference
android:icon="@drawable/ic_permission" android:icon="@drawable/ic_permission"
android:key="@string/pref_key_site_permissions" android:key="@string/pref_key_site_permissions"

@ -0,0 +1,16 @@
<?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/. -->
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="true"
android:icon="@drawable/ic_tracking_protection"
android:key="@string/pref_key_tracking_protection"
android:summary="@string/preferences_tracking_protection_description"
android:title="@string/preferences_tracking_protection" />
<Preference
android:icon="@drawable/ic_internet"
android:key="@string/pref_key_tracking_protection_exceptions"
android:title="@string/preferences_tracking_protection_exceptions" />
</androidx.preference.PreferenceScreen>
Loading…
Cancel
Save