diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 30d471326..f08c817a7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -123,6 +123,55 @@ android:resource="@mipmap/ic_launcher" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TrackingProtectionFragmentDirections.actionTrackingProtectionFragmentToBrowserFragment( - customTabSessionId - ) + customTabSessionId + ) } private fun load( diff --git a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt index 64b1b4a07..776c27bf8 100644 --- a/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/IntentReceiverActivity.kt @@ -6,11 +6,13 @@ package org.mozilla.fenix import android.app.Activity import android.content.Intent +import android.content.pm.PackageManager import android.os.Bundle import androidx.annotation.VisibleForTesting import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import mozilla.components.feature.intent.processing.TabIntentProcessor +import mozilla.components.support.utils.Browsers import org.mozilla.fenix.customtabs.AuthCustomTabActivity import org.mozilla.fenix.customtabs.AuthCustomTabActivity.Companion.EXTRA_AUTH_CUSTOM_TAB import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity @@ -37,7 +39,22 @@ class IntentReceiverActivity : Activity() { } suspend fun processIntent(intent: Intent) { - val tabIntentProcessor = if (settings().launchLinksInPrivateTab) { + val didLaunchPrivateLink = packageManager + ?.getActivityInfo(componentName, PackageManager.GET_META_DATA) + ?.metaData + ?.getBoolean(LAUNCH_PRIVATE_LINK) ?: false + + /* If LAUNCH_PRIVATE_LINK is set AND we're the default browser they must have pressed "always." + This is because LAUNCH_PRIVATE_LINK is only accessible through the "launch browser intent" menu + Which only appears if the user doesn't have a default set. */ + if (didLaunchPrivateLink && Browsers.all(this).isDefaultBrowser) { + this.settings().openLinksInAPrivateTab = true + } else if (!Browsers.all(this).isDefaultBrowser) { + /* If the user has unset us as the default browser, unset alwaysOpenInPrivateMode */ + this.settings().openLinksInAPrivateTab = false + } + + val tabIntentProcessor = if (settings().openLinksInAPrivateTab || didLaunchPrivateLink) { components.intentProcessors.privateIntentProcessor } else { components.intentProcessors.intentProcessor @@ -105,6 +122,9 @@ class IntentReceiverActivity : Activity() { } companion object { + // This constant must match the metadata from the private activity-alias + const val LAUNCH_PRIVATE_LINK = "org.mozilla.fenix.LAUNCH_PRIVATE_LINK" + const val ACTION_OPEN_TAB = "org.mozilla.fenix.OPEN_TAB" const val ACTION_OPEN_PRIVATE_TAB = "org.mozilla.fenix.OPEN_PRIVATE_TAB" } diff --git a/app/src/main/java/org/mozilla/fenix/settings/DefaultBrowserSettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/DefaultBrowserSettingsFragment.kt new file mode 100644 index 000000000..66f3ef759 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/settings/DefaultBrowserSettingsFragment.kt @@ -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.content.Intent +import android.content.SharedPreferences +import android.os.Build +import android.os.Build.VERSION.SDK_INT +import android.os.Bundle +import android.provider.Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.preference.CheckBoxPreference +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import mozilla.components.support.utils.Browsers +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.getPreferenceKey +import org.mozilla.fenix.ext.settings + +/** + * Lets the user control their default browser preferences + */ +class DefaultBrowserSettingsFragment : PreferenceFragmentCompat() { + + private val preferenceChangeListener = + SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> + when (key) { + getPreferenceKey(R.string.pref_key_telemetry) -> { + if (sharedPreferences.getBoolean(key, requireContext().settings().isTelemetryEnabled)) { + context?.components?.analytics?.metrics?.start() + } else { + context?.components?.analytics?.metrics?.stop() + } + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + context?.let { + preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener) + } + + val makeDefaultBrowserKey = getPreferenceKey(R.string.pref_key_make_default_browser) + val preferenceMakeDefaultBrowser = findPreference(makeDefaultBrowserKey) + + preferenceMakeDefaultBrowser?.onPreferenceClickListener = + getClickListenerForMakeDefaultBrowser() + } + + override fun onResume() { + super.onResume() + (activity as AppCompatActivity).title = getString(R.string.preferences_set_as_default_browser) + (activity as AppCompatActivity).supportActionBar?.show() + + updatePreferences() + } + + override fun onDestroy() { + context?.let { + preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener) + } + super.onDestroy() + } + + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { + setPreferencesFromResource(R.xml.default_browser_preferences, rootKey) + updatePreferences() + } + + private fun updatePreferences() { + findPreference(getPreferenceKey(R.string.pref_key_make_default_browser)) + ?.updateSwitch() + + findPreference(getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab))?.apply { + isEnabled = Browsers.all(requireContext()).isDefaultBrowser + isChecked = context.settings().openLinksInAPrivateTab + onPreferenceChangeListener = SharedPreferenceUpdater() + } + } + + private fun getClickListenerForMakeDefaultBrowser(): Preference.OnPreferenceClickListener { + return if (SDK_INT >= Build.VERSION_CODES.N) { + Preference.OnPreferenceClickListener { + val intent = Intent( + ACTION_MANAGE_DEFAULT_APPS_SETTINGS + ) + startActivity(intent) + true + } + } else { + defaultClickListener + } + } + + private val defaultClickListener = + Preference.OnPreferenceClickListener { preference -> + Toast.makeText(context, "${preference.title} Clicked", Toast.LENGTH_SHORT).show() + true + } +} diff --git a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt index 315518b5f..4ebcc97c4 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SettingsFragment.kt @@ -12,8 +12,6 @@ import android.net.Uri import android.os.Build import android.os.Build.VERSION.SDK_INT import android.os.Bundle -import android.provider.Settings -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import androidx.navigation.Navigation @@ -22,7 +20,6 @@ import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat -import androidx.preference.SwitchPreference import kotlinx.coroutines.launch import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType @@ -44,7 +41,6 @@ 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_launch_links_in_private_tab import org.mozilla.fenix.R.string.pref_key_leakcanary import org.mozilla.fenix.R.string.pref_key_make_default_browser import org.mozilla.fenix.R.string.pref_key_privacy_link @@ -100,7 +96,7 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener) if (SDK_INT <= Build.VERSION_CODES.M) { - findPreference(getPreferenceKey(R.string.pref_key_make_default_browser))?.apply { + findPreference(getPreferenceKey(pref_key_make_default_browser))?.apply { isVisible = false } } @@ -115,9 +111,6 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { (activity as AppCompatActivity).title = getString(R.string.settings_title) (activity as AppCompatActivity).supportActionBar?.show() - val defaultBrowserPreference = - findPreference(getPreferenceKey(R.string.pref_key_make_default_browser)) - defaultBrowserPreference?.updateSwitch() val trackingProtectionPreference = findPreference(getPreferenceKey(R.string.pref_key_tracking_protection_settings)) @@ -166,6 +159,9 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { // TODO #220 ItsNotBrokenSnack(context!!).showSnackbar(issueNumber = "220") } + resources.getString(pref_key_make_default_browser) -> { + navigateToDefaultBrowserFragment() + } resources.getString(pref_key_data_choices) -> { navigateToDataChoices() } @@ -239,25 +235,11 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { } private fun setupPreferences() { - val makeDefaultBrowserKey = getPreferenceKey(pref_key_make_default_browser) val leakKey = getPreferenceKey(pref_key_leakcanary) val debuggingKey = getPreferenceKey(pref_key_remote_debugging) - val preferenceLaunchLinksPrivateTabKey = getPreferenceKey( - pref_key_launch_links_in_private_tab - ) - val preferenceMakeDefaultBrowser = findPreference(makeDefaultBrowserKey) val preferenceLeakCanary = findPreference(leakKey) val preferenceRemoteDebugging = findPreference(debuggingKey) - val preferenceLaunchLinksInPrivateTab = findPreference(preferenceLaunchLinksPrivateTabKey) - - preferenceLaunchLinksInPrivateTab?.setOnPreferenceClickListener { - requireContext().settings().launchLinksInPrivateTab = !requireContext().settings().launchLinksInPrivateTab - true - } - - preferenceMakeDefaultBrowser?.onPreferenceClickListener = - getClickListenerForMakeDefaultBrowser() if (!Config.channel.isReleased) { preferenceLeakCanary?.setOnPreferenceChangeListener { _, newValue -> @@ -274,25 +256,6 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { } } - private val defaultClickListener = OnPreferenceClickListener { preference -> - Toast.makeText(context, "${preference.title} Clicked", Toast.LENGTH_SHORT).show() - true - } - - private fun getClickListenerForMakeDefaultBrowser(): OnPreferenceClickListener { - return if (SDK_INT >= Build.VERSION_CODES.N) { - OnPreferenceClickListener { - val intent = Intent( - Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS - ) - startActivity(intent) - true - } - } else { - defaultClickListener - } - } - private fun navigateToSearchEngineSettings() { val directions = SettingsFragmentDirections.actionSettingsFragmentToSearchEngineFragment() Navigation.findNavController(view!!).navigate(directions) @@ -319,6 +282,11 @@ class SettingsFragment : PreferenceFragmentCompat(), AccountObserver { Navigation.findNavController(view!!).navigate(directions) } + private fun navigateToDefaultBrowserFragment() { + val directions = SettingsFragmentDirections.actionSettingsFragmentToDefaultBrowserFragment() + Navigation.findNavController(view!!).navigate(directions) + } + private fun navigateToDataChoices() { val directions = SettingsFragmentDirections.actionSettingsFragmentToDataChoicesFragment() Navigation.findNavController(view!!).navigate(directions) 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 bb4327d6c..020afa581 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -95,8 +95,8 @@ class Settings private constructor( default = false ) - var launchLinksInPrivateTab by booleanPreference( - appContext.getPreferenceKey(R.string.pref_key_launch_links_in_private_tab), + var openLinksInAPrivateTab by booleanPreference( + appContext.getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab), default = false ) diff --git a/app/src/main/res/layout/checkbox_left_preference.xml b/app/src/main/res/layout/checkbox_left_preference.xml new file mode 100644 index 000000000..fcc2cd5b8 --- /dev/null +++ b/app/src/main/res/layout/checkbox_left_preference.xml @@ -0,0 +1,52 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/delete_browsing_category_checkbox.xml b/app/src/main/res/layout/delete_browsing_category_checkbox.xml index 47296e7f6..fcc2cd5b8 100644 --- a/app/src/main/res/layout/delete_browsing_category_checkbox.xml +++ b/app/src/main/res/layout/delete_browsing_category_checkbox.xml @@ -12,7 +12,7 @@ android:focusable="true" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" - android:paddingStart="64dp" + android:paddingStart="8dp" android:paddingEnd="?android:attr/scrollbarSize"> + - + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + android:background="?android:attr/selectableItemBackground" + android:clickable="true" + android:focusable="true" + app:deleteBrowsingDataItemTitle="@string/preferences_delete_browsing_data_tabs_title" + app:deleteBrowsingDataItemSubtitle="@string/preferences_delete_browsing_data_tabs_subtitle" /> + + diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index c58cb4331..ef150658f 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -100,7 +100,7 @@ pref_key_tracking_protection_onboarding - pref_key_launch_links_in_private_tab + pref_key_open_links_in_a_private_tab pref_key_bounce_quick_action diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b4f63b6a..326f4e0e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,7 +3,7 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - Firefox Preview (Private) + Private Firefox Preview diff --git a/app/src/main/res/xml/default_browser_preferences.xml b/app/src/main/res/xml/default_browser_preferences.xml new file mode 100644 index 000000000..5d040f9a3 --- /dev/null +++ b/app/src/main/res/xml/default_browser_preferences.xml @@ -0,0 +1,15 @@ + + + + + + diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 1a8545bbf..2973e5d75 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -46,7 +46,8 @@ android:key="@string/pref_key_accessibility" android:title="@string/preferences_accessibility" /> - @@ -58,10 +59,6 @@ android:icon="@drawable/ic_tracking_protection_enabled" android:key="@string/pref_key_tracking_protection_settings" android:title="@string/preference_enhanced_tracking_protection" /> -