mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-03 23:15:31 +00:00
Bug 1825126 - Implement onInstallPermissionRequest in WebExtensionSupport.
Co-authored-by: William Durand <will+git@drnd.me> Co-authored-by: arturo mejia <arturomejiamarmol@gmail.com>
This commit is contained in:
parent
b3f1997fa2
commit
bea6f0b0da
@ -186,6 +186,8 @@ class SettingsSubMenuAddonsManagerRobot {
|
||||
}
|
||||
|
||||
private fun assertAddonPermissionPrompt(addonName: String) {
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Add $addonName?")), waitingTime)
|
||||
|
||||
onView(allOf(withId(R.id.title), withText("Add $addonName?")))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
|
||||
@ -221,6 +223,8 @@ class SettingsSubMenuAddonsManagerRobot {
|
||||
}
|
||||
|
||||
private fun allowPermissionToInstall() {
|
||||
mDevice.waitNotNull(Until.findObject(By.text("Add")), waitingTime)
|
||||
|
||||
onView(allOf(withId(R.id.allow_button), withText("Add")))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
.perform(click())
|
||||
|
@ -11,7 +11,6 @@ import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.accessibility.AccessibilityEvent
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
@ -26,8 +25,8 @@ import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.AddonManagerException
|
||||
import mozilla.components.feature.addons.ui.AddonInstallationDialogFragment
|
||||
import mozilla.components.feature.addons.ui.AddonsManagerAdapter
|
||||
import mozilla.components.feature.addons.ui.PermissionsDialogFragment
|
||||
import mozilla.components.feature.addons.ui.translateName
|
||||
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||
import org.mozilla.fenix.BuildConfig
|
||||
import org.mozilla.fenix.Config
|
||||
import org.mozilla.fenix.R
|
||||
@ -35,9 +34,10 @@ import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.databinding.FragmentAddOnsManagementBinding
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getRootView
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.ext.showToolbar
|
||||
import org.mozilla.fenix.extension.WebExtensionPromptFeature
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.concurrent.CancellationException
|
||||
@ -52,6 +52,9 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
|
||||
private var binding: FragmentAddOnsManagementBinding? = null
|
||||
|
||||
private val webExtensionPromptFeature = ViewBoundFeatureWrapper<WebExtensionPromptFeature>()
|
||||
private lateinit var addons: List<Addon>
|
||||
|
||||
/**
|
||||
* Whether or not an add-on installation is in progress.
|
||||
*/
|
||||
@ -71,6 +74,17 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentAddOnsManagementBinding.bind(view)
|
||||
bindRecyclerView()
|
||||
webExtensionPromptFeature.set(
|
||||
feature = WebExtensionPromptFeature(
|
||||
store = requireComponents.core.store,
|
||||
provideAddons = { addons },
|
||||
context = requireContext(),
|
||||
fragmentManager = parentFragmentManager,
|
||||
view = view,
|
||||
),
|
||||
owner = this,
|
||||
view = view,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@ -78,13 +92,6 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
showToolbar(getString(R.string.preferences_addons))
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
findPreviousDialogFragment()?.let { dialog ->
|
||||
dialog.onPositiveButtonClicked = onPositiveButtonClicked
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
// letting go of the resources to avoid memory leak.
|
||||
@ -95,7 +102,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
private fun bindRecyclerView() {
|
||||
val managementView = AddonsManagementView(
|
||||
navController = findNavController(),
|
||||
showPermissionDialog = ::showPermissionDialog,
|
||||
onInstallButtonClicked = ::installAddon,
|
||||
)
|
||||
|
||||
val recyclerView = binding?.addOnsList
|
||||
@ -107,7 +114,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
val allowCache = args.installAddonId == null || installExternalAddonComplete
|
||||
lifecycleScope.launch(IO) {
|
||||
try {
|
||||
val addons = requireContext().components.addonManager.getAddons(allowCache = allowCache)
|
||||
addons = requireContext().components.addonManager.getAddons(allowCache)
|
||||
// Add-ons that should be excluded in Mozilla Online builds
|
||||
val excludedAddonIDs = if (Config.channel.isMozillaOnline &&
|
||||
!BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.isNullOrEmpty()
|
||||
@ -167,7 +174,7 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
if (addonToInstall.isInstalled()) {
|
||||
showErrorSnackBar(getString(R.string.addon_already_installed))
|
||||
} else {
|
||||
showPermissionDialog(addonToInstall)
|
||||
installAddon(addonToInstall)
|
||||
}
|
||||
}
|
||||
installExternalAddonComplete = true
|
||||
@ -198,43 +205,11 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
)
|
||||
}
|
||||
|
||||
private fun findPreviousDialogFragment(): PermissionsDialogFragment? {
|
||||
return parentFragmentManager.findFragmentByTag(PERMISSIONS_DIALOG_FRAGMENT_TAG) as? PermissionsDialogFragment
|
||||
}
|
||||
|
||||
private fun hasExistingPermissionDialogFragment(): Boolean {
|
||||
return findPreviousDialogFragment() != null
|
||||
}
|
||||
|
||||
private fun hasExistingAddonInstallationDialogFragment(): Boolean {
|
||||
return parentFragmentManager.findFragmentByTag(INSTALLATION_DIALOG_FRAGMENT_TAG)
|
||||
as? AddonInstallationDialogFragment != null
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun showPermissionDialog(addon: Addon) {
|
||||
if (!isInstallationInProgress && !hasExistingPermissionDialogFragment()) {
|
||||
val dialog = PermissionsDialogFragment.newInstance(
|
||||
addon = addon,
|
||||
promptsStyling = PermissionsDialogFragment.PromptsStyling(
|
||||
gravity = Gravity.BOTTOM,
|
||||
shouldWidthMatchParent = true,
|
||||
positiveButtonBackgroundColor = ThemeManager.resolveAttribute(
|
||||
R.attr.accent,
|
||||
requireContext(),
|
||||
),
|
||||
positiveButtonTextColor = ThemeManager.resolveAttribute(
|
||||
R.attr.textOnColorPrimary,
|
||||
requireContext(),
|
||||
),
|
||||
positiveButtonRadius = (resources.getDimensionPixelSize(R.dimen.tab_corner_radius)).toFloat(),
|
||||
),
|
||||
onPositiveButtonClicked = onPositiveButtonClicked,
|
||||
)
|
||||
dialog.show(parentFragmentManager, PERMISSIONS_DIALOG_FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showInstallationDialog(addon: Addon) {
|
||||
if (!isInstallationInProgress && !hasExistingAddonInstallationDialogFragment()) {
|
||||
val context = requireContext()
|
||||
@ -282,16 +257,8 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
}
|
||||
}
|
||||
|
||||
private val onPositiveButtonClicked: ((Addon) -> Unit) = { addon ->
|
||||
binding?.addonProgressOverlay?.overlayCardView?.visibility = View.VISIBLE
|
||||
|
||||
if (requireContext().settings().accessibilityServicesEnabled) {
|
||||
binding?.let { announceForAccessibility(it.addonProgressOverlay.addOnsOverlayText.text) }
|
||||
}
|
||||
|
||||
isInstallationInProgress = true
|
||||
|
||||
val installOperation = requireContext().components.addonManager.installAddon(
|
||||
internal fun installAddon(addon: Addon) {
|
||||
requireContext().components.addonManager.installAddon(
|
||||
addon,
|
||||
onSuccess = {
|
||||
runIfFragmentIsAttached {
|
||||
@ -321,39 +288,9 @@ class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
binding?.addonProgressOverlay?.cancelButton?.setOnClickListener {
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
val safeBinding = binding
|
||||
// Hide the installation progress overlay once cancellation is successful.
|
||||
if (installOperation.cancel().await()) {
|
||||
safeBinding?.addonProgressOverlay?.overlayCardView?.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun announceForAccessibility(announcementText: CharSequence) {
|
||||
val event = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
AccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT)
|
||||
}
|
||||
|
||||
binding?.addonProgressOverlay?.overlayCardView?.onInitializeAccessibilityEvent(event)
|
||||
event.text.add(announcementText)
|
||||
event.contentDescription = null
|
||||
binding?.addonProgressOverlay?.overlayCardView?.let {
|
||||
it.parent?.requestSendAccessibilityEvent(
|
||||
it,
|
||||
event,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PERMISSIONS_DIALOG_FRAGMENT_TAG = "ADDONS_PERMISSIONS_DIALOG_FRAGMENT"
|
||||
private const val INSTALLATION_DIALOG_FRAGMENT_TAG = "ADDONS_INSTALLATION_DIALOG_FRAGMENT"
|
||||
private const val BUNDLE_KEY_INSTALL_EXTERNAL_ADDON_COMPLETE = "INSTALL_EXTERNAL_ADDON_COMPLETE"
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import org.mozilla.fenix.ext.navigateSafe
|
||||
*/
|
||||
class AddonsManagementView(
|
||||
private val navController: NavController,
|
||||
private val showPermissionDialog: (Addon) -> Unit,
|
||||
private val onInstallButtonClicked: (Addon) -> Unit,
|
||||
) : AddonsManagerAdapterDelegate {
|
||||
|
||||
override fun onAddonItemClicked(addon: Addon) {
|
||||
@ -27,7 +27,7 @@ class AddonsManagementView(
|
||||
}
|
||||
|
||||
override fun onInstallAddonButtonClicked(addon: Addon) {
|
||||
showPermissionDialog(addon)
|
||||
onInstallButtonClicked(addon)
|
||||
}
|
||||
|
||||
override fun onNotYetSupportedSectionClicked(unsupportedAddons: List<Addon>) {
|
||||
|
@ -59,6 +59,7 @@ import mozilla.components.concept.engine.permission.SitePermissions
|
||||
import mozilla.components.concept.engine.prompt.ShareData
|
||||
import mozilla.components.feature.accounts.FxaCapability
|
||||
import mozilla.components.feature.accounts.FxaWebChannelFeature
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.app.links.AppLinksFeature
|
||||
import mozilla.components.feature.contextmenu.ContextMenuCandidate
|
||||
import mozilla.components.feature.contextmenu.ContextMenuFeature
|
||||
@ -134,6 +135,7 @@ import org.mozilla.fenix.downloads.ThirdPartyDownloadDialog
|
||||
import org.mozilla.fenix.ext.accessibilityManager
|
||||
import org.mozilla.fenix.ext.breadcrumb
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.getFenixAddons
|
||||
import org.mozilla.fenix.ext.getPreferenceKey
|
||||
import org.mozilla.fenix.ext.hideToolbar
|
||||
import org.mozilla.fenix.ext.nav
|
||||
@ -142,6 +144,7 @@ import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.ext.runIfFragmentIsAttached
|
||||
import org.mozilla.fenix.ext.secure
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.extension.WebExtensionPromptFeature
|
||||
import org.mozilla.fenix.home.HomeScreenViewModel
|
||||
import org.mozilla.fenix.home.SharedViewModel
|
||||
import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks
|
||||
@ -203,6 +206,7 @@ abstract class BaseBrowserFragment :
|
||||
private val fullScreenFeature = ViewBoundFeatureWrapper<FullScreenFeature>()
|
||||
private val swipeRefreshFeature = ViewBoundFeatureWrapper<SwipeRefreshFeature>()
|
||||
private val webchannelIntegration = ViewBoundFeatureWrapper<FxaWebChannelFeature>()
|
||||
private val webExtensionPromptFeature = ViewBoundFeatureWrapper<WebExtensionPromptFeature>()
|
||||
private val sitePermissionWifiIntegration =
|
||||
ViewBoundFeatureWrapper<SitePermissionsWifiIntegration>()
|
||||
private val secureWindowFeature = ViewBoundFeatureWrapper<SecureWindowFeature>()
|
||||
@ -894,6 +898,17 @@ abstract class BaseBrowserFragment :
|
||||
view = view,
|
||||
)
|
||||
|
||||
webExtensionPromptFeature.set(
|
||||
feature = WebExtensionPromptFeature(
|
||||
store = requireComponents.core.store,
|
||||
provideAddons = ::provideAddons,
|
||||
context = requireContext(),
|
||||
fragmentManager = parentFragmentManager,
|
||||
view = view,
|
||||
),
|
||||
owner = this,
|
||||
view = view,
|
||||
)
|
||||
initializeEngineView(toolbarHeight)
|
||||
}
|
||||
|
||||
@ -1605,4 +1620,13 @@ abstract class BaseBrowserFragment :
|
||||
|
||||
return isValidStatus && isSameTab
|
||||
}
|
||||
|
||||
private suspend fun provideAddons(): List<Addon> {
|
||||
return withContext(IO) {
|
||||
// We deactivated the cache to get the most up-to-date list of add-ons to match against.
|
||||
// as this will be used to install add-ons from AMO.
|
||||
val addons = requireContext().components.addonManager.getFenixAddons(allowCache = false)
|
||||
addons
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
app/src/main/java/org/mozilla/fenix/ext/AddonManager.kt
Normal file
26
app/src/main/java/org/mozilla/fenix/ext/AddonManager.kt
Normal file
@ -0,0 +1,26 @@
|
||||
/* 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.ext
|
||||
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.AddonManager
|
||||
import org.mozilla.fenix.BuildConfig
|
||||
import org.mozilla.fenix.Config
|
||||
|
||||
/**
|
||||
* Returns the list of all installed and recommended add-ons filters out all the
|
||||
* add-ons on [BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS].
|
||||
*/
|
||||
suspend fun AddonManager.getFenixAddons(allowCache: Boolean = true): List<Addon> {
|
||||
val addons = getAddons(allowCache = allowCache)
|
||||
val excludedAddonIDs = if (Config.channel.isMozillaOnline &&
|
||||
!BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.isNullOrEmpty()
|
||||
) {
|
||||
BuildConfig.MOZILLA_ONLINE_ADDON_EXCLUSIONS.toList()
|
||||
} else {
|
||||
emptyList<String>()
|
||||
}
|
||||
return addons.filterNot { it.id in excludedAddonIDs }
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/* 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.extension
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import mozilla.components.browser.state.action.WebExtensionAction
|
||||
import mozilla.components.browser.state.state.extension.WebExtensionPromptRequest
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.ui.PermissionsDialogFragment
|
||||
import mozilla.components.lib.state.ext.flowScoped
|
||||
import mozilla.components.support.base.feature.LifecycleAwareFeature
|
||||
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.addons.showSnackBar
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.theme.ThemeManager
|
||||
|
||||
/**
|
||||
* Feature implementation for handling [WebExtensionPromptRequest] and showing the respective UI.
|
||||
*/
|
||||
class WebExtensionPromptFeature(
|
||||
private val store: BrowserStore,
|
||||
private val provideAddons: suspend () -> List<Addon>,
|
||||
private val context: Context,
|
||||
private val view: View,
|
||||
private val fragmentManager: FragmentManager,
|
||||
) : LifecycleAwareFeature {
|
||||
|
||||
/**
|
||||
* Whether or not an add-on installation is in progress.
|
||||
*/
|
||||
private var isInstallationInProgress = false
|
||||
private var scope: CoroutineScope? = null
|
||||
|
||||
/**
|
||||
* Starts observing the selected session to listen for window requests
|
||||
* and opens / closes tabs as needed.
|
||||
*/
|
||||
override fun start() {
|
||||
scope = store.flowScoped { flow ->
|
||||
flow.mapNotNull { state ->
|
||||
state.webExtensionPromptRequest
|
||||
}.ifChanged().collect { promptRequest ->
|
||||
if (promptRequest is WebExtensionPromptRequest.Permissions && !hasExistingPermissionDialogFragment()) {
|
||||
val addon = provideAddons().find { addon ->
|
||||
addon.id == promptRequest.extension.id
|
||||
}
|
||||
|
||||
// If the add-on is not found, it is already installed because the install process can only
|
||||
// be triggered for add-ons "known" by Fenix (the add-on is either part of the official list
|
||||
// of supported extensions OR part of the user custom AMO collection).
|
||||
if (addon == null) {
|
||||
promptRequest.onConfirm(false)
|
||||
consumePromptRequest()
|
||||
showSnackBar(
|
||||
view,
|
||||
context.getString(R.string.addon_already_installed),
|
||||
FenixSnackbar.LENGTH_LONG,
|
||||
)
|
||||
} else {
|
||||
showPermissionDialog(
|
||||
addon,
|
||||
promptRequest,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tryToReAttachButtonHandlersToPreviousDialog()
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops observing the selected session for incoming window requests.
|
||||
*/
|
||||
override fun stop() {
|
||||
scope?.cancel()
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun showPermissionDialog(
|
||||
addon: Addon,
|
||||
promptRequest: WebExtensionPromptRequest.Permissions,
|
||||
) {
|
||||
if (!isInstallationInProgress && !hasExistingPermissionDialogFragment()) {
|
||||
val dialog = PermissionsDialogFragment.newInstance(
|
||||
addon = addon,
|
||||
promptsStyling = PermissionsDialogFragment.PromptsStyling(
|
||||
gravity = Gravity.BOTTOM,
|
||||
shouldWidthMatchParent = true,
|
||||
positiveButtonBackgroundColor = ThemeManager.resolveAttribute(
|
||||
R.attr.accent,
|
||||
context,
|
||||
),
|
||||
positiveButtonTextColor = ThemeManager.resolveAttribute(
|
||||
R.attr.textOnColorPrimary,
|
||||
context,
|
||||
),
|
||||
positiveButtonRadius =
|
||||
(context.resources.getDimensionPixelSize(R.dimen.tab_corner_radius)).toFloat(),
|
||||
),
|
||||
onPositiveButtonClicked = {
|
||||
handleApprovedPermissions(promptRequest)
|
||||
},
|
||||
onNegativeButtonClicked = {
|
||||
handleDeniedPermissions(promptRequest)
|
||||
},
|
||||
)
|
||||
dialog.show(
|
||||
fragmentManager,
|
||||
PERMISSIONS_DIALOG_FRAGMENT_TAG,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryToReAttachButtonHandlersToPreviousDialog() {
|
||||
findPreviousDialogFragment()?.let { dialog ->
|
||||
dialog.onPositiveButtonClicked = { addon ->
|
||||
store.state.webExtensionPromptRequest?.let { promptRequest ->
|
||||
if (addon.id == promptRequest.extension.id &&
|
||||
promptRequest is WebExtensionPromptRequest.Permissions
|
||||
) {
|
||||
handleApprovedPermissions(promptRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
dialog.onNegativeButtonClicked = {
|
||||
store.state.webExtensionPromptRequest?.let { promptRequest ->
|
||||
if (promptRequest is WebExtensionPromptRequest.Permissions) {
|
||||
handleDeniedPermissions(promptRequest)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDeniedPermissions(promptRequest: WebExtensionPromptRequest.Permissions) {
|
||||
promptRequest.onConfirm(false)
|
||||
consumePromptRequest()
|
||||
}
|
||||
|
||||
private fun handleApprovedPermissions(promptRequest: WebExtensionPromptRequest.Permissions) {
|
||||
promptRequest.onConfirm(true)
|
||||
consumePromptRequest()
|
||||
}
|
||||
|
||||
private fun consumePromptRequest() {
|
||||
store.dispatch(WebExtensionAction.ConsumePromptRequestWebExtensionAction)
|
||||
}
|
||||
|
||||
private fun hasExistingPermissionDialogFragment(): Boolean {
|
||||
return findPreviousDialogFragment() != null
|
||||
}
|
||||
|
||||
private fun findPreviousDialogFragment(): PermissionsDialogFragment? {
|
||||
return fragmentManager.findFragmentByTag(PERMISSIONS_DIALOG_FRAGMENT_TAG) as? PermissionsDialogFragment
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PERMISSIONS_DIALOG_FRAGMENT_TAG = "ADDONS_PERMISSIONS_DIALOG_FRAGMENT"
|
||||
}
|
||||
}
|
@ -32,7 +32,6 @@ class AddonsManagementFragmentTest {
|
||||
every { fragment.context } returns context
|
||||
every { fragment.view } returns view
|
||||
every { fragment.showErrorSnackBar(any()) } returns Unit
|
||||
every { fragment.showPermissionDialog(any()) } returns Unit
|
||||
every { fragment.getString(R.string.addon_not_supported_error) } returns addonNotSupportedErrorMessage
|
||||
every { fragment.getString(R.string.addon_already_installed) } returns addonAlreadyInstalledErrorMessage
|
||||
}
|
||||
@ -57,14 +56,4 @@ class AddonsManagementFragmentTest {
|
||||
fragment.installExternalAddon(supportedAddons, "d1")
|
||||
verify { fragment.showErrorSnackBar(addonAlreadyInstalledErrorMessage) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN add-on is installed from external source WHEN supported and not installed THEN start installation`() {
|
||||
val addon1 = Addon("1", downloadId = "d1", installedState = mockk())
|
||||
val addon2 = Addon("2", downloadId = "d2")
|
||||
val supportedAddons = listOf(addon1, addon2)
|
||||
|
||||
fragment.installExternalAddon(supportedAddons, "d2")
|
||||
verify { fragment.showPermissionDialog(addon2) }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user