android/source/AndroidManifest.xml                                |    1 
 android/source/src/java/org/libreoffice/FormattingController.java |   38 
+++-------
 2 files changed, 13 insertions(+), 26 deletions(-)

New commits:
commit e99991216e47751b80238825aaeb21702d46dc34
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Mon May 13 15:36:20 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Tue May 14 08:37:49 2024 +0200

    android: Fix taking photos by dropping permission
    
    At least on recent devices (seen e.g. on an AVD
    with API level 34 and a Fairphone 3 with LineageOS 20
    (based on Android 13)), inserting a picture by
    taking a photo using the camera didn't work,
    "nothing was happening" when choosing the corresponding
    option from the formatting toolbar with experimental
    editing mode enabled.
    
    This is due to the system filtering information about
    other apps/packages with target API level >= 30 for
    privacy reasons, see [1] for more details.
    
    As described at [2], requesting the `CAMERA`
    permission is not required:
    
    > Users might take pictures in your app, using the pre-installed
    > system camera app.
    >
    > In this situation, don't declare the CAMERA permission. Instead,
    > invoke the ACTION_IMAGE_CAPTURE intent action.
    
    In fact, specifying the permission is even counter-productive
    and would cause this to not work, as also described at [2]:
    
    > Note: If your app declares Manifest.permission.CAMERA
    > permission and is not granted, then the action results in
    > a SecurityException.
    
    Rather than explicitly requesting the permission, just
    drop it from the AndroidManifest, as it's not needed.
    Also drop the additional code interacting with the package
    manager, as that doesn't work with newer API
    versions as described above.
    
    With these changes in place, inserting a photo works fine
    in tests in API 21 and API 34 AVDs and on the
    above-mentioned Fairphone 3.
    
    [1] https://developer.android.com/training/package-visibility
    [2] 
https://developer.android.com/privacy-and-security/minimize-permission-requests#take-photo
    
    Change-Id: Ia1ee4e4de577a269e2b79bf5460d08b1bf2bee56
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167603
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/android/source/AndroidManifest.xml 
b/android/source/AndroidManifest.xml
index 3ece77d62bfd..ba71fdddb197 100644
--- a/android/source/AndroidManifest.xml
+++ b/android/source/AndroidManifest.xml
@@ -6,7 +6,6 @@
     <uses-feature android:glEsVersion="0x00020000" android:required="true" />
     <!-- App wants to know if device supports USB host capability(not 
mandatory) -->
     <uses-feature android:name="android.hardware.usb.host" 
android:required="false"/>
-    <uses-feature android:name="android.hardware.camera.any" 
android:required="false"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
     <application
diff --git a/android/source/src/java/org/libreoffice/FormattingController.java 
b/android/source/src/java/org/libreoffice/FormattingController.java
index 1d72c10a2ac7..378a3ecb87bc 100644
--- a/android/source/src/java/org/libreoffice/FormattingController.java
+++ b/android/source/src/java/org/libreoffice/FormattingController.java
@@ -366,31 +366,19 @@ class FormattingController implements 
View.OnClickListener {
             return;
         }
         Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
-        // Ensure that there's a camera activity to handle the intent
-        if (takePictureIntent.resolveActivity(mContext.getPackageManager()) != 
null) {
-            // Create the File where the photo should go
-            File photoFile = null;
-            try {
-                photoFile = createImageFile();
-            } catch (IOException ex) {
-                ex.printStackTrace();
-            }
-            // Continue only if the File was successfully created
-            if (photoFile != null) {
-                Uri photoURI = FileProvider.getUriForFile(mContext,
-                        mContext.getPackageName() + ".fileprovider",
-                        photoFile);
-                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
-                // Grant permissions to potential photo/camera apps (for some 
Android versions)
-                List<ResolveInfo> resInfoList = mContext.getPackageManager()
-                        .queryIntentActivities(takePictureIntent, 
PackageManager.MATCH_DEFAULT_ONLY);
-                for (ResolveInfo resolveInfo : resInfoList) {
-                    String packageName = resolveInfo.activityInfo.packageName;
-                    mContext.grantUriPermission(packageName, photoURI, 
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
-                            | Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                }
-                mContext.startActivityForResult(takePictureIntent, TAKE_PHOTO);
-            }
+        // Create the File where the photo should go
+        File photoFile = null;
+        try {
+            photoFile = createImageFile();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+        // Continue only if the File was successfully created
+        if (photoFile != null) {
+            Uri photoURI = FileProvider.getUriForFile(mContext,
+                    mContext.getPackageName() + ".fileprovider", photoFile);
+            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
+            mContext.startActivityForResult(takePictureIntent, TAKE_PHOTO);
         }
     }
 

Reply via email to