Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc8b48a9 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Add useful app-op-note message to async Location deliveries

Test: atest CtsAppOpsTestCases
Bug: 136505050
Change-Id: I1a34cd993132cc4fdf87c92625595240bb8ec4a7
parent e0d74cdf
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -42,11 +42,11 @@ import com.android.internal.location.ProviderProperties;
interface ILocationManager
{
    void requestLocationUpdates(in LocationRequest request, in ILocationListener listener,
            in PendingIntent intent, String packageName);
            in PendingIntent intent, String packageName, String listenerIdentifier);
    void removeUpdates(in ILocationListener listener, in PendingIntent intent, String packageName);

    void requestGeofence(in LocationRequest request, in Geofence geofence,
            in PendingIntent intent, String packageName);
            in PendingIntent intent, String packageName, String listenerIdentifier);
    void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName);

    Location getLastLocation(in LocationRequest request, String packageName);
@@ -64,22 +64,23 @@ interface ILocationManager

    boolean sendNiResponse(int notifId, int userResponse);

    boolean addGnssMeasurementsListener(in IGnssMeasurementsListener listener, in String packageName);
    boolean addGnssMeasurementsListener(in IGnssMeasurementsListener listener,
             String packageName, String listenerIdentifier);
    void injectGnssMeasurementCorrections(in GnssMeasurementCorrections corrections,
            in String packageName);
    long getGnssCapabilities(in String packageName);
    void removeGnssMeasurementsListener(in IGnssMeasurementsListener listener);

    boolean addGnssNavigationMessageListener(
            in IGnssNavigationMessageListener listener,
            in String packageName);
    boolean addGnssNavigationMessageListener(in IGnssNavigationMessageListener listener,
             String packageName, String listenerIdentifier);
    void removeGnssNavigationMessageListener(in IGnssNavigationMessageListener listener);

    int getGnssYearOfHardware();
    String getGnssHardwareModelName();

    int getGnssBatchSize(String packageName);
    boolean addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName);
    boolean addGnssBatchingCallback(in IBatchedLocationCallback callback, String packageName,
             String listenerIdentifier);
    void removeGnssBatchingCallback();
    boolean startGnssBatch(long periodNanos, boolean wakeOnFifoFull, String packageName);
    void flushGnssBatch(String packageName);
