diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml
index b3413864..f070dce2 100644
--- a/app/android/app/src/main/AndroidManifest.xml
+++ b/app/android/app/src/main/AndroidManifest.xml
@@ -205,6 +205,11 @@
android:exported="false"
android:theme="@style/AppTheme" />
+
+
diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt
index ec3846f2..e7f1afe6 100644
--- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt
+++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BaseBrowserFragment.kt
@@ -22,6 +22,7 @@ import androidx.annotation.CallSuper
import androidx.core.content.edit
import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
+import eu.weblibre.flutter_mozilla_components.addons.WebExtensionActionPopupActivity
import eu.weblibre.flutter_mozilla_components.addons.WebExtensionPromptFeature
import eu.weblibre.flutter_mozilla_components.databinding.FragmentBrowserBinding
import eu.weblibre.flutter_mozilla_components.ext.getPreferenceKey
@@ -32,12 +33,7 @@ import eu.weblibre.flutter_mozilla_components.integration.ReaderViewIntegration
import eu.weblibre.flutter_mozilla_components.activities.ExternalAppBrowserActivity
import eu.weblibre.flutter_mozilla_components.services.DownloadService
import io.flutter.Log
-import mozilla.components.browser.state.action.TabListAction
-import mozilla.components.browser.state.action.WebExtensionAction
-import mozilla.components.browser.state.state.EngineState
-import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.state.WebExtensionState
-import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.thumbnails.BrowserThumbnails
import mozilla.components.concept.engine.EngineView
import mozilla.components.feature.app.links.AppLinksFeature
@@ -521,16 +517,14 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
protected open fun onEngineSetupComplete() {}
private fun openPopup(webExtensionState: WebExtensionState) {
- val store = components.core.store
- val popupSession = store.state.extensions[webExtensionState.id]?.popupSession ?: return
-
- val tab = createTab(url = "", source = SessionState.Source.Internal.None)
- .copy(engineState = EngineState(popupSession))
- store.dispatch(TabListAction.AddTabAction(tab, select = true))
-
- store.dispatch(
- WebExtensionAction.UpdatePopupSessionAction(webExtensionState.id, popupSession = null)
+ val intent = Intent(
+ components.profileApplicationContext,
+ WebExtensionActionPopupActivity::class.java
)
+ intent.putExtra("web_extension_id", webExtensionState.id)
+ intent.putExtra("web_extension_name", webExtensionState.name)
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ startActivity(intent)
}
@CallSuper
diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/WebExtensionActionPopupActivity.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/WebExtensionActionPopupActivity.kt
new file mode 100644
index 00000000..5e704f14
--- /dev/null
+++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/WebExtensionActionPopupActivity.kt
@@ -0,0 +1,127 @@
+/* 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 eu.weblibre.flutter_mozilla_components.addons
+
+import android.content.Context
+import android.os.Bundle
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import eu.weblibre.flutter_mozilla_components.GlobalComponents
+import mozilla.components.browser.state.action.WebExtensionAction
+import mozilla.components.concept.engine.EngineSession
+import mozilla.components.concept.engine.EngineView
+import mozilla.components.concept.engine.window.WindowRequest
+import mozilla.components.lib.state.ext.consumeFrom
+import eu.weblibre.flutter_mozilla_components.R
+
+/**
+ * An activity to show the pop up action of a web extension.
+ */
+class WebExtensionActionPopupActivity : AppCompatActivity() {
+ private val components by lazy {
+ requireNotNull(GlobalComponents.components) { "Components not initialized" }
+ }
+
+ private lateinit var webExtensionId: String
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_add_on_settings)
+
+ webExtensionId = requireNotNull(intent.getStringExtra("web_extension_id"))
+ intent.getStringExtra("web_extension_name")?.let {
+ title = it
+ }
+
+ supportFragmentManager
+ .beginTransaction()
+ .replace(R.id.addonSettingsContainer, WebExtensionActionPopupFragment.create(webExtensionId))
+ .commit()
+ }
+
+ override fun onCreateView(parent: View?, name: String, context: Context, attrs: AttributeSet): View? =
+ when (name) {
+ EngineView::class.java.name -> components.core.engine.createView(context, attrs).asView()
+ else -> super.onCreateView(parent, name, context, attrs)
+ }
+
+ /**
+ * A fragment to show the web extension action popup with [EngineView].
+ */
+ class WebExtensionActionPopupFragment : Fragment(), EngineSession.Observer {
+ private val components by lazy {
+ requireNotNull(GlobalComponents.components) { "Components not initialized" }
+ }
+
+ private var engineSession: EngineSession? = null
+ private lateinit var webExtensionId: String
+
+ private val addonSettingsEngineView: EngineView
+ get() = requireView().findViewById(R.id.addonSettingsEngineView) as EngineView
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ webExtensionId = requireNotNull(arguments?.getString("web_extension_id"))
+ engineSession = components.core.store.state.extensions[webExtensionId]?.popupSession
+
+ return inflater.inflate(R.layout.fragment_add_on_settings, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val session = engineSession
+ if (session != null) {
+ addonSettingsEngineView.render(session)
+ consumePopupSession()
+ } else {
+ consumeFrom(components.core.store) { state ->
+ state.extensions[webExtensionId]?.let { extState ->
+ extState.popupSession?.let {
+ if (engineSession == null) {
+ addonSettingsEngineView.render(it)
+ consumePopupSession()
+ engineSession = it
+ }
+ }
+ }
+ }
+ }
+ }
+
+ 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?.onBackPressedDispatcher?.onBackPressed()
+ }
+ }
+
+ private fun consumePopupSession() {
+ components.core.store.dispatch(
+ WebExtensionAction.UpdatePopupSessionAction(webExtensionId, popupSession = null),
+ )
+ }
+
+ companion object {
+ fun create(webExtensionId: String) = WebExtensionActionPopupFragment().apply {
+ arguments = Bundle().apply {
+ putString("web_extension_id", webExtensionId)
+ }
+ }
+ }
+ }
+}
diff --git a/packages/flutter_mozilla_components/android/src/main/res/layout/activity_add_on_settings.xml b/packages/flutter_mozilla_components/android/src/main/res/layout/activity_add_on_settings.xml
new file mode 100644
index 00000000..0a1cc218
--- /dev/null
+++ b/packages/flutter_mozilla_components/android/src/main/res/layout/activity_add_on_settings.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/packages/flutter_mozilla_components/android/src/main/res/layout/fragment_add_on_settings.xml b/packages/flutter_mozilla_components/android/src/main/res/layout/fragment_add_on_settings.xml
new file mode 100644
index 00000000..6f5546b3
--- /dev/null
+++ b/packages/flutter_mozilla_components/android/src/main/res/layout/fragment_add_on_settings.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/packages/flutter_mozilla_components/example/android/app/src/main/AndroidManifest.xml b/packages/flutter_mozilla_components/example/android/app/src/main/AndroidManifest.xml
index c6a67197..0f6233c0 100644
--- a/packages/flutter_mozilla_components/example/android/app/src/main/AndroidManifest.xml
+++ b/packages/flutter_mozilla_components/example/android/app/src/main/AndroidManifest.xml
@@ -91,6 +91,11 @@
android:exported="false"
android:theme="@style/Theme.AppCompat.Light" />
+
+