Loading location/java/android/location/ILocationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -48,10 +48,10 @@ interface ILocationManager Location getLastLocation(in LocationRequest request, String packageName, String attributionTag); boolean getCurrentLocation(in LocationRequest request, in ICancellationSignal cancellationSignal, in ILocationListener listener, String packageName, String attributionTag); String packageName, String attributionTag, String listenerId); void requestLocationUpdates(in LocationRequest request, in ILocationListener listener, in PendingIntent intent, String packageName, String attributionTag); in PendingIntent intent, String packageName, String attributionTag, String listenerId); void removeUpdates(in ILocationListener listener, in PendingIntent intent); void requestGeofence(in LocationRequest request, in Geofence geofence, Loading location/java/android/location/LocationManager.java +17 −7 Original line number Diff line number Diff line Loading @@ -712,7 +712,7 @@ public class LocationManager { currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS); } GetCurrentLocationTransport listenerTransport = new GetCurrentLocationTransport(executor, GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor, consumer); if (cancellationSignal != null) { Loading @@ -723,14 +723,15 @@ public class LocationManager { try { if (mService.getCurrentLocation(currentLocationRequest, remoteCancellationSignal, listenerTransport, mContext.getPackageName(), mContext.getAttributionTag())) { listenerTransport.register(mContext.getSystemService(AlarmManager.class), transport, mContext.getPackageName(), mContext.getAttributionTag(), transport.getListenerId())) { transport.register(mContext.getSystemService(AlarmManager.class), remoteCancellationSignal); if (cancellationSignal != null) { cancellationSignal.setOnCancelListener(listenerTransport::cancel); cancellationSignal.setOnCancelListener(transport::cancel); } } else { listenerTransport.fail(); transport.fail(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -1169,7 +1170,8 @@ public class LocationManager { boolean registered = false; try { mService.requestLocationUpdates(locationRequest, transport, null, mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(), transport.getListenerId()); registered = true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -1214,7 +1216,7 @@ public class LocationManager { try { mService.requestLocationUpdates(locationRequest, null, pendingIntent, mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(), null); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2519,6 +2521,10 @@ public class LocationManager { mRemoteCancellationSignal = null; } public String getListenerId() { return mConsumer.getClass().getName() + "@" + System.identityHashCode(mConsumer); } public synchronized void register(AlarmManager alarmManager, ICancellationSignal remoteCancellationSignal) { if (mConsumer == null) { Loading Loading @@ -2644,6 +2650,10 @@ public class LocationManager { return mListener; } public String getListenerId() { return mListener.getClass().getName() + "@" + System.identityHashCode(mListener); } public void register(@NonNull Executor executor) { Preconditions.checkArgument(executor != null, "invalid null executor"); mExecutor = executor; Loading location/java/android/location/util/identity/CallerIdentity.java +31 −5 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ public final class CallerIdentity { public static CallerIdentity forTest(int uid, int pid, String packageName, @Nullable String attributionTag, @PermissionLevel int permissionLevel) { return new CallerIdentity(uid, pid, packageName, attributionTag, return new CallerIdentity(uid, pid, packageName, attributionTag, null, permissionLevel); } Loading @@ -95,7 +95,7 @@ public final class CallerIdentity { */ public static CallerIdentity fromContext(Context context) { return new CallerIdentity(Process.myUid(), Process.myPid(), context.getPackageName(), context.getFeatureId(), context.getPackageName(), context.getAttributionTag(), null, getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid())); } Loading @@ -106,12 +106,22 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String attributionTag) { return fromBinder(context, packageName, attributionTag, null); } /** * Creates a CallerIdentity from the current binder identity, using the given package, feature * id, and listener id. The package will be checked to enforce it belongs to the calling uid, * and a security exception will be thrown if it is invalid. */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String attributionTag, @Nullable String listenerId) { int uid = Binder.getCallingUid(); if (!ArrayUtils.contains(context.getPackageManager().getPackagesForUid(uid), packageName)) { throw new SecurityException("invalid package \"" + packageName + "\" for uid " + uid); } return fromBinderUnsafe(context, packageName, attributionTag); return fromBinderUnsafe(context, packageName, attributionTag, listenerId); } /** Loading @@ -122,8 +132,19 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String attributionTag) { return fromBinderUnsafe(context, packageName, attributionTag, null); } /** * Creates a CallerIdentity from the current binder identity, using the given package, feature * id, and listener id. The package will not be checked to enforce that it belongs to the * calling uid - this method should only be used if the package will be validated by some other * means, such as an appops call. */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String attributionTag, @Nullable String listenerId) { return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName, attributionTag, packageName, attributionTag, listenerId, getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid())); } Loading Loading @@ -193,6 +214,9 @@ public final class CallerIdentity { /** The calling attribution tag. */ public final @Nullable String attributionTag; /** The calling listener id. */ public final @Nullable String listenerId; /** * The calling location permission level. This field should only be used for validating * permissions for API access. It should not be used for validating permissions for location Loading @@ -201,12 +225,14 @@ public final class CallerIdentity { public final @PermissionLevel int permissionLevel; private CallerIdentity(int uid, int pid, String packageName, @Nullable String attributionTag, @PermissionLevel int permissionLevel) { @Nullable String attributionTag, @Nullable String listenerId, @PermissionLevel int permissionLevel) { this.uid = uid; this.pid = pid; this.userId = UserHandle.getUserId(uid); this.packageName = Objects.requireNonNull(packageName); this.attributionTag = attributionTag; this.listenerId = listenerId; this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE, PERMISSION_FINE, "permissionLevel"); } Loading services/core/java/com/android/server/location/AppOpsHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -192,7 +192,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -211,7 +211,7 @@ public class AppOpsHelper { callerIdentity.packageName, false, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -246,7 +246,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading services/core/java/com/android/server/location/LocationManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -1829,12 +1829,13 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void requestLocationUpdates(LocationRequest request, ILocationListener listener, PendingIntent intent, String packageName, String attributionTag) { PendingIntent intent, String packageName, String attributionTag, String listenerId) { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, listenerId); identity.enforceLocationPermission(PERMISSION_COARSE); WorkSource workSource = request.getWorkSource(); Loading Loading @@ -2022,7 +2023,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean getCurrentLocation(LocationRequest locationRequest, ICancellationSignal remoteCancellationSignal, ILocationListener listener, String packageName, String attributionTag) { String packageName, String attributionTag, String listenerId) { // side effect of validating locationRequest and packageName Location lastLocation = getLastLocation(locationRequest, packageName, attributionTag); if (lastLocation != null) { Loading @@ -2047,7 +2048,8 @@ public class LocationManagerService extends ILocationManager.Stub { } } requestLocationUpdates(locationRequest, listener, null, packageName, attributionTag); requestLocationUpdates(locationRequest, listener, null, packageName, attributionTag, listenerId); CancellationSignal cancellationSignal = CancellationSignal.fromTransport( remoteCancellationSignal); if (cancellationSignal != null) { Loading Loading
location/java/android/location/ILocationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -48,10 +48,10 @@ interface ILocationManager Location getLastLocation(in LocationRequest request, String packageName, String attributionTag); boolean getCurrentLocation(in LocationRequest request, in ICancellationSignal cancellationSignal, in ILocationListener listener, String packageName, String attributionTag); String packageName, String attributionTag, String listenerId); void requestLocationUpdates(in LocationRequest request, in ILocationListener listener, in PendingIntent intent, String packageName, String attributionTag); in PendingIntent intent, String packageName, String attributionTag, String listenerId); void removeUpdates(in ILocationListener listener, in PendingIntent intent); void requestGeofence(in LocationRequest request, in Geofence geofence, Loading
location/java/android/location/LocationManager.java +17 −7 Original line number Diff line number Diff line Loading @@ -712,7 +712,7 @@ public class LocationManager { currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS); } GetCurrentLocationTransport listenerTransport = new GetCurrentLocationTransport(executor, GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor, consumer); if (cancellationSignal != null) { Loading @@ -723,14 +723,15 @@ public class LocationManager { try { if (mService.getCurrentLocation(currentLocationRequest, remoteCancellationSignal, listenerTransport, mContext.getPackageName(), mContext.getAttributionTag())) { listenerTransport.register(mContext.getSystemService(AlarmManager.class), transport, mContext.getPackageName(), mContext.getAttributionTag(), transport.getListenerId())) { transport.register(mContext.getSystemService(AlarmManager.class), remoteCancellationSignal); if (cancellationSignal != null) { cancellationSignal.setOnCancelListener(listenerTransport::cancel); cancellationSignal.setOnCancelListener(transport::cancel); } } else { listenerTransport.fail(); transport.fail(); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -1169,7 +1170,8 @@ public class LocationManager { boolean registered = false; try { mService.requestLocationUpdates(locationRequest, transport, null, mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(), transport.getListenerId()); registered = true; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); Loading Loading @@ -1214,7 +1216,7 @@ public class LocationManager { try { mService.requestLocationUpdates(locationRequest, null, pendingIntent, mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(), null); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -2519,6 +2521,10 @@ public class LocationManager { mRemoteCancellationSignal = null; } public String getListenerId() { return mConsumer.getClass().getName() + "@" + System.identityHashCode(mConsumer); } public synchronized void register(AlarmManager alarmManager, ICancellationSignal remoteCancellationSignal) { if (mConsumer == null) { Loading Loading @@ -2644,6 +2650,10 @@ public class LocationManager { return mListener; } public String getListenerId() { return mListener.getClass().getName() + "@" + System.identityHashCode(mListener); } public void register(@NonNull Executor executor) { Preconditions.checkArgument(executor != null, "invalid null executor"); mExecutor = executor; Loading
location/java/android/location/util/identity/CallerIdentity.java +31 −5 Original line number Diff line number Diff line Loading @@ -86,7 +86,7 @@ public final class CallerIdentity { public static CallerIdentity forTest(int uid, int pid, String packageName, @Nullable String attributionTag, @PermissionLevel int permissionLevel) { return new CallerIdentity(uid, pid, packageName, attributionTag, return new CallerIdentity(uid, pid, packageName, attributionTag, null, permissionLevel); } Loading @@ -95,7 +95,7 @@ public final class CallerIdentity { */ public static CallerIdentity fromContext(Context context) { return new CallerIdentity(Process.myUid(), Process.myPid(), context.getPackageName(), context.getFeatureId(), context.getPackageName(), context.getAttributionTag(), null, getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid())); } Loading @@ -106,12 +106,22 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String attributionTag) { return fromBinder(context, packageName, attributionTag, null); } /** * Creates a CallerIdentity from the current binder identity, using the given package, feature * id, and listener id. The package will be checked to enforce it belongs to the calling uid, * and a security exception will be thrown if it is invalid. */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String attributionTag, @Nullable String listenerId) { int uid = Binder.getCallingUid(); if (!ArrayUtils.contains(context.getPackageManager().getPackagesForUid(uid), packageName)) { throw new SecurityException("invalid package \"" + packageName + "\" for uid " + uid); } return fromBinderUnsafe(context, packageName, attributionTag); return fromBinderUnsafe(context, packageName, attributionTag, listenerId); } /** Loading @@ -122,8 +132,19 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String attributionTag) { return fromBinderUnsafe(context, packageName, attributionTag, null); } /** * Creates a CallerIdentity from the current binder identity, using the given package, feature * id, and listener id. The package will not be checked to enforce that it belongs to the * calling uid - this method should only be used if the package will be validated by some other * means, such as an appops call. */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String attributionTag, @Nullable String listenerId) { return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName, attributionTag, packageName, attributionTag, listenerId, getPermissionLevel(context, Binder.getCallingPid(), Binder.getCallingUid())); } Loading Loading @@ -193,6 +214,9 @@ public final class CallerIdentity { /** The calling attribution tag. */ public final @Nullable String attributionTag; /** The calling listener id. */ public final @Nullable String listenerId; /** * The calling location permission level. This field should only be used for validating * permissions for API access. It should not be used for validating permissions for location Loading @@ -201,12 +225,14 @@ public final class CallerIdentity { public final @PermissionLevel int permissionLevel; private CallerIdentity(int uid, int pid, String packageName, @Nullable String attributionTag, @PermissionLevel int permissionLevel) { @Nullable String attributionTag, @Nullable String listenerId, @PermissionLevel int permissionLevel) { this.uid = uid; this.pid = pid; this.userId = UserHandle.getUserId(uid); this.packageName = Objects.requireNonNull(packageName); this.attributionTag = attributionTag; this.listenerId = listenerId; this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE, PERMISSION_FINE, "permissionLevel"); } Loading
services/core/java/com/android/server/location/AppOpsHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -192,7 +192,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -211,7 +211,7 @@ public class AppOpsHelper { callerIdentity.packageName, false, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -246,7 +246,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.attributionTag, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading
services/core/java/com/android/server/location/LocationManagerService.java +6 −4 Original line number Diff line number Diff line Loading @@ -1829,12 +1829,13 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void requestLocationUpdates(LocationRequest request, ILocationListener listener, PendingIntent intent, String packageName, String attributionTag) { PendingIntent intent, String packageName, String attributionTag, String listenerId) { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, listenerId); identity.enforceLocationPermission(PERMISSION_COARSE); WorkSource workSource = request.getWorkSource(); Loading Loading @@ -2022,7 +2023,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean getCurrentLocation(LocationRequest locationRequest, ICancellationSignal remoteCancellationSignal, ILocationListener listener, String packageName, String attributionTag) { String packageName, String attributionTag, String listenerId) { // side effect of validating locationRequest and packageName Location lastLocation = getLastLocation(locationRequest, packageName, attributionTag); if (lastLocation != null) { Loading @@ -2047,7 +2048,8 @@ public class LocationManagerService extends ILocationManager.Stub { } } requestLocationUpdates(locationRequest, listener, null, packageName, attributionTag); requestLocationUpdates(locationRequest, listener, null, packageName, attributionTag, listenerId); CancellationSignal cancellationSignal = CancellationSignal.fromTransport( remoteCancellationSignal); if (cancellationSignal != null) { Loading