diff --git a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataController.kt b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataController.kt index 311b078e7..b7bf2b8c7 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataController.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataController.kt @@ -17,6 +17,7 @@ import kotlin.coroutines.CoroutineContext interface DeleteBrowsingDataController { suspend fun deleteTabs() suspend fun deleteBrowsingData() + suspend fun deleteHistoryAndDOMStorages() suspend fun deleteCollections(collections: List) suspend fun deleteCookies() suspend fun deleteCachedFiles() @@ -27,6 +28,7 @@ class DefaultDeleteBrowsingDataController( val context: Context, val coroutineContext: CoroutineContext = Dispatchers.Main ) : DeleteBrowsingDataController { + override suspend fun deleteTabs() { withContext(coroutineContext) { context.components.useCases.tabsUseCases.removeAllTabs.invoke() @@ -44,7 +46,7 @@ class DefaultDeleteBrowsingDataController( } } - suspend fun deleteHistoryAndDOMStorages() { + override suspend fun deleteHistoryAndDOMStorages() { withContext(coroutineContext) { context.components.core.engine.clearData(Engine.BrowsingData.select(Engine.BrowsingData.DOM_STORAGES)) } diff --git a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitFragment.kt index d8de98bc6..7d19ac190 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitFragment.kt @@ -12,9 +12,22 @@ 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 +import org.mozilla.fenix.ext.settings class DeleteBrowsingDataOnQuitFragment : PreferenceFragmentCompat() { + + private val checkboxes by lazy { + val context = requireContext() + DeleteBrowsingDataOnQuitType.values() + .asSequence() + .mapNotNull { type -> + findPreference(type.getPreferenceKey(context))?.let { pref -> + type to pref + } + } + .toMap() + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.delete_browsing_data_quit_preferences, rootKey) } @@ -25,81 +38,42 @@ class DeleteBrowsingDataOnQuitFragment : PreferenceFragmentCompat() { activity?.title = getString(R.string.preferences_delete_browsing_data_on_quit) (activity as AppCompatActivity).supportActionBar?.show() + // Delete Browsing Data on Quit Switch + val deleteOnQuitPref = findPreference( + getPreferenceKey(R.string.pref_key_delete_browsing_data_on_quit) + ) + deleteOnQuitPref?.apply { + onPreferenceChangeListener = object : SharedPreferenceUpdater() { + override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { + setAllCheckboxes(newValue as Boolean) + return super.onPreferenceChange(preference, newValue) + } + } + isChecked = context.settings().shouldDeleteBrowsingDataOnQuit + } + val checkboxUpdater = object : SharedPreferenceUpdater() { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { super.onPreferenceChange(preference, newValue) - if (!Settings.getInstance(preference.context).shouldDeleteAnyDataOnQuit()) { - findPreference( - 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() + val settings = preference.context.settings() + + if (!settings.shouldDeleteAnyDataOnQuit()) { + deleteOnQuitPref?.isChecked = false + settings.shouldDeleteBrowsingDataOnQuit = false } return true } } - val switchUpdater = object : SharedPreferenceUpdater() { - override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { - setAllCheckboxes(newValue as Boolean) - return super.onPreferenceChange(preference, newValue) - } - } - - findPreference(getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit))?.apply { - onPreferenceChangeListener = checkboxUpdater - } - findPreference(getPreferenceKey(R.string.pref_key_delete_browsing_history_on_quit))?.apply { - onPreferenceChangeListener = checkboxUpdater - } - findPreference(getPreferenceKey(R.string.pref_key_delete_caches_on_quit))?.apply { - onPreferenceChangeListener = checkboxUpdater - } - findPreference(getPreferenceKey(R.string.pref_key_delete_permissions_on_quit))?.apply { - onPreferenceChangeListener = checkboxUpdater - } - findPreference(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(deleteOnQuitKey)?.apply { - onPreferenceChangeListener = switchUpdater - isChecked = Settings.getInstance(context!!).shouldDeleteBrowsingDataOnQuit + checkboxes.forEach { (_, pref) -> + pref.onPreferenceChangeListener = checkboxUpdater } } private fun setAllCheckboxes(newValue: Boolean) { - val openTabs = - findPreference(getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit)) - val history = - findPreference(getPreferenceKey(R.string.pref_key_delete_browsing_history_on_quit)) - val cache = - findPreference(getPreferenceKey(R.string.pref_key_delete_caches_on_quit)) - val permissions = - findPreference(getPreferenceKey(R.string.pref_key_delete_permissions_on_quit)) - val cookies = - findPreference(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() + checkboxes.forEach { (type, pref) -> + pref.isChecked = newValue + pref.context.settings().setDeleteDataOnQuit(type, newValue) + } } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitType.kt b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitType.kt new file mode 100644 index 000000000..a6d53fe9e --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/DeleteBrowsingDataOnQuitType.kt @@ -0,0 +1,20 @@ +/* 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.content.Context +import androidx.annotation.StringRes +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.getPreferenceKey + +enum class DeleteBrowsingDataOnQuitType(@StringRes private val prefKey: Int) { + TABS(R.string.pref_key_delete_open_tabs_on_quit), + HISTORY(R.string.pref_key_delete_browsing_history_on_quit), + COOKIES(R.string.pref_key_delete_cookies_on_quit), + CACHE(R.string.pref_key_delete_caches_on_quit), + PERMISSIONS(R.string.pref_key_delete_permissions_on_quit); + + fun getPreferenceKey(context: Context) = context.getPreferenceKey(prefKey) +} diff --git a/app/src/main/java/org/mozilla/fenix/utils/DeleteAndQuit.kt b/app/src/main/java/org/mozilla/fenix/utils/DeleteAndQuit.kt index 7203a0cdc..b96021778 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/DeleteAndQuit.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/DeleteAndQuit.kt @@ -6,35 +6,43 @@ package org.mozilla.fenix.utils import android.app.Activity import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.joinAll import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.mozilla.fenix.ext.settings import org.mozilla.fenix.settings.DefaultDeleteBrowsingDataController +import org.mozilla.fenix.settings.DeleteBrowsingDataController +import org.mozilla.fenix.settings.DeleteBrowsingDataOnQuitType /** * Deletes selected browsing data and finishes the activity. */ fun deleteAndQuit(activity: Activity, coroutineScope: CoroutineScope) { coroutineScope.launch { + val settings = activity.settings() val controller = DefaultDeleteBrowsingDataController(activity, coroutineContext) - if (Settings.getInstance(activity).deleteCacheOnQuit) { - controller.deleteCachedFiles() - } - if (Settings.getInstance(activity).deleteTabsOnQuit) { - controller.deleteTabs() - } - if (Settings.getInstance(activity).deletePermissionsOnQuit) { - launch(Dispatchers.IO) { - controller.deleteSitePermissions() + DeleteBrowsingDataOnQuitType.values().map { type -> + launch { + if (settings.getDeleteDataOnQuit(type)) { + controller.deleteType(type) + } } - } - if (Settings.getInstance(activity).deleteCookiesOnQuit) { - controller.deleteCookies() - } - if (Settings.getInstance(activity).deleteHistoryOnQuit) { - controller.deleteHistoryAndDOMStorages() - } + }.joinAll() activity.finish() } } + +private suspend fun DeleteBrowsingDataController.deleteType(type: DeleteBrowsingDataOnQuitType) { + when (type) { + DeleteBrowsingDataOnQuitType.TABS -> deleteTabs() + DeleteBrowsingDataOnQuitType.HISTORY -> deleteHistoryAndDOMStorages() + DeleteBrowsingDataOnQuitType.COOKIES -> deleteCookies() + DeleteBrowsingDataOnQuitType.CACHE -> deleteCachedFiles() + DeleteBrowsingDataOnQuitType.PERMISSIONS -> withContext(IO) { + deleteSitePermissions() + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 5446c3859..8f3590f53 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -21,6 +21,7 @@ import org.mozilla.fenix.Config import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.MozillaProductDetector import org.mozilla.fenix.ext.getPreferenceKey +import org.mozilla.fenix.settings.DeleteBrowsingDataOnQuitType import org.mozilla.fenix.settings.PhoneFeature import java.security.InvalidParameterException @@ -174,39 +175,16 @@ class Settings private constructor( default = false ) - var deleteTabsOnQuit by booleanPreference( - appContext.getPreferenceKey(R.string.pref_key_delete_open_tabs_on_quit), - default = false - ) + fun getDeleteDataOnQuit(type: DeleteBrowsingDataOnQuitType): Boolean = + preferences.getBoolean(type.getPreferenceKey(appContext), 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 + fun setDeleteDataOnQuit(type: DeleteBrowsingDataOnQuitType, value: Boolean) { + preferences.edit().putBoolean(type.getPreferenceKey(appContext), value).apply() } + fun shouldDeleteAnyDataOnQuit() = + DeleteBrowsingDataOnQuitType.values().any { getDeleteDataOnQuit(it) } + val themeSettingString: String get() = when { shouldFollowDeviceTheme -> appContext.getString(R.string.preference_follow_device_theme) diff --git a/app/src/test/java/org/mozilla/fenix/utils/DeleteAndQuitTest.kt b/app/src/test/java/org/mozilla/fenix/utils/DeleteAndQuitTest.kt index 4c238817e..b55b8b3b8 100644 --- a/app/src/test/java/org/mozilla/fenix/utils/DeleteAndQuitTest.kt +++ b/app/src/test/java/org/mozilla/fenix/utils/DeleteAndQuitTest.kt @@ -30,6 +30,7 @@ import org.mozilla.fenix.TestApplication import org.mozilla.fenix.components.PermissionStorage import org.mozilla.fenix.ext.clearAndCommit import org.mozilla.fenix.ext.components +import org.mozilla.fenix.settings.DeleteBrowsingDataOnQuitType import org.robolectric.annotation.Config @ObsoleteCoroutinesApi @@ -76,7 +77,7 @@ class DeleteAndQuitTest { @Test fun `delete only tabs and quit`() = runBlockingTest { // When - settings.deleteTabsOnQuit = true + settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.TABS, true) deleteAndQuit(activity, this) @@ -103,11 +104,9 @@ class DeleteAndQuitTest { @Test fun `delete everything and quit`() = runBlockingTest { // When - settings.deleteTabsOnQuit = true - settings.deletePermissionsOnQuit = true - settings.deleteHistoryOnQuit = true - settings.deleteCookiesOnQuit = true - settings.deleteCacheOnQuit = true + DeleteBrowsingDataOnQuitType.values().forEach { + settings.setDeleteDataOnQuit(it, true) + } deleteAndQuit(activity, this) diff --git a/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt b/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt index a80030f5a..7edd8b91f 100644 --- a/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt +++ b/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt @@ -19,6 +19,7 @@ import org.junit.runner.RunWith import org.mozilla.fenix.TestApplication import org.mozilla.fenix.ext.clearAndCommit import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.settings.DeleteBrowsingDataOnQuitType import org.mozilla.fenix.settings.PhoneFeature import org.robolectric.annotation.Config @@ -80,20 +81,20 @@ class SettingsTest { assertFalse(settings.shouldDeleteAnyDataOnQuit()) // When - settings.deleteTabsOnQuit = true + settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.TABS, true) // Then assertTrue(settings.shouldDeleteAnyDataOnQuit()) // When - settings.deletePermissionsOnQuit = true + settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.PERMISSIONS, true) // Then assertTrue(settings.shouldDeleteAnyDataOnQuit()) // When - settings.deletePermissionsOnQuit = false - settings.deleteTabsOnQuit = false + settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.TABS, false) + settings.setDeleteDataOnQuit(DeleteBrowsingDataOnQuitType.PERMISSIONS, false) // Then assertFalse(settings.shouldDeleteAnyDataOnQuit())