Loading location/java/android/location/ILocationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -47,10 +47,10 @@ interface ILocationManager Location getLastLocation(in LocationRequest request, String packageName, String featureId); boolean getCurrentLocation(in LocationRequest request, in ICancellationSignal cancellationSignal, in ILocationListener listener, String packageName, String featureId); String packageName, String featureId, String listenerId); void requestLocationUpdates(in LocationRequest request, in ILocationListener listener, in PendingIntent intent, String packageName, String featureId); in PendingIntent intent, String packageName, String featureId, 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 @@ -718,7 +718,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 @@ -729,14 +729,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 @@ -1175,7 +1176,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 @@ -1220,7 +1222,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 @@ -2558,6 +2560,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 @@ -2683,6 +2689,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 services/core/java/com/android/server/LocationManagerService.java +5 −4 Original line number Diff line number Diff line Loading @@ -1836,12 +1836,13 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void requestLocationUpdates(LocationRequest request, ILocationListener listener, PendingIntent intent, String packageName, String featureId) { PendingIntent intent, String packageName, String featureId, String listenerId) { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, listenerId); identity.enforceLocationPermission(); WorkSource workSource = request.getWorkSource(); Loading Loading @@ -2027,7 +2028,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean getCurrentLocation(LocationRequest locationRequest, ICancellationSignal remoteCancellationSignal, ILocationListener listener, String packageName, String featureId) { String packageName, String featureId, String listenerId) { // side effect of validating locationRequest and packageName Location lastLocation = getLastLocation(locationRequest, packageName, featureId); if (lastLocation != null) { Loading @@ -2052,7 +2053,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } requestLocationUpdates(locationRequest, listener, null, packageName, featureId); requestLocationUpdates(locationRequest, listener, null, packageName, featureId, listenerId); CancellationSignal cancellationSignal = CancellationSignal.fromTransport( remoteCancellationSignal); if (cancellationSignal != null) { Loading services/core/java/com/android/server/location/AppOpsHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -191,7 +191,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -210,7 +210,7 @@ public class AppOpsHelper { callerIdentity.packageName, false, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -245,7 +245,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading services/core/java/com/android/server/location/CallerIdentity.java +35 −3 Original line number Diff line number Diff line Loading @@ -83,12 +83,22 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String featureId) { return fromBinder(context, packageName, featureId, 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 featureId, @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, featureId); return fromBinderUnsafe(context, packageName, featureId, listenerId); } /** Loading @@ -99,8 +109,19 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String featureId) { return fromBinderUnsafe(context, packageName, featureId, 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 featureId, @Nullable String listenerId) { return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.getCallingUserId(), packageName, featureId, UserHandle.getCallingUserId(), packageName, featureId, listenerId, getBinderPermissionLevel(context)); } Loading Loading @@ -157,6 +178,9 @@ public final class CallerIdentity { /** The calling feature id. */ public final @Nullable String featureId; /** 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 @@ -167,11 +191,18 @@ public final class CallerIdentity { @VisibleForTesting public CallerIdentity(int uid, int pid, int userId, String packageName, @Nullable String featureId, @PermissionLevel int permissionLevel) { this(uid, pid, userId, packageName, featureId, null, permissionLevel); } private CallerIdentity(int uid, int pid, int userId, String packageName, @Nullable String featureId, @Nullable String listenerId, @PermissionLevel int permissionLevel) { this.uid = uid; this.pid = pid; this.userId = userId; this.packageName = Objects.requireNonNull(packageName); this.featureId = featureId; this.listenerId = listenerId; this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE, PERMISSION_FINE, "permissionLevel"); } Loading Loading @@ -216,7 +247,8 @@ public final class CallerIdentity { return uid == that.uid && pid == that.pid && packageName.equals(that.packageName) && Objects.equals(featureId, that.featureId); && Objects.equals(featureId, that.featureId) && Objects.equals(listenerId, that.listenerId); } @Override Loading Loading
location/java/android/location/ILocationManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -47,10 +47,10 @@ interface ILocationManager Location getLastLocation(in LocationRequest request, String packageName, String featureId); boolean getCurrentLocation(in LocationRequest request, in ICancellationSignal cancellationSignal, in ILocationListener listener, String packageName, String featureId); String packageName, String featureId, String listenerId); void requestLocationUpdates(in LocationRequest request, in ILocationListener listener, in PendingIntent intent, String packageName, String featureId); in PendingIntent intent, String packageName, String featureId, 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 @@ -718,7 +718,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 @@ -729,14 +729,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 @@ -1175,7 +1176,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 @@ -1220,7 +1222,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 @@ -2558,6 +2560,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 @@ -2683,6 +2689,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
services/core/java/com/android/server/LocationManagerService.java +5 −4 Original line number Diff line number Diff line Loading @@ -1836,12 +1836,13 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void requestLocationUpdates(LocationRequest request, ILocationListener listener, PendingIntent intent, String packageName, String featureId) { PendingIntent intent, String packageName, String featureId, String listenerId) { if (request == null) { request = DEFAULT_LOCATION_REQUEST; } CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId, listenerId); identity.enforceLocationPermission(); WorkSource workSource = request.getWorkSource(); Loading Loading @@ -2027,7 +2028,7 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean getCurrentLocation(LocationRequest locationRequest, ICancellationSignal remoteCancellationSignal, ILocationListener listener, String packageName, String featureId) { String packageName, String featureId, String listenerId) { // side effect of validating locationRequest and packageName Location lastLocation = getLastLocation(locationRequest, packageName, featureId); if (lastLocation != null) { Loading @@ -2052,7 +2053,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } requestLocationUpdates(locationRequest, listener, null, packageName, featureId); requestLocationUpdates(locationRequest, listener, null, packageName, featureId, listenerId); CancellationSignal cancellationSignal = CancellationSignal.fromTransport( remoteCancellationSignal); if (cancellationSignal != null) { Loading
services/core/java/com/android/server/location/AppOpsHelper.java +3 −3 Original line number Diff line number Diff line Loading @@ -191,7 +191,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading @@ -210,7 +210,7 @@ public class AppOpsHelper { callerIdentity.packageName, false, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading Loading @@ -245,7 +245,7 @@ public class AppOpsHelper { callerIdentity.uid, callerIdentity.packageName, callerIdentity.featureId, null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED; } finally { Binder.restoreCallingIdentity(identity); } Loading
services/core/java/com/android/server/location/CallerIdentity.java +35 −3 Original line number Diff line number Diff line Loading @@ -83,12 +83,22 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinder(Context context, String packageName, @Nullable String featureId) { return fromBinder(context, packageName, featureId, 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 featureId, @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, featureId); return fromBinderUnsafe(context, packageName, featureId, listenerId); } /** Loading @@ -99,8 +109,19 @@ public final class CallerIdentity { */ public static CallerIdentity fromBinderUnsafe(Context context, String packageName, @Nullable String featureId) { return fromBinderUnsafe(context, packageName, featureId, 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 featureId, @Nullable String listenerId) { return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), UserHandle.getCallingUserId(), packageName, featureId, UserHandle.getCallingUserId(), packageName, featureId, listenerId, getBinderPermissionLevel(context)); } Loading Loading @@ -157,6 +178,9 @@ public final class CallerIdentity { /** The calling feature id. */ public final @Nullable String featureId; /** 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 @@ -167,11 +191,18 @@ public final class CallerIdentity { @VisibleForTesting public CallerIdentity(int uid, int pid, int userId, String packageName, @Nullable String featureId, @PermissionLevel int permissionLevel) { this(uid, pid, userId, packageName, featureId, null, permissionLevel); } private CallerIdentity(int uid, int pid, int userId, String packageName, @Nullable String featureId, @Nullable String listenerId, @PermissionLevel int permissionLevel) { this.uid = uid; this.pid = pid; this.userId = userId; this.packageName = Objects.requireNonNull(packageName); this.featureId = featureId; this.listenerId = listenerId; this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE, PERMISSION_FINE, "permissionLevel"); } Loading Loading @@ -216,7 +247,8 @@ public final class CallerIdentity { return uid == that.uid && pid == that.pid && packageName.equals(that.packageName) && Objects.equals(featureId, that.featureId); && Objects.equals(featureId, that.featureId) && Objects.equals(listenerId, that.listenerId); } @Override Loading