Merge "DO NOT MERGE Add listener ids for location listening operations" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-04-08 18:45:19 +00:00
committed by Android (Google) Code Review
5 changed files with 62 additions and 19 deletions

View File

@@ -47,10 +47,10 @@ interface ILocationManager
Location getLastLocation(in LocationRequest request, String packageName, String featureId); Location getLastLocation(in LocationRequest request, String packageName, String featureId);
boolean getCurrentLocation(in LocationRequest request, boolean getCurrentLocation(in LocationRequest request,
in ICancellationSignal cancellationSignal, in ILocationListener listener, in ICancellationSignal cancellationSignal, in ILocationListener listener,
String packageName, String featureId); String packageName, String featureId, String listenerId);
void requestLocationUpdates(in LocationRequest request, in ILocationListener listener, 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 removeUpdates(in ILocationListener listener, in PendingIntent intent);
void requestGeofence(in LocationRequest request, in Geofence geofence, void requestGeofence(in LocationRequest request, in Geofence geofence,

View File

@@ -718,7 +718,7 @@ public class LocationManager {
currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS); currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
} }
GetCurrentLocationTransport listenerTransport = new GetCurrentLocationTransport(executor, GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor,
consumer); consumer);
if (cancellationSignal != null) { if (cancellationSignal != null) {
@@ -729,14 +729,15 @@ public class LocationManager {
try { try {
if (mService.getCurrentLocation(currentLocationRequest, remoteCancellationSignal, if (mService.getCurrentLocation(currentLocationRequest, remoteCancellationSignal,
listenerTransport, mContext.getPackageName(), mContext.getAttributionTag())) { transport, mContext.getPackageName(), mContext.getAttributionTag(),
listenerTransport.register(mContext.getSystemService(AlarmManager.class), transport.getListenerId())) {
transport.register(mContext.getSystemService(AlarmManager.class),
remoteCancellationSignal); remoteCancellationSignal);
if (cancellationSignal != null) { if (cancellationSignal != null) {
cancellationSignal.setOnCancelListener(listenerTransport::cancel); cancellationSignal.setOnCancelListener(transport::cancel);
} }
} else { } else {
listenerTransport.fail(); transport.fail();
} }
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
@@ -1175,7 +1176,8 @@ public class LocationManager {
boolean registered = false; boolean registered = false;
try { try {
mService.requestLocationUpdates(locationRequest, transport, null, mService.requestLocationUpdates(locationRequest, transport, null,
mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(),
transport.getListenerId());
registered = true; registered = true;
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
@@ -1220,7 +1222,7 @@ public class LocationManager {
try { try {
mService.requestLocationUpdates(locationRequest, null, pendingIntent, mService.requestLocationUpdates(locationRequest, null, pendingIntent,
mContext.getPackageName(), mContext.getAttributionTag()); mContext.getPackageName(), mContext.getAttributionTag(), null);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
@@ -2558,6 +2560,10 @@ public class LocationManager {
mRemoteCancellationSignal = null; mRemoteCancellationSignal = null;
} }
public String getListenerId() {
return mConsumer.getClass().getName() + "@" + System.identityHashCode(mConsumer);
}
public synchronized void register(AlarmManager alarmManager, public synchronized void register(AlarmManager alarmManager,
ICancellationSignal remoteCancellationSignal) { ICancellationSignal remoteCancellationSignal) {
if (mConsumer == null) { if (mConsumer == null) {
@@ -2683,6 +2689,10 @@ public class LocationManager {
return mListener; return mListener;
} }
public String getListenerId() {
return mListener.getClass().getName() + "@" + System.identityHashCode(mListener);
}
public void register(@NonNull Executor executor) { public void register(@NonNull Executor executor) {
Preconditions.checkArgument(executor != null, "invalid null executor"); Preconditions.checkArgument(executor != null, "invalid null executor");
mExecutor = executor; mExecutor = executor;

View File

@@ -1836,12 +1836,13 @@ public class LocationManagerService extends ILocationManager.Stub {
@Override @Override
public void requestLocationUpdates(LocationRequest request, ILocationListener listener, public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
PendingIntent intent, String packageName, String featureId) { PendingIntent intent, String packageName, String featureId, String listenerId) {
if (request == null) { if (request == null) {
request = DEFAULT_LOCATION_REQUEST; request = DEFAULT_LOCATION_REQUEST;
} }
CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, featureId,
listenerId);
identity.enforceLocationPermission(); identity.enforceLocationPermission();
WorkSource workSource = request.getWorkSource(); WorkSource workSource = request.getWorkSource();
@@ -2027,7 +2028,7 @@ public class LocationManagerService extends ILocationManager.Stub {
@Override @Override
public boolean getCurrentLocation(LocationRequest locationRequest, public boolean getCurrentLocation(LocationRequest locationRequest,
ICancellationSignal remoteCancellationSignal, ILocationListener listener, ICancellationSignal remoteCancellationSignal, ILocationListener listener,
String packageName, String featureId) { String packageName, String featureId, String listenerId) {
// side effect of validating locationRequest and packageName // side effect of validating locationRequest and packageName
Location lastLocation = getLastLocation(locationRequest, packageName, featureId); Location lastLocation = getLastLocation(locationRequest, packageName, featureId);
if (lastLocation != null) { if (lastLocation != null) {
@@ -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( CancellationSignal cancellationSignal = CancellationSignal.fromTransport(
remoteCancellationSignal); remoteCancellationSignal);
if (cancellationSignal != null) { if (cancellationSignal != null) {

View File

@@ -191,7 +191,7 @@ public class AppOpsHelper {
callerIdentity.uid, callerIdentity.uid,
callerIdentity.packageName, callerIdentity.packageName,
callerIdentity.featureId, callerIdentity.featureId,
null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED;
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }
@@ -210,7 +210,7 @@ public class AppOpsHelper {
callerIdentity.packageName, callerIdentity.packageName,
false, false,
callerIdentity.featureId, callerIdentity.featureId,
null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED;
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }
@@ -245,7 +245,7 @@ public class AppOpsHelper {
callerIdentity.uid, callerIdentity.uid,
callerIdentity.packageName, callerIdentity.packageName,
callerIdentity.featureId, callerIdentity.featureId,
null) == AppOpsManager.MODE_ALLOWED; callerIdentity.listenerId) == AppOpsManager.MODE_ALLOWED;
} finally { } finally {
Binder.restoreCallingIdentity(identity); Binder.restoreCallingIdentity(identity);
} }

View File

@@ -83,12 +83,22 @@ public final class CallerIdentity {
*/ */
public static CallerIdentity fromBinder(Context context, String packageName, public static CallerIdentity fromBinder(Context context, String packageName,
@Nullable String featureId) { @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(); int uid = Binder.getCallingUid();
if (!ArrayUtils.contains(context.getPackageManager().getPackagesForUid(uid), packageName)) { if (!ArrayUtils.contains(context.getPackageManager().getPackagesForUid(uid), packageName)) {
throw new SecurityException("invalid package \"" + packageName + "\" for uid " + uid); throw new SecurityException("invalid package \"" + packageName + "\" for uid " + uid);
} }
return fromBinderUnsafe(context, packageName, featureId); return fromBinderUnsafe(context, packageName, featureId, listenerId);
} }
/** /**
@@ -99,8 +109,19 @@ public final class CallerIdentity {
*/ */
public static CallerIdentity fromBinderUnsafe(Context context, String packageName, public static CallerIdentity fromBinderUnsafe(Context context, String packageName,
@Nullable String featureId) { @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(), return new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(),
UserHandle.getCallingUserId(), packageName, featureId, UserHandle.getCallingUserId(), packageName, featureId, listenerId,
getBinderPermissionLevel(context)); getBinderPermissionLevel(context));
} }
@@ -157,6 +178,9 @@ public final class CallerIdentity {
/** The calling feature id. */ /** The calling feature id. */
public final @Nullable String featureId; 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 * 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 * permissions for API access. It should not be used for validating permissions for location
@@ -167,11 +191,18 @@ public final class CallerIdentity {
@VisibleForTesting @VisibleForTesting
public CallerIdentity(int uid, int pid, int userId, String packageName, public CallerIdentity(int uid, int pid, int userId, String packageName,
@Nullable String featureId, @PermissionLevel int permissionLevel) { @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.uid = uid;
this.pid = pid; this.pid = pid;
this.userId = userId; this.userId = userId;
this.packageName = Objects.requireNonNull(packageName); this.packageName = Objects.requireNonNull(packageName);
this.featureId = featureId; this.featureId = featureId;
this.listenerId = listenerId;
this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE, this.permissionLevel = Preconditions.checkArgumentInRange(permissionLevel, PERMISSION_NONE,
PERMISSION_FINE, "permissionLevel"); PERMISSION_FINE, "permissionLevel");
} }
@@ -216,7 +247,8 @@ public final class CallerIdentity {
return uid == that.uid return uid == that.uid
&& pid == that.pid && pid == that.pid
&& packageName.equals(that.packageName) && packageName.equals(that.packageName)
&& Objects.equals(featureId, that.featureId); && Objects.equals(featureId, that.featureId)
&& Objects.equals(listenerId, that.listenerId);
} }
@Override @Override