Separates tracker bucket sorting code
parent
7214f40008
commit
a61391ef58
|
@ -0,0 +1,81 @@
|
||||||
|
/* 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.trackingprotection
|
||||||
|
|
||||||
|
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.AD
|
||||||
|
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.ANALYTICS
|
||||||
|
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.SOCIAL
|
||||||
|
import mozilla.components.concept.engine.content.blocking.Tracker
|
||||||
|
import org.mozilla.fenix.ext.getHostFromUrl
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.SOCIAL_MEDIA_TRACKERS
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.TRACKING_CONTENT
|
||||||
|
import java.util.EnumMap
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts [Tracker]s into different buckets and exposes them as a map.
|
||||||
|
*/
|
||||||
|
class TrackerBuckets {
|
||||||
|
|
||||||
|
private var trackers = emptyList<Tracker>()
|
||||||
|
var buckets = emptyMap<TrackingProtectionCategory, List<String>>()
|
||||||
|
private set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If [newTrackers] has changed since the last call,
|
||||||
|
* update [buckets] based on the new trackers list.
|
||||||
|
*/
|
||||||
|
fun updateIfNeeded(newTrackers: List<Tracker>) {
|
||||||
|
if (newTrackers != trackers) {
|
||||||
|
trackers = newTrackers
|
||||||
|
buckets = putTrackersInBuckets(newTrackers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there are no trackers.
|
||||||
|
*/
|
||||||
|
fun isEmpty() = buckets.isEmpty()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the tracker URLs for a given category.
|
||||||
|
*/
|
||||||
|
operator fun get(key: TrackingProtectionCategory) = buckets[key].orEmpty()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private fun putTrackersInBuckets(
|
||||||
|
list: List<Tracker>
|
||||||
|
): Map<TrackingProtectionCategory, List<String>> {
|
||||||
|
val map = EnumMap<TrackingProtectionCategory, List<String>>(TrackingProtectionCategory::class.java)
|
||||||
|
for (item in list) {
|
||||||
|
when {
|
||||||
|
CRYPTOMINING in item.trackingCategories -> {
|
||||||
|
map[CRYPTOMINERS] = map[CRYPTOMINERS].orEmpty() +
|
||||||
|
(item.url.getHostFromUrl() ?: item.url)
|
||||||
|
}
|
||||||
|
FINGERPRINTING in item.trackingCategories -> {
|
||||||
|
map[FINGERPRINTERS] = map[FINGERPRINTERS].orEmpty() +
|
||||||
|
(item.url.getHostFromUrl() ?: item.url)
|
||||||
|
}
|
||||||
|
SOCIAL in item.trackingCategories -> {
|
||||||
|
map[SOCIAL_MEDIA_TRACKERS] = map[SOCIAL_MEDIA_TRACKERS].orEmpty() +
|
||||||
|
(item.url.getHostFromUrl() ?: item.url)
|
||||||
|
}
|
||||||
|
AD in item.trackingCategories ||
|
||||||
|
SOCIAL in item.trackingCategories ||
|
||||||
|
ANALYTICS in item.trackingCategories -> {
|
||||||
|
map[TRACKING_CONTENT] = map[TRACKING_CONTENT].orEmpty() +
|
||||||
|
(item.url.getHostFromUrl() ?: item.url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,19 +9,13 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.core.view.isGone
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
import kotlinx.android.extensions.LayoutContainer
|
||||||
import kotlinx.android.synthetic.main.component_tracking_protection_panel.*
|
import kotlinx.android.synthetic.main.component_tracking_protection_panel.*
|
||||||
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.url
|
import kotlinx.android.synthetic.main.fragment_quick_settings_dialog_sheet.url
|
||||||
import kotlinx.android.synthetic.main.switch_with_description.view.*
|
import kotlinx.android.synthetic.main.switch_with_description.view.*
|
||||||
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.SOCIAL
|
|
||||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.AD
|
|
||||||
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.ANALYTICS
|
|
||||||
import mozilla.components.concept.engine.content.blocking.Tracker
|
|
||||||
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
|
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.getHostFromUrl
|
|
||||||
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CROSS_SITE_TRACKING_COOKIES
|
||||||
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS
|
||||||
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS
|
||||||
|
@ -63,40 +57,24 @@ interface TrackingProtectionPanelViewInteractor {
|
||||||
class TrackingProtectionPanelView(
|
class TrackingProtectionPanelView(
|
||||||
override val containerView: ViewGroup,
|
override val containerView: ViewGroup,
|
||||||
val interactor: TrackingProtectionPanelInteractor
|
val interactor: TrackingProtectionPanelInteractor
|
||||||
) : LayoutContainer {
|
) : LayoutContainer, View.OnClickListener {
|
||||||
|
|
||||||
val view: ConstraintLayout = LayoutInflater.from(containerView.context)
|
val view: ConstraintLayout = LayoutInflater.from(containerView.context)
|
||||||
.inflate(R.layout.component_tracking_protection_panel, containerView, true)
|
.inflate(R.layout.component_tracking_protection_panel, containerView, true)
|
||||||
.findViewById(R.id.panel_wrapper)
|
.findViewById(R.id.panel_wrapper)
|
||||||
|
|
||||||
private val context get() = view.context
|
private var mode: TrackingProtectionState.Mode = TrackingProtectionState.Mode.Normal
|
||||||
|
|
||||||
var mode: TrackingProtectionState.Mode = TrackingProtectionState.Mode.Normal
|
private var bucketedTrackers = TrackerBuckets()
|
||||||
private set
|
private var bucketedLoadedTrackers = TrackerBuckets()
|
||||||
|
|
||||||
var trackers: List<Tracker> = listOf()
|
|
||||||
private set
|
|
||||||
|
|
||||||
var bucketedTrackers: HashMap<TrackingProtectionCategory, List<String>> = HashMap()
|
|
||||||
|
|
||||||
var loadedTrackers: List<Tracker> = listOf()
|
|
||||||
private set
|
|
||||||
|
|
||||||
var bucketedLoadedTrackers: HashMap<TrackingProtectionCategory, List<String>> = HashMap()
|
|
||||||
|
|
||||||
fun update(state: TrackingProtectionState) {
|
fun update(state: TrackingProtectionState) {
|
||||||
if (state.mode != mode) {
|
if (state.mode != mode) {
|
||||||
mode = state.mode
|
mode = state.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.listTrackers != trackers) {
|
bucketedTrackers.updateIfNeeded(state.listTrackers)
|
||||||
trackers = state.listTrackers
|
bucketedLoadedTrackers.updateIfNeeded(state.listTrackersLoaded)
|
||||||
bucketedTrackers = getHashMapOfTrackersForCategory(state.listTrackers)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.listTrackersLoaded != loadedTrackers) {
|
|
||||||
loadedTrackers = state.listTrackersLoaded
|
|
||||||
bucketedLoadedTrackers = getHashMapOfTrackersForCategory(state.listTrackersLoaded)
|
|
||||||
}
|
|
||||||
|
|
||||||
when (val mode = state.mode) {
|
when (val mode = state.mode) {
|
||||||
is TrackingProtectionState.Mode.Normal -> setUIForNormalMode(state)
|
is TrackingProtectionState.Mode.Normal -> setUIForNormalMode(state)
|
||||||
|
@ -110,143 +88,84 @@ class TrackingProtectionPanelView(
|
||||||
private fun setUIForNormalMode(state: TrackingProtectionState) {
|
private fun setUIForNormalMode(state: TrackingProtectionState) {
|
||||||
details_mode.visibility = View.GONE
|
details_mode.visibility = View.GONE
|
||||||
normal_mode.visibility = View.VISIBLE
|
normal_mode.visibility = View.VISIBLE
|
||||||
protection_settings.visibility =
|
protection_settings.isGone = state.session?.customTabConfig != null
|
||||||
if (state.session?.customTabConfig != null) View.GONE else View.VISIBLE
|
|
||||||
|
|
||||||
not_blocking_header.visibility =
|
not_blocking_header.isGone = bucketedLoadedTrackers.isEmpty()
|
||||||
if (bucketedLoadedTrackers.size == 0) View.GONE else View.VISIBLE
|
|
||||||
bindUrl(state.url)
|
bindUrl(state.url)
|
||||||
bindTrackingProtectionInfo(state.isTrackingProtectionEnabled)
|
bindTrackingProtectionInfo(state.isTrackingProtectionEnabled)
|
||||||
protection_settings.setOnClickListener {
|
protection_settings.setOnClickListener {
|
||||||
interactor.selectTrackingProtectionSettings()
|
interactor.selectTrackingProtectionSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
blocking_header.visibility =
|
blocking_header.isGone = bucketedTrackers.isEmpty()
|
||||||
if (bucketedTrackers.size == 0) View.GONE else View.VISIBLE
|
|
||||||
updateCategoryVisibility()
|
updateCategoryVisibility()
|
||||||
setCategoryClickListeners()
|
setCategoryClickListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("ComplexMethod")
|
|
||||||
private fun updateCategoryVisibility() {
|
private fun updateCategoryVisibility() {
|
||||||
cross_site_tracking.visibility = bucketedTrackers.getVisibility(CROSS_SITE_TRACKING_COOKIES)
|
cross_site_tracking.isGone = bucketedTrackers[CROSS_SITE_TRACKING_COOKIES].isEmpty()
|
||||||
social_media_trackers.visibility = bucketedTrackers.getVisibility(SOCIAL_MEDIA_TRACKERS)
|
social_media_trackers.isGone = bucketedTrackers[SOCIAL_MEDIA_TRACKERS].isEmpty()
|
||||||
fingerprinters.visibility = bucketedTrackers.getVisibility(FINGERPRINTERS)
|
fingerprinters.isGone = bucketedTrackers[FINGERPRINTERS].isEmpty()
|
||||||
tracking_content.visibility = bucketedTrackers.getVisibility(TRACKING_CONTENT)
|
tracking_content.isGone = bucketedTrackers[TRACKING_CONTENT].isEmpty()
|
||||||
cryptominers.visibility = bucketedTrackers.getVisibility(CRYPTOMINERS)
|
cryptominers.isGone = bucketedTrackers[CRYPTOMINERS].isEmpty()
|
||||||
|
|
||||||
cross_site_tracking_loaded.visibility =
|
cross_site_tracking_loaded.isGone =
|
||||||
bucketedLoadedTrackers.getVisibility(CROSS_SITE_TRACKING_COOKIES)
|
bucketedLoadedTrackers[CROSS_SITE_TRACKING_COOKIES].isEmpty()
|
||||||
social_media_trackers_loaded.visibility =
|
social_media_trackers_loaded.isGone =
|
||||||
bucketedLoadedTrackers.getVisibility(SOCIAL_MEDIA_TRACKERS)
|
bucketedLoadedTrackers[SOCIAL_MEDIA_TRACKERS].isEmpty()
|
||||||
fingerprinters_loaded.visibility = bucketedLoadedTrackers.getVisibility(FINGERPRINTERS)
|
fingerprinters_loaded.isGone = bucketedLoadedTrackers[FINGERPRINTERS].isEmpty()
|
||||||
tracking_content_loaded.visibility = bucketedLoadedTrackers.getVisibility(TRACKING_CONTENT)
|
tracking_content_loaded.isGone = bucketedLoadedTrackers[TRACKING_CONTENT].isEmpty()
|
||||||
cryptominers_loaded.visibility = bucketedLoadedTrackers.getVisibility(CRYPTOMINERS)
|
cryptominers_loaded.isGone = bucketedLoadedTrackers[CRYPTOMINERS].isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun HashMap<TrackingProtectionCategory, List<String>>.getVisibility(
|
|
||||||
category: TrackingProtectionCategory
|
|
||||||
): Int = if (this[category]?.isNotEmpty() == true) View.VISIBLE else View.GONE
|
|
||||||
|
|
||||||
private fun setCategoryClickListeners() {
|
private fun setCategoryClickListeners() {
|
||||||
social_media_trackers.setOnClickListener {
|
social_media_trackers.setOnClickListener(this)
|
||||||
interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = true)
|
fingerprinters.setOnClickListener(this)
|
||||||
}
|
cross_site_tracking.setOnClickListener(this)
|
||||||
fingerprinters.setOnClickListener {
|
tracking_content.setOnClickListener(this)
|
||||||
interactor.openDetails(FINGERPRINTERS, categoryBlocked = true)
|
cryptominers.setOnClickListener(this)
|
||||||
}
|
social_media_trackers_loaded.setOnClickListener(this)
|
||||||
cross_site_tracking.setOnClickListener {
|
fingerprinters_loaded.setOnClickListener(this)
|
||||||
interactor.openDetails(CROSS_SITE_TRACKING_COOKIES, categoryBlocked = true)
|
cross_site_tracking_loaded.setOnClickListener(this)
|
||||||
}
|
tracking_content_loaded.setOnClickListener(this)
|
||||||
tracking_content.setOnClickListener {
|
cryptominers_loaded.setOnClickListener(this)
|
||||||
interactor.openDetails(TRACKING_CONTENT, categoryBlocked = true)
|
|
||||||
}
|
|
||||||
cryptominers.setOnClickListener {
|
|
||||||
interactor.openDetails(CRYPTOMINERS, categoryBlocked = true)
|
|
||||||
}
|
|
||||||
social_media_trackers_loaded.setOnClickListener {
|
|
||||||
interactor.openDetails(SOCIAL_MEDIA_TRACKERS, categoryBlocked = false)
|
|
||||||
}
|
|
||||||
fingerprinters_loaded.setOnClickListener {
|
|
||||||
interactor.openDetails(FINGERPRINTERS, categoryBlocked = false)
|
|
||||||
}
|
|
||||||
cross_site_tracking_loaded.setOnClickListener {
|
|
||||||
interactor.openDetails(CROSS_SITE_TRACKING_COOKIES, categoryBlocked = false)
|
|
||||||
}
|
|
||||||
tracking_content_loaded.setOnClickListener {
|
|
||||||
interactor.openDetails(TRACKING_CONTENT, categoryBlocked = false)
|
|
||||||
}
|
|
||||||
cryptominers_loaded.setOnClickListener {
|
|
||||||
interactor.openDetails(CRYPTOMINERS, categoryBlocked = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View) {
|
||||||
|
val category = getCategory(v) ?: return
|
||||||
|
interactor.openDetails(category, categoryBlocked = !isLoaded(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setUIForDetailsMode(
|
private fun setUIForDetailsMode(
|
||||||
category: TrackingProtectionCategory,
|
category: TrackingProtectionCategory,
|
||||||
categoryBlocked: Boolean
|
categoryBlocked: Boolean
|
||||||
) {
|
) {
|
||||||
|
val context = view.context
|
||||||
|
|
||||||
normal_mode.visibility = View.GONE
|
normal_mode.visibility = View.GONE
|
||||||
details_mode.visibility = View.VISIBLE
|
details_mode.visibility = View.VISIBLE
|
||||||
category_title.text = context.getString(category.title)
|
category_title.text = context.getString(category.title)
|
||||||
val stringList = bucketedTrackers[category]?.joinToString("\n")
|
blocking_text_list.text = bucketedTrackers[category].joinToString("\n")
|
||||||
blocking_text_list.text = stringList
|
|
||||||
category_description.text = context.getString(category.description)
|
category_description.text = context.getString(category.description)
|
||||||
details_blocking_header.text =
|
details_blocking_header.text = context.getString(
|
||||||
context.getString(
|
if (categoryBlocked) {
|
||||||
if (categoryBlocked) R.string.enhanced_tracking_protection_blocked else
|
R.string.enhanced_tracking_protection_blocked
|
||||||
|
} else {
|
||||||
R.string.enhanced_tracking_protection_allowed
|
R.string.enhanced_tracking_protection_allowed
|
||||||
|
}
|
||||||
)
|
)
|
||||||
details_back.setOnClickListener {
|
details_back.setOnClickListener {
|
||||||
interactor.onBackPressed()
|
interactor.onBackPressed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHashMapOfTrackersForCategory(
|
|
||||||
list: List<Tracker>
|
|
||||||
): HashMap<TrackingProtectionCategory, List<String>> {
|
|
||||||
val hashMap = HashMap<TrackingProtectionCategory, List<String>>()
|
|
||||||
items@ for (item in list) {
|
|
||||||
when {
|
|
||||||
item.trackingCategories.contains(CRYPTOMINING) -> {
|
|
||||||
hashMap[CRYPTOMINERS] =
|
|
||||||
(hashMap[CRYPTOMINERS]
|
|
||||||
?: listOf()).plus(item.url.getHostFromUrl() ?: item.url)
|
|
||||||
continue@items
|
|
||||||
}
|
|
||||||
item.trackingCategories.contains(FINGERPRINTING) -> {
|
|
||||||
hashMap[FINGERPRINTERS] =
|
|
||||||
(hashMap[FINGERPRINTERS]
|
|
||||||
?: listOf()).plus(item.url.getHostFromUrl() ?: item.url)
|
|
||||||
continue@items
|
|
||||||
}
|
|
||||||
item.trackingCategories.contains(SOCIAL) -> {
|
|
||||||
hashMap[SOCIAL_MEDIA_TRACKERS] =
|
|
||||||
(hashMap[SOCIAL_MEDIA_TRACKERS] ?: listOf()).plus(
|
|
||||||
item.url.getHostFromUrl() ?: item.url
|
|
||||||
)
|
|
||||||
continue@items
|
|
||||||
}
|
|
||||||
item.trackingCategories.contains(AD) ||
|
|
||||||
item.trackingCategories.contains(SOCIAL) ||
|
|
||||||
item.trackingCategories.contains(ANALYTICS) -> {
|
|
||||||
hashMap[TRACKING_CONTENT] =
|
|
||||||
(hashMap[TRACKING_CONTENT] ?: listOf()).plus(
|
|
||||||
item.url.getHostFromUrl() ?: item.url
|
|
||||||
)
|
|
||||||
continue@items
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hashMap
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bindUrl(url: String) {
|
private fun bindUrl(url: String) {
|
||||||
this.url.text = url.toUri().hostWithoutCommonPrefixes
|
this.url.text = url.toUri().hostWithoutCommonPrefixes
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindTrackingProtectionInfo(isTrackingProtectionOn: Boolean) {
|
private fun bindTrackingProtectionInfo(isTrackingProtectionOn: Boolean) {
|
||||||
tracking_protection.switchItemDescription.text =
|
tracking_protection.switchItemDescription.text =
|
||||||
context.getString(if (isTrackingProtectionOn) R.string.etp_panel_on else R.string.etp_panel_off)
|
view.context.getString(if (isTrackingProtectionOn) R.string.etp_panel_on else R.string.etp_panel_off)
|
||||||
tracking_protection.switch_widget.isChecked = isTrackingProtectionOn
|
tracking_protection.switch_widget.isChecked = isTrackingProtectionOn
|
||||||
|
|
||||||
tracking_protection.switch_widget.setOnCheckedChangeListener { _, isChecked ->
|
tracking_protection.switch_widget.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
@ -264,4 +183,37 @@ class TrackingProtectionPanelView(
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the [TrackingProtectionCategory] corresponding to the view ID.
|
||||||
|
*/
|
||||||
|
private fun getCategory(v: View) = when (v.id) {
|
||||||
|
R.id.social_media_trackers, R.id.social_media_trackers_loaded -> SOCIAL_MEDIA_TRACKERS
|
||||||
|
R.id.fingerprinters, R.id.fingerprinters_loaded -> FINGERPRINTERS
|
||||||
|
R.id.cross_site_tracking, R.id.cross_site_tracking_loaded -> CROSS_SITE_TRACKING_COOKIES
|
||||||
|
R.id.tracking_content, R.id.tracking_content_loaded -> TRACKING_CONTENT
|
||||||
|
R.id.cryptominers, R.id.cryptominers_loaded -> CRYPTOMINERS
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the view corresponds to a "loaded" category
|
||||||
|
*/
|
||||||
|
private fun isLoaded(v: View) = when (v.id) {
|
||||||
|
R.id.social_media_trackers_loaded,
|
||||||
|
R.id.fingerprinters_loaded,
|
||||||
|
R.id.cross_site_tracking_loaded,
|
||||||
|
R.id.tracking_content_loaded,
|
||||||
|
R.id.cryptominers_loaded -> true
|
||||||
|
|
||||||
|
R.id.social_media_trackers,
|
||||||
|
R.id.fingerprinters,
|
||||||
|
R.id.cross_site_tracking,
|
||||||
|
R.id.tracking_content,
|
||||||
|
R.id.cryptominers -> false
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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.trackingprotection
|
||||||
|
|
||||||
|
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.AD
|
||||||
|
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy.TrackingCategory.FINGERPRINTING
|
||||||
|
import mozilla.components.concept.engine.content.blocking.Tracker
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.CRYPTOMINERS
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.FINGERPRINTERS
|
||||||
|
import org.mozilla.fenix.trackingprotection.TrackingProtectionCategory.TRACKING_CONTENT
|
||||||
|
|
||||||
|
class TrackerBucketsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `initializes with empty map`() {
|
||||||
|
assertTrue(TrackerBuckets().isEmpty())
|
||||||
|
assertTrue(TrackerBuckets().buckets.isEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getter accesses corresponding bucket`() {
|
||||||
|
val buckets = TrackerBuckets()
|
||||||
|
buckets.updateIfNeeded(listOf(
|
||||||
|
Tracker("http://facebook.com", listOf(FINGERPRINTING, AD)),
|
||||||
|
Tracker("https://google.com", listOf(AD)),
|
||||||
|
Tracker("https://mozilla.com")
|
||||||
|
))
|
||||||
|
|
||||||
|
assertEquals(listOf("google.com"), buckets[TRACKING_CONTENT])
|
||||||
|
assertEquals(listOf("facebook.com"), buckets[FINGERPRINTERS])
|
||||||
|
assertEquals(emptyList<String>(), buckets[CRYPTOMINERS])
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `sorts trackers into bucket`() {
|
||||||
|
val buckets = TrackerBuckets()
|
||||||
|
buckets.updateIfNeeded(listOf(
|
||||||
|
Tracker("http://facebook.com", listOf(FINGERPRINTING, AD)),
|
||||||
|
Tracker("https://google.com", listOf(AD)),
|
||||||
|
Tracker("https://mozilla.com")
|
||||||
|
))
|
||||||
|
|
||||||
|
assertEquals(mapOf(
|
||||||
|
TRACKING_CONTENT to listOf("google.com"),
|
||||||
|
FINGERPRINTERS to listOf("facebook.com")
|
||||||
|
), buckets.buckets)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue