From 7ab57a14b0e49330497a75407697e04035c7c60e Mon Sep 17 00:00:00 2001 From: Fabian Freund Date: Thu, 11 Sep 2025 07:16:52 +0200 Subject: [PATCH] fix file upload --- .../BaseBrowserFragment.kt | 41 +++++++++++++++++++ .../BrowserFragment.kt | 7 ++++ .../EngineProvider.kt | 2 +- .../components/Core.kt | 7 +++- 4 files changed, 55 insertions(+), 2 deletions(-) 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 51b2067f..a41ed4dd 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 @@ -16,6 +16,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.FrameLayout +import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.CallSuper @@ -34,6 +35,7 @@ import mozilla.components.feature.downloads.temporary.ShareResourceFeature import mozilla.components.feature.media.fullscreen.MediaSessionFullscreenFeature import mozilla.components.feature.privatemode.feature.SecureWindowFeature import mozilla.components.feature.prompts.PromptFeature +import mozilla.components.feature.prompts.file.AndroidPhotoPicker import mozilla.components.feature.session.FullScreenFeature import mozilla.components.feature.session.PictureInPictureFeature import mozilla.components.feature.session.SessionFeature @@ -43,6 +45,7 @@ import mozilla.components.feature.sitepermissions.SitePermissionsRules import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction import mozilla.components.feature.webauthn.WebAuthnFeature import mozilla.components.support.base.feature.ActivityResultHandler +import mozilla.components.support.base.feature.PermissionsFeature import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.log.logger.Logger @@ -74,6 +77,20 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit private var pictureInPictureFeature: PictureInPictureFeature? = null + // Registers a photo picker activity launcher in single-select mode. + private val singleMediaPicker = + AndroidPhotoPicker.singleMediaPicker( + { this }, + { promptFeature.get() }, + ) + + // Registers a photo picker activity launcher in multi-select mode. + private val multipleMediaPicker = + AndroidPhotoPicker.multipleMediaPicker( + { this }, + { promptFeature.get() }, + ) + private val sessionId: String? get() = arguments?.getString(SESSION_ID_KEY) @@ -224,6 +241,11 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit onNeedToRequestPermissions = { permissions -> requestPromptsPermissionsLauncher.launch(permissions) }, + androidPhotoPicker = AndroidPhotoPicker( + requireContext(), + singleMediaPicker, + multipleMediaPicker, + ), ), owner = this, view = view, @@ -392,6 +414,21 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit } } + @Suppress("OVERRIDE_DEPRECATION") + final override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray, + ) { + val feature: PermissionsFeature? = when (requestCode) { + REQUEST_CODE_DOWNLOAD_PERMISSIONS -> downloadsFeature.get() + REQUEST_CODE_PROMPT_PERMISSIONS -> promptFeature.get() + REQUEST_CODE_APP_PERMISSIONS -> sitePermissionsFeature.get() + else -> null + } + feature?.onPermissionsResult(permissions, grantResults) + } + @CallSuper override fun onActivityResult(requestCode: Int, data: Intent?, resultCode: Int): Boolean { return activityResultHandler.any { it.onActivityResult(requestCode, data, resultCode) } @@ -400,6 +437,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit companion object { private const val SESSION_ID_KEY = "session_id" + private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1 + private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2 + private const val REQUEST_CODE_APP_PERMISSIONS = 3 + @JvmStatic protected fun Bundle.putSessionId(sessionId: String?) { putString(SESSION_ID_KEY, sessionId) diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BrowserFragment.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BrowserFragment.kt index d06ed558..bb7a425a 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BrowserFragment.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/BrowserFragment.kt @@ -10,6 +10,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View +import androidx.annotation.CallSuper import eu.weblibre.flutter_mozilla_components.addons.WebExtensionActionPopupActivity import eu.weblibre.flutter_mozilla_components.feature.ReadabilityExtractFeature import eu.weblibre.flutter_mozilla_components.feature.WebExtensionToolbarFeature @@ -39,6 +40,12 @@ class BrowserFragment() : BaseBrowserFragment(), UserInteractionHandler { } } + @Deprecated("Deprecated in Java") + @CallSuper + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, data, resultCode) + } + @Suppress("LongMethod") override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/EngineProvider.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/EngineProvider.kt index dd84436b..4de96e51 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/EngineProvider.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/EngineProvider.kt @@ -70,7 +70,7 @@ object EngineProvider { builder.aboutConfigEnabled(true) builder.extensionsProcessEnabled(true) builder.extensionsWebAPIEnabled(true) - builder.debugLogging(components.logLevel == Log.Priority.DEBUG) + //builder.debugLogging(components.logLevel == Log.Priority.DEBUG) builder.consoleOutput(components.logLevel == Log.Priority.DEBUG) builder.contentBlocking(contentBlocking.build()) diff --git a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/Core.kt b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/Core.kt index ab5dd674..28ed7112 100644 --- a/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/Core.kt +++ b/packages/flutter_mozilla_components/android/src/main/kotlin/eu/weblibre/flutter_mozilla_components/components/Core.kt @@ -46,8 +46,11 @@ import mozilla.components.feature.addons.update.DefaultAddonUpdater import mozilla.components.feature.customtabs.store.CustomTabsServiceStore import mozilla.components.feature.downloads.DownloadMiddleware import mozilla.components.feature.media.MediaSessionFeature +import mozilla.components.feature.media.middleware.LastMediaAccessMiddleware import mozilla.components.feature.media.middleware.RecordingDevicesMiddleware +import mozilla.components.feature.prompts.PromptMiddleware import mozilla.components.feature.prompts.file.FileUploadsDirCleaner +import mozilla.components.feature.prompts.file.FileUploadsDirCleanerMiddleware import mozilla.components.feature.readerview.ReaderViewMiddleware import mozilla.components.feature.session.HistoryDelegate import mozilla.components.feature.session.middleware.LastAccessMiddleware @@ -166,9 +169,11 @@ class Core(private val context: Context, ReaderViewMiddleware(), UndoMiddleware(), LastAccessMiddleware(), -// PromptMiddleware(), SessionPrioritizationMiddleware(), RecordingDevicesMiddleware(context, components.notificationsDelegate), + PromptMiddleware(), + FileUploadsDirCleanerMiddleware(fileUploadsDirCleaner), + LastMediaAccessMiddleware(), ) + EngineMiddleware.create( engine, // We are disabling automatic suspending of engine sessions under memory pressure.