Snap for 6869386 from 76c0c8b4bc09caf87b8dd338d90aab772e5422d4 to rvc-qpr1-release
Change-Id: I975991f4fa4a7e663b473083c0d4d524c7c07311
diff --git a/src/com/android/providers/media/LocalCallingIdentity.java b/src/com/android/providers/media/LocalCallingIdentity.java
index 6f554b4..4d3700b 100644
--- a/src/com/android/providers/media/LocalCallingIdentity.java
+++ b/src/com/android/providers/media/LocalCallingIdentity.java
@@ -34,6 +34,7 @@
import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteImages;
import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteStorage;
import static com.android.providers.media.util.PermissionUtils.checkPermissionWriteVideo;
+import static com.android.providers.media.util.PermissionUtils.checkWriteImagesOrVideoAppOps;
import android.annotation.Nullable;
import android.app.AppOpsManager;
@@ -213,6 +214,8 @@
public static final int PERMISSION_WRITE_VIDEO = 1 << 20;
public static final int PERMISSION_WRITE_IMAGES = 1 << 21;
+ public static final int PERMISSION_IS_SYSTEM_GALLERY = 1 <<22;
+
private int hasPermission;
private int hasPermissionResolved;
@@ -271,6 +274,9 @@
case PERMISSION_WRITE_IMAGES:
return checkPermissionWriteImages(
context, pid, uid, getPackageName(), attributionTag);
+ case PERMISSION_IS_SYSTEM_GALLERY:
+ return checkWriteImagesOrVideoAppOps(
+ context, uid, getPackageName(), attributionTag);
default:
return false;
}
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index d3b6515..772ee64 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -44,6 +44,7 @@
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_REDACTION_NEEDED;
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SELF;
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SHELL;
+import static com.android.providers.media.LocalCallingIdentity.PERMISSION_IS_SYSTEM_GALLERY;
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_AUDIO;
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_IMAGES;
import static com.android.providers.media.LocalCallingIdentity.PERMISSION_READ_VIDEO;
@@ -6295,7 +6296,15 @@
final LocalCallingIdentity token =
clearLocalCallingIdentity(getCachedCallingIdentityForFuse(uid));
try {
- return uid != android.os.Process.SHELL_UID && isCallingPackageManager();
+ if (uid != android.os.Process.SHELL_UID && isCallingPackageManager()) {
+ return true;
+ }
+ // We bypass db operations for legacy system galleries with W_E_S (see b/167307393).
+ // Tracking a longer term solution in b/168784136.
+ if (isCallingPackageLegacyWrite() && isCallingPackageSystemGallery()) {
+ return true;
+ }
+ return false;
} finally {
restoreLocalCallingIdentity(token);
}
@@ -7727,6 +7736,10 @@
return builder.build();
}
+ private boolean isCallingPackageSystemGallery() {
+ return mCallingIdentity.get().hasPermission(PERMISSION_IS_SYSTEM_GALLERY);
+ }
+
@Deprecated
private String getCallingPackageOrSelf() {
return mCallingIdentity.get().getPackageName();
diff --git a/src/com/android/providers/media/util/PermissionUtils.java b/src/com/android/providers/media/util/PermissionUtils.java
index fc10b78..adbe0e2 100644
--- a/src/com/android/providers/media/util/PermissionUtils.java
+++ b/src/com/android/providers/media/util/PermissionUtils.java
@@ -185,6 +185,20 @@
generateAppOpMessage(packageName, sOpDescription.get()));
}
+ /**
+ * Returns {@code true} if the given package has write images or write video app op, which
+ * indicates the package is a system gallery.
+ */
+ public static boolean checkWriteImagesOrVideoAppOps(@NonNull Context context, int uid,
+ @NonNull String packageName, @Nullable String attributionTag) {
+ return checkAppOp(
+ context, OPSTR_WRITE_MEDIA_IMAGES, uid, packageName, attributionTag,
+ generateAppOpMessage(packageName, sOpDescription.get()))
+ || checkAppOp(
+ context, OPSTR_WRITE_MEDIA_VIDEO, uid, packageName, attributionTag,
+ generateAppOpMessage(packageName, sOpDescription.get()));
+ }
+
@VisibleForTesting
static boolean checkNoIsolatedStorageGranted(@NonNull Context context, int uid,
@NonNull String packageName, @Nullable String attributionTag) {
@@ -223,6 +237,27 @@
}
/**
+ * Checks *only* App Ops.
+ */
+ private static boolean checkAppOp(@NonNull Context context,
+ @NonNull String op, int uid, @NonNull String packageName,
+ @Nullable String attributionTag, @Nullable String opMessage) {
+ final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+ final int mode = appOps.noteOpNoThrow(op, uid, packageName, attributionTag, opMessage);
+ switch (mode) {
+ case AppOpsManager.MODE_ALLOWED:
+ return true;
+ case AppOpsManager.MODE_DEFAULT:
+ case AppOpsManager.MODE_IGNORED:
+ case AppOpsManager.MODE_ERRORED:
+ return false;
+ default:
+ throw new IllegalStateException(op + " has unknown mode " + mode);
+ }
+ }
+
+
+ /**
* Checks *only* App Ops, also returns true for legacy apps.
*/
private static boolean checkAppOpAllowingLegacy(@NonNull Context context,