From 7fb1ca4cb24dbe7bb267f6d00300f4191eea973f Mon Sep 17 00:00:00 2001 From: himanshuz Date: Fri, 28 Apr 2023 17:45:24 +0000 Subject: [PATCH] Adding a way to communicate user space for AppOp changes. Currently, AppOpps Manager just provides package name to its upstream listeners, which detemine the correct app by utiliing context bound package manager APIs. However, this gives issues for MediaProvider, as root user and clone user both share the MediaProvider of root user, providing no way for MP process to know if an AppOp was intended for root user or cloned user app. By adding a new hidden API which takes userId and is overridden by MP, we can convey the desired userId to MP process. Using this userId, MP can clear media_grants for correct userId (user 0 or cloned user), in case a corresponding app_op is recieved. For other impl, the original functionality of not getting userId is retained. Test: atest CtsAppOpsTestCases CtsAppOps2TestCases Bug: 278843665, 278644253 Change-Id: I7ff844dae27757492f31c795432600cab48b2bb5 --- core/java/android/app/AppOpsManager.java | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 9e59ee496de1a..ccd83f7567302 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -60,6 +60,7 @@ import android.os.RemoteCallback; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; +import android.os.UserHandle; import android.os.UserManager; import android.provider.DeviceConfig; import android.util.ArrayMap; @@ -7084,6 +7085,26 @@ public class AppOpsManager { */ public interface OnOpChangedListener { public void onOpChanged(String op, String packageName); + + /** + * Implementations can override this method to add handling logic for AppOp changes. + * + * Normally, listeners to AppOp changes work in the same User Space as the App whose Op + * has changed. However, in some case listeners can have a single instance responsible for + * multiple users. (For ex single Media Provider instance in user 0 is responsible for both + * cloned and user 0 spaces). For handling such cases correctly, listeners need to be + * passed userId in addition to PackageName and Op. + + * The default impl is to fallback onto {@link #onOpChanged(String, String) + * + * @param op The Op that changed. + * @param packageName Package of the app whose Op changed. + * @param userId User Space of the app whose Op changed. + * @hide + */ + default void onOpChanged(@NonNull String op, @NonNull String packageName, int userId) { + onOpChanged(op, packageName); + } } /** @@ -7756,7 +7777,9 @@ public class AppOpsManager { ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName); } if (sAppOpInfos[op].name != null) { - callback.onOpChanged(sAppOpInfos[op].name, packageName); + + callback.onOpChanged(sAppOpInfos[op].name, packageName, + UserHandle.getUserId(uid)); } } };