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)); } } };