Commit 05a4faec authored by Tiger Oakes's avatar Tiger Oakes Committed by Christian Sadilek
Browse files

Add tryGetHostFromUrl and update ExceptionDomains

parent bea79436
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -13,16 +13,11 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.exceptions.ExceptionDomains
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import java.net.MalformedURLException
import java.net.URL
import org.mozilla.fenix.ext.tryGetHostFromUrl

class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
    override fun onLoadRequest(session: EngineSession, uri: String): RequestInterceptor.InterceptionResponse? {
        val host = try {
            URL(uri).host
        } catch (e: MalformedURLException) {
            uri
        }
        val host = uri.tryGetHostFromUrl()

        adjustTrackingProtection(host, context, session)

@@ -35,7 +30,7 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
    }

    private fun adjustTrackingProtection(host: String, context: Context, session: EngineSession) {
        val trackingProtectionException = ExceptionDomains.load(context).contains(host)
        val trackingProtectionException = ExceptionDomains(context).load().contains(host)
        val trackingProtectionEnabled = context.settings.shouldUseTrackingProtection
        if (trackingProtectionException || !trackingProtectionEnabled) {
            session.disableTrackingProtection()
+36 −30
Original line number Diff line number Diff line
@@ -6,73 +6,79 @@ 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

/**
 * Contains functionality to manage custom domains for allow-list.
 */
object ExceptionDomains {
    private const val PREFERENCE_NAME = "exceptions"
    private const val KEY_DOMAINS = "exceptions_domains"
    private const val SEPARATOR = "@<;>@"
class ExceptionDomains(context: Context) : PreferencesHolder {

    private var exceptions: List<String>? = null
    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.
     *
     * @param context the application context
     * @return list of custom domains
     */
    fun load(context: Context): List<String> {
    fun load(): List<String> {
        if (exceptions == null) {
            exceptions = (preferences(context)
                .getString(KEY_DOMAINS, "") ?: "")
                .split(SEPARATOR)
                .filter { !it.isEmpty() }
            exceptions = domains.split(SEPARATOR).filter { it.isNotEmpty() }
        }

        return exceptions ?: listOf()
        return exceptions.orEmpty()
    }

    /**
     * Saves the provided domains to preferences.
     *
     * @param context the application context
     * @param domains list of domains
     */
    fun save(context: Context, domains: List<String>) {
    fun save(domains: List<String>) {
        exceptions = domains

        preferences(context)
            .edit()
            .putString(KEY_DOMAINS, domains.joinToString(separator = SEPARATOR))
            .apply()
        this.domains = domains.joinToString(separator = SEPARATOR)
    }

    /**
     * Adds the provided domain to preferences.
     *
     * @param context the application context
     * @param domain the domain to add
     */
    fun add(context: Context, domain: String) {
        val domains = mutableListOf<String>()
        domains.addAll(load(context))
        domains.add(domain)

        save(context, domains)
    fun add(domain: String) {
        save(domains = load() + domain)
    }

    /**
     * Removes the provided domain from preferences.
     *
     * @param context the application context
     * @param domains the domain to remove
     */
    fun remove(context: Context, domains: List<String>) {
        save(context, load(context) - domains)
    fun remove(domains: List<String>) {
        save(domains = load() - domains)
    }

    private fun preferences(context: Context): SharedPreferences =
        context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE)
    /**
     * 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 {
            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
    }
}
+7 −9
Original line number Diff line number Diff line
@@ -66,15 +66,17 @@ class ExceptionsFragment : Fragment() {

    private fun deleteAllItems() {
        viewLifecycleOwner.lifecycleScope.launch(IO) {
            val domains = ExceptionDomains.load(context!!)
            ExceptionDomains.remove(context!!, domains)
            ExceptionDomains(requireContext()).run {
                val domains = load()
                remove(domains)
            }
            reloadData()
        }
    }

    private fun deleteOneItem(item: ExceptionsItem) {
        viewLifecycleOwner.lifecycleScope.launch(IO) {
            ExceptionDomains.remove(context!!, listOf(item.url))
            ExceptionDomains(requireContext()).remove(listOf(item.url))
            reloadData()
        }
    }
@@ -89,12 +91,8 @@ class ExceptionsFragment : Fragment() {
    }

    private fun loadAndMapExceptions(): List<ExceptionsItem> {
        return ExceptionDomains.load(context!!)
            .map { item ->
                ExceptionsItem(
                    item
                )
            }
        return ExceptionDomains(requireContext()).load()
            .map { item -> ExceptionsItem(item) }
    }

    private suspend fun reloadData() {
+5 −5
Original line number Diff line number Diff line
@@ -7,9 +7,9 @@ package org.mozilla.fenix.ext
import android.content.Context
import androidx.core.net.toUri
import kotlinx.coroutines.runBlocking
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes
import java.net.MalformedURLException
import java.net.URL
import mozilla.components.support.ktx.android.net.hostWithoutCommonPrefixes

/**
 * Replaces the keys with the values with the map provided.
@@ -21,13 +21,13 @@ fun String.replace(pairs: Map<String, String>): String {
}

/**
 * Try to parse and get host part if this [String] is valid URL.
 * Returns **null** otherwise.
 * Tries to parse and get host part if this [String] is valid URL.
 * Otherwise returns the string.
 */
fun String?.getHostFromUrl(): String? = try {
fun String.tryGetHostFromUrl(): String = try {
    URL(this).host
} catch (e: MalformedURLException) {
    null
    this
}

/**
+2 −3
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@ package org.mozilla.fenix.library.history
import androidx.paging.ItemKeyedDataSource
import mozilla.components.concept.storage.VisitInfo
import org.mozilla.fenix.components.history.PagedHistoryProvider
import org.mozilla.fenix.ext.getHostFromUrl
import org.mozilla.fenix.ext.tryGetHostFromUrl

class HistoryDataSource(
    private val historyProvider: PagedHistoryProvider
@@ -44,8 +44,7 @@ class HistoryDataSource(
            return { id, visit ->
                val title = visit.title
                    ?.takeIf(String::isNotEmpty)
                    ?: visit.url.getHostFromUrl()
                    ?: visit.url
                    ?: visit.url.tryGetHostFromUrl()

                HistoryItem(offset + id, title, visit.url, visit.visitTime)
            }
Loading