mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] Clean up tracking protection fragment (https://github.com/mozilla-mobile/fenix/pull/6532)
* Clean up exceptions fragment * Clean up tracking protection fragment * Move saved logins to list adapter
This commit is contained in:
parent
38e97e4f16
commit
aacb184521
@ -313,8 +313,8 @@ class CollectionCreationView(
|
||||
}
|
||||
}
|
||||
|
||||
fun onKey(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
return if (event?.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
fun onKey(keyCode: Int, event: KeyEvent): Boolean {
|
||||
return if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
interactor.onBackPressed(step)
|
||||
true
|
||||
} else {
|
||||
|
@ -6,50 +6,44 @@ package org.mozilla.fenix.exceptions
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.mozilla.fenix.exceptions.viewholders.ExceptionsDeleteButtonViewHolder
|
||||
import org.mozilla.fenix.exceptions.viewholders.ExceptionsHeaderViewHolder
|
||||
import org.mozilla.fenix.exceptions.viewholders.ExceptionsListItemViewHolder
|
||||
|
||||
private sealed class AdapterItem {
|
||||
sealed class AdapterItem {
|
||||
object DeleteButton : AdapterItem()
|
||||
object Header : AdapterItem()
|
||||
data class Item(val item: ExceptionsItem) : AdapterItem()
|
||||
}
|
||||
|
||||
private class ExceptionsList(val exceptions: List<ExceptionsItem>) {
|
||||
val items: List<AdapterItem>
|
||||
|
||||
init {
|
||||
val items = mutableListOf<AdapterItem>()
|
||||
items.add(AdapterItem.Header)
|
||||
for (exception in exceptions) {
|
||||
items.add(AdapterItem.Item(exception))
|
||||
}
|
||||
items.add(AdapterItem.DeleteButton)
|
||||
this.items = items
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter for a list of sites that are exempted from Tracking Protection,
|
||||
* along with controls to remove the exception.
|
||||
*/
|
||||
class ExceptionsAdapter(
|
||||
private val interactor: ExceptionsInteractor
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
private var exceptionsList: ExceptionsList = ExceptionsList(emptyList())
|
||||
) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(DiffCallback) {
|
||||
|
||||
fun updateData(items: List<ExceptionsItem>) {
|
||||
this.exceptionsList = ExceptionsList(items)
|
||||
notifyDataSetChanged()
|
||||
/**
|
||||
* Change the list of items that are displayed.
|
||||
* Header and footer items are added to the list as well.
|
||||
*/
|
||||
fun updateData(exceptions: List<ExceptionsItem>) {
|
||||
val adapterItems = mutableListOf<AdapterItem>()
|
||||
adapterItems.add(AdapterItem.Header)
|
||||
exceptions.mapTo(adapterItems) { AdapterItem.Item(it) }
|
||||
adapterItems.add(AdapterItem.DeleteButton)
|
||||
submitList(adapterItems)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = exceptionsList.items.size
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (exceptionsList.items[position]) {
|
||||
is AdapterItem.DeleteButton -> ExceptionsDeleteButtonViewHolder.LAYOUT_ID
|
||||
is AdapterItem.Header -> ExceptionsHeaderViewHolder.LAYOUT_ID
|
||||
override fun getItemViewType(position: Int) = when (getItem(position)) {
|
||||
AdapterItem.DeleteButton -> ExceptionsDeleteButtonViewHolder.LAYOUT_ID
|
||||
AdapterItem.Header -> ExceptionsHeaderViewHolder.LAYOUT_ID
|
||||
is AdapterItem.Item -> ExceptionsListItemViewHolder.LAYOUT_ID
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
||||
@ -66,10 +60,18 @@ class ExceptionsAdapter(
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is ExceptionsListItemViewHolder -> (exceptionsList.items[position] as AdapterItem.Item).also {
|
||||
holder.bind(it.item)
|
||||
if (holder is ExceptionsListItemViewHolder) {
|
||||
val adapterItem = getItem(position) as AdapterItem.Item
|
||||
holder.bind(adapterItem.item)
|
||||
}
|
||||
}
|
||||
|
||||
private object DiffCallback : DiffUtil.ItemCallback<AdapterItem>() {
|
||||
override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
|
||||
areContentsTheSame(oldItem, newItem)
|
||||
|
||||
@Suppress("DiffUtilEquals")
|
||||
override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) =
|
||||
oldItem == newItem
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ import org.mozilla.fenix.components.StoreProvider
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
|
||||
/**
|
||||
* Displays a list of sites that are exempted from Tracking Protection,
|
||||
* along with controls to remove the exception.
|
||||
*/
|
||||
class ExceptionsFragment : Fragment() {
|
||||
private lateinit var exceptionsStore: ExceptionsFragmentStore
|
||||
private lateinit var exceptionsView: ExceptionsView
|
||||
@ -89,11 +93,8 @@ class ExceptionsFragment : Fragment() {
|
||||
|
||||
private fun reloadExceptions() {
|
||||
trackingProtectionUseCases.fetchExceptions { resultList ->
|
||||
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(resultList.map {
|
||||
ExceptionsItem(
|
||||
it
|
||||
)
|
||||
}))
|
||||
val exceptionsList = resultList.map { ExceptionsItem(it) }
|
||||
exceptionsStore.dispatch(ExceptionsFragmentAction.Change(exceptionsList))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import android.text.SpannableString
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.text.style.UnderlineSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.component_exceptions.view.*
|
||||
@ -41,21 +41,20 @@ interface ExceptionsViewInteractor {
|
||||
* View that contains and configures the Exceptions List
|
||||
*/
|
||||
class ExceptionsView(
|
||||
private val container: ViewGroup,
|
||||
override val containerView: ViewGroup,
|
||||
val interactor: ExceptionsInteractor
|
||||
) : LayoutContainer {
|
||||
|
||||
val view: FrameLayout = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_exceptions, container, true)
|
||||
val view: FrameLayout = LayoutInflater.from(containerView.context)
|
||||
.inflate(R.layout.component_exceptions, containerView, true)
|
||||
.findViewById(R.id.exceptions_wrapper)
|
||||
|
||||
override val containerView: View?
|
||||
get() = container
|
||||
private val exceptionsAdapter = ExceptionsAdapter(interactor)
|
||||
|
||||
init {
|
||||
view.exceptions_list.apply {
|
||||
adapter = ExceptionsAdapter(interactor)
|
||||
layoutManager = LinearLayoutManager(container.context)
|
||||
adapter = exceptionsAdapter
|
||||
layoutManager = LinearLayoutManager(containerView.context)
|
||||
}
|
||||
val learnMoreText = view.exceptions_learn_more.text.toString()
|
||||
val textWithLink = SpannableString(learnMoreText).apply {
|
||||
@ -69,9 +68,8 @@ class ExceptionsView(
|
||||
}
|
||||
|
||||
fun update(state: ExceptionsFragmentState) {
|
||||
view.exceptions_empty_view.visibility =
|
||||
if (state.items.isEmpty()) View.VISIBLE else View.GONE
|
||||
view.exceptions_list.visibility = if (state.items.isEmpty()) View.GONE else View.VISIBLE
|
||||
(view.exceptions_list.adapter as ExceptionsAdapter).updateData(state.items)
|
||||
view.exceptions_empty_view.isVisible = state.items.isEmpty()
|
||||
view.exceptions_list.isVisible = state.items.isNotEmpty()
|
||||
exceptionsAdapter.updateData(state.items)
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,9 @@ import org.mozilla.fenix.exceptions.ExceptionsItem
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.loadIntoView
|
||||
|
||||
/**
|
||||
* View holder for a single website that is exempted from Tracking Protection.
|
||||
*/
|
||||
class ExceptionsListItemViewHolder(
|
||||
view: View,
|
||||
private val interactor: ExceptionsInteractor
|
||||
|
@ -6,51 +6,31 @@ package org.mozilla.fenix.logins
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
|
||||
private sealed class AdapterItem {
|
||||
data class Item(val item: SavedLoginsItem) : AdapterItem()
|
||||
}
|
||||
|
||||
private class SavedLoginsList(savedLogins: List<SavedLoginsItem>) {
|
||||
val items: List<AdapterItem> = savedLogins.map { AdapterItem.Item(it) }
|
||||
}
|
||||
|
||||
class SavedLoginsAdapter(
|
||||
private val interactor: SavedLoginsInteractor
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
private var savedLoginsList: SavedLoginsList = SavedLoginsList(emptyList())
|
||||
) : ListAdapter<SavedLoginsItem, SavedLoginsListItemViewHolder>(DiffCallback) {
|
||||
|
||||
fun updateData(items: List<SavedLoginsItem>) {
|
||||
this.savedLoginsList = SavedLoginsList(items)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = savedLoginsList.items.size
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (savedLoginsList.items[position]) {
|
||||
is AdapterItem.Item -> SavedLoginsListItemViewHolder.LAYOUT_ID
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SavedLoginsListItemViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
|
||||
|
||||
return when (viewType) {
|
||||
SavedLoginsListItemViewHolder.LAYOUT_ID -> SavedLoginsListItemViewHolder(
|
||||
view,
|
||||
interactor
|
||||
)
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
return SavedLoginsListItemViewHolder(view, interactor)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is SavedLoginsListItemViewHolder -> (savedLoginsList.items[position] as AdapterItem.Item).also {
|
||||
holder.bind(it.item)
|
||||
}
|
||||
override fun onBindViewHolder(holder: SavedLoginsListItemViewHolder, position: Int) {
|
||||
holder.bind(getItem(position))
|
||||
}
|
||||
|
||||
private object DiffCallback : DiffUtil.ItemCallback<SavedLoginsItem>() {
|
||||
override fun areItemsTheSame(oldItem: SavedLoginsItem, newItem: SavedLoginsItem) =
|
||||
oldItem.url == newItem.url
|
||||
|
||||
override fun areContentsTheSame(oldItem: SavedLoginsItem, newItem: SavedLoginsItem) =
|
||||
oldItem == newItem
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,12 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import kotlinx.android.synthetic.main.fragment_saved_logins.view.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import mozilla.components.lib.state.ext.consumeFrom
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.StoreProvider
|
||||
@ -56,7 +56,7 @@ class SavedLoginsFragment : Fragment() {
|
||||
}
|
||||
savedLoginsInteractor = SavedLoginsInteractor(::itemClicked)
|
||||
savedLoginsView = SavedLoginsView(view.savedLoginsLayout, savedLoginsInteractor)
|
||||
loadAndMapLogins()
|
||||
lifecycleScope.launch(Main) { loadAndMapLogins() }
|
||||
return view
|
||||
}
|
||||
|
||||
@ -69,8 +69,10 @@ class SavedLoginsFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we pause this fragment, we want to pop users back to reauth
|
||||
*/
|
||||
override fun onPause() {
|
||||
// If we pause this fragment, we want to pop users back to reauth
|
||||
if (findNavController().currentDestination?.id != R.id.savedLoginSiteInfoFragment) {
|
||||
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
findNavController().popBackStack(R.id.loginsFragment, false)
|
||||
@ -85,22 +87,16 @@ class SavedLoginsFragment : Fragment() {
|
||||
findNavController().navigate(directions)
|
||||
}
|
||||
|
||||
private fun loadAndMapLogins() {
|
||||
lifecycleScope.launch(IO) {
|
||||
val syncedLogins = async {
|
||||
context!!.components.core.passwordsStorage.withUnlocked {
|
||||
private suspend fun loadAndMapLogins() {
|
||||
val syncedLogins = withContext(IO) {
|
||||
requireContext().components.core.passwordsStorage.withUnlocked {
|
||||
it.list().await().map { item ->
|
||||
SavedLoginsItem(
|
||||
item.hostname,
|
||||
item.username,
|
||||
item.password
|
||||
)
|
||||
SavedLoginsItem(item.hostname, item.username, item.password)
|
||||
}
|
||||
}
|
||||
}.await()
|
||||
launch(Dispatchers.Main) {
|
||||
}
|
||||
withContext(Main) {
|
||||
savedLoginsStore.dispatch(SavedLoginsFragmentAction.UpdateLogins(syncedLogins))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
package org.mozilla.fenix.logins
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.isVisible
|
||||
@ -29,26 +28,25 @@ interface SavedLoginsViewInteractor {
|
||||
* View that contains and configures the Saved Logins List
|
||||
*/
|
||||
class SavedLoginsView(
|
||||
private val container: ViewGroup,
|
||||
override val containerView: ViewGroup,
|
||||
val interactor: SavedLoginsInteractor
|
||||
) : LayoutContainer {
|
||||
|
||||
val view: FrameLayout = LayoutInflater.from(container.context)
|
||||
.inflate(R.layout.component_saved_logins, container, true)
|
||||
val view: FrameLayout = LayoutInflater.from(containerView.context)
|
||||
.inflate(R.layout.component_saved_logins, containerView, true)
|
||||
.findViewById(R.id.saved_logins_wrapper)
|
||||
|
||||
override val containerView: View?
|
||||
get() = container
|
||||
private val loginsAdapter = SavedLoginsAdapter(interactor)
|
||||
|
||||
init {
|
||||
view.saved_logins_list.apply {
|
||||
adapter = SavedLoginsAdapter(interactor)
|
||||
layoutManager = LinearLayoutManager(container.context)
|
||||
adapter = loginsAdapter
|
||||
layoutManager = LinearLayoutManager(containerView.context)
|
||||
}
|
||||
}
|
||||
|
||||
fun update(state: SavedLoginsFragmentState) {
|
||||
view.saved_logins_list.isVisible = state.items.isNotEmpty()
|
||||
(view.saved_logins_list.adapter as SavedLoginsAdapter).updateData(state.items)
|
||||
loginsAdapter.submitList(state.items)
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,6 @@
|
||||
package org.mozilla.fenix.trackingprotection
|
||||
|
||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory
|
||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.CRYPTOMINING
|
||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING
|
||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.MOZILLA_SOCIAL
|
||||
import mozilla.components.concept.engine.content.blocking.Tracker
|
||||
import mozilla.components.concept.engine.content.blocking.TrackerLog
|
||||
import org.mozilla.fenix.ext.tryGetHostFromUrl
|
||||
@ -27,7 +24,7 @@ class TrackerBuckets {
|
||||
|
||||
private var trackers = emptyList<TrackerLog>()
|
||||
|
||||
data class BucketedTrackerLog(var blockedBucketMap: BucketMap, var loadedBucketMap: BucketMap)
|
||||
data class BucketedTrackerLog(val blockedBucketMap: BucketMap, val loadedBucketMap: BucketMap)
|
||||
|
||||
var buckets: BucketedTrackerLog = BucketedTrackerLog(emptyMap(), emptyMap())
|
||||
private set
|
||||
@ -60,78 +57,63 @@ class TrackerBuckets {
|
||||
if (blocked) buckets.blockedBucketMap[key].orEmpty() else buckets.loadedBucketMap[key].orEmpty()
|
||||
|
||||
companion object {
|
||||
@Suppress("ComplexMethod")
|
||||
|
||||
private fun putTrackersInBuckets(
|
||||
list: List<TrackerLog>
|
||||
): BucketedTrackerLog {
|
||||
val blockedMap =
|
||||
EnumMap<TrackingProtectionCategory, List<String>>(TrackingProtectionCategory::class.java)
|
||||
val loadedMap =
|
||||
EnumMap<TrackingProtectionCategory, List<String>>(TrackingProtectionCategory::class.java)
|
||||
val blockedMap = createMap()
|
||||
val loadedMap = createMap()
|
||||
for (item in list) {
|
||||
|
||||
if (item.cookiesHasBeenBlocked) {
|
||||
blockedMap[CROSS_SITE_TRACKING_COOKIES] =
|
||||
blockedMap[CROSS_SITE_TRACKING_COOKIES].orEmpty() + item.url.tryGetHostFromUrl()
|
||||
blockedMap.addTrackerHost(CROSS_SITE_TRACKING_COOKIES, item)
|
||||
}
|
||||
|
||||
// Blocked categories
|
||||
bucketBlockedCategories(item, blockedMap)
|
||||
for (category in item.blockedCategories) {
|
||||
blockedMap.addTrackerHost(category, item)
|
||||
}
|
||||
|
||||
// Loaded categories
|
||||
bucketLoadedCategories(item, loadedMap)
|
||||
for (category in item.loadedCategories) {
|
||||
loadedMap.addTrackerHost(category, item)
|
||||
}
|
||||
}
|
||||
return BucketedTrackerLog(blockedMap, loadedMap)
|
||||
}
|
||||
|
||||
private fun bucketLoadedCategories(
|
||||
item: TrackerLog,
|
||||
loadedMap: EnumMap<TrackingProtectionCategory, List<String>>
|
||||
/**
|
||||
* Create an empty mutable map of [TrackingProtectionCategory] to hostnames.
|
||||
*/
|
||||
private fun createMap() =
|
||||
EnumMap<TrackingProtectionCategory, MutableList<String>>(TrackingProtectionCategory::class.java)
|
||||
|
||||
/**
|
||||
* Add the hostname of the [TrackerLog.url] into the map for the given category
|
||||
* from Android Components. The category is transformed into a corresponding Fenix bucket,
|
||||
* and the item is discarded if the category doesn't have a match.
|
||||
*/
|
||||
private fun MutableMap<TrackingProtectionCategory, MutableList<String>>.addTrackerHost(
|
||||
category: TrackingCategory,
|
||||
tracker: TrackerLog
|
||||
) {
|
||||
item.loadedCategories.forEach { category ->
|
||||
if (CRYPTOMINING == category) {
|
||||
loadedMap[CRYPTOMINERS] = loadedMap[CRYPTOMINERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (FINGERPRINTING == category) {
|
||||
loadedMap[FINGERPRINTERS] = loadedMap[FINGERPRINTERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (MOZILLA_SOCIAL == category) {
|
||||
loadedMap[SOCIAL_MEDIA_TRACKERS] =
|
||||
loadedMap[SOCIAL_MEDIA_TRACKERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (TrackingCategory.SCRIPTS_AND_SUB_RESOURCES == category) {
|
||||
loadedMap[TRACKING_CONTENT] = loadedMap[TRACKING_CONTENT].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
val key = when (category) {
|
||||
TrackingCategory.CRYPTOMINING -> CRYPTOMINERS
|
||||
TrackingCategory.FINGERPRINTING -> FINGERPRINTERS
|
||||
TrackingCategory.MOZILLA_SOCIAL -> SOCIAL_MEDIA_TRACKERS
|
||||
TrackingCategory.SCRIPTS_AND_SUB_RESOURCES -> TRACKING_CONTENT
|
||||
else -> return
|
||||
}
|
||||
addTrackerHost(key, tracker)
|
||||
}
|
||||
|
||||
private fun bucketBlockedCategories(
|
||||
item: TrackerLog,
|
||||
blockedMap: EnumMap<TrackingProtectionCategory, List<String>>
|
||||
/**
|
||||
* Add the hostname of the [TrackerLog.url] into the map for the given [TrackingProtectionCategory].
|
||||
*/
|
||||
private fun MutableMap<TrackingProtectionCategory, MutableList<String>>.addTrackerHost(
|
||||
key: TrackingProtectionCategory,
|
||||
tracker: TrackerLog
|
||||
) {
|
||||
item.blockedCategories.forEach { category ->
|
||||
if (CRYPTOMINING == category) {
|
||||
blockedMap[CRYPTOMINERS] = blockedMap[CRYPTOMINERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (FINGERPRINTING == category) {
|
||||
blockedMap[FINGERPRINTERS] = blockedMap[FINGERPRINTERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (MOZILLA_SOCIAL == category) {
|
||||
blockedMap[SOCIAL_MEDIA_TRACKERS] =
|
||||
blockedMap[SOCIAL_MEDIA_TRACKERS].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
if (TrackingCategory.SCRIPTS_AND_SUB_RESOURCES == category) {
|
||||
blockedMap[TRACKING_CONTENT] = blockedMap[TRACKING_CONTENT].orEmpty() +
|
||||
item.url.tryGetHostFromUrl()
|
||||
}
|
||||
}
|
||||
getOrPut(key) { mutableListOf() }.add(tracker.url.tryGetHostFromUrl())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.whenStarted
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import kotlinx.android.synthetic.main.fragment_tracking_protection.view.*
|
||||
@ -39,28 +40,7 @@ import org.mozilla.fenix.ext.requireComponents
|
||||
|
||||
class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHandler {
|
||||
|
||||
private val safeArguments get() = requireNotNull(arguments)
|
||||
|
||||
private val sessionId: String by lazy {
|
||||
TrackingProtectionPanelDialogFragmentArgs.fromBundle(
|
||||
safeArguments
|
||||
).sessionId
|
||||
}
|
||||
|
||||
private val url: String by lazy {
|
||||
TrackingProtectionPanelDialogFragmentArgs.fromBundle(safeArguments).url
|
||||
}
|
||||
|
||||
private val trackingProtectionEnabled: Boolean by lazy {
|
||||
TrackingProtectionPanelDialogFragmentArgs.fromBundle(safeArguments)
|
||||
.trackingProtectionEnabled
|
||||
}
|
||||
|
||||
private val promptGravity: Int by lazy {
|
||||
TrackingProtectionPanelDialogFragmentArgs.fromBundle(
|
||||
safeArguments
|
||||
).gravity
|
||||
}
|
||||
private val args by navArgs<TrackingProtectionPanelDialogFragmentArgs>()
|
||||
|
||||
private fun inflateRootView(container: ViewGroup? = null): View {
|
||||
val contextThemeWrapper = ContextThemeWrapper(
|
||||
@ -84,16 +64,16 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflateRootView(container)
|
||||
val session = requireComponents.core.sessionManager.findSessionById(sessionId)
|
||||
val session = requireComponents.core.sessionManager.findSessionById(args.sessionId)
|
||||
session?.register(sessionObserver, view = view)
|
||||
trackingProtectionStore = StoreProvider.get(this) {
|
||||
TrackingProtectionStore(
|
||||
TrackingProtectionState(
|
||||
session,
|
||||
url,
|
||||
trackingProtectionEnabled,
|
||||
listOf(),
|
||||
TrackingProtectionState.Mode.Normal
|
||||
args.url,
|
||||
args.trackingProtectionEnabled,
|
||||
listTrackers = listOf(),
|
||||
mode = TrackingProtectionState.Mode.Normal
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -127,7 +107,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||
private fun updateTrackers() {
|
||||
context?.let { context ->
|
||||
val session =
|
||||
context.components.core.sessionManager.findSessionById(sessionId) ?: return
|
||||
context.components.core.sessionManager.findSessionById(args.sessionId) ?: return
|
||||
val useCase = TrackingProtectionUseCases(
|
||||
sessionManager = context.components.core.sessionManager,
|
||||
engine = context.components.core.engine
|
||||
@ -174,7 +154,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||
sessionManager = context.components.core.sessionManager,
|
||||
engine = context.components.core.engine
|
||||
)
|
||||
val session = context.components.core.sessionManager.findSessionById(sessionId)
|
||||
val session = context.components.core.sessionManager.findSessionById(args.sessionId)
|
||||
session?.let {
|
||||
if (isEnabled) {
|
||||
useCase.removeException(it)
|
||||
@ -192,7 +172,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return if (promptGravity == Gravity.BOTTOM) {
|
||||
return if (args.gravity == Gravity.BOTTOM) {
|
||||
object : BottomSheetDialog(requireContext(), this.theme) {
|
||||
override fun onBackPressed() {
|
||||
this@TrackingProtectionPanelDialogFragment.onBackPressed()
|
||||
@ -224,7 +204,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), BackHan
|
||||
)
|
||||
|
||||
window?.apply {
|
||||
setGravity(promptGravity)
|
||||
setGravity(args.gravity)
|
||||
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||
// This must be called after addContentView, or it won't fully fill to the edge.
|
||||
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
Loading…
Reference in New Issue
Block a user