+27 −7
Original line number Diff line number Diff line
@@ -541,6 +541,23 @@ public class LocationManager {
        }
    }

    /**
     * Create a string that allows an app to identify a listener
     *
     * @param listener The listener
     *
     * @return A identifying string
     */
    private static String getListenerIdentifier(@NonNull Object listener) {
        StringBuilder sb = new StringBuilder();

        sb.append(listener.getClass().getName());
        sb.append('@');
        sb.append(Integer.toHexString(System.identityHashCode(listener)));

        return sb.toString();
    }

    /**
     * Register for a single location update using the named provider and
     * a callback.
@@ -981,7 +998,7 @@ public class LocationManager {
            boolean registered = false;
            try {
                mService.requestLocationUpdates(locationRequest, transport, null,
                        mContext.getPackageName());
                        mContext.getPackageName(), getListenerIdentifier(listener));
                registered = true;
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
@@ -1026,7 +1043,7 @@ public class LocationManager {

        try {
            mService.requestLocationUpdates(locationRequest, null, pendingIntent,
                    mContext.getPackageName());
                    mContext.getPackageName(), getListenerIdentifier(pendingIntent));
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -1471,7 +1488,8 @@ public class LocationManager {
        Geofence fence = Geofence.createCircle(latitude, longitude, radius);
        LocationRequest request = new LocationRequest().setExpireIn(expiration);
        try {
            mService.requestGeofence(request, fence, intent, mContext.getPackageName());
            mService.requestGeofence(request, fence, intent, mContext.getPackageName(),
                    getListenerIdentifier(intent));
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -1548,7 +1566,8 @@ public class LocationManager {
        Preconditions.checkArgument(fence != null, "invalid null geofence");

        try {
            mService.requestGeofence(request, fence, intent, mContext.getPackageName());
            mService.requestGeofence(request, fence, intent, mContext.getPackageName(),
                    getListenerIdentifier(intent));
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -2538,7 +2557,7 @@ public class LocationManager {

            mListenerTransport = new GnssMeasurementsListener();
            return mService.addGnssMeasurementsListener(mListenerTransport,
                    mContext.getPackageName());
                    mContext.getPackageName(), "gnss measurement callback");
        }

        @Override
@@ -2574,7 +2593,7 @@ public class LocationManager {

            mListenerTransport = new GnssNavigationMessageListener();
            return mService.addGnssNavigationMessageListener(mListenerTransport,
                    mContext.getPackageName());
                    mContext.getPackageName(), "gnss navigation callback");
        }

        @Override
@@ -2609,7 +2628,8 @@ public class LocationManager {
            Preconditions.checkState(mListenerTransport == null);

            mListenerTransport = new BatchedLocationCallback();
            return mService.addGnssBatchingCallback(mListenerTransport, mContext.getPackageName());
            return mService.addGnssBatchingCallback(mListenerTransport, mContext.getPackageName(),
                     "batched location callback");
        }

        @Override
+16 −10
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server;

import android.Manifest;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.content.Context;
@@ -298,7 +299,8 @@ public class GnssManagerService {
     * @param packageName name of requesting package
     * @return true if callback is successfully added, false otherwise
     */
    public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName) {
    public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName,
            @NonNull String listenerIdentity) {
        mContext.enforceCallingPermission(
                android.Manifest.permission.LOCATION_HARDWARE,
                "Location Hardware permission not granted to access hardware batching");
@@ -316,7 +318,8 @@ public class GnssManagerService {
        }

        CallerIdentity callerIdentity =
                new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
                new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName,
                        listenerIdentity);
        synchronized (mGnssBatchingLock) {
            mGnssBatchingCallback = callback;
            mGnssBatchingDeathCallback =
@@ -494,7 +497,7 @@ public class GnssManagerService {
    private <TListener extends IInterface> boolean addGnssDataListenerLocked(
            TListener listener,
            String packageName,
            String listenerName,
            @NonNull String listenerIdentifier,
            RemoteListenerHelper<TListener> gnssDataProvider,
            ArrayMap<IBinder,
                    LinkedListener<TListener>> gnssDataListeners,
@@ -513,10 +516,11 @@ public class GnssManagerService {
        }

        CallerIdentity callerIdentity =
                new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
                new CallerIdentity(Binder.getCallingUid(), Binder.getCallingPid(), packageName,
                        listenerIdentifier);
        LinkedListener<TListener> linkedListener =
                new LocationManagerServiceUtils.LinkedListener<>(
                        listener, listenerName, callerIdentity, binderDeathCallback);
                        listener, listenerIdentifier, callerIdentity, binderDeathCallback);
        IBinder binder = listener.asBinder();
        if (!linkedListener.linkToListenerDeathNotificationLocked(binder)) {
            return false;
@@ -606,7 +610,7 @@ public class GnssManagerService {
            return addGnssDataListenerLocked(
                    listener,
                    packageName,
                    "GnssStatusListener",
                    "Gnss status",
                    mGnssStatusProvider,
                    mGnssStatusListeners,
                    this::unregisterGnssStatusCallback);
@@ -632,12 +636,13 @@ public class GnssManagerService {
     * @return true if listener is successfully added, false otherwise
     */
    public boolean addGnssMeasurementsListener(
            IGnssMeasurementsListener listener, String packageName) {
            IGnssMeasurementsListener listener, String packageName,
            @NonNull String listenerIdentifier) {
        synchronized (mGnssMeasurementsListeners) {
            return addGnssDataListenerLocked(
                    listener,
                    packageName,
                    "GnssMeasurementsListener",
                    listenerIdentifier,
                    mGnssMeasurementsProvider,
                    mGnssMeasurementsListeners,
                    this::removeGnssMeasurementsListener);
@@ -689,12 +694,13 @@ public class GnssManagerService {
     * @return true if listener is successfully added, false otherwise
     */
    public boolean addGnssNavigationMessageListener(
            IGnssNavigationMessageListener listener, String packageName) {
            IGnssNavigationMessageListener listener, String packageName,
            @NonNull String listenerIdentifier) {
        synchronized (mGnssNavigationMessageListeners) {
            return addGnssDataListenerLocked(
                    listener,
                    packageName,
                    "GnssNavigationMessageListener",
                    listenerIdentifier,
                    mGnssNavigationMessageProvider,
                    mGnssNavigationMessageListeners,
                    this::removeGnssNavigationMessageListener);
+46 −29
Original line number Diff line number Diff line
@@ -1223,8 +1223,10 @@ public class LocationManagerService extends ILocationManager.Stub {
        PowerManager.WakeLock mWakeLock;

        private Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid,
                String packageName, WorkSource workSource, boolean hideFromAppOps) {
            super(new CallerIdentity(uid, pid, packageName), "LocationListener");
                String packageName, WorkSource workSource, boolean hideFromAppOps,
                @NonNull String listenerIdentifier) {
            super(new CallerIdentity(uid, pid, packageName, listenerIdentifier),
                    "LocationListener");
            mListener = listener;
            mPendingIntent = intent;
            if (listener != null) {
@@ -1532,9 +1534,12 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    @Override
    public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName) {
    public boolean addGnssBatchingCallback(IBatchedLocationCallback callback, String packageName,
            String listenerIdentifier) {
        Preconditions.checkNotNull(listenerIdentifier);

        return mGnssManagerService == null ? false : mGnssManagerService.addGnssBatchingCallback(
                callback, packageName);
                callback, packageName, listenerIdentifier);
    }

    @Override
@@ -1696,11 +1701,12 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
    }

    private boolean reportLocationAccessNoThrow(
            int pid, int uid, String packageName, int allowedResolutionLevel) {
    private boolean reportLocationAccessNoThrow(int pid, int uid, String packageName,
            int allowedResolutionLevel, @Nullable String message) {
        int op = resolutionLevelToOp(allowedResolutionLevel);
        if (op >= 0) {
            if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
            if (mAppOps.noteOpNoThrow(op, uid, packageName, message)
                    != AppOpsManager.MODE_ALLOWED) {
                return false;
            }
        }
@@ -2133,12 +2139,13 @@ public class LocationManagerService extends ILocationManager.Stub {

    @GuardedBy("mLock")
    private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid,
            String packageName, WorkSource workSource, boolean hideFromAppOps) {
            String packageName, WorkSource workSource, boolean hideFromAppOps,
            @NonNull String listenerIdentifier) {
        IBinder binder = listener.asBinder();
        Receiver receiver = mReceivers.get(binder);
        if (receiver == null) {
            receiver = new Receiver(listener, null, pid, uid, packageName, workSource,
                    hideFromAppOps);
                    hideFromAppOps, listenerIdentifier);
            if (!receiver.linkToListenerDeathNotificationLocked(
                    receiver.getListener().asBinder())) {
                return null;
@@ -2150,11 +2157,11 @@ public class LocationManagerService extends ILocationManager.Stub {

    @GuardedBy("mLock")
    private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName,
            WorkSource workSource, boolean hideFromAppOps) {
            WorkSource workSource, boolean hideFromAppOps, @NonNull String listenerIdentifier) {
        Receiver receiver = mReceivers.get(intent);
        if (receiver == null) {
            receiver = new Receiver(null, intent, pid, uid, packageName, workSource,
                    hideFromAppOps);
                    hideFromAppOps, listenerIdentifier);
            mReceivers.put(intent, receiver);
        }
        return receiver;
@@ -2216,7 +2223,9 @@ public class LocationManagerService extends ILocationManager.Stub {

    @Override
    public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
            PendingIntent intent, String packageName) {
            PendingIntent intent, String packageName, String listenerIdentifier) {
        Preconditions.checkNotNull(listenerIdentifier);

        synchronized (mLock) {
            if (request == null) request = DEFAULT_LOCATION_REQUEST;
            checkPackageName(packageName);
@@ -2271,10 +2280,10 @@ public class LocationManagerService extends ILocationManager.Stub {
                Receiver receiver;
                if (intent != null) {
                    receiver = getReceiverLocked(intent, pid, uid, packageName, workSource,
                            hideFromAppOps);
                            hideFromAppOps, listenerIdentifier);
                } else {
                    receiver = getReceiverLocked(listener, pid, uid, packageName, workSource,
                            hideFromAppOps);
                            hideFromAppOps, listenerIdentifier);
                }
                requestLocationUpdatesLocked(sanitizedRequest, receiver, uid, packageName);
            } finally {
@@ -2343,9 +2352,9 @@ public class LocationManagerService extends ILocationManager.Stub {
        synchronized (mLock) {
            Receiver receiver;
            if (intent != null) {
                receiver = getReceiverLocked(intent, pid, uid, packageName, null, false);
                receiver = getReceiverLocked(intent, pid, uid, packageName, null, false, "");
            } else {
                receiver = getReceiverLocked(listener, pid, uid, packageName, null, false);
                receiver = getReceiverLocked(listener, pid, uid, packageName, null, false, "");
            }

            long identity = Binder.clearCallingIdentity();
@@ -2464,8 +2473,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                }
                // Don't report location access if there is no last location to deliver.
                if (lastLocation != null) {
                    if (!reportLocationAccessNoThrow(
                            pid, uid, packageName, allowedResolutionLevel)) {
                    if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel,
                            null)) {
                        if (D) {
                            Log.d(TAG, "not returning last loc for no op app: " + packageName);
                        }
@@ -2519,7 +2528,9 @@ public class LocationManagerService extends ILocationManager.Stub {

    @Override
    public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent,
            String packageName) {
            String packageName, String listenerIdentifier) {
        Preconditions.checkNotNull(listenerIdentifier);

        if (request == null) request = DEFAULT_LOCATION_REQUEST;
        int allowedResolutionLevel = getCallerAllowedResolutionLevel();
        checkResolutionLevelIsSufficientForGeofenceUse(allowedResolutionLevel);
@@ -2564,9 +2575,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                        mActivityManager.getPackageImportance(packageName));
            }

            mGeofenceManager.addFence(sanitizedRequest, geofence, intent,
                    allowedResolutionLevel,
                    uid, packageName);
            mGeofenceManager.addFence(sanitizedRequest, geofence, intent, allowedResolutionLevel,
                    uid, packageName, listenerIdentifier);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
@@ -2613,10 +2623,13 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    @Override
    public boolean addGnssMeasurementsListener(
            IGnssMeasurementsListener listener, String packageName) {
    public boolean addGnssMeasurementsListener(IGnssMeasurementsListener listener,
            String packageName, String listenerIdentifier) {
        Preconditions.checkNotNull(listenerIdentifier);

        return mGnssManagerService == null ? false
                : mGnssManagerService.addGnssMeasurementsListener(listener, packageName);
                : mGnssManagerService.addGnssMeasurementsListener(listener, packageName,
                        listenerIdentifier);
    }

    @Override
@@ -2643,10 +2656,13 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    @Override
    public boolean addGnssNavigationMessageListener(
            IGnssNavigationMessageListener listener, String packageName) {
    public boolean addGnssNavigationMessageListener(IGnssNavigationMessageListener listener,
            String packageName, String listenerIdentifier) {
        Preconditions.checkNotNull(listenerIdentifier);

        return mGnssManagerService == null ? false
                : mGnssManagerService.addGnssNavigationMessageListener(listener, packageName);
                : mGnssManagerService.addGnssNavigationMessageListener(listener, packageName,
                        listenerIdentifier);
    }

    @Override
@@ -2943,7 +2959,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                            receiver.mCallerIdentity.mPid,
                            receiver.mCallerIdentity.mUid,
                            receiver.mCallerIdentity.mPackageName,
                            receiver.mAllowedResolutionLevel)) {
                            receiver.mAllowedResolutionLevel,
                            "Location sent to " + receiver.mCallerIdentity.mListenerIdentifier)) {
                        if (D) {
                            Log.d(TAG, "skipping loc update for no op app: "
                                    + receiver.mCallerIdentity.mPackageName);
+6 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.location;

import android.annotation.NonNull;

/**
 * Represents the calling process's uid, pid, and package name.
 */
@@ -23,10 +25,13 @@ public class CallerIdentity {
    public final int mUid;
    public final int mPid;
    public final String mPackageName;
    public final @NonNull String mListenerIdentifier;

    public CallerIdentity(int uid, int pid, String packageName) {
    public CallerIdentity(int uid, int pid, String packageName,
            @NonNull String listenerIdentifier) {
        mUid = uid;
        mPid = pid;
        mPackageName = packageName;
        mListenerIdentifier = listenerIdentifier;
    }
}
Loading