Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
For #3700 - Add Setting to Delete Data on "Quit" menu action
Browse files Browse the repository at this point in the history
  • Loading branch information
ekager committed Sep 5, 2019
1 parent d18ec43 commit f7653f3
Show file tree
Hide file tree
Showing 20 changed files with 574 additions and 12 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Expand Up @@ -329,6 +329,7 @@ dependencies {

implementation Deps.kotlin_stdlib
implementation Deps.kotlin_coroutines
testImplementation Deps.kotlin_coroutines_test
implementation Deps.androidx_appcompat
implementation Deps.androidx_constraintlayout
implementation Deps.androidx_coordinatorlayout
Expand Down
Expand Up @@ -171,7 +171,8 @@ abstract class BaseBrowserFragment : Fragment(), BackHandler, SessionManager.Obs
it.action = Intent.ACTION_VIEW
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK
},
bottomSheetBehavior = QuickActionSheetBehavior.from(nestedScrollQuickAction)
bottomSheetBehavior = QuickActionSheetBehavior.from(nestedScrollQuickAction),
scope = lifecycleScope
)

browserInteractor =
Expand Down
Expand Up @@ -253,7 +253,7 @@ sealed class Event {
enum class Item {
SETTINGS, LIBRARY, HELP, DESKTOP_VIEW_ON, DESKTOP_VIEW_OFF, FIND_IN_PAGE, NEW_TAB,
NEW_PRIVATE_TAB, SHARE, REPORT_SITE_ISSUE, BACK, FORWARD, RELOAD, STOP, OPEN_IN_FENIX,
SAVE_TO_COLLECTION, ADD_TO_HOMESCREEN
SAVE_TO_COLLECTION, ADD_TO_HOMESCREEN, QUIT
}

override val extras: Map<Events.browserMenuActionKeys, String>?
Expand Down
Expand Up @@ -8,6 +8,7 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.core.widget.NestedScrollView
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.navigation.NavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand All @@ -29,6 +30,7 @@ import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.toTab
import org.mozilla.fenix.lib.Do
import org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior
import org.mozilla.fenix.utils.deleteAndQuit

/**
* An interface that handles the view manipulation of the BrowserToolbar, triggered by the Interactor
Expand All @@ -49,7 +51,8 @@ class DefaultBrowserToolbarController(
private val viewModel: CreateCollectionViewModel,
private val getSupportUrl: () -> String,
private val openInFenixIntent: Intent,
private val bottomSheetBehavior: QuickActionSheetBehavior<NestedScrollView>
private val bottomSheetBehavior: QuickActionSheetBehavior<NestedScrollView>,
private val scope: LifecycleCoroutineScope
) : BrowserToolbarController {

override fun handleToolbarClick() {
Expand Down Expand Up @@ -156,6 +159,7 @@ class DefaultBrowserToolbarController(
// Close this activity since it is no longer displaying any session
(context as Activity).finish()
}
ToolbarMenu.Item.Quit -> context.deleteAndQuit(scope)
}
}

Expand Down Expand Up @@ -184,6 +188,7 @@ class DefaultBrowserToolbarController(
ToolbarMenu.Item.Share -> Event.BrowserMenuItemTapped.Item.SHARE
ToolbarMenu.Item.SaveToCollection -> Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION
ToolbarMenu.Item.AddToHomeScreen -> Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN
ToolbarMenu.Item.Quit -> Event.BrowserMenuItemTapped.Item.QUIT
}

context.components.analytics.metrics.track(Event.BrowserMenuItemTapped(eventItem))
Expand Down
Expand Up @@ -17,6 +17,7 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.Settings

class DefaultToolbarMenu(
private val context: Context,
Expand Down Expand Up @@ -203,6 +204,18 @@ class DefaultToolbarMenu(
)
}

if (Settings.getInstance(context).shouldDeleteBrowsingDataOnQuit) {
items.add(
BrowserMenuImageText(
context.getString(R.string.delete_browsing_data_on_quit_action),
R.drawable.ic_delete,
ThemeManager.resolveAttribute(R.attr.primaryText, context)
) {
onItemTapped.invoke(ToolbarMenu.Item.Quit)
}
)
}

items.add(
BrowserMenuDivider()
)
Expand Down
Expand Up @@ -25,6 +25,7 @@ interface ToolbarMenu {
object OpenInFenix : Item()
object SaveToCollection : Item()
object AddToHomeScreen : Item()
object Quit : Item()
}

val menuBuilder: BrowserMenuBuilder
Expand Down
@@ -0,0 +1,105 @@
/* 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.CheckBoxPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.utils.Settings

class DeleteBrowsingDataOnQuitFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.delete_browsing_data_quit_preferences, rootKey)
}

@Suppress("ComplexMethod")
override fun onResume() {
super.onResume()
activity?.title = getString(R.string.preferences_delete_browsing_data_on_quit)
(activity as AppCompatActivity).supportActionBar?.show()

class CheckboxUpdater : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
super.onPreferenceChange(preference, newValue)
if (!Settings.getInstance(preference.context).shouldDeleteAnyDataOnQuit()) {
findPreference<SwitchPreference>(
getPreferenceKey(R.string.pref_key_delete_browsing_data_on_quit)
)?.apply {
isChecked = false
}
Settings.getInstance(preference.context).preferences.edit().putBoolean(
getString(R.string.pref_key_delete_browsing_data_on_quit),
false
).apply()
}
return true
}
}

class SwitchUpdater : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
setAllCheckboxes(newValue as Boolean)
return super.onPreferenceChange(preference, newValue)
}
}

findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit))?.apply {
onPreferenceChangeListener = CheckboxUpdater()
}
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_browsing_history_on_quit))?.apply {
onPreferenceChangeListener = CheckboxUpdater()
}
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_caches_on_quit))?.apply {
onPreferenceChangeListener = CheckboxUpdater()
}
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_permissions_on_quit))?.apply {
onPreferenceChangeListener = CheckboxUpdater()
}
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_cookies_on_quit))?.apply {
onPreferenceChangeListener = CheckboxUpdater()
}

// Delete Browsing Data on Quit Switch
val deleteOnQuitKey = getPreferenceKey(R.string.pref_key_delete_browsing_data_on_quit)
findPreference<SwitchPreference>(deleteOnQuitKey)?.apply {
onPreferenceChangeListener = SwitchUpdater()
isChecked = Settings.getInstance(context!!).shouldDeleteBrowsingDataOnQuit
}
}

private fun setAllCheckboxes(newValue: Boolean) {
val openTabs =
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit))
val history =
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_browsing_history_on_quit))
val cache =
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_caches_on_quit))
val permissions =
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_permissions_on_quit))
val cookies =
findPreference<CheckBoxPreference>(getPreferenceKey(R.string.pref_key_delete_cookies_on_quit))

openTabs?.isChecked = newValue
history?.isChecked = newValue
cache?.isChecked = newValue
permissions?.isChecked = newValue
cookies?.isChecked = newValue

Settings.getInstance(context!!).preferences.edit().putBoolean(openTabs?.key, newValue)
.apply()
Settings.getInstance(context!!).preferences.edit().putBoolean(history?.key, newValue)
.apply()
Settings.getInstance(context!!).preferences.edit().putBoolean(cache?.key, newValue).apply()
Settings.getInstance(context!!).preferences.edit().putBoolean(permissions?.key, newValue)
.apply()
Settings.getInstance(context!!).preferences.edit().putBoolean(cookies?.key, newValue)
.apply()
}
}
12 changes: 11 additions & 1 deletion app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt
Expand Up @@ -39,6 +39,7 @@ import org.mozilla.fenix.R.string.pref_key_account_auth_error
import org.mozilla.fenix.R.string.pref_key_account_category
import org.mozilla.fenix.R.string.pref_key_data_choices
import org.mozilla.fenix.R.string.pref_key_delete_browsing_data
import org.mozilla.fenix.R.string.pref_key_delete_browsing_data_on_quit_preference
import org.mozilla.fenix.R.string.pref_key_help
import org.mozilla.fenix.R.string.pref_key_language
import org.mozilla.fenix.R.string.pref_key_leakcanary
Expand Down Expand Up @@ -141,7 +142,7 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
updateAccountUIState(context!!, requireComponents.backgroundServices.accountManager.accountProfile())
}

@Suppress("ComplexMethod")
@Suppress("ComplexMethod", "LongMethod")
override fun onPreferenceTreeClick(preference: Preference): Boolean {
when (preference.key) {
resources.getString(pref_key_search_engine_settings) -> {
Expand Down Expand Up @@ -195,6 +196,9 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
resources.getString(pref_key_delete_browsing_data) -> {
navigateToDeleteBrowsingData()
}
resources.getString(pref_key_delete_browsing_data_on_quit_preference) -> {
navigateToDeleteBrowsingDataOnQuit()
}
resources.getString(pref_key_theme) -> {
navigateToThemeSettings()
}
Expand Down Expand Up @@ -327,6 +331,12 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver {
Navigation.findNavController(view!!).navigate(directions)
}

private fun navigateToDeleteBrowsingDataOnQuit() {
val directions =
SettingsFragmentDirections.actionSettingsFragmentToDeleteBrowsingDataOnQuitFragment()
Navigation.findNavController(view!!).navigate(directions)
}

override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
lifecycleScope.launch {
context?.let {
Expand Down
Expand Up @@ -8,7 +8,7 @@ import org.mozilla.fenix.utils.Settings
* Updates the corresponding [android.content.SharedPreferences] when the boolean [Preference] is changed.
* The preference key is used as the shared preference key.
*/
class SharedPreferenceUpdater : Preference.OnPreferenceChangeListener {
open class SharedPreferenceUpdater : Preference.OnPreferenceChangeListener {

override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
val newBooleanValue = newValue as? Boolean ?: return false
Expand Down
55 changes: 55 additions & 0 deletions app/src/main/java/org/mozilla/fenix/utils/DeleteAndQuit.kt
@@ -0,0 +1,55 @@
/* 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.utils

import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import mozilla.components.concept.engine.Engine
import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components

/**
* Deletes selected browsing data and finishes the activity
*/
fun Context.deleteAndQuit(coroutineScope: CoroutineScope) {
coroutineScope.launch {
runBlocking {
if (Settings.getInstance(this@deleteAndQuit).deleteCacheOnQuit) {
withContext(coroutineContext) {
this@deleteAndQuit.components.core.engine.clearData(Engine.BrowsingData.allCaches())
}
}
if (Settings.getInstance(this@deleteAndQuit).deleteTabsOnQuit) {
withContext(coroutineContext) {
this@deleteAndQuit.components.useCases.tabsUseCases.removeAllTabs.invoke()
}
}
if (Settings.getInstance(this@deleteAndQuit).deletePermissionsOnQuit) {
launch(Dispatchers.IO) {
this@deleteAndQuit.components.core.permissionStorage.deleteAllSitePermissions()
}
}
if (Settings.getInstance(this@deleteAndQuit).deleteCookiesOnQuit) {
withContext(coroutineContext) {
this@deleteAndQuit.components.core.engine.clearData(
Engine.BrowsingData.select(
Engine.BrowsingData.COOKIES
)
)
}
}
if (Settings.getInstance(this@deleteAndQuit).deleteHistoryOnQuit) {
withContext(coroutineContext) {
this@deleteAndQuit.components.core.historyStorage.deleteEverything()
}
}
}
this@deleteAndQuit.asActivity()?.finish()
}
}
38 changes: 38 additions & 0 deletions app/src/main/java/org/mozilla/fenix/utils/Settings.kt
Expand Up @@ -142,6 +142,44 @@ class Settings private constructor(
default = false
)

var shouldDeleteBrowsingDataOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_browsing_data_on_quit),
default = false
)

var deleteTabsOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit),
default = false
)

var deleteHistoryOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_browsing_history_on_quit),
default = false
)

var deleteCookiesOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_cookies_on_quit),
default = false
)

var deleteCacheOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_caches_on_quit),
default = false
)

var deletePermissionsOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_permissions_on_quit),
default = false
)

fun shouldDeleteAnyDataOnQuit(): Boolean {
return deleteCacheOnQuit ||
deleteCookiesOnQuit ||
deleteHistoryOnQuit ||
deletePermissionsOnQuit ||
deleteTabsOnQuit
}

val themeSettingString: String
get() = when {
shouldFollowDeviceTheme -> appContext.getString(R.string.preference_follow_device_theme)
Expand Down

0 comments on commit f7653f3

Please sign in to comment.