mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-02 03:40:16 +00:00
For #1084 - Add tracking protection toggle to quick settings dialog
This commit is contained in:
parent
3f906dc58a
commit
01a181975d
@ -517,10 +517,14 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||
val quickSettingsSheet = QuickSettingsSheetDialogFragment.newInstance(
|
||||
url = session.url,
|
||||
isSecured = session.securityInfo.secure,
|
||||
isTrackingProtectionOn = Settings.getInstance(context!!).shouldUseTrackingProtection,
|
||||
sitePermissions = sitePermissions
|
||||
)
|
||||
quickSettingsSheet.sitePermissions = sitePermissions
|
||||
quickSettingsSheet.show(requireFragmentManager(), QuickSettingsSheetDialogFragment.FRAGMENT_TAG)
|
||||
quickSettingsSheet.show(
|
||||
requireFragmentManager(),
|
||||
QuickSettingsSheetDialogFragment.FRAGMENT_TAG
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -572,6 +576,6 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
|
||||
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2
|
||||
private const val REQUEST_CODE_APP_PERMISSIONS = 3
|
||||
private const val TOOLBAR_HEIGHT = 56f
|
||||
private const val REPORT_SITE_ISSUE_URL = "https://webcompat.com/issues/new?url=%s&label=browser-fenix"
|
||||
const val REPORT_SITE_ISSUE_URL = "https://webcompat.com/issues/new?url=%s&label=browser-fenix"
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,16 @@ class SettingsFragment : PreferenceFragmentCompat(), CoroutineScope, AccountObse
|
||||
requireComponents.search.searchEngineManager.getDefaultSearchEngine(it).name
|
||||
}
|
||||
|
||||
val trackingProtectionPreference =
|
||||
findPreference<Preference>(getString(R.string.pref_key_tracking_protection_settings))
|
||||
trackingProtectionPreference?.summary = context?.let {
|
||||
if (org.mozilla.fenix.utils.Settings.getInstance(it).shouldUseTrackingProtection) {
|
||||
getString(R.string.tracking_protection_on)
|
||||
} else {
|
||||
getString(R.string.tracking_protection_off)
|
||||
}
|
||||
}
|
||||
|
||||
val themesPreference =
|
||||
findPreference<Preference>(getString(R.string.pref_key_theme))
|
||||
themesPreference?.summary = context?.let {
|
||||
|
@ -9,6 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
|
||||
@ -40,6 +41,7 @@ class TrackingProtectionFragment : PreferenceFragmentCompat() {
|
||||
sessions.forEach { getEngineSession(it)?.enableTrackingProtection(policy) }
|
||||
}
|
||||
}
|
||||
requireContext().components.useCases.sessionUseCases.reload.invoke()
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ class QuickSettingsComponent(
|
||||
mode = QuickSettingsState.Mode.Normal(
|
||||
change.url,
|
||||
change.isSecured,
|
||||
change.isTrackingProtectionOn,
|
||||
change.sitePermissions
|
||||
)
|
||||
)
|
||||
@ -97,15 +98,27 @@ class QuickSettingsComponent(
|
||||
|
||||
data class QuickSettingsState(val mode: Mode) : ViewState {
|
||||
sealed class Mode {
|
||||
data class Normal(val url: String, val isSecured: Boolean, val sitePermissions: SitePermissions?) : Mode()
|
||||
data class ActionLabelUpdated(val phoneFeature: PhoneFeature, val sitePermissions: SitePermissions?) :
|
||||
data class Normal(
|
||||
val url: String,
|
||||
val isSecured: Boolean,
|
||||
val isTrackingProtectionOn: Boolean,
|
||||
val sitePermissions: SitePermissions?
|
||||
) : Mode()
|
||||
|
||||
data class ActionLabelUpdated(
|
||||
val phoneFeature: PhoneFeature,
|
||||
val sitePermissions: SitePermissions?
|
||||
) :
|
||||
Mode()
|
||||
|
||||
data class CheckPendingFeatureBlockedByAndroid(val sitePermissions: SitePermissions?) : Mode()
|
||||
data class CheckPendingFeatureBlockedByAndroid(val sitePermissions: SitePermissions?) :
|
||||
Mode()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class QuickSettingsAction : Action {
|
||||
data class SelectReportProblem(val url: String) : QuickSettingsAction()
|
||||
data class ToggleTrackingProtection(val trackingProtection: Boolean) : QuickSettingsAction()
|
||||
data class SelectBlockedByAndroid(val permissions: Array<String>) : QuickSettingsAction()
|
||||
data class TogglePermission(val featurePhone: PhoneFeature) : QuickSettingsAction()
|
||||
}
|
||||
@ -114,6 +127,7 @@ sealed class QuickSettingsChange : Change {
|
||||
data class Change(
|
||||
val url: String,
|
||||
val isSecured: Boolean,
|
||||
val isTrackingProtectionOn: Boolean,
|
||||
val sitePermissions: SitePermissions?
|
||||
) : QuickSettingsChange()
|
||||
|
||||
|
@ -10,6 +10,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -17,7 +18,9 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.browser.BrowserFragment
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.mvi.ActionBusFactory
|
||||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||
@ -27,6 +30,7 @@ import kotlin.coroutines.CoroutineContext
|
||||
private const val KEY_URL = "KEY_URL"
|
||||
private const val KEY_IS_SECURED = "KEY_IS_SECURED"
|
||||
private const val KEY_SITE_PERMISSIONS = "KEY_SITE_PERMISSIONS"
|
||||
private const val KEY_IS_TP_ON = "KEY_IS_TP_ON"
|
||||
private const val REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS = 4
|
||||
|
||||
@SuppressWarnings("TooManyFunctions")
|
||||
@ -34,6 +38,7 @@ class QuickSettingsSheetDialogFragment : BottomSheetDialogFragment(), CoroutineS
|
||||
private val safeArguments get() = requireNotNull(arguments)
|
||||
private val url: String by lazy { safeArguments.getString(KEY_URL) }
|
||||
private val isSecured: Boolean by lazy { safeArguments.getBoolean(KEY_IS_SECURED) }
|
||||
private val isTrackingProtectionOn: Boolean by lazy { safeArguments.getBoolean(KEY_IS_TP_ON) }
|
||||
private lateinit var quickSettingsComponent: QuickSettingsComponent
|
||||
private lateinit var job: Job
|
||||
|
||||
@ -59,7 +64,7 @@ class QuickSettingsSheetDialogFragment : BottomSheetDialogFragment(), CoroutineS
|
||||
quickSettingsComponent = QuickSettingsComponent(
|
||||
rootView as ConstraintLayout, ActionBusFactory.get(this),
|
||||
QuickSettingsState(
|
||||
QuickSettingsState.Mode.Normal(url, isSecured, sitePermissions)
|
||||
QuickSettingsState.Mode.Normal(url, isSecured, isTrackingProtectionOn, sitePermissions)
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -70,6 +75,7 @@ class QuickSettingsSheetDialogFragment : BottomSheetDialogFragment(), CoroutineS
|
||||
fun newInstance(
|
||||
url: String,
|
||||
isSecured: Boolean,
|
||||
isTrackingProtectionOn: Boolean,
|
||||
sitePermissions: SitePermissions?
|
||||
): QuickSettingsSheetDialogFragment {
|
||||
|
||||
@ -79,6 +85,7 @@ class QuickSettingsSheetDialogFragment : BottomSheetDialogFragment(), CoroutineS
|
||||
with(arguments) {
|
||||
putString(KEY_URL, url)
|
||||
putBoolean(KEY_IS_SECURED, isSecured)
|
||||
putBoolean(KEY_IS_TP_ON, isTrackingProtectionOn)
|
||||
putParcelable(KEY_SITE_PERMISSIONS, sitePermissions)
|
||||
}
|
||||
fragment.arguments = arguments
|
||||
@ -110,6 +117,37 @@ class QuickSettingsSheetDialogFragment : BottomSheetDialogFragment(), CoroutineS
|
||||
is QuickSettingsAction.SelectBlockedByAndroid -> {
|
||||
requestPermissions(it.permissions, REQUEST_CODE_QUICK_SETTINGS_PERMISSIONS)
|
||||
}
|
||||
is QuickSettingsAction.SelectReportProblem -> {
|
||||
launch(Dispatchers.Main) {
|
||||
val reportUrl =
|
||||
String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, it.url)
|
||||
requireComponents.useCases.sessionUseCases.loadUrl.invoke(reportUrl)
|
||||
}
|
||||
}
|
||||
is QuickSettingsAction.ToggleTrackingProtection -> {
|
||||
val trackingEnabled = it.trackingProtection
|
||||
with(requireComponents.core) {
|
||||
val policy =
|
||||
createTrackingProtectionPolicy(trackingEnabled)
|
||||
PreferenceManager.getDefaultSharedPreferences(context).edit()
|
||||
.putBoolean(
|
||||
context!!.getString(R.string.pref_key_tracking_protection),
|
||||
trackingEnabled
|
||||
).apply()
|
||||
engine.settings.trackingProtectionPolicy = policy
|
||||
|
||||
with(sessionManager) {
|
||||
sessions.forEach {
|
||||
getEngineSession(it)?.enableTrackingProtection(
|
||||
policy
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
launch(Dispatchers.Main) {
|
||||
requireContext().components.useCases.sessionUseCases.reload.invoke()
|
||||
}
|
||||
}
|
||||
is QuickSettingsAction.TogglePermission -> {
|
||||
|
||||
launch {
|
||||
|
@ -8,6 +8,7 @@ import android.view.View
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Switch
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
@ -19,6 +20,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions
|
||||
import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION
|
||||
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
|
||||
import mozilla.components.support.ktx.kotlin.toUri
|
||||
import org.mozilla.fenix.DefaultThemeManager
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.mvi.UIView
|
||||
import org.mozilla.fenix.settings.PhoneFeature
|
||||
@ -28,6 +30,7 @@ import org.mozilla.fenix.settings.PhoneFeature.MICROPHONE
|
||||
import org.mozilla.fenix.settings.PhoneFeature.NOTIFICATION
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class QuickSettingsUIView(
|
||||
container: ViewGroup,
|
||||
actionEmitter: Observer<QuickSettingsAction>,
|
||||
@ -38,6 +41,8 @@ class QuickSettingsUIView(
|
||||
) {
|
||||
private val securityInfoLabel: TextView
|
||||
private val urlLabel: TextView
|
||||
private val trackingProtectionSwitch: Switch
|
||||
private val reportProblemAction: TextView
|
||||
private val cameraActionLabel: TextView
|
||||
private val cameraLabel: TextView
|
||||
private val microphoneActionLabel: TextView
|
||||
@ -53,6 +58,8 @@ class QuickSettingsUIView(
|
||||
init {
|
||||
urlLabel = view.findViewById<AppCompatTextView>(R.id.url)
|
||||
securityInfoLabel = view.findViewById<AppCompatTextView>(R.id.security_info)
|
||||
trackingProtectionSwitch = view.findViewById(R.id.tracking_protection)
|
||||
reportProblemAction = view.findViewById(R.id.report_problem)
|
||||
cameraActionLabel = view.findViewById<AppCompatTextView>(R.id.camera_action_label)
|
||||
cameraLabel = view.findViewById<AppCompatTextView>(R.id.camera_icon)
|
||||
microphoneActionLabel = view.findViewById<AppCompatTextView>(R.id.microphone_action_label)
|
||||
@ -68,6 +75,8 @@ class QuickSettingsUIView(
|
||||
is QuickSettingsState.Mode.Normal -> {
|
||||
bindUrl(state.mode.url)
|
||||
bindSecurityInfo(state.mode.isSecured)
|
||||
bindReportProblemAction(state.mode.url)
|
||||
bindTrackingProtectionInfo(state.mode.isTrackingProtectionOn)
|
||||
bindPhoneFeatureItem(cameraActionLabel, CAMERA, state.mode.sitePermissions)
|
||||
bindPhoneFeatureItem(microphoneActionLabel, MICROPHONE, state.mode.sitePermissions)
|
||||
bindPhoneFeatureItem(notificationActionLabel, NOTIFICATION, state.mode.sitePermissions)
|
||||
@ -90,6 +99,38 @@ class QuickSettingsUIView(
|
||||
urlLabel.text = url.toUri().hostWithoutCommonPrefixes
|
||||
}
|
||||
|
||||
private fun bindTrackingProtectionInfo(isTrackingProtectionOn: Boolean) {
|
||||
val drawableId =
|
||||
if (isTrackingProtectionOn) R.drawable.ic_tracking_protection else
|
||||
R.drawable.ic_tracking_protection_disabled
|
||||
val drawableTint = if (isTrackingProtectionOn) DefaultThemeManager.resolveAttribute(
|
||||
R.attr.primaryText,
|
||||
context
|
||||
) else DefaultThemeManager.resolveAttribute(R.attr.neutral, context)
|
||||
val icon = AppCompatResources.getDrawable(context, drawableId)
|
||||
val resolvedColor = ContextCompat.getColor(context, drawableTint)
|
||||
icon?.setTint(resolvedColor)
|
||||
trackingProtectionSwitch.setTextColor(resolvedColor)
|
||||
trackingProtectionSwitch.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null)
|
||||
trackingProtectionSwitch.isChecked = isTrackingProtectionOn
|
||||
|
||||
trackingProtectionSwitch.setOnCheckedChangeListener { _, isChecked ->
|
||||
actionEmitter.onNext(
|
||||
QuickSettingsAction.ToggleTrackingProtection(
|
||||
isChecked
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindReportProblemAction(url: String) {
|
||||
reportProblemAction.setOnClickListener {
|
||||
actionEmitter.onNext(
|
||||
QuickSettingsAction.SelectReportProblem(url)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindSecurityInfo(isSecured: Boolean) {
|
||||
val stringId: Int
|
||||
val drawableId: Int
|
||||
|
@ -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="?primaryText"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M17.9,10.825C17.92,10.583 17.939,10.228 17.955,9.8L19.994,7.757C19.988,8.963 19.958,10.284 19.888,11.017C19.584,14.191 18.966,15.932 17.437,17.911C16.1139,19.5759 14.209,20.6776 12.106,20.994L12,21.006L11.893,20.994C10.5742,20.796 9.3208,20.2893 8.235,19.515L9.683,18.067C10.3916,18.5151 11.1773,18.8277 12,18.989C13.5187,18.7058 14.8864,17.8899 15.857,16.688C17.153,15.01 17.631,13.641 17.9,10.825ZM20.207,3.793C20.5973,4.1812 20.6005,4.8119 20.214,5.204L5.214,20.204C4.9629,20.464 4.5911,20.5682 4.2415,20.4767C3.8919,20.3852 3.6188,20.1121 3.5273,19.7625C3.4358,19.4129 3.54,19.0411 3.8,18.79L5.8,16.79C4.7719,15.0326 4.1919,13.0494 4.111,11.015C4.012,9.973 4,7.767 4,6.1C4.0096,5.0498 4.7782,4.161 5.816,4L12,2.986L18.187,3.999C18.2894,4.0247 18.3897,4.0581 18.487,4.099L18.793,3.793C19.1835,3.4026 19.8165,3.4026 20.207,3.793ZM6.1,10.826C6.1631,12.3919 6.5575,13.9266 7.257,15.329L8.717,13.864C8.3635,12.8432 8.1528,11.7785 8.091,10.7C8.066,10.439 8.015,9.667 8,7.7L12,7.041L12,10.586L16.789,5.797L12,5.014L6.138,5.972C6.0646,5.9767 6.0058,6.0347 6,6.108C6,8.4 6.031,10.076 6.1,10.826Z" />
|
||||
</vector>
|
@ -35,14 +35,48 @@
|
||||
app:layout_constraintTop_toBottomOf="@id/url"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/line_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_height="1dp"
|
||||
android:background="?neutral"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/security_info"/>
|
||||
android:id="@+id/line_divider_security"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?neutral"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/security_info" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/tracking_protection"
|
||||
style="@style/QuickSettingsText.Icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/quicksettings_item_height"
|
||||
android:drawableStart="@drawable/ic_tracking_protection"
|
||||
android:paddingEnd="24dp"
|
||||
android:text="@string/preferences_tracking_protection"
|
||||
app:layout_constraintBottom_toTopOf="@id/report_problem"
|
||||
app:layout_constraintTop_toBottomOf="@id/line_divider_security" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/report_problem"
|
||||
style="@style/QuickSettingsText.Icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/quicksettings_item_height"
|
||||
android:gravity="top"
|
||||
android:paddingStart="48dp"
|
||||
android:text="@string/tracking_protection_report_problem"
|
||||
android:textColor="?accentBright"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/line_divider"
|
||||
app:layout_constraintTop_toBottomOf="@id/tracking_protection" />
|
||||
|
||||
<View
|
||||
android:id="@+id/line_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?neutral"
|
||||
app:layout_constraintBottom_toTopOf="@id/camera_icon"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/camera_icon"
|
||||
|
@ -386,4 +386,10 @@
|
||||
<string name="phone_feature_blocked_by_android">Blocked by Android</string>
|
||||
<!-- Preference for showing a list of websites that the default configurations won't apply to them -->
|
||||
<string name="preference_exceptions">Exceptions</string>
|
||||
<!-- Action in Quick Settings dialog to report a site problem related to tracking protection -->
|
||||
<string name="tracking_protection_report_problem">Report a problem</string>
|
||||
<!-- Summary of tracking protection preference if tracking protection is set to on -->
|
||||
<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>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user