Merge branch 'lineage-21.0' of https://github.com/LineageOS/android_packages_apps_Gallery2 into leaf-3.1

Change-Id: I72e31ea65fd9e60ec6e02d76682d8bd769b2554c
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a652ed5..c242f0b 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -53,6 +53,7 @@
     <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
     <!-- add for guest to set system property -->
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
@@ -234,7 +235,9 @@
             <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                 android:resource="@xml/device_filter" />
         </activity>
-        <service android:name="com.android.gallery3d.ingest.IngestService" />
+        <service android:name="com.android.gallery3d.ingest.IngestService"
+            android:exported="false"
+            android:foregroundServiceType="dataSync" />
 
         <activity android:name="com.android.gallery3d.app.Wallpaper"
                 android:configChanges="keyboardHidden|orientation|screenSize"
@@ -270,6 +273,7 @@
 
         <service
                 android:name="com.android.gallery3d.filtershow.pipeline.ProcessingService"
+                android:foregroundServiceType="shortService"
                 android:exported="false" />
 
         <activity
diff --git a/src/com/android/gallery3d/filtershow/tools/SaveImage.java b/src/com/android/gallery3d/filtershow/tools/SaveImage.java
index 26cdfa5..c7fa6dc 100755
--- a/src/com/android/gallery3d/filtershow/tools/SaveImage.java
+++ b/src/com/android/gallery3d/filtershow/tools/SaveImage.java
@@ -40,9 +40,12 @@
 import android.graphics.RectF;
 import android.net.Uri;
 import android.os.Environment;
+import android.os.Process;
+import android.os.UserHandle;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Images.ImageColumns;
+import android.text.TextUtils;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -103,6 +106,9 @@
     public static final int MAX_PROCESSING_STEPS = 6;
     public static final String DEFAULT_SAVE_DIRECTORY = "EditedOnlinePhotos";
 
+    // sync with UserHandle.PER_UID_RANGE
+    private static int PER_UID_RANGE = 100000;
+
     // In order to support the new edit-save behavior such that user won't see
     // the edited image together with the original image, we are adding a new
     // auxiliary directory for the edited image. Basically, the original image
@@ -690,7 +696,20 @@
      * @return The file object. Return null if srcUri is invalid or not a local
      * file.
      */
-    public static File getLocalFileFromUri(Context context, Uri srcUri) {
+    public static File getLocalFileFromUri(Context context, Uri orgUri) {
+
+        Uri srcUri;
+        if (uriHasUserId(orgUri)) {
+            if (getUserHandleFromUri(orgUri).equals(Process.myUserHandle())) {
+                srcUri = getUriWithoutUserId(orgUri);
+            } else {
+                Log.e(LOGTAG, "Trying to access URI of another user");
+                return null;
+            }
+        } else {
+            srcUri = orgUri;
+        }
+
         if (srcUri == null) {
             Log.e(LOGTAG, "srcUri is null.");
             return null;
@@ -914,4 +933,28 @@
         }
         return underlay;
     }
+
+    private static UserHandle getUserHandleFromUri(Uri uri) {
+        if (uri == null || uri.getEncodedAuthority() == null) return null;
+        final String userIdString = uri.getUserInfo();
+        try {
+            return UserHandle.getUserHandleForUid(Integer.parseInt(userIdString) * PER_UID_RANGE);
+        } catch (NumberFormatException e) {
+            Log.e(LOGTAG, "Error parsing userId.", e);
+            return null;
+        }
+    }
+
+    private static Uri getUriWithoutUserId(Uri uri) {
+        if (uri == null || uri.getEncodedAuthority() == null) return null;
+        int end = uri.getEncodedAuthority().lastIndexOf('@');
+        Uri.Builder builder = uri.buildUpon();
+        builder.encodedAuthority(uri.getEncodedAuthority().substring(end+1));
+        return builder.build();
+    }
+
+    private static boolean uriHasUserId(Uri uri) {
+        if (uri == null) return false;
+        return !TextUtils.isEmpty(uri.getUserInfo());
+    }
 }