For #1084 - Add tracking protection toggle to quick settings dialog
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
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -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