SaveImage: Check and strip userID from URI before accessing

https://github.com/LineageOS/android_frameworks_base/commit/0236d1c5cf434af7f0b1cd71b47316496d1faeca started
adding userId in the URIs of screenshots.

Check and only proceed if the user can access the URI. This fixes edit
action as well that is broken due to mentioned change.

Issue: calyxos#1942
Change-Id: I42833a6c61ed5296fbfeda3564400581c2b29b8a
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
diff --git a/src/com/android/gallery3d/filtershow/tools/SaveImage.java b/src/com/android/gallery3d/filtershow/tools/SaveImage.java
index 26cdfa5..56f213a 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.getAuthority() == 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.getAuthority() == null) return null;
+        int end = uri.getAuthority().lastIndexOf('@');
+        Uri.Builder builder = uri.buildUpon();
+        builder.authority(uri.getAuthority().substring(end+1));
+        return builder.build();
+    }
+
+    private static boolean uriHasUserId(Uri uri) {
+        if (uri == null) return false;
+        return !TextUtils.isEmpty(uri.getUserInfo());
+    }
 }