Use new API for ETP Exceptions
parent
ca8ba57635
commit
18c0525ff6
|
@ -1378,7 +1378,7 @@ tracking_protection:
|
||||||
etp_setting_changed:
|
etp_setting_changed:
|
||||||
type: event
|
type: event
|
||||||
description: >
|
description: >
|
||||||
A user added a tracking protection exception through the TP toggle in the panel.
|
A user changed their tracking protection level setting to either strict or standard.
|
||||||
extra_keys:
|
extra_keys:
|
||||||
etp_setting:
|
etp_setting:
|
||||||
description: "The new setting for ETP: strict, standard"
|
description: "The new setting for ETP: strict, standard"
|
||||||
|
|
|
@ -11,17 +11,15 @@ import mozilla.components.browser.errorpages.ErrorType
|
||||||
import mozilla.components.concept.engine.EngineSession
|
import mozilla.components.concept.engine.EngineSession
|
||||||
import mozilla.components.concept.engine.request.RequestInterceptor
|
import mozilla.components.concept.engine.request.RequestInterceptor
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
import org.mozilla.fenix.ext.tryGetHostFromUrl
|
|
||||||
|
|
||||||
class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
||||||
override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? {
|
override fun onLoadRequest(
|
||||||
val host = uri.tryGetHostFromUrl()
|
session: EngineSession,
|
||||||
|
uri: String
|
||||||
adjustTrackingProtection(host, context, session)
|
): RequestInterceptor.InterceptionResponse? {
|
||||||
|
adjustTrackingProtection(context, session)
|
||||||
// WebChannel-driven authentication does not require a separate redirect interceptor.
|
// WebChannel-driven authentication does not require a separate redirect interceptor.
|
||||||
return if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
|
return if (context.isInExperiment(Experiments.asFeatureWebChannelsDisabled)) {
|
||||||
context.components.services.accountsAuthFeature.interceptor.onLoadRequest(session, uri)
|
context.components.services.accountsAuthFeature.interceptor.onLoadRequest(session, uri)
|
||||||
|
@ -30,10 +28,9 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun adjustTrackingProtection(host: String, context: Context, session: EngineSession) {
|
private fun adjustTrackingProtection(context: Context, session: EngineSession) {
|
||||||
val trackingProtectionException = ExceptionDomains(context).load().contains(host)
|
|
||||||
val trackingProtectionEnabled = context.settings().shouldUseTrackingProtection
|
val trackingProtectionEnabled = context.settings().shouldUseTrackingProtection
|
||||||
if (trackingProtectionException || !trackingProtectionEnabled) {
|
if (!trackingProtectionEnabled) {
|
||||||
session.disableTrackingProtection()
|
session.disableTrackingProtection()
|
||||||
} else {
|
} else {
|
||||||
val core = context.components.core
|
val core = context.components.core
|
||||||
|
|
|
@ -36,6 +36,7 @@ import mozilla.appservices.places.BookmarkRoot
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.feature.contextmenu.ContextMenuCandidate
|
import mozilla.components.feature.contextmenu.ContextMenuCandidate
|
||||||
import mozilla.components.feature.readerview.ReaderViewFeature
|
import mozilla.components.feature.readerview.ReaderViewFeature
|
||||||
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
|
@ -224,14 +225,21 @@ class BrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navToTrackingProtectionPanel(session: Session) {
|
override fun navToTrackingProtectionPanel(session: Session) {
|
||||||
val directions =
|
val useCase = TrackingProtectionUseCases(
|
||||||
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(
|
sessionManager = requireComponents.core.sessionManager,
|
||||||
sessionId = session.id,
|
engine = requireComponents.core.engine
|
||||||
url = session.url,
|
)
|
||||||
trackingProtectionEnabled = session.trackerBlockingEnabled,
|
useCase.containsException(session) { contains ->
|
||||||
gravity = getAppropriateLayoutGravity()
|
val isEnabled = session.trackerBlockingEnabled && !contains
|
||||||
)
|
val directions =
|
||||||
nav(R.id.browserFragment, directions)
|
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(
|
||||||
|
sessionId = session.id,
|
||||||
|
url = session.url,
|
||||||
|
trackingProtectionEnabled = isEnabled,
|
||||||
|
gravity = getAppropriateLayoutGravity()
|
||||||
|
)
|
||||||
|
nav(R.id.browserFragment, directions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEngineMargins(): Pair<Int, Int> {
|
override fun getEngineMargins(): Pair<Int, Int> {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import mozilla.components.feature.pwa.ext.trustedOrigins
|
||||||
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
|
import mozilla.components.feature.pwa.feature.WebAppActivityFeature
|
||||||
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
|
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
|
||||||
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
|
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
|
||||||
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import mozilla.components.support.base.feature.BackHandler
|
import mozilla.components.support.base.feature.BackHandler
|
||||||
|
@ -154,15 +155,22 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), BackHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun navToTrackingProtectionPanel(session: Session) {
|
override fun navToTrackingProtectionPanel(session: Session) {
|
||||||
val directions =
|
val useCase = TrackingProtectionUseCases(
|
||||||
ExternalAppBrowserFragmentDirections
|
sessionManager = requireComponents.core.sessionManager,
|
||||||
.actionExternalAppBrowserFragmentToTrackingProtectionPanelDialogFragment(
|
engine = requireComponents.core.engine
|
||||||
sessionId = session.id,
|
)
|
||||||
url = session.url,
|
useCase.containsException(session) { contains ->
|
||||||
trackingProtectionEnabled = session.trackerBlockingEnabled,
|
val isEnabled = session.trackerBlockingEnabled && !contains
|
||||||
gravity = getAppropriateLayoutGravity()
|
val directions =
|
||||||
)
|
ExternalAppBrowserFragmentDirections
|
||||||
nav(R.id.externalAppBrowserFragment, directions)
|
.actionExternalAppBrowserFragmentToTrackingProtectionPanelDialogFragment(
|
||||||
|
sessionId = session.id,
|
||||||
|
url = session.url,
|
||||||
|
trackingProtectionEnabled = isEnabled,
|
||||||
|
gravity = getAppropriateLayoutGravity()
|
||||||
|
)
|
||||||
|
nav(R.id.externalAppBrowserFragment, directions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEngineMargins(): Pair<Int, Int> {
|
override fun getEngineMargins(): Pair<Int, Int> {
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
/* 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.exceptions
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import mozilla.components.support.ktx.android.content.PreferencesHolder
|
|
||||||
import mozilla.components.support.ktx.android.content.stringPreference
|
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
|
||||||
import org.mozilla.fenix.ext.metrics
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains functionality to manage custom domains for allow-list.
|
|
||||||
*/
|
|
||||||
class ExceptionDomains(val context: Context) : PreferencesHolder {
|
|
||||||
|
|
||||||
override val preferences: SharedPreferences =
|
|
||||||
context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE)
|
|
||||||
|
|
||||||
private var domains by stringPreference(KEY_DOMAINS, default = "")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the previously added/saved custom domains from preferences.
|
|
||||||
*
|
|
||||||
* @return list of custom domains
|
|
||||||
*/
|
|
||||||
fun load(): List<String> {
|
|
||||||
if (exceptions == null) {
|
|
||||||
exceptions = domains.split(SEPARATOR).filter { it.isNotEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
return exceptions.orEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the provided domains to preferences.
|
|
||||||
*
|
|
||||||
* @param domains list of domains
|
|
||||||
*/
|
|
||||||
fun save(domains: List<String>) {
|
|
||||||
exceptions = domains
|
|
||||||
|
|
||||||
this.domains = domains.joinToString(separator = SEPARATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the provided domain to preferences.
|
|
||||||
*
|
|
||||||
* @param domain the domain to add
|
|
||||||
*/
|
|
||||||
fun add(domain: String) {
|
|
||||||
save(domains = load() + domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the provided domain from preferences.
|
|
||||||
*
|
|
||||||
* @param domains the domain to remove
|
|
||||||
*/
|
|
||||||
fun remove(domains: List<String>) {
|
|
||||||
save(domains = load() - domains)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds or removes the provided domain from preferences.
|
|
||||||
*
|
|
||||||
* If present, the domain will be removed. Otherwise, it will be added.
|
|
||||||
*/
|
|
||||||
fun toggle(domain: String) {
|
|
||||||
if (domain in load()) {
|
|
||||||
remove(listOf(domain))
|
|
||||||
} else {
|
|
||||||
context.metrics.track(Event.TrackingProtectionException)
|
|
||||||
add(domain)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val PREFERENCE_NAME = "exceptions"
|
|
||||||
private const val KEY_DOMAINS = "exceptions_domains"
|
|
||||||
private const val SEPARATOR = "@<;>@"
|
|
||||||
|
|
||||||
private var exceptions: List<String>? = null
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,29 +5,28 @@
|
||||||
package org.mozilla.fenix.exceptions
|
package org.mozilla.fenix.exceptions
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
|
import kotlinx.android.synthetic.main.fragment_exceptions.view.*
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
|
||||||
import kotlinx.coroutines.Dispatchers.Main
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.coroutineScope
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import org.mozilla.fenix.BrowserDirection
|
import org.mozilla.fenix.BrowserDirection
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.StoreProvider
|
import org.mozilla.fenix.components.StoreProvider
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
|
|
||||||
class ExceptionsFragment : Fragment() {
|
class ExceptionsFragment : Fragment() {
|
||||||
private lateinit var exceptionsStore: ExceptionsFragmentStore
|
private lateinit var exceptionsStore: ExceptionsFragmentStore
|
||||||
private lateinit var exceptionsView: ExceptionsView
|
private lateinit var exceptionsView: ExceptionsView
|
||||||
private lateinit var exceptionsInteractor: ExceptionsInteractor
|
private lateinit var exceptionsInteractor: ExceptionsInteractor
|
||||||
|
private lateinit var trackingProtectionUseCases: TrackingProtectionUseCases
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
@ -41,16 +40,21 @@ class ExceptionsFragment : Fragment() {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
val view = inflater.inflate(R.layout.fragment_exceptions, container, false)
|
val view = inflater.inflate(R.layout.fragment_exceptions, container, false)
|
||||||
|
trackingProtectionUseCases = TrackingProtectionUseCases(
|
||||||
|
sessionManager = view.context.components.core.sessionManager,
|
||||||
|
engine = view.context.components.core.engine
|
||||||
|
)
|
||||||
exceptionsStore = StoreProvider.get(this) {
|
exceptionsStore = StoreProvider.get(this) {
|
||||||
ExceptionsFragmentStore(
|
ExceptionsFragmentStore(
|
||||||
ExceptionsFragmentState(
|
ExceptionsFragmentState(
|
||||||
items = loadAndMapExceptions()
|
items = listOf()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
exceptionsInteractor =
|
exceptionsInteractor =
|
||||||
ExceptionsInteractor(::openLearnMore, ::deleteOneItem, ::deleteAllItems)
|
ExceptionsInteractor(::openLearnMore, ::deleteOneItem, ::deleteAllItems)
|
||||||
exceptionsView = ExceptionsView(view.exceptionsLayout, exceptionsInteractor)
|
exceptionsView = ExceptionsView(view.exceptionsLayout, exceptionsInteractor)
|
||||||
|
reloadExceptions()
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,20 +67,15 @@ class ExceptionsFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteAllItems() {
|
private fun deleteAllItems() {
|
||||||
viewLifecycleOwner.lifecycleScope.launch(IO) {
|
trackingProtectionUseCases.removeAllExceptions()
|
||||||
ExceptionDomains(requireContext()).run {
|
reloadExceptions()
|
||||||
val domains = load()
|
|
||||||
remove(domains)
|
|
||||||
}
|
|
||||||
reloadData()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteOneItem(item: ExceptionsItem) {
|
private fun deleteOneItem(item: ExceptionsItem) {
|
||||||
viewLifecycleOwner.lifecycleScope.launch(IO) {
|
// We can't currently delete one item in this Exceptions list with a URL with the GV API
|
||||||
ExceptionDomains(requireContext()).remove(listOf(item.url))
|
// See https://github.com/mozilla-mobile/android-components/issues/4699
|
||||||
reloadData()
|
Log.e("Remove one exception", "$item")
|
||||||
}
|
reloadExceptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openLearnMore() {
|
private fun openLearnMore() {
|
||||||
|
@ -88,18 +87,13 @@ class ExceptionsFragment : Fragment() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAndMapExceptions(): List<ExceptionsItem> {
|
private fun reloadExceptions() {
|
||||||
return ExceptionDomains(requireContext()).load()
|
trackingProtectionUseCases.fetchExceptions { resultList ->
|
||||||
.map { item -> ExceptionsItem(item) }
|
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(resultList.map {
|
||||||
}
|
ExceptionsItem(
|
||||||
|
it
|
||||||
private suspend fun reloadData() {
|
)
|
||||||
val items = loadAndMapExceptions()
|
}))
|
||||||
|
|
||||||
coroutineScope {
|
|
||||||
launch(Main) {
|
|
||||||
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(items))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,14 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.feature.session.SessionUseCases.ReloadUrlUseCase
|
import mozilla.components.feature.session.SessionUseCases.ReloadUrlUseCase
|
||||||
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
|
import mozilla.components.feature.tabs.TabsUseCases.AddNewTabUseCase
|
||||||
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
|
import mozilla.components.support.base.feature.OnNeedToRequestPermissions
|
||||||
import org.mozilla.fenix.browser.BrowserFragment
|
import org.mozilla.fenix.browser.BrowserFragment
|
||||||
import org.mozilla.fenix.components.PermissionStorage
|
import org.mozilla.fenix.components.PermissionStorage
|
||||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.tryGetHostFromUrl
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
||||||
import org.mozilla.fenix.settings.toggle
|
import org.mozilla.fenix.settings.toggle
|
||||||
|
@ -36,9 +37,8 @@ interface QuickSettingsController {
|
||||||
/**
|
/**
|
||||||
* Handles turning on/off tracking protection.
|
* Handles turning on/off tracking protection.
|
||||||
*
|
*
|
||||||
* @param websiteUrl [String] the website URL for which to toggle tracking protection.
|
* */
|
||||||
*/
|
fun handleTrackingProtectionToggled(trackingEnabled: Boolean)
|
||||||
fun handleTrackingProtectionToggled(websiteUrl: String, trackingEnabled: Boolean)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles showing the tracking protection settings.
|
* Handles showing the tracking protection settings.
|
||||||
|
@ -89,7 +89,6 @@ interface QuickSettingsController {
|
||||||
* @param sitePermissions [SitePermissions]? list of website permissions and their status.
|
* @param sitePermissions [SitePermissions]? list of website permissions and their status.
|
||||||
* @param settings [Settings] application settings.
|
* @param settings [Settings] application settings.
|
||||||
* @param permissionStorage [PermissionStorage] app state for website permissions exception.
|
* @param permissionStorage [PermissionStorage] app state for website permissions exception.
|
||||||
* @param trackingExceptions [ExceptionDomains] allows setting whether to allow trackers or not.
|
|
||||||
* @param reload [ReloadUrlUseCase] callback allowing for reloading the current web page.
|
* @param reload [ReloadUrlUseCase] callback allowing for reloading the current web page.
|
||||||
* @param addNewTab [AddNewTabUseCase] callback allowing for loading a URL in a new tab.
|
* @param addNewTab [AddNewTabUseCase] callback allowing for loading a URL in a new tab.
|
||||||
* @param requestRuntimePermissions [OnNeedToRequestPermissions] callback allowing for requesting
|
* @param requestRuntimePermissions [OnNeedToRequestPermissions] callback allowing for requesting
|
||||||
|
@ -98,6 +97,7 @@ interface QuickSettingsController {
|
||||||
* @param displayTrackingProtection callback for when the [TrackingProtectionView] needs to be displayed.
|
* @param displayTrackingProtection callback for when the [TrackingProtectionView] needs to be displayed.
|
||||||
* @param displayPermissions callback for when [WebsitePermissionsView] needs to be displayed.
|
* @param displayPermissions callback for when [WebsitePermissionsView] needs to be displayed.
|
||||||
* @param dismiss callback allowing to request this entire Fragment to be dismissed.
|
* @param dismiss callback allowing to request this entire Fragment to be dismissed.
|
||||||
|
* @param trackingProtectionUseCases usecase allowing us to add or remove tracking protection exceptions
|
||||||
*/
|
*/
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
class DefaultQuickSettingsController(
|
class DefaultQuickSettingsController(
|
||||||
|
@ -109,22 +109,28 @@ class DefaultQuickSettingsController(
|
||||||
private var sitePermissions: SitePermissions?,
|
private var sitePermissions: SitePermissions?,
|
||||||
private val settings: Settings,
|
private val settings: Settings,
|
||||||
private val permissionStorage: PermissionStorage,
|
private val permissionStorage: PermissionStorage,
|
||||||
private val trackingExceptions: ExceptionDomains,
|
|
||||||
private val reload: ReloadUrlUseCase,
|
private val reload: ReloadUrlUseCase,
|
||||||
private val addNewTab: AddNewTabUseCase,
|
private val addNewTab: AddNewTabUseCase,
|
||||||
private val requestRuntimePermissions: OnNeedToRequestPermissions = { },
|
private val requestRuntimePermissions: OnNeedToRequestPermissions = { },
|
||||||
private val reportSiteIssue: () -> Unit,
|
private val reportSiteIssue: () -> Unit,
|
||||||
private val displayTrackingProtection: () -> Unit,
|
private val displayTrackingProtection: () -> Unit,
|
||||||
private val displayPermissions: () -> Unit,
|
private val displayPermissions: () -> Unit,
|
||||||
private val dismiss: () -> Unit
|
private val dismiss: () -> Unit,
|
||||||
|
private val trackingProtectionUseCases: TrackingProtectionUseCases
|
||||||
) : QuickSettingsController {
|
) : QuickSettingsController {
|
||||||
|
|
||||||
override fun handleTrackingProtectionToggled(
|
override fun handleTrackingProtectionToggled(
|
||||||
websiteUrl: String,
|
|
||||||
trackingEnabled: Boolean
|
trackingEnabled: Boolean
|
||||||
) {
|
) {
|
||||||
val host = websiteUrl.tryGetHostFromUrl()
|
session?.let {
|
||||||
trackingExceptions.toggle(host)
|
if (trackingEnabled) {
|
||||||
|
trackingProtectionUseCases.removeException(it)
|
||||||
|
} else {
|
||||||
|
context.metrics.track(Event.TrackingProtectionException)
|
||||||
|
trackingProtectionUseCases.addException(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reload(session)
|
reload(session)
|
||||||
|
|
||||||
quickSettingsStore.dispatch(
|
quickSettingsStore.dispatch(
|
||||||
|
@ -246,13 +252,17 @@ class DefaultQuickSettingsController(
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
PhoneFeature.CAMERA -> WebsitePermission.Camera(
|
PhoneFeature.CAMERA -> WebsitePermission.Camera(
|
||||||
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
|
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
|
||||||
|
)
|
||||||
PhoneFeature.LOCATION -> WebsitePermission.Location(
|
PhoneFeature.LOCATION -> WebsitePermission.Location(
|
||||||
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
|
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
|
||||||
|
)
|
||||||
PhoneFeature.MICROPHONE -> WebsitePermission.Microphone(
|
PhoneFeature.MICROPHONE -> WebsitePermission.Microphone(
|
||||||
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
|
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
|
||||||
|
)
|
||||||
PhoneFeature.NOTIFICATION -> WebsitePermission.Notification(
|
PhoneFeature.NOTIFICATION -> WebsitePermission.Notification(
|
||||||
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid)
|
defaultStatus, defaultVisible, defaultEnabled, defaultBlockedByAndroid
|
||||||
|
)
|
||||||
PhoneFeature.AUTOPLAY -> defaultWebsitePermission!! // fail-fast
|
PhoneFeature.AUTOPLAY -> defaultWebsitePermission!! // fail-fast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ class QuickSettingsInteractor(
|
||||||
controller.handleReportTrackingProblem(websiteUrl)
|
controller.handleReportTrackingProblem(websiteUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProtectionToggled(websiteUrl: String, trackingEnabled: Boolean) {
|
override fun onProtectionToggled(trackingEnabled: Boolean) {
|
||||||
controller.handleTrackingProtectionToggled(websiteUrl, trackingEnabled)
|
controller.handleTrackingProtectionToggled(trackingEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onProtectionSettingsSelected() {
|
override fun onProtectionSettingsSelected() {
|
||||||
|
|
|
@ -26,11 +26,11 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.*
|
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.*
|
||||||
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.view.*
|
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.view.*
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.IntentReceiverActivity
|
import org.mozilla.fenix.IntentReceiverActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
@ -50,7 +50,11 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
||||||
private lateinit var websiteTrackingProtectionView: TrackingProtectionView
|
private lateinit var websiteTrackingProtectionView: TrackingProtectionView
|
||||||
private lateinit var interactor: QuickSettingsInteractor
|
private lateinit var interactor: QuickSettingsInteractor
|
||||||
private val safeArguments get() = requireNotNull(arguments)
|
private val safeArguments get() = requireNotNull(arguments)
|
||||||
private val promptGravity: Int by lazy { QuickSettingsSheetDialogFragmentArgs.fromBundle(safeArguments).gravity }
|
private val promptGravity: Int by lazy {
|
||||||
|
QuickSettingsSheetDialogFragmentArgs.fromBundle(
|
||||||
|
safeArguments
|
||||||
|
).gravity
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
@ -80,7 +84,6 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
||||||
sitePermissions = args.sitePermissions,
|
sitePermissions = args.sitePermissions,
|
||||||
settings = Settings.getInstance(context),
|
settings = Settings.getInstance(context),
|
||||||
permissionStorage = context.components.core.permissionStorage,
|
permissionStorage = context.components.core.permissionStorage,
|
||||||
trackingExceptions = ExceptionDomains(context),
|
|
||||||
reload = context.components.useCases.sessionUseCases.reload,
|
reload = context.components.useCases.sessionUseCases.reload,
|
||||||
addNewTab = context.components.useCases.tabsUseCases.addTab,
|
addNewTab = context.components.useCases.tabsUseCases.addTab,
|
||||||
requestRuntimePermissions = { permissions ->
|
requestRuntimePermissions = { permissions ->
|
||||||
|
@ -89,13 +92,20 @@ class QuickSettingsSheetDialogFragment : AppCompatDialogFragment() {
|
||||||
reportSiteIssue = ::launchIntentReceiver,
|
reportSiteIssue = ::launchIntentReceiver,
|
||||||
displayTrackingProtection = ::showTrackingProtectionView,
|
displayTrackingProtection = ::showTrackingProtectionView,
|
||||||
displayPermissions = ::showPermissionsView,
|
displayPermissions = ::showPermissionsView,
|
||||||
dismiss = ::dismiss
|
dismiss = ::dismiss,
|
||||||
|
trackingProtectionUseCases = TrackingProtectionUseCases(
|
||||||
|
context.components.core.sessionManager,
|
||||||
|
context.components.core.engine
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
interactor = QuickSettingsInteractor(quickSettingsController)
|
interactor = QuickSettingsInteractor(quickSettingsController)
|
||||||
|
|
||||||
websiteTrackingProtectionView = TrackingProtectionView(rootView.trackingProtectionLayout, interactor)
|
websiteTrackingProtectionView =
|
||||||
|
TrackingProtectionView(rootView.trackingProtectionLayout, interactor)
|
||||||
websiteInfoView = WebsiteInfoView(rootView.websiteInfoLayout)
|
websiteInfoView = WebsiteInfoView(rootView.websiteInfoLayout)
|
||||||
websitePermissionsView = WebsitePermissionsView(rootView.websitePermissionsLayout, interactor)
|
websitePermissionsView =
|
||||||
|
WebsitePermissionsView(rootView.websitePermissionsLayout, interactor)
|
||||||
|
|
||||||
return rootView
|
return rootView
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ interface TrackingProtectionInteractor {
|
||||||
/**
|
/**
|
||||||
* Indicates the user want to toggle the tracking protection on / off.
|
* Indicates the user want to toggle the tracking protection on / off.
|
||||||
*/
|
*/
|
||||||
fun onProtectionToggled(websiteUrl: String, trackingEnabled: Boolean)
|
fun onProtectionToggled(trackingEnabled: Boolean)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates the user want to see all tracking protection settings.
|
* Indicates the user want to see all tracking protection settings.
|
||||||
|
@ -84,7 +84,7 @@ class TrackingProtectionView(
|
||||||
trackingProtectionSwitch.isEnabled = state.isTrackingProtectionEnabledPerApp
|
trackingProtectionSwitch.isEnabled = state.isTrackingProtectionEnabledPerApp
|
||||||
if (state.isTrackingProtectionEnabledPerApp) {
|
if (state.isTrackingProtectionEnabledPerApp) {
|
||||||
trackingProtectionSwitch.setOnCheckedChangeListener { _, isChecked ->
|
trackingProtectionSwitch.setOnCheckedChangeListener { _, isChecked ->
|
||||||
interactor.onProtectionToggled(state.websiteUrl, isChecked)
|
interactor.onProtectionToggled(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,10 @@ import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.StoreProvider
|
import org.mozilla.fenix.components.StoreProvider
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.metrics
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.ext.nav
|
import org.mozilla.fenix.ext.nav
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.tryGetHostFromUrl
|
|
||||||
|
|
||||||
class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHandler {
|
class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHandler {
|
||||||
|
|
||||||
|
@ -172,12 +170,22 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||||
|
|
||||||
private fun toggleTrackingProtection(isEnabled: Boolean) {
|
private fun toggleTrackingProtection(isEnabled: Boolean) {
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val host = url.tryGetHostFromUrl()
|
val useCase = TrackingProtectionUseCases(
|
||||||
lifecycleScope.launch {
|
sessionManager = context.components.core.sessionManager,
|
||||||
ExceptionDomains(context).toggle(host)
|
engine = context.components.core.engine
|
||||||
}
|
)
|
||||||
with(context.components) {
|
val session = context.components.core.sessionManager.findSessionById(sessionId)
|
||||||
useCases.sessionUseCases.reload.invoke(core.sessionManager.findSessionById(sessionId))
|
session?.let {
|
||||||
|
if (isEnabled) {
|
||||||
|
useCase.removeException(it)
|
||||||
|
} else {
|
||||||
|
context.metrics.track(Event.TrackingProtectionException)
|
||||||
|
useCase.addException(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(context.components) {
|
||||||
|
useCases.sessionUseCases.reload.invoke(session)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerBlockingChanged(isEnabled))
|
trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerBlockingChanged(isEnabled))
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
tools:text="mozilla.org" />
|
tools:text="mozilla.org" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
android:visibility="gone"
|
||||||
android:id="@+id/delete_exception"
|
android:id="@+id/delete_exception"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -24,6 +24,7 @@ import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import mozilla.components.browser.session.Session
|
import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.feature.session.SessionUseCases
|
import mozilla.components.feature.session.SessionUseCases
|
||||||
|
import mozilla.components.feature.session.TrackingProtectionUseCases
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||||
import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION
|
import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
|
@ -33,7 +34,8 @@ import org.junit.runner.RunWith
|
||||||
import org.mozilla.fenix.TestApplication
|
import org.mozilla.fenix.TestApplication
|
||||||
import org.mozilla.fenix.browser.BrowserFragment
|
import org.mozilla.fenix.browser.BrowserFragment
|
||||||
import org.mozilla.fenix.components.PermissionStorage
|
import org.mozilla.fenix.components.PermissionStorage
|
||||||
import org.mozilla.fenix.exceptions.ExceptionDomains
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.metrics
|
||||||
import org.mozilla.fenix.settings.PhoneFeature
|
import org.mozilla.fenix.settings.PhoneFeature
|
||||||
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
|
||||||
import org.mozilla.fenix.settings.toggle
|
import org.mozilla.fenix.settings.toggle
|
||||||
|
@ -53,7 +55,6 @@ class DefaultQuickSettingsControllerTest {
|
||||||
private val sitePermissions = SitePermissions(origin = "", savedAt = 123)
|
private val sitePermissions = SitePermissions(origin = "", savedAt = 123)
|
||||||
private val appSettings = mockk<Settings>(relaxed = true)
|
private val appSettings = mockk<Settings>(relaxed = true)
|
||||||
private val permissionStorage = mockk<PermissionStorage>(relaxed = true)
|
private val permissionStorage = mockk<PermissionStorage>(relaxed = true)
|
||||||
private val trackingExceptions = mockk<ExceptionDomains>(relaxed = true)
|
|
||||||
private val reload = mockk<SessionUseCases.ReloadUrlUseCase>(relaxed = true)
|
private val reload = mockk<SessionUseCases.ReloadUrlUseCase>(relaxed = true)
|
||||||
private val addNewTab = mockk<TabsUseCases.AddNewTabUseCase>(relaxed = true)
|
private val addNewTab = mockk<TabsUseCases.AddNewTabUseCase>(relaxed = true)
|
||||||
private val requestPermissions = mockk<(Array<String>) -> Unit>(relaxed = true)
|
private val requestPermissions = mockk<(Array<String>) -> Unit>(relaxed = true)
|
||||||
|
@ -61,6 +62,7 @@ class DefaultQuickSettingsControllerTest {
|
||||||
private val displayTrackingProtection = mockk<() -> Unit>(relaxed = true)
|
private val displayTrackingProtection = mockk<() -> Unit>(relaxed = true)
|
||||||
private val displayPermissions = mockk<() -> Unit>(relaxed = true)
|
private val displayPermissions = mockk<() -> Unit>(relaxed = true)
|
||||||
private val dismiss = mockk<() -> Unit>(relaxed = true)
|
private val dismiss = mockk<() -> Unit>(relaxed = true)
|
||||||
|
private val trackingProtectionUseCases = mockk<TrackingProtectionUseCases>(relaxed = true)
|
||||||
private val controller = DefaultQuickSettingsController(
|
private val controller = DefaultQuickSettingsController(
|
||||||
context = context,
|
context = context,
|
||||||
quickSettingsStore = store,
|
quickSettingsStore = store,
|
||||||
|
@ -70,32 +72,30 @@ class DefaultQuickSettingsControllerTest {
|
||||||
sitePermissions = sitePermissions,
|
sitePermissions = sitePermissions,
|
||||||
settings = appSettings,
|
settings = appSettings,
|
||||||
permissionStorage = permissionStorage,
|
permissionStorage = permissionStorage,
|
||||||
trackingExceptions = trackingExceptions,
|
|
||||||
reload = reload,
|
reload = reload,
|
||||||
addNewTab = addNewTab,
|
addNewTab = addNewTab,
|
||||||
requestRuntimePermissions = requestPermissions,
|
requestRuntimePermissions = requestPermissions,
|
||||||
reportSiteIssue = reportIssue,
|
reportSiteIssue = reportIssue,
|
||||||
displayTrackingProtection = displayTrackingProtection,
|
displayTrackingProtection = displayTrackingProtection,
|
||||||
displayPermissions = displayPermissions,
|
displayPermissions = displayPermissions,
|
||||||
dismiss = dismiss
|
dismiss = dismiss,
|
||||||
|
trackingProtectionUseCases = trackingProtectionUseCases
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `handleTrackingProtectionToggled should toggle tracking and reload website`() {
|
fun `handleTrackingProtectionToggled should toggle tracking and reload website`() {
|
||||||
val testWebsiteHost = "host.com"
|
|
||||||
val websiteHost = slot<String>()
|
|
||||||
val session = slot<Session>()
|
val session = slot<Session>()
|
||||||
every { store.dispatch(any()) } returns mockk()
|
every { store.dispatch(any()) } returns mockk()
|
||||||
|
|
||||||
controller.handleTrackingProtectionToggled("https://$testWebsiteHost/page1", false)
|
controller.handleTrackingProtectionToggled(false)
|
||||||
|
|
||||||
verifyOrder {
|
verifyOrder {
|
||||||
trackingExceptions.toggle(capture(websiteHost))
|
trackingProtectionUseCases.addException(capture(session))
|
||||||
|
context.metrics.track(Event.TrackingProtectionException)
|
||||||
reload(capture(session))
|
reload(capture(session))
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAll {
|
assertAll {
|
||||||
assertThat(websiteHost.isCaptured).isTrue()
|
|
||||||
assertThat(websiteHost.captured).isEqualTo(testWebsiteHost)
|
|
||||||
assertThat(session.isCaptured).isTrue()
|
assertThat(session.isCaptured).isTrue()
|
||||||
assertThat(session.captured).isEqualTo(browserSession)
|
assertThat(session.captured).isEqualTo(browserSession)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,8 @@ class DefaultQuickSettingsControllerTest {
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
fun `handleReportTrackingProblem should open a report issue webpage and dismiss when in normal mode`() {
|
fun `handleReportTrackingProblem should open a report issue webpage and dismiss when in normal mode`() {
|
||||||
val websiteWithIssuesUrl = "https://host.com/page1"
|
val websiteWithIssuesUrl = "https://host.com/page1"
|
||||||
val testReportUrl = String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
|
val testReportUrl =
|
||||||
|
String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
|
||||||
val reportUrl = slot<String>()
|
val reportUrl = slot<String>()
|
||||||
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
|
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
|
||||||
every { browserSession.isCustomTabSession() } returns false
|
every { browserSession.isCustomTabSession() } returns false
|
||||||
|
@ -140,7 +141,8 @@ class DefaultQuickSettingsControllerTest {
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
fun `handleReportTrackingProblem should open a report issue in browser from custom tab and dismiss`() {
|
fun `handleReportTrackingProblem should open a report issue in browser from custom tab and dismiss`() {
|
||||||
val websiteWithIssuesUrl = "https://host.com/page1"
|
val websiteWithIssuesUrl = "https://host.com/page1"
|
||||||
val testReportUrl = String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
|
val testReportUrl =
|
||||||
|
String.format(BrowserFragment.REPORT_SITE_ISSUE_URL, websiteWithIssuesUrl)
|
||||||
val reportUrl = slot<String>()
|
val reportUrl = slot<String>()
|
||||||
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
|
// `handleReportTrackingProblem` will behave differently depending on `isCustomTabSession`
|
||||||
every { browserSession.isCustomTabSession() } returns true
|
every { browserSession.isCustomTabSession() } returns true
|
||||||
|
@ -237,7 +239,8 @@ class DefaultQuickSettingsControllerTest {
|
||||||
featureGranted.getCorrespondingPermission()
|
featureGranted.getCorrespondingPermission()
|
||||||
}
|
}
|
||||||
val permissionStatus = featureGranted.getActionLabel(context, sitePermissions, appSettings)
|
val permissionStatus = featureGranted.getActionLabel(context, sitePermissions, appSettings)
|
||||||
val permissionEnabled = featureGranted.shouldBeEnabled(context, sitePermissions, appSettings)
|
val permissionEnabled =
|
||||||
|
featureGranted.shouldBeEnabled(context, sitePermissions, appSettings)
|
||||||
val action = slot<QuickSettingsFragmentAction>()
|
val action = slot<QuickSettingsFragmentAction>()
|
||||||
every { store.dispatch(any()) } returns mockk()
|
every { store.dispatch(any()) } returns mockk()
|
||||||
|
|
||||||
|
@ -249,9 +252,15 @@ class DefaultQuickSettingsControllerTest {
|
||||||
assertAll {
|
assertAll {
|
||||||
assertThat(action.isCaptured).isTrue()
|
assertThat(action.isCaptured).isTrue()
|
||||||
assertThat(action.captured).isInstanceOf(WebsitePermissionAction.TogglePermission::class)
|
assertThat(action.captured).isInstanceOf(WebsitePermissionAction.TogglePermission::class)
|
||||||
assertThat((action.captured as WebsitePermissionAction.TogglePermission).websitePermission).isEqualTo(permission)
|
assertThat((action.captured as WebsitePermissionAction.TogglePermission).websitePermission).isEqualTo(
|
||||||
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedStatus).isEqualTo(permissionStatus)
|
permission
|
||||||
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedEnabledStatus).isEqualTo(permissionEnabled)
|
)
|
||||||
|
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedStatus).isEqualTo(
|
||||||
|
permissionStatus
|
||||||
|
)
|
||||||
|
assertThat((action.captured as WebsitePermissionAction.TogglePermission).updatedEnabledStatus).isEqualTo(
|
||||||
|
permissionEnabled
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,24 +281,25 @@ class DefaultQuickSettingsControllerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
fun `handlePermissionsChange should store the updated permission and reload webpage`() = runBlocking {
|
fun `handlePermissionsChange should store the updated permission and reload webpage`() =
|
||||||
val testPermissions = mockk<SitePermissions>()
|
runBlocking {
|
||||||
val permissions = slot<SitePermissions>()
|
val testPermissions = mockk<SitePermissions>()
|
||||||
val session = slot<Session>()
|
val permissions = slot<SitePermissions>()
|
||||||
|
val session = slot<Session>()
|
||||||
|
|
||||||
controller.handlePermissionsChange(testPermissions)
|
controller.handlePermissionsChange(testPermissions)
|
||||||
|
|
||||||
verifyOrder {
|
verifyOrder {
|
||||||
permissionStorage.updateSitePermissions(capture(permissions))
|
permissionStorage.updateSitePermissions(capture(permissions))
|
||||||
reload(capture(session))
|
reload(capture(session))
|
||||||
|
}
|
||||||
|
assertAll {
|
||||||
|
assertThat(permissions.isCaptured).isTrue()
|
||||||
|
assertThat(permissions.captured).isEqualTo(testPermissions)
|
||||||
|
assertThat(session.isCaptured).isTrue()
|
||||||
|
assertThat(session.captured).isEqualTo(browserSession)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assertAll {
|
|
||||||
assertThat(permissions.isCaptured).isTrue()
|
|
||||||
assertThat(permissions.captured).isEqualTo(testPermissions)
|
|
||||||
assertThat(session.isCaptured).isTrue()
|
|
||||||
assertThat(session.captured).isEqualTo(browserSession)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `WebsitePermission#getBackingFeature should return the PhoneFeature this permission is mapped from`() {
|
fun `WebsitePermission#getBackingFeature should return the PhoneFeature this permission is mapped from`() {
|
||||||
|
|
|
@ -36,20 +36,15 @@ class QuickSettingsInteractorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `onProtectionToggled should delegate the controller`() {
|
fun `onProtectionToggled should delegate the controller`() {
|
||||||
val websiteUrl = "https://host.com/page1"
|
|
||||||
val trackingEnabled = true
|
val trackingEnabled = true
|
||||||
val url = slot<String>()
|
|
||||||
val trackingStatus = slot<Boolean>()
|
val trackingStatus = slot<Boolean>()
|
||||||
|
|
||||||
interactor.onProtectionToggled(websiteUrl, trackingEnabled)
|
interactor.onProtectionToggled(trackingEnabled)
|
||||||
|
|
||||||
verifyAll {
|
verifyAll {
|
||||||
controller.handleTrackingProtectionToggled(capture(url), capture(trackingStatus))
|
controller.handleTrackingProtectionToggled(capture(trackingStatus))
|
||||||
}
|
}
|
||||||
assertAll {
|
assertAll {
|
||||||
assertThat(url.isCaptured).isTrue()
|
|
||||||
assertThat(url.captured).isEqualTo(websiteUrl)
|
|
||||||
|
|
||||||
assertThat(trackingStatus.isCaptured).isTrue()
|
assertThat(trackingStatus.isCaptured).isTrue()
|
||||||
assertThat(trackingStatus.captured).isEqualTo(trackingEnabled)
|
assertThat(trackingStatus.captured).isEqualTo(trackingEnabled)
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ The following metrics are added to the ping:
|
||||||
| sync_auth.sign_up |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User registered a new Firefox Account, and was signed into it |[1](https://github.com/mozilla-mobile/fenix/pull/4931#issuecomment-529740300)||2020-03-01 |
|
| sync_auth.sign_up |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |User registered a new Firefox Account, and was signed into it |[1](https://github.com/mozilla-mobile/fenix/pull/4931#issuecomment-529740300)||2020-03-01 |
|
||||||
| tab.media_pause |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the pause icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
|
| tab.media_pause |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the pause icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
|
||||||
| tab.media_play |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the play icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
|
| tab.media_play |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the play icon on a tab from the home screen |[1](https://github.com/mozilla-mobile/fenix/pull/5266)||2020-03-01 |
|
||||||
| tracking_protection.etp_setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user added a tracking protection exception through the TP toggle in the panel. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)|<ul><li>etp_setting: The new setting for ETP: strict, standard</li></ul>|2020-03-01 |
|
| tracking_protection.etp_setting_changed |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user changed their tracking protection level setting to either strict or standard. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)|<ul><li>etp_setting: The new setting for ETP: strict, standard</li></ul>|2020-03-01 |
|
||||||
| tracking_protection.etp_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened tracking protection settings through settings. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
| tracking_protection.etp_settings |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user opened tracking protection settings through settings. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
||||||
| tracking_protection.etp_shield |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the tracking protection shield icon in toolbar. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
| tracking_protection.etp_shield |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed the tracking protection shield icon in toolbar. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
||||||
| tracking_protection.etp_tracker_list |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed into a list of categorized trackers in tracking protection panel. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
| tracking_protection.etp_tracker_list |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user pressed into a list of categorized trackers in tracking protection panel. |[1](https://github.com/mozilla-mobile/fenix/pull/5414#issuecomment-532847188)||2020-03-01 |
|
||||||
|
|
Loading…
Reference in New Issue