From fcd3c0b38be08400dce832299873608311aa73d7 Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Tue, 17 Feb 2026 09:52:42 +0100 Subject: [PATCH] improve addon activities --- app/android/app/src/main/AndroidManifest.xml | 6 + .../addons/AddonInternalSettingsActivity.kt | 105 ++++++++++++++++++ .../addons/InstalledAddonDetailsActivity.kt | 19 +++- .../addons/WebExtensionActionPopupActivity.kt | 13 ++- .../android/app/src/main/AndroidManifest.xml | 6 + 5 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/AddonInternalSettingsActivity.kt diff --git a/app/android/app/src/main/AndroidManifest.xml b/app/android/app/src/main/AndroidManifest.xml index f070dce2..89b79531 100644 --- a/app/android/app/src/main/AndroidManifest.xml +++ b/app/android/app/src/main/AndroidManifest.xml @@ -205,6 +205,12 @@ android:exported="false" android:theme="@style/AppTheme" /> + + ("add_on"), + ) + + title = addon.translateName(this) + + val fragment = AddonInternalSettingsFragment.create(addon) + + supportFragmentManager + .beginTransaction() + .replace(R.id.addonSettingsContainer, fragment) + .commit() + + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (!fragment.onBackPressed()) { + finish() + } + } + }) + } + + 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 internal settings of an add-on with [EngineView]. + * + * Creates a fresh engine session and loads the addon's options page URL into it. + */ + class AddonInternalSettingsFragment : AddonPopupBaseFragment() { + + private val addonSettingsEngineView: EngineView + get() = requireView().findViewById(R.id.addonSettingsEngineView) as EngineView + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + initializeSession() + return inflater.inflate(R.layout.fragment_add_on_settings, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val optionsPageUrl = arguments?.getParcelableCompat("add_on", Addon::class.java) + ?.installedState?.optionsPageUrl + + if (optionsPageUrl != null) { + engineSession?.let { session -> + addonSettingsEngineView.render(session) + session.loadUrl(optionsPageUrl) + } + } else { + activity?.finish() + } + } + + companion object { + fun create(addon: Addon) = AddonInternalSettingsFragment().apply { + arguments = Bundle().apply { + putParcelable("add_on", addon) + } + } + } + } +} diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/InstalledAddonDetailsActivity.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/InstalledAddonDetailsActivity.kt index 2181c91b..cccd498e 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/InstalledAddonDetailsActivity.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/addons/InstalledAddonDetailsActivity.kt @@ -137,10 +137,21 @@ class InstalledAddonDetailsActivity : AppCompatActivity() { view.isEnabled = shouldSettingsBeVisible(addon) view.setOnClickListener { val optionsPageUrl = addon.installedState?.optionsPageUrl ?: return@setOnClickListener - components.useCases.tabsUseCases.addTab(optionsPageUrl, selectTab = true) - val intent = packageManager.getLaunchIntentForPackage(packageName) - intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) - startActivity(intent) + if (addon.installedState?.openOptionsPageInTab == true) { + // Open settings in a browser tab, reusing an existing tab if already open. + components.useCases.tabsUseCases.selectOrAddTab( + url = optionsPageUrl, + ignoreFragment = true, + ) + val intent = packageManager.getLaunchIntentForPackage(packageName) + intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) + startActivity(intent) + } else { + // Open settings in an internal view with proper extension API support. + val intent = Intent(this, AddonInternalSettingsActivity::class.java) + intent.putExtra("add_on", addon) + startActivity(intent) + } } } 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 index bb426c24..16e6e5b3 100644 --- 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 @@ -10,6 +10,7 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import eu.weblibre.flutter_mozilla_components.GlobalComponents import eu.weblibre.flutter_mozilla_components.R @@ -37,10 +38,20 @@ class WebExtensionActionPopupActivity : AppCompatActivity() { title = it } + val fragment = WebExtensionActionPopupFragment.create(webExtensionId) + supportFragmentManager .beginTransaction() - .replace(R.id.addonSettingsContainer, WebExtensionActionPopupFragment.create(webExtensionId)) + .replace(R.id.addonSettingsContainer, fragment) .commit() + + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (!fragment.onBackPressed()) { + finishAndRemoveTask() + } + } + }) } override fun onCreateView(parent: View?, name: String, context: Context, attrs: AttributeSet): View? = 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 0f6233c0..f09f6e73 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,12 @@ android:exported="false" android:theme="@style/Theme.AppCompat.Light" /> + +