For #8143: Allow add-on popups to display prompts
parent
9adc617765
commit
40031e6130
|
@ -8,30 +8,25 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import kotlinx.android.synthetic.main.fragment_add_on_internal_settings.*
|
import kotlinx.android.synthetic.main.fragment_add_on_internal_settings.*
|
||||||
import mozilla.components.concept.engine.EngineSession
|
|
||||||
import mozilla.components.feature.addons.ui.translate
|
import mozilla.components.feature.addons.ui.translate
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
|
||||||
import org.mozilla.fenix.ext.showToolbar
|
import org.mozilla.fenix.ext.showToolbar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fragment to show the internal settings of an add-on.
|
* A fragment to show the internal settings of an add-on.
|
||||||
*/
|
*/
|
||||||
class AddonInternalSettingsFragment : Fragment() {
|
class AddonInternalSettingsFragment : AddonPopupBaseFragment() {
|
||||||
|
|
||||||
private val args by navArgs<AddonInternalSettingsFragmentArgs>()
|
private val args by navArgs<AddonInternalSettingsFragmentArgs>()
|
||||||
private lateinit var engineSession: EngineSession
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
engineSession = requireComponents.core.engine.createSession()
|
initializeSession()
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_add_on_internal_settings, container, false)
|
return inflater.inflate(R.layout.fragment_add_on_internal_settings, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +38,9 @@ class AddonInternalSettingsFragment : Fragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
engineSession?.let { engineSession ->
|
||||||
addonSettingsEngineView.render(engineSession)
|
addonSettingsEngineView.render(engineSession)
|
||||||
engineSession.loadUrl(args.addon.installedState!!.optionsPageUrl)
|
engineSession.loadUrl(args.addon.installedState!!.optionsPageUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
engineSession.close()
|
|
||||||
super.onDestroyView()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/* 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.addons
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.NavHostFragment.findNavController
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
|
import mozilla.components.browser.state.action.CustomTabListAction
|
||||||
|
import mozilla.components.browser.state.state.CustomTabSessionState
|
||||||
|
import mozilla.components.browser.state.state.EngineState
|
||||||
|
import mozilla.components.browser.state.state.SessionState
|
||||||
|
import mozilla.components.browser.state.state.createCustomTab
|
||||||
|
import mozilla.components.concept.engine.EngineSession
|
||||||
|
import mozilla.components.concept.engine.prompt.PromptRequest
|
||||||
|
import mozilla.components.concept.engine.window.WindowRequest
|
||||||
|
import mozilla.components.feature.prompts.PromptFeature
|
||||||
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides shared functionality to our fragments for add-on settings and
|
||||||
|
* browser/page action popups.
|
||||||
|
*/
|
||||||
|
abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer {
|
||||||
|
private val promptsFeature = ViewBoundFeatureWrapper<PromptFeature>()
|
||||||
|
|
||||||
|
protected var session: SessionState? = null
|
||||||
|
protected var engineSession: EngineSession? = null
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
session?.let {
|
||||||
|
promptsFeature.set(
|
||||||
|
feature = PromptFeature(
|
||||||
|
fragment = this,
|
||||||
|
store = requireComponents.core.store,
|
||||||
|
customTabId = it.id,
|
||||||
|
fragmentManager = parentFragmentManager,
|
||||||
|
onNeedToRequestPermissions = { permissions ->
|
||||||
|
requestPermissions(permissions, REQUEST_CODE_PROMPT_PERMISSIONS)
|
||||||
|
}),
|
||||||
|
owner = this,
|
||||||
|
view = view
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
engineSession?.close()
|
||||||
|
session?.let {
|
||||||
|
requireComponents.core.store.dispatch(CustomTabListAction.RemoveCustomTabAction(it.id))
|
||||||
|
}
|
||||||
|
super.onDestroyView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
engineSession?.register(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
engineSession?.unregister(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPromptRequest(promptRequest: PromptRequest) {
|
||||||
|
session?.let { session ->
|
||||||
|
requireComponents.core.store.dispatch(
|
||||||
|
ContentAction.UpdatePromptRequestAction(
|
||||||
|
session.id,
|
||||||
|
promptRequest
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onWindowRequest(windowRequest: WindowRequest) {
|
||||||
|
if (windowRequest.type == WindowRequest.Type.CLOSE) {
|
||||||
|
findNavController().popBackStack()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun initializeSession(fromEngineSession: EngineSession? = null) {
|
||||||
|
engineSession = fromEngineSession ?: requireComponents.core.engine.createSession()
|
||||||
|
session = createCustomTab("").copy(engineState = EngineState(engineSession))
|
||||||
|
requireComponents.core.store.dispatch(CustomTabListAction.AddCustomTabAction(session as CustomTabSessionState))
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
when (requestCode) {
|
||||||
|
REQUEST_CODE_PROMPT_PERMISSIONS -> promptsFeature.get()?.onPermissionsResult(permissions, grantResults)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
import kotlinx.android.synthetic.main.fragment_add_on_internal_settings.*
|
import kotlinx.android.synthetic.main.fragment_add_on_internal_settings.*
|
||||||
|
@ -16,7 +15,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import mozilla.components.browser.state.action.WebExtensionAction
|
import mozilla.components.browser.state.action.WebExtensionAction
|
||||||
import mozilla.components.concept.engine.EngineSession
|
import mozilla.components.concept.engine.EngineSession
|
||||||
import mozilla.components.concept.engine.EngineView
|
import mozilla.components.concept.engine.EngineView
|
||||||
import mozilla.components.concept.engine.window.WindowRequest
|
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
|
@ -25,10 +23,9 @@ import org.mozilla.fenix.ext.showToolbar
|
||||||
/**
|
/**
|
||||||
* A fragment to show the web extension action popup with [EngineView].
|
* A fragment to show the web extension action popup with [EngineView].
|
||||||
*/
|
*/
|
||||||
class WebExtensionActionPopupFragment : Fragment(), EngineSession.Observer {
|
class WebExtensionActionPopupFragment : AddonPopupBaseFragment(), EngineSession.Observer {
|
||||||
|
|
||||||
private val args by navArgs<WebExtensionActionPopupFragmentArgs>()
|
private val args by navArgs<WebExtensionActionPopupFragmentArgs>()
|
||||||
private var engineSession: EngineSession? = null
|
|
||||||
private val coreComponents by lazy { requireComponents.core }
|
private val coreComponents by lazy { requireComponents.core }
|
||||||
private val safeArguments get() = requireNotNull(arguments)
|
private val safeArguments get() = requireNotNull(arguments)
|
||||||
private var sessionConsumed
|
private var sessionConsumed
|
||||||
|
@ -43,8 +40,8 @@ class WebExtensionActionPopupFragment : Fragment(), EngineSession.Observer {
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
// Grab the [EngineSession] from the store when the view is created if it is available.
|
// Grab the [EngineSession] from the store when the view is created if it is available.
|
||||||
if (engineSession == null) {
|
coreComponents.store.state.extensions[args.webExtensionId]?.popupSession?.let {
|
||||||
engineSession = coreComponents.store.state.extensions[args.webExtensionId]?.popupSession
|
initializeSession(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_add_on_internal_settings, container, false)
|
return inflater.inflate(R.layout.fragment_add_on_internal_settings, container, false)
|
||||||
|
@ -56,22 +53,6 @@ class WebExtensionActionPopupFragment : Fragment(), EngineSession.Observer {
|
||||||
showToolbar(title)
|
showToolbar(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
engineSession?.register(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
engineSession?.unregister(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onWindowRequest(windowRequest: WindowRequest) {
|
|
||||||
if (windowRequest.type == WindowRequest.Type.CLOSE) {
|
|
||||||
activity?.onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
@ -86,6 +67,7 @@ class WebExtensionActionPopupFragment : Fragment(), EngineSession.Observer {
|
||||||
state.extensions[args.webExtensionId]?.let { extState ->
|
state.extensions[args.webExtensionId]?.let { extState ->
|
||||||
val popupSession = extState.popupSession
|
val popupSession = extState.popupSession
|
||||||
if (popupSession != null) {
|
if (popupSession != null) {
|
||||||
|
initializeSession(popupSession)
|
||||||
addonSettingsEngineView.render(popupSession)
|
addonSettingsEngineView.render(popupSession)
|
||||||
popupSession.register(this)
|
popupSession.register(this)
|
||||||
consumePopupSession()
|
consumePopupSession()
|
||||||
|
|
Loading…
Reference in New Issue