From 4523f96ff185769614258ae3620a96dde9158547 Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Tue, 14 Apr 2020 19:04:41 -0700 Subject: [PATCH] DO NOT MERGE Add utilities for creating AppOps listenerIds Use utilities to support location listenerIds. Bug: 153687899 Test: presubmits Change-Id: Ie138c98a5f864490c6560166b652ea9509fa8728 --- core/java/android/app/AppOpsManager.java | 38 +++++++++++++++++++ .../android/location/LocationManager.java | 5 ++- .../location/LocationManagerService.java | 7 +++- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 3a708a6f699bc..8e0d939487e3c 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -2585,6 +2585,44 @@ public class AppOpsManager { return !sOpDisableReset[op]; } + /** + * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. + * + * This is intended for use client side, when the receiver id must be created before the + * associated call is made to the system server. If using {@link PendingIntent} as the receiver, + * avoid using this method as it will include a pointless additional x-process call. Instead to + * prefer passing the PendingIntent to the system server, and then invoking + * {@link #toReceiverId(PendingIntent)} instead. + * + * @param obj the receiver in use + * @return a string representation of the receiver suitable for app ops use + * @hide + */ + // TODO: this should probably be @SystemApi as well + public static @NonNull String toReceiverId(@NonNull Object obj) { + if (obj instanceof PendingIntent) { + return toReceiverId((PendingIntent) obj); + } else { + return obj.getClass().getName() + "@" + System.identityHashCode(obj); + } + } + + /** + * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}. + * + * This is intended for use server side, where ActivityManagerService can be referenced without + * an additional x-process call. + * + * @param pendingIntent the pendingIntent in use + * @return a string representation of the pending intent suitable for app ops use + * @see #toReceiverId(Object) + * @hide + */ + // TODO: this should probably be @SystemApi as well + public static @NonNull String toReceiverId(@NonNull PendingIntent pendingIntent) { + return pendingIntent.getTag(""); + } + /** * When to not enforce {@link #setUserRestriction restrictions}. * diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index d1b41dfccf635..9b4aebcd8affd 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -34,6 +34,7 @@ import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.app.AlarmManager; +import android.app.AppOpsManager; import android.app.PendingIntent; import android.app.PropertyInvalidatedCache; import android.compat.Compatibility; @@ -2561,7 +2562,7 @@ public class LocationManager { } public String getListenerId() { - return mConsumer.getClass().getName() + "@" + System.identityHashCode(mConsumer); + return AppOpsManager.toReceiverId(mConsumer); } public synchronized void register(AlarmManager alarmManager, @@ -2690,7 +2691,7 @@ public class LocationManager { } public String getListenerId() { - return mListener.getClass().getName() + "@" + System.identityHashCode(mListener); + return AppOpsManager.toReceiverId(mListener); } public void register(@NonNull Executor executor) { diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 72cc13a2a4196..4f8708a7599a1 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -36,6 +36,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -1827,6 +1828,9 @@ public class LocationManagerService extends ILocationManager.Stub { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } + if (listenerId == null && intent != null) { + listenerId = AppOpsManager.toReceiverId(intent); + } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, listenerId); @@ -2093,7 +2097,8 @@ public class LocationManagerService extends ILocationManager.Stub { request = DEFAULT_LOCATION_REQUEST; } - CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId); + CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, + AppOpsManager.toReceiverId(intent)); identity.enforceLocationPermission(); Objects.requireNonNull(intent);