Loading services/core/java/com/android/server/location/LocationManagerService.java +11 −19 Original line number Diff line number Diff line Loading @@ -1133,9 +1133,7 @@ public class LocationManagerService extends ILocationManager.Stub { return; } String dumpFilter = args.length == 0 ? null : args[0]; ipw.println("Location Manager State:"); ipw.print("Location Manager State:"); ipw.increaseIndent(); ipw.println("Elapsed Realtime: " + TimeUtils.formatDuration(SystemClock.elapsedRealtime())); Loading Loading @@ -1173,28 +1171,22 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Location Providers:"); ipw.increaseIndent(); for (LocationProviderManager manager : mProviderManagers) { if (dumpFilter == null || manager.getName().equals(dumpFilter)) { manager.dump(fd, ipw, args); } } ipw.decreaseIndent(); if (dumpFilter == null || GPS_PROVIDER.equals(dumpFilter)) { if (mGnssManagerService != null) { ipw.println("GNSS Manager:"); ipw.increaseIndent(); mGnssManagerService.dump(fd, ipw, args); ipw.decreaseIndent(); } } if (dumpFilter == null || "geofence".equals(dumpFilter)) { ipw.println("Geofence Manager:"); ipw.increaseIndent(); mGeofenceManager.dump(fd, ipw, args); ipw.decreaseIndent(); } } private class LocalService extends LocationManagerInternal { Loading services/core/java/com/android/server/location/LocationProviderManager.java +160 −57 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ import com.android.server.LocalServices; import com.android.server.PendingIntentUtils; import com.android.server.location.LocationPermissions.PermissionLevel; import com.android.server.location.listeners.ListenerMultiplexer; import com.android.server.location.listeners.RemovableListenerRegistration; import com.android.server.location.listeners.RemoteListenerRegistration; import com.android.server.location.util.AppForegroundHelper; import com.android.server.location.util.AppForegroundHelper.AppForegroundListener; import com.android.server.location.util.AppOpsHelper; Loading Loading @@ -154,15 +154,8 @@ class LocationProviderManager extends @Override public void deliverOnLocationChanged(Location location, @Nullable Runnable onCompleteCallback) throws RemoteException { mListener.onLocationChanged(location, onCompleteCallback == null ? null : new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) { onCompleteCallback.run(); } }); @Nullable Runnable onCompleteCallback) throws RemoteException { mListener.onLocationChanged(location, SingleUseCallback.wrap(onCompleteCallback)); } @Override Loading Loading @@ -221,7 +214,7 @@ class LocationProviderManager extends } protected abstract class Registration extends RemovableListenerRegistration<LocationRequest, LocationTransport> { RemoteListenerRegistration<LocationRequest, LocationTransport> { @PermissionLevel protected final int mPermissionLevel; private final WorkSource mWorkSource; Loading Loading @@ -306,11 +299,12 @@ class LocationProviderManager extends } @Override protected final void onInactive() { protected final ListenerOperation<LocationTransport> onInactive() { onHighPowerUsageChanged(); if (!getRequest().getHideFromAppOps()) { mLocationAttributionHelper.reportLocationStop(getIdentity(), getName(), getKey()); } return null; } @Override Loading Loading @@ -826,6 +820,12 @@ class LocationProviderManager extends @GuardedBy("mLock") @Override protected void onProviderListenerRegister() { try { ((IBinder) getKey()).linkToDeath(this, 0); } catch (RemoteException e) { remove(); } mExpirationRealtimeMs = getRequest().getExpirationRealtimeMs( SystemClock.elapsedRealtime()); Loading @@ -837,12 +837,6 @@ class LocationProviderManager extends 0, this, FgThread.getHandler(), getWorkSource()); } try { ((IBinder) getKey()).linkToDeath(this, 0); } catch (RemoteException e) { remove(); } // start listening for provider enabled/disabled events addEnabledListener(this); Loading Loading @@ -1066,8 +1060,13 @@ class LocationProviderManager extends mUserInfoHelper.addListener(mUserChangedListener); mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener); long identity = Binder.clearCallingIdentity(); try { // initialize enabled state onUserStarted(UserHandle.USER_ALL); } finally { Binder.restoreCallingIdentity(identity); } } } Loading @@ -1077,10 +1076,15 @@ class LocationProviderManager extends mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener); // notify and remove all listeners long identity = Binder.clearCallingIdentity(); try { onUserStopped(UserHandle.USER_ALL); removeRegistrationIf(key -> true); mEnabledListeners.clear(); } finally { Binder.restoreCallingIdentity(identity); } mEnabledListeners.clear(); mStarted = false; } } Loading Loading @@ -1141,14 +1145,26 @@ class LocationProviderManager extends public void setRealProvider(AbstractLocationProvider provider) { synchronized (mLock) { Preconditions.checkState(mStarted); long identity = Binder.clearCallingIdentity(); try { mProvider.setRealProvider(provider); } finally { Binder.restoreCallingIdentity(identity); } } } public void setMockProvider(@Nullable MockProvider provider) { synchronized (mLock) { Preconditions.checkState(mStarted); long identity = Binder.clearCallingIdentity(); try { mProvider.setMockProvider(provider); } finally { Binder.restoreCallingIdentity(identity); } // when removing a mock provider, also clear any mock last locations and reset the // location fudger. the mock provider could have been used to infer the current Loading @@ -1170,7 +1186,12 @@ class LocationProviderManager extends throw new IllegalArgumentException(mName + " provider is not a test provider"); } long identity = Binder.clearCallingIdentity(); try { mProvider.setMockProviderAllowed(enabled); } finally { Binder.restoreCallingIdentity(identity); } } } Loading @@ -1180,6 +1201,8 @@ class LocationProviderManager extends throw new IllegalArgumentException(mName + " provider is not a test provider"); } long identity = Binder.clearCallingIdentity(); try { String locationProvider = location.getProvider(); if (!TextUtils.isEmpty(locationProvider) && !mName.equals(locationProvider)) { // The location has an explicit provider that is different from the mock Loading @@ -1189,6 +1212,9 @@ class LocationProviderManager extends } mProvider.setMockProviderLocation(location); } finally { Binder.restoreCallingIdentity(identity); } } } Loading Loading @@ -1279,7 +1305,7 @@ class LocationProviderManager extends } } public void getCurrentLocation(LocationRequest request, CallerIdentity identity, public void getCurrentLocation(LocationRequest request, CallerIdentity callerIdentity, int permissionLevel, ICancellationSignal cancellationTransport, ILocationCallback callback) { Preconditions.checkArgument(mName.equals(request.getProvider())); Loading @@ -1291,12 +1317,12 @@ class LocationProviderManager extends GetCurrentLocationListenerRegistration registration = new GetCurrentLocationListenerRegistration( request, identity, callerIdentity, new GetCurrentLocationTransport(callback), permissionLevel); synchronized (mLock) { Location lastLocation = getLastLocation(request, identity, permissionLevel); Location lastLocation = getLastLocation(request, callerIdentity, permissionLevel); if (lastLocation != null) { long locationAgeMs = NANOSECONDS.toMillis( SystemClock.elapsedRealtimeNanos() Loading @@ -1314,7 +1340,13 @@ class LocationProviderManager extends } // if last location isn't good enough then we add a location request long identity = Binder.clearCallingIdentity(); try { addRegistration(callback.asBinder(), registration); } finally { Binder.restoreCallingIdentity(identity); } CancellationSignal cancellationSignal = CancellationSignal.fromTransport( cancellationTransport); if (cancellationSignal != null) { Loading @@ -1329,48 +1361,73 @@ class LocationProviderManager extends } public void sendExtraCommand(int uid, int pid, String command, Bundle extras) { long identity = Binder.clearCallingIdentity(); try { mProvider.sendExtraCommand(uid, pid, command, extras); } finally { Binder.restoreCallingIdentity(identity); } } public void registerLocationRequest(LocationRequest request, CallerIdentity identity, public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, @PermissionLevel int permissionLevel, ILocationListener listener) { Preconditions.checkArgument(mName.equals(request.getProvider())); synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { addRegistration( listener.asBinder(), new LocationListenerRegistration( request, identity, callerIdentity, new LocationListenerTransport(listener), permissionLevel)); } finally { Binder.restoreCallingIdentity(identity); } } } public void registerLocationRequest(LocationRequest request, CallerIdentity identity, public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, @PermissionLevel int permissionLevel, PendingIntent pendingIntent) { Preconditions.checkArgument(mName.equals(request.getProvider())); synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { addRegistration( pendingIntent, new LocationPendingIntentRegistration( request, identity, callerIdentity, new LocationPendingIntentTransport(mContext, pendingIntent), permissionLevel)); } finally { Binder.restoreCallingIdentity(identity); } } } public void unregisterLocationRequest(ILocationListener listener) { synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(listener.asBinder()); } finally { Binder.restoreCallingIdentity(identity); } } } public void unregisterLocationRequest(PendingIntent pendingIntent) { synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(pendingIntent); } finally { Binder.restoreCallingIdentity(identity); } } } Loading Loading @@ -1958,4 +2015,50 @@ class LocationProviderManager extends } } } private static class SingleUseCallback extends IRemoteCallback.Stub { @Nullable public static IRemoteCallback wrap(@Nullable Runnable callback) { return callback == null ? null : new SingleUseCallback(callback); } @GuardedBy("this") @Nullable private Runnable mCallback; private SingleUseCallback(Runnable callback) { mCallback = Objects.requireNonNull(callback); } @Override public void sendResult(Bundle data) { Runnable callback; synchronized (this) { callback = mCallback; mCallback = null; } // prevent this callback from being run more than once - otherwise this could provide an // attack vector for a malicious app to break assumptions on how many times a callback // may be invoked, and thus crash system server. if (callback == null) { return; } long identity = Binder.clearCallingIdentity(); try { callback.run(); } catch (RuntimeException e) { // since this is within a oneway binder transaction there is nowhere // for exceptions to go - move onto another thread to crash system // server so we find out about it FgThread.getExecutor().execute(() -> { throw new AssertionError(e); }); throw e; } finally { Binder.restoreCallingIdentity(identity); } } } } services/core/java/com/android/server/location/geofence/GeofenceManager.java +17 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationRequest; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.PowerManager; import android.os.SystemClock; import android.os.WorkSource; Loading Loading @@ -291,17 +292,28 @@ public class GeofenceManager extends @Nullable String attributionTag) { LocationPermissions.enforceCallingOrSelfLocationPermission(mContext, PERMISSION_FINE); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, AppOpsManager.toReceiverId(pendingIntent)); CallerIdentity callerIdentity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, AppOpsManager.toReceiverId(pendingIntent)); long identity = Binder.clearCallingIdentity(); try { addRegistration(new GeofenceKey(pendingIntent, geofence), new GeofenceRegistration(geofence, identity, pendingIntent)); new GeofenceRegistration(geofence, callerIdentity, pendingIntent)); } finally { Binder.restoreCallingIdentity(identity); } } /** * Removes the geofence associated with the PendingIntent. */ public void removeGeofence(PendingIntent pendingIntent) { long identity = Binder.clearCallingIdentity(); try { removeRegistrationIf(key -> key.getPendingIntent().equals(pendingIntent)); } finally { Binder.restoreCallingIdentity(identity); } } @Override Loading services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +16 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.Nullable; import android.location.LocationManagerInternal; import android.location.LocationManagerInternal.ProviderEnabledListener; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.IBinder; import android.os.IInterface; import android.os.Process; Loading Loading @@ -218,16 +219,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter /** * Adds a listener with the given identity and request. */ protected void addListener(TRequest request, CallerIdentity identity, TListener listener) { protected void addListener(TRequest request, CallerIdentity callerIdentity, TListener listener) { long identity = Binder.clearCallingIdentity(); try { addRegistration(listener.asBinder(), new GnssListenerRegistration(request, identity, listener)); new GnssListenerRegistration(request, callerIdentity, listener)); } finally { Binder.restoreCallingIdentity(identity); } } /** * Removes the given listener. */ public void removeListener(TListener listener) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(listener.asBinder()); } finally { Binder.restoreCallingIdentity(identity); } } @Override Loading services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +20 −3 Original line number Diff line number Diff line Loading @@ -2022,6 +2022,21 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { boolean dumpAll = false; int opti = 0; while (opti < args.length) { String opt = args[opti]; if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { break; } opti++; if ("-a".equals(opt)) { dumpAll = true; break; } } StringBuilder s = new StringBuilder(); s.append("mStarted=").append(mStarted).append(" (changed "); TimeUtils.formatDuration(SystemClock.elapsedRealtime() Loading Loading @@ -2053,9 +2068,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements s.append("]\n"); } s.append(mGnssMetrics.dumpGnssMetricsAsText()); if (dumpAll) { s.append("native internal state: \n"); s.append(" ").append(native_get_internal_state()); s.append("\n"); } pw.append(s); } Loading Loading
services/core/java/com/android/server/location/LocationManagerService.java +11 −19 Original line number Diff line number Diff line Loading @@ -1133,9 +1133,7 @@ public class LocationManagerService extends ILocationManager.Stub { return; } String dumpFilter = args.length == 0 ? null : args[0]; ipw.println("Location Manager State:"); ipw.print("Location Manager State:"); ipw.increaseIndent(); ipw.println("Elapsed Realtime: " + TimeUtils.formatDuration(SystemClock.elapsedRealtime())); Loading Loading @@ -1173,28 +1171,22 @@ public class LocationManagerService extends ILocationManager.Stub { ipw.println("Location Providers:"); ipw.increaseIndent(); for (LocationProviderManager manager : mProviderManagers) { if (dumpFilter == null || manager.getName().equals(dumpFilter)) { manager.dump(fd, ipw, args); } } ipw.decreaseIndent(); if (dumpFilter == null || GPS_PROVIDER.equals(dumpFilter)) { if (mGnssManagerService != null) { ipw.println("GNSS Manager:"); ipw.increaseIndent(); mGnssManagerService.dump(fd, ipw, args); ipw.decreaseIndent(); } } if (dumpFilter == null || "geofence".equals(dumpFilter)) { ipw.println("Geofence Manager:"); ipw.increaseIndent(); mGeofenceManager.dump(fd, ipw, args); ipw.decreaseIndent(); } } private class LocalService extends LocationManagerInternal { Loading
services/core/java/com/android/server/location/LocationProviderManager.java +160 −57 Original line number Diff line number Diff line Loading @@ -84,7 +84,7 @@ import com.android.server.LocalServices; import com.android.server.PendingIntentUtils; import com.android.server.location.LocationPermissions.PermissionLevel; import com.android.server.location.listeners.ListenerMultiplexer; import com.android.server.location.listeners.RemovableListenerRegistration; import com.android.server.location.listeners.RemoteListenerRegistration; import com.android.server.location.util.AppForegroundHelper; import com.android.server.location.util.AppForegroundHelper.AppForegroundListener; import com.android.server.location.util.AppOpsHelper; Loading Loading @@ -154,15 +154,8 @@ class LocationProviderManager extends @Override public void deliverOnLocationChanged(Location location, @Nullable Runnable onCompleteCallback) throws RemoteException { mListener.onLocationChanged(location, onCompleteCallback == null ? null : new IRemoteCallback.Stub() { @Override public void sendResult(Bundle data) { onCompleteCallback.run(); } }); @Nullable Runnable onCompleteCallback) throws RemoteException { mListener.onLocationChanged(location, SingleUseCallback.wrap(onCompleteCallback)); } @Override Loading Loading @@ -221,7 +214,7 @@ class LocationProviderManager extends } protected abstract class Registration extends RemovableListenerRegistration<LocationRequest, LocationTransport> { RemoteListenerRegistration<LocationRequest, LocationTransport> { @PermissionLevel protected final int mPermissionLevel; private final WorkSource mWorkSource; Loading Loading @@ -306,11 +299,12 @@ class LocationProviderManager extends } @Override protected final void onInactive() { protected final ListenerOperation<LocationTransport> onInactive() { onHighPowerUsageChanged(); if (!getRequest().getHideFromAppOps()) { mLocationAttributionHelper.reportLocationStop(getIdentity(), getName(), getKey()); } return null; } @Override Loading Loading @@ -826,6 +820,12 @@ class LocationProviderManager extends @GuardedBy("mLock") @Override protected void onProviderListenerRegister() { try { ((IBinder) getKey()).linkToDeath(this, 0); } catch (RemoteException e) { remove(); } mExpirationRealtimeMs = getRequest().getExpirationRealtimeMs( SystemClock.elapsedRealtime()); Loading @@ -837,12 +837,6 @@ class LocationProviderManager extends 0, this, FgThread.getHandler(), getWorkSource()); } try { ((IBinder) getKey()).linkToDeath(this, 0); } catch (RemoteException e) { remove(); } // start listening for provider enabled/disabled events addEnabledListener(this); Loading Loading @@ -1066,8 +1060,13 @@ class LocationProviderManager extends mUserInfoHelper.addListener(mUserChangedListener); mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener); long identity = Binder.clearCallingIdentity(); try { // initialize enabled state onUserStarted(UserHandle.USER_ALL); } finally { Binder.restoreCallingIdentity(identity); } } } Loading @@ -1077,10 +1076,15 @@ class LocationProviderManager extends mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener); // notify and remove all listeners long identity = Binder.clearCallingIdentity(); try { onUserStopped(UserHandle.USER_ALL); removeRegistrationIf(key -> true); mEnabledListeners.clear(); } finally { Binder.restoreCallingIdentity(identity); } mEnabledListeners.clear(); mStarted = false; } } Loading Loading @@ -1141,14 +1145,26 @@ class LocationProviderManager extends public void setRealProvider(AbstractLocationProvider provider) { synchronized (mLock) { Preconditions.checkState(mStarted); long identity = Binder.clearCallingIdentity(); try { mProvider.setRealProvider(provider); } finally { Binder.restoreCallingIdentity(identity); } } } public void setMockProvider(@Nullable MockProvider provider) { synchronized (mLock) { Preconditions.checkState(mStarted); long identity = Binder.clearCallingIdentity(); try { mProvider.setMockProvider(provider); } finally { Binder.restoreCallingIdentity(identity); } // when removing a mock provider, also clear any mock last locations and reset the // location fudger. the mock provider could have been used to infer the current Loading @@ -1170,7 +1186,12 @@ class LocationProviderManager extends throw new IllegalArgumentException(mName + " provider is not a test provider"); } long identity = Binder.clearCallingIdentity(); try { mProvider.setMockProviderAllowed(enabled); } finally { Binder.restoreCallingIdentity(identity); } } } Loading @@ -1180,6 +1201,8 @@ class LocationProviderManager extends throw new IllegalArgumentException(mName + " provider is not a test provider"); } long identity = Binder.clearCallingIdentity(); try { String locationProvider = location.getProvider(); if (!TextUtils.isEmpty(locationProvider) && !mName.equals(locationProvider)) { // The location has an explicit provider that is different from the mock Loading @@ -1189,6 +1212,9 @@ class LocationProviderManager extends } mProvider.setMockProviderLocation(location); } finally { Binder.restoreCallingIdentity(identity); } } } Loading Loading @@ -1279,7 +1305,7 @@ class LocationProviderManager extends } } public void getCurrentLocation(LocationRequest request, CallerIdentity identity, public void getCurrentLocation(LocationRequest request, CallerIdentity callerIdentity, int permissionLevel, ICancellationSignal cancellationTransport, ILocationCallback callback) { Preconditions.checkArgument(mName.equals(request.getProvider())); Loading @@ -1291,12 +1317,12 @@ class LocationProviderManager extends GetCurrentLocationListenerRegistration registration = new GetCurrentLocationListenerRegistration( request, identity, callerIdentity, new GetCurrentLocationTransport(callback), permissionLevel); synchronized (mLock) { Location lastLocation = getLastLocation(request, identity, permissionLevel); Location lastLocation = getLastLocation(request, callerIdentity, permissionLevel); if (lastLocation != null) { long locationAgeMs = NANOSECONDS.toMillis( SystemClock.elapsedRealtimeNanos() Loading @@ -1314,7 +1340,13 @@ class LocationProviderManager extends } // if last location isn't good enough then we add a location request long identity = Binder.clearCallingIdentity(); try { addRegistration(callback.asBinder(), registration); } finally { Binder.restoreCallingIdentity(identity); } CancellationSignal cancellationSignal = CancellationSignal.fromTransport( cancellationTransport); if (cancellationSignal != null) { Loading @@ -1329,48 +1361,73 @@ class LocationProviderManager extends } public void sendExtraCommand(int uid, int pid, String command, Bundle extras) { long identity = Binder.clearCallingIdentity(); try { mProvider.sendExtraCommand(uid, pid, command, extras); } finally { Binder.restoreCallingIdentity(identity); } } public void registerLocationRequest(LocationRequest request, CallerIdentity identity, public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, @PermissionLevel int permissionLevel, ILocationListener listener) { Preconditions.checkArgument(mName.equals(request.getProvider())); synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { addRegistration( listener.asBinder(), new LocationListenerRegistration( request, identity, callerIdentity, new LocationListenerTransport(listener), permissionLevel)); } finally { Binder.restoreCallingIdentity(identity); } } } public void registerLocationRequest(LocationRequest request, CallerIdentity identity, public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, @PermissionLevel int permissionLevel, PendingIntent pendingIntent) { Preconditions.checkArgument(mName.equals(request.getProvider())); synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { addRegistration( pendingIntent, new LocationPendingIntentRegistration( request, identity, callerIdentity, new LocationPendingIntentTransport(mContext, pendingIntent), permissionLevel)); } finally { Binder.restoreCallingIdentity(identity); } } } public void unregisterLocationRequest(ILocationListener listener) { synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(listener.asBinder()); } finally { Binder.restoreCallingIdentity(identity); } } } public void unregisterLocationRequest(PendingIntent pendingIntent) { synchronized (mLock) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(pendingIntent); } finally { Binder.restoreCallingIdentity(identity); } } } Loading Loading @@ -1958,4 +2015,50 @@ class LocationProviderManager extends } } } private static class SingleUseCallback extends IRemoteCallback.Stub { @Nullable public static IRemoteCallback wrap(@Nullable Runnable callback) { return callback == null ? null : new SingleUseCallback(callback); } @GuardedBy("this") @Nullable private Runnable mCallback; private SingleUseCallback(Runnable callback) { mCallback = Objects.requireNonNull(callback); } @Override public void sendResult(Bundle data) { Runnable callback; synchronized (this) { callback = mCallback; mCallback = null; } // prevent this callback from being run more than once - otherwise this could provide an // attack vector for a malicious app to break assumptions on how many times a callback // may be invoked, and thus crash system server. if (callback == null) { return; } long identity = Binder.clearCallingIdentity(); try { callback.run(); } catch (RuntimeException e) { // since this is within a oneway binder transaction there is nowhere // for exceptions to go - move onto another thread to crash system // server so we find out about it FgThread.getExecutor().execute(() -> { throw new AssertionError(e); }); throw e; } finally { Binder.restoreCallingIdentity(identity); } } } }
services/core/java/com/android/server/location/geofence/GeofenceManager.java +17 −5 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationRequest; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.PowerManager; import android.os.SystemClock; import android.os.WorkSource; Loading Loading @@ -291,17 +292,28 @@ public class GeofenceManager extends @Nullable String attributionTag) { LocationPermissions.enforceCallingOrSelfLocationPermission(mContext, PERMISSION_FINE); CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, AppOpsManager.toReceiverId(pendingIntent)); CallerIdentity callerIdentity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, AppOpsManager.toReceiverId(pendingIntent)); long identity = Binder.clearCallingIdentity(); try { addRegistration(new GeofenceKey(pendingIntent, geofence), new GeofenceRegistration(geofence, identity, pendingIntent)); new GeofenceRegistration(geofence, callerIdentity, pendingIntent)); } finally { Binder.restoreCallingIdentity(identity); } } /** * Removes the geofence associated with the PendingIntent. */ public void removeGeofence(PendingIntent pendingIntent) { long identity = Binder.clearCallingIdentity(); try { removeRegistrationIf(key -> key.getPendingIntent().equals(pendingIntent)); } finally { Binder.restoreCallingIdentity(identity); } } @Override Loading
services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +16 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.annotation.Nullable; import android.location.LocationManagerInternal; import android.location.LocationManagerInternal.ProviderEnabledListener; import android.location.util.identity.CallerIdentity; import android.os.Binder; import android.os.IBinder; import android.os.IInterface; import android.os.Process; Loading Loading @@ -218,16 +219,27 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter /** * Adds a listener with the given identity and request. */ protected void addListener(TRequest request, CallerIdentity identity, TListener listener) { protected void addListener(TRequest request, CallerIdentity callerIdentity, TListener listener) { long identity = Binder.clearCallingIdentity(); try { addRegistration(listener.asBinder(), new GnssListenerRegistration(request, identity, listener)); new GnssListenerRegistration(request, callerIdentity, listener)); } finally { Binder.restoreCallingIdentity(identity); } } /** * Removes the given listener. */ public void removeListener(TListener listener) { long identity = Binder.clearCallingIdentity(); try { removeRegistration(listener.asBinder()); } finally { Binder.restoreCallingIdentity(identity); } } @Override Loading
services/core/java/com/android/server/location/gnss/GnssLocationProvider.java +20 −3 Original line number Diff line number Diff line Loading @@ -2022,6 +2022,21 @@ public class GnssLocationProvider extends AbstractLocationProvider implements @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { boolean dumpAll = false; int opti = 0; while (opti < args.length) { String opt = args[opti]; if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { break; } opti++; if ("-a".equals(opt)) { dumpAll = true; break; } } StringBuilder s = new StringBuilder(); s.append("mStarted=").append(mStarted).append(" (changed "); TimeUtils.formatDuration(SystemClock.elapsedRealtime() Loading Loading @@ -2053,9 +2068,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements s.append("]\n"); } s.append(mGnssMetrics.dumpGnssMetricsAsText()); if (dumpAll) { s.append("native internal state: \n"); s.append(" ").append(native_get_internal_state()); s.append("\n"); } pw.append(s); } Loading