summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-09-28 23:11:38 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-09-28 23:11:38 +0000
commit5b21ddc50aa232a3a1d7d470b0f8ea9ee91fc4c8 (patch)
treee6e57a61b316ab365f7825d407a78ca6c23f14ad
parenta4e1d5a7f78b90be84c4740cbfc1e3f166aeddeb (diff)
parent76c0c8b4bc09caf87b8dd338d90aab772e5422d4 (diff)
downloadMediaProvider-android11-qpr1-release.tar.gz
Change-Id: I975991f4fa4a7e663b473083c0d4d524c7c07311
-rw-r--r--src/com/android/providers/media/LocalCallingIdentity.java6
-rw-r--r--src/com/android/providers/media/MediaProvider.java15
-rw-r--r--src/com/android/providers/media/util/PermissionUtils.java35
3 files changed, 55 insertions, 1 deletions
diff --git a/src/com/android/providers/media/LocalCallingIdentity.java b/src/com/android/providers/media/LocalCallingIdentity.java
index 6f554b407..4d3700b21 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.checkPermissionWr
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 class LocalCallingIdentity {
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 @@ public class LocalCallingIdentity {
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 d3b651571..772ee64e8 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_MAN
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 @@ public class MediaProvider extends ContentProvider {
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 @@ public class MediaProvider extends ContentProvider {
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 fc10b78c5..adbe0e210 100644
--- a/src/com/android/providers/media/util/PermissionUtils.java
+++ b/src/com/android/providers/media/util/PermissionUtils.java
@@ -185,6 +185,20 @@ public class PermissionUtils {
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 @@ public class PermissionUtils {
}
/**
+ * 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,