MixinNetwork / MixinNetwork/flutter-plugins

[android] error reading image data dragged from Chrome browser

Open
#502 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
512
Forks
292
Avg merge
15h 8m
Merged PRs (30d)
7

Description

Reproduce Steps

Steps to reproduce the behavior:

  1. Open Chrome and a Flutter app with desktop_drop side by side on Android tablet or emulator
  2. Drag an image from a web page loaded in Chrome to the Flutter app
  3. The returned file contains content:// url as file.path and attempt to read data from the content:// url obtained from the DropDoneDetails.files..path (e.g. using the saf_stream package) is failing with "Permission Denial" error

Expected behavior

It should be possible to read the content data

Version (please complete the following information):

  • Flutter Version: 3.47
  • OS: Android
  • plugin: desktop_drop 0.8.4
I/flutter ( 7970): Failed to copy content URI content://com.android.chrome.DropDataProvider/1789068043787: PlatformException(PluginError, Permission Denial: opening provider org.chromium.ui.dragdrop.DropDataContentProvider from ProcessRecord{ca7db50 7970:***/u0a212} (pid=7970, uid=10212) that is not exported from UID 10145, null, null)
I/flutter ( 7970): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:653:7)
I/flutter ( 7970): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:366:18)
I/flutter ( 7970): <asynchronous suspension>
I/flutter ( 7970): #2      MethodChannelSafStream.copyToLocalFile (package:saf_stream/saf_stream_method_channel.dart:58:5)
I/flutter ( 7970): <asynchronous suspension>
...
Why it fails:
  1. activity.requestDragAndDropPermissions(event) successfully obtains temporary read permissions for the content:// URI during the drop event.
  2. The plugin collects the URI strings (content://org.chromium.ui.dragdrop.DropDataContentProvider/...).
  3. Crucial Flaw: The plugin immediately calls permission.release() before sending the URIs over the MethodChannel to Flutter.
  4. By the time the Flutter Dart code receives the URI string via performOperation and attempts to read it (via SAF, ContentResolver, or SafStream), the drag-and-drop permission has already been revoked.
  5. Consequently, Android throws java.lang.SecurityException: Permission Denial when the app tries to open the input stream.
Required Changes in DesktopDropPlugin.kt

To allow reading from non-exported content:// providers across process boundaries:

  1. Copy content:// URIs to a local cache file while the permission is held: Before calling permission.release(), use contentResolver.openInputStream(uri) on the Android side to write the stream data into a temporary file in activity.cacheDir.
  2. Return the local file path to Flutter: Send the cached file path to Flutter instead of the raw content:// URI string.
  3. Release permission after copying: Call permission.release() inside a finally block once the file copy is complete.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with DesktopDropPlugin.kt and trace how requestDragAndDropPermissions, URI collection, and permission.release() are handled during a drop. Reproduce the Chrome-to-Flutter Android case, then verify that dropped content can be read after the callback completes and that permissions are released only after the data is safely available.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, flutter, kotlin
Domain
mobile-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.