From a5e9439c6e7cd9352fe4cfd29088a530095d7534 Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Fri, 22 Nov 2019 07:38:13 -0800 Subject: [PATCH] Clean up tracking protection fragment (#6532) * Clean up exceptions fragment * Clean up tracking protection fragment * Move saved logins to list adapter --- .../collections/CollectionCreationView.kt | 4 +- .../fenix/exceptions/ExceptionsAdapter.kt | 66 ++++++------- .../fenix/exceptions/ExceptionsFragment.kt | 11 ++- .../fenix/exceptions/ExceptionsView.kt | 22 ++--- .../ExceptionsListItemViewHolder.kt | 3 + .../fenix/logins/SavedLoginsAdapter.kt | 50 +++------- .../fenix/logins/SavedLoginsFragment.kt | 32 +++---- .../mozilla/fenix/logins/SavedLoginsView.kt | 16 ++-- .../trackingprotection/TrackerBuckets.kt | 96 ++++++++----------- .../TrackingProtectionPanelDialogFragment.kt | 42 +++----- 10 files changed, 141 insertions(+), 201 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt index cd1e36c42..84fa051aa 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationView.kt @@ -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 { diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt index ea4d41788..59e827a47 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsAdapter.kt @@ -6,49 +6,43 @@ 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) { - val items: List - - init { - val items = mutableListOf() - 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() { - private var exceptionsList: ExceptionsList = ExceptionsList(emptyList()) +) : ListAdapter(DiffCallback) { - fun updateData(items: List) { - 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) { + val adapterItems = mutableListOf() + 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 - is AdapterItem.Item -> ExceptionsListItemViewHolder.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 { @@ -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() { + override fun areItemsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = + areContentsTheSame(oldItem, newItem) + + @Suppress("DiffUtilEquals") + override fun areContentsTheSame(oldItem: AdapterItem, newItem: AdapterItem) = + oldItem == newItem + } } diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt index 2a4e19525..7601415a2 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsFragment.kt @@ -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)) } } } diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt index 82cbc1b47..e6c815ee3 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt +++ b/app/src/main/java/org/mozilla/fenix/exceptions/ExceptionsView.kt @@ -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) } } diff --git a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt b/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt index dd27299dd..03de65b7e 100644 --- a/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/exceptions/viewholders/ExceptionsListItemViewHolder.kt @@ -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 diff --git a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsAdapter.kt b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsAdapter.kt index a1548010a..9b4cfcd6c 100644 --- a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsAdapter.kt @@ -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) { - val items: List = savedLogins.map { AdapterItem.Item(it) } -} - class SavedLoginsAdapter( private val interactor: SavedLoginsInteractor -) : RecyclerView.Adapter() { - private var savedLoginsList: SavedLoginsList = SavedLoginsList(emptyList()) +) : ListAdapter(DiffCallback) { - fun updateData(items: List) { - 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() { + override fun areItemsTheSame(oldItem: SavedLoginsItem, newItem: SavedLoginsItem) = + oldItem.url == newItem.url + + override fun areContentsTheSame(oldItem: SavedLoginsItem, newItem: SavedLoginsItem) = + oldItem == newItem } } diff --git a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsFragment.kt b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsFragment.kt index 020c6dcf4..2fbcab20c 100644 --- a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsFragment.kt @@ -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 { - it.list().await().map { item -> - SavedLoginsItem( - item.hostname, - item.username, - item.password - ) - } + 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) } - }.await() - launch(Dispatchers.Main) { - savedLoginsStore.dispatch(SavedLoginsFragmentAction.UpdateLogins(syncedLogins)) } } + withContext(Main) { + savedLoginsStore.dispatch(SavedLoginsFragmentAction.UpdateLogins(syncedLogins)) + } } } diff --git a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsView.kt b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsView.kt index 4e886f2e7..bc875b28d 100644 --- a/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsView.kt +++ b/app/src/main/java/org/mozilla/fenix/logins/SavedLoginsView.kt @@ -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) } } diff --git a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackerBuckets.kt b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackerBuckets.kt index ed95b0c68..4d429b9fd 100644 --- a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackerBuckets.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackerBuckets.kt @@ -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() - 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 ): BucketedTrackerLog { - val blockedMap = - EnumMap>(TrackingProtectionCategory::class.java) - val loadedMap = - EnumMap>(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> + /** + * Create an empty mutable map of [TrackingProtectionCategory] to hostnames. + */ + private fun createMap() = + EnumMap>(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>.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> + /** + * Add the hostname of the [TrackerLog.url] into the map for the given [TrackingProtectionCategory]. + */ + private fun MutableMap>.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()) } } } diff --git a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt index 77b244c2f..18e704930 100644 --- a/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/trackingprotection/TrackingProtectionPanelDialogFragment.kt @@ -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() 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)