apache / cordova-plugin-camera

Apache Cordova Plugin camera
https://cordova.apache.org/
Apache License 2.0
960 stars 1.52k forks source link

Allow using Android photo picker instead of READ_MEDIA_IMAGES and READ_MEDIA_VIDEO #866

Open dpalou opened 6 months ago

dpalou commented 6 months ago

Feature Request

Motivation Behind Feature

On August 31 2024, a new Google policy will take effect to restrict the usage of READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions. These permissions are used by the Camera plugin.

Google recommends using the Android photo picker in apps where it's not frequent to access these files. It would be great if this plugin allows using this photo picker instead of the READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions.

Feature Description

If Android's photo picker works fine for all use cases of the plugin, then it would probably be better to remove all usage of READ_MEDIA_IMAGES and READ_MEDIA_VIDEO permissions and use the photo picker instead.

If the permissions are still needed for some cases then we should probably need a parameter or preference to pick how do we want to get the media files: either using the permissions or using the picker.

breautek commented 6 months ago

It's on our radar, we just not sure how we should deal with it yet... The photo picker is obviously one path, but given that this plugin utilises the Camera intent I'm not sure if it's a good fit here.

If I recall correctly through the camera intent the user can already choose from a gallery implemented by the camera app... but I could be wrong on this detail, I'm not entirely familiar with the camera code base.

Currently the ultimate reason for the READ_MEDIA permissions is because camera returns external storage file:// URLs and the only way those are readable via file APIs is via those permissions. Natively, these permissions are not required if we use the content resolver via the content:// uris because the app already has temporary access to the user picked files, but we translate the content:// paths to file:// paths to remain compatible with filesystem APIs.

Even if we use the photo picker, I assume the native side receives content:// uris that needs to be translated if it wants to be compatible with file plugin, which will likely introduce the same requirement of needing READ_MEDIA permissions which is obviously not good...

What would solve this problem is if we copy the granted file into the app's internal cache so the app has it's own version of the picked file. The native side can do this without requiring READ_MEDIA permissions via the content/media store APIs and the returned file path to the webview will be an internal storage file path and thus won't hit the SAF restrictions with filesystem APIs. I'm not entirely convinced this is a good idea however because it means copies of files won't be in sync with the actual user gallery, and especially for larger content like videos, copying files can be heavy.

sidibukhari commented 6 months ago

I think the developer need to think the approach of using photo picker and move away from READ_MEDIA. The reason I think this way is because Google now enforcing app that provide personal finance app cannot have that permission. Since my organization work on such app, we can no longer use this plugin as it is because it need that permission to work. Appealing to Google doesn't work at all. However, I am still looking forward on this plugin to move away from the permission. Maybe in distant future it will. Cheers.

ElementalSystems commented 6 months ago

I too have a commercial app that depends on occasional photo access - it is unlikely be allowed under the new (future) google restrictions. The suggested photo picker direction would be the best solution for my use case.

lorenzodallavecchia commented 6 months ago

Currently the ultimate reason for the READ_MEDIA permissions is because camera returns external storage file:// URLs

Aren't media access permissions also needed when using Camera.PictureSourceType.PHOTOLIBRARY and Camera.PictureSourceType.SAVEDPHOTOALBUM? I think Android Photo Picker applies to those cases.

fywstar commented 6 months ago

If we only use Camera.DestinationType.DATA_URL, then READ_MEDIA permissions are not necessary. Is it right?

breautek commented 6 months ago

Currently the ultimate reason for the READ_MEDIA permissions is because camera returns external storage file:// URLs

Aren't media access permissions also needed when using Camera.PictureSourceType.PHOTOLIBRARY and Camera.PictureSourceType.SAVEDPHOTOALBUM? I think Android Photo Picker applies to those cases.

I think I was inaccurate on my detail earlier... It seems like the camera plugin when capturing an image from the camera hardware, the native side will use the content uri and copy the image to internal storage partition, and the file URI returned is a path to internal storage. In this case, the READ_MEDIA permission isn't necessary.

However I believe you're right, if the image is sourced from the photo album, it returns the external storage file uri to that resource which does require READ_MEDIA permission.

It does appear that the file plugin has some support with content uri paths via ContentFilesystem. I'm thinking the best path forward is to see if that class actually works as expected and to maybe start experimenting with content:// paths being returned to the webview. I'm not sure if there are any drawbacks other than access to content urls isn't persistent, so it will unsafe to store as the read/write permission to that content is temporary. It will have to be up to the user to decide how to handle that case, such as storing a cache copy of the resource, if they need long-term access to it. (e.g. setting an user's profile pic.)

In general, if working with content urls more closely does work, it will probably make the file plugin a bit more powerful since content urls can represent data not necessary on the user's disk, but from a remote source (e.g. Google Drive).

onType.DATA_URL, then READ_MEDIA permissions are not necessary. Is it right?

READ_MEDIA permissions is necessary when trying to use the Filesystem API (via file plugin) or the native java.io.File classes. Choosing DATA_URL may allow you to avoid using the File plugin, but it really depends on what the native side is doing to read the content, so I'm not sure if it will completely allow you to avoid requiring the permission.

On the other note, DATA_URL is harsh on memory consumption, so it really should be avoided at all costs.

fywstar commented 6 months ago

@breautek Thanks for your reply. I tried modifying the source code and removed the code that requests permissions, and it seemed to be no problem amazingly.