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

Commit 08b96123 authored by Anil Admal's avatar Anil Admal
Browse files

Do not report GNSS requests from location providers to AppOps

Bug: 123529857
Test: Verified with a real device that GNSS status requests from
      GmsCore (location providers) is not reported to AppOps.

Change-Id: I67bd99c3bc7f3e8e725e6c35f64d9e9fb99f6e5c
parent e2841c52
Loading
Loading
Loading
Loading
+68 −78
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.location.AbstractLocationProvider;
import com.android.server.location.ActivityRecognitionProxy;
import com.android.server.location.CallerIdentity;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeofenceManager;
import com.android.server.location.GeofenceProxy;
@@ -223,10 +224,10 @@ public class LocationManagerService extends ILocationManager.Stub {
    private final ArraySet<String> mIgnoreSettingsPackageWhitelist = new ArraySet<>();

    @GuardedBy("mLock")
    private final ArrayMap<IBinder, Identity> mGnssMeasurementsListeners = new ArrayMap<>();
    private final ArrayMap<IBinder, CallerIdentity> mGnssMeasurementsListeners = new ArrayMap<>();

    @GuardedBy("mLock")
    private final ArrayMap<IBinder, Identity>
    private final ArrayMap<IBinder, CallerIdentity>
            mGnssNavigationMessageListeners = new ArrayMap<>();

    // current active user on the device - other users are denied location data
@@ -455,7 +456,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        ArrayList<Receiver> deadReceivers = null;

        for (Receiver receiver : mReceivers.values()) {
            if (receiver.mIdentity.mPackageName.equals(packageName)) {
            if (receiver.mCallerIdentity.mPackageName.equals(packageName)) {
                if (deadReceivers == null) {
                    deadReceivers = new ArrayList<>();
                }
@@ -478,7 +479,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        for (Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
            String provider = entry.getKey();
            for (UpdateRecord record : entry.getValue()) {
                if (record.mReceiver.mIdentity.mUid == uid
                if (record.mReceiver.mCallerIdentity.mUid == uid
                        && record.mIsForegroundUid != foreground) {
                    if (D) {
                        Log.d(TAG, "request from uid " + uid + " is now "
@@ -486,7 +487,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                    }
                    record.updateForeground(foreground);

                    if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
                    if (!isThrottlingExemptLocked(record.mReceiver.mCallerIdentity)) {
                        affectedProviders.add(provider);
                    }
                }
@@ -496,8 +497,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            applyRequirementsLocked(provider);
        }

        for (Entry<IBinder, Identity> entry : mGnssMeasurementsListeners.entrySet()) {
            Identity callerIdentity = entry.getValue();
        for (Entry<IBinder, CallerIdentity> entry : mGnssMeasurementsListeners.entrySet()) {
            CallerIdentity callerIdentity = entry.getValue();
            if (callerIdentity.mUid == uid) {
                if (D) {
                    Log.d(TAG, "gnss measurements listener from uid " + uid
@@ -506,7 +507,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                if (foreground || isThrottlingExemptLocked(entry.getValue())) {
                    mGnssMeasurementsProvider.addListener(
                            IGnssMeasurementsListener.Stub.asInterface(entry.getKey()),
                            callerIdentity.mUid, callerIdentity.mPackageName);
                            callerIdentity);
                } else {
                    mGnssMeasurementsProvider.removeListener(
                            IGnssMeasurementsListener.Stub.asInterface(entry.getKey()));
@@ -514,8 +515,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            }
        }

        for (Entry<IBinder, Identity> entry : mGnssNavigationMessageListeners.entrySet()) {
            Identity callerIdentity = entry.getValue();
        for (Entry<IBinder, CallerIdentity> entry : mGnssNavigationMessageListeners.entrySet()) {
            CallerIdentity callerIdentity = entry.getValue();
            if (callerIdentity.mUid == uid) {
                if (D) {
                    Log.d(TAG, "gnss navigation message listener from uid "
@@ -525,7 +526,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                if (foreground || isThrottlingExemptLocked(entry.getValue())) {
                    mGnssNavigationMessageProvider.addListener(
                            IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()),
                            callerIdentity.mUid, callerIdentity.mPackageName);
                            callerIdentity);
                } else {
                    mGnssNavigationMessageProvider.removeListener(
                            IGnssNavigationMessageListener.Stub.asInterface(entry.getKey()));
@@ -836,18 +837,6 @@ public class LocationManagerService extends ILocationManager.Stub {
        onProviderAllowedChangedLocked(false);
    }

    private static final class Identity {
        final int mUid;
        final int mPid;
        final String mPackageName;

        Identity(int uid, int pid, String packageName) {
            mUid = uid;
            mPid = pid;
            mPackageName = packageName;
        }
    }

    private class LocationProvider implements AbstractLocationProvider.LocationProviderManager {

        private final String mName;
@@ -1235,7 +1224,7 @@ public class LocationManagerService extends ILocationManager.Stub {
     */
    private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished {
        private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000;
        final Identity mIdentity;
        final CallerIdentity mCallerIdentity;
        private final int mAllowedResolutionLevel;  // resolution level allowed to receiver

        private final ILocationListener mListener;
@@ -1263,7 +1252,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                mKey = intent;
            }
            mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid);
            mIdentity = new Identity(uid, pid, packageName);
            mCallerIdentity = new CallerIdentity(uid, pid, packageName);
            if (workSource != null && workSource.isEmpty()) {
                workSource = null;
            }
@@ -1275,7 +1264,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            // construct/configure wakelock
            mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
            if (workSource == null) {
                workSource = new WorkSource(mIdentity.mUid, mIdentity.mPackageName);
                workSource = new WorkSource(mCallerIdentity.mUid, mCallerIdentity.mPackageName);
            }
            mWakeLock.setWorkSource(workSource);

@@ -1378,14 +1367,14 @@ public class LocationManagerService extends ILocationManager.Stub {
                int op) {
            if (!currentlyMonitoring) {
                if (allowMonitoring) {
                    return mAppOps.startOpNoThrow(op, mIdentity.mUid, mIdentity.mPackageName)
                            == AppOpsManager.MODE_ALLOWED;
                    return mAppOps.startOpNoThrow(op, mCallerIdentity.mUid,
                            mCallerIdentity.mPackageName) == AppOpsManager.MODE_ALLOWED;
                }
            } else {
                if (!allowMonitoring
                        || mAppOps.noteOpNoThrow(op, mIdentity.mUid, mIdentity.mPackageName)
                        != AppOpsManager.MODE_ALLOWED) {
                    mAppOps.finishOp(op, mIdentity.mUid, mIdentity.mPackageName);
                        || mAppOps.noteOpNoThrow(op, mCallerIdentity.mUid,
                        mCallerIdentity.mPackageName) != AppOpsManager.MODE_ALLOWED) {
                    mAppOps.finishOp(op, mCallerIdentity.mUid, mCallerIdentity.mPackageName);
                    return false;
                }
            }
@@ -1723,7 +1712,6 @@ public class LocationManagerService extends ILocationManager.Stub {
        }
    }


    @Override
    public void flushGnssBatch(String packageName) {
        mContext.enforceCallingPermission(android.Manifest.permission.LOCATION_HARDWARE,
@@ -2015,7 +2003,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        if (records != null) {
            for (UpdateRecord record : records) {
                if (!isCurrentProfileLocked(
                        UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
                        UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
                    continue;
                }

@@ -2074,13 +2062,13 @@ public class LocationManagerService extends ILocationManager.Stub {
            providerRequest.lowPowerMode = true;
            for (UpdateRecord record : records) {
                if (!isCurrentProfileLocked(
                        UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
                        UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
                    continue;
                }
                if (!checkLocationAccess(
                        record.mReceiver.mIdentity.mPid,
                        record.mReceiver.mIdentity.mUid,
                        record.mReceiver.mIdentity.mPackageName,
                        record.mReceiver.mCallerIdentity.mPid,
                        record.mReceiver.mCallerIdentity.mUid,
                        record.mReceiver.mCallerIdentity.mPackageName,
                        record.mReceiver.mAllowedResolutionLevel)) {
                    continue;
                }
@@ -2091,7 +2079,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                LocationRequest locationRequest = record.mRealRequest;
                long interval = locationRequest.getInterval();

                if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
                if (!isThrottlingExemptLocked(record.mReceiver.mCallerIdentity)) {
                    if (!record.mIsForegroundUid) {
                        interval = Math.max(interval, backgroundThrottleInterval);
                    }
@@ -2121,7 +2109,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2;
                for (UpdateRecord record : records) {
                    if (isCurrentProfileLocked(
                            UserHandle.getUserId(record.mReceiver.mIdentity.mUid))) {
                            UserHandle.getUserId(record.mReceiver.mCallerIdentity.mUid))) {
                        LocationRequest locationRequest = record.mRequest;

                        // Don't assign battery blame for update records whose
@@ -2138,8 +2126,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                                // Assign blame to caller if there's no WorkSource associated with
                                // the request or if it's invalid.
                                worksource.add(
                                        record.mReceiver.mIdentity.mUid,
                                        record.mReceiver.mIdentity.mPackageName);
                                        record.mReceiver.mCallerIdentity.mUid,
                                        record.mReceiver.mCallerIdentity.mPackageName);
                            }
                        }
                    }
@@ -2176,17 +2164,17 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    @GuardedBy("mLock")
    private boolean isThrottlingExemptLocked(Identity identity) {
        if (identity.mUid == Process.SYSTEM_UID) {
    private boolean isThrottlingExemptLocked(CallerIdentity callerIdentity) {
        if (callerIdentity.mUid == Process.SYSTEM_UID) {
            return true;
        }

        if (mBackgroundThrottlePackageWhitelist.contains(identity.mPackageName)) {
        if (mBackgroundThrottlePackageWhitelist.contains(callerIdentity.mPackageName)) {
            return true;
        }

        for (LocationProvider provider : mProviders) {
            if (identity.mPackageName.equals(provider.getPackageLocked())) {
            if (callerIdentity.mPackageName.equals(provider.getPackageLocked())) {
                return true;
            }
        }
@@ -2200,12 +2188,13 @@ public class LocationManagerService extends ILocationManager.Stub {
            return false;
        }

        if (mIgnoreSettingsPackageWhitelist.contains(record.mReceiver.mIdentity.mPackageName)) {
        if (mIgnoreSettingsPackageWhitelist.contains(
                record.mReceiver.mCallerIdentity.mPackageName)) {
            return true;
        }

        for (LocationProvider provider : mProviders) {
            if (record.mReceiver.mIdentity.mPackageName.equals(provider.getPackageLocked())) {
            if (record.mReceiver.mCallerIdentity.mPackageName.equals(provider.getPackageLocked())) {
                return true;
            }
        }
@@ -2231,7 +2220,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            mRequest = request;
            mReceiver = receiver;
            mIsForegroundUid = isImportanceForeground(
                    mActivityManager.getPackageImportance(mReceiver.mIdentity.mPackageName));
                    mActivityManager.getPackageImportance(mReceiver.mCallerIdentity.mPackageName));

            ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
            if (records == null) {
@@ -2244,7 +2233,7 @@ public class LocationManagerService extends ILocationManager.Stub {

            // Update statistics for historical location requests by package/provider
            mRequestStatistics.startRequesting(
                    mReceiver.mIdentity.mPackageName, provider, request.getInterval(),
                    mReceiver.mCallerIdentity.mPackageName, provider, request.getInterval(),
                    mIsForegroundUid);
        }

@@ -2254,14 +2243,14 @@ public class LocationManagerService extends ILocationManager.Stub {
        private void updateForeground(boolean isForeground) {
            mIsForegroundUid = isForeground;
            mRequestStatistics.updateForeground(
                    mReceiver.mIdentity.mPackageName, mProvider, isForeground);
                    mReceiver.mCallerIdentity.mPackageName, mProvider, isForeground);
        }

        /**
         * Method to be called when a record will no longer be used.
         */
        private void disposeLocked(boolean removeReceiver) {
            mRequestStatistics.stopRequesting(mReceiver.mIdentity.mPackageName, mProvider);
            mRequestStatistics.stopRequesting(mReceiver.mCallerIdentity.mPackageName, mProvider);

            // remove from mRecordsByProvider
            ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
@@ -2283,8 +2272,8 @@ public class LocationManagerService extends ILocationManager.Stub {

        @Override
        public String toString() {
            return "UpdateRecord[" + mProvider + " " + mReceiver.mIdentity.mPackageName
                    + "(" + mReceiver.mIdentity.mUid + (mIsForegroundUid ? " foreground"
            return "UpdateRecord[" + mProvider + " " + mReceiver.mCallerIdentity.mPackageName
                    + "(" + mReceiver.mCallerIdentity.mUid + (mIsForegroundUid ? " foreground"
                    : " background")
                    + ")" + " " + mRealRequest + " "
                    + mReceiver.mWorkSource + "]";
@@ -2459,7 +2448,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
                    + " " + name + " " + request + " from " + packageName + "(" + uid + " "
                    + (record.mIsForegroundUid ? "foreground" : "background")
                    + (isThrottlingExemptLocked(receiver.mIdentity)
                    + (isThrottlingExemptLocked(receiver.mCallerIdentity)
                    ? " [whitelisted]" : "") + ")");
        }

@@ -2735,7 +2724,8 @@ public class LocationManagerService extends ILocationManager.Stub {

        // TODO(b/120449926): The GNSS status listeners should be handled similar to the GNSS
        // measurements listeners.
        return mGnssStatusProvider.addListener(callback, Binder.getCallingUid(), packageName);
        return mGnssStatusProvider.addListener(callback, new CallerIdentity(Binder.getCallingUid(),
                Binder.getCallingPid(), packageName));
    }

    @Override
@@ -2751,8 +2741,8 @@ public class LocationManagerService extends ILocationManager.Stub {
        }

        synchronized (mLock) {
            Identity callerIdentity
                    = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
            CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
                    Binder.getCallingPid(), packageName);
            // TODO(b/120481270): Register for client death notification and update map.
            mGnssMeasurementsListeners.put(listener.asBinder(), callerIdentity);
            long identity = Binder.clearCallingIdentity();
@@ -2760,8 +2750,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                if (isThrottlingExemptLocked(callerIdentity)
                        || isImportanceForeground(
                        mActivityManager.getPackageImportance(packageName))) {
                    return mGnssMeasurementsProvider.addListener(listener,
                            callerIdentity.mUid, callerIdentity.mPackageName);
                    return mGnssMeasurementsProvider.addListener(listener, callerIdentity);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
@@ -2816,8 +2805,8 @@ public class LocationManagerService extends ILocationManager.Stub {
        }

        synchronized (mLock) {
            Identity callerIdentity
                    = new Identity(Binder.getCallingUid(), Binder.getCallingPid(), packageName);
            CallerIdentity callerIdentity = new CallerIdentity(Binder.getCallingUid(),
                    Binder.getCallingPid(), packageName);

            // TODO(b/120481270): Register for client death notification and update map.
            mGnssNavigationMessageListeners.put(listener.asBinder(), callerIdentity);
@@ -2826,8 +2815,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                if (isThrottlingExemptLocked(callerIdentity)
                        || isImportanceForeground(
                        mActivityManager.getPackageImportance(packageName))) {
                    return mGnssNavigationMessageProvider.addListener(listener,
                            callerIdentity.mUid, callerIdentity.mPackageName);
                    return mGnssNavigationMessageProvider.addListener(listener, callerIdentity);
                }
            } finally {
                Binder.restoreCallingIdentity(identity);
@@ -3110,33 +3098,33 @@ public class LocationManagerService extends ILocationManager.Stub {
                continue;
            }

            int receiverUserId = UserHandle.getUserId(receiver.mIdentity.mUid);
            int receiverUserId = UserHandle.getUserId(receiver.mCallerIdentity.mUid);
            if (!isCurrentProfileLocked(receiverUserId)
                    && !isLocationProviderLocked(receiver.mIdentity.mUid)) {
                    && !isLocationProviderLocked(receiver.mCallerIdentity.mUid)) {
                if (D) {
                    Log.d(TAG, "skipping loc update for background user " + receiverUserId +
                            " (current user: " + mCurrentUserId + ", app: " +
                            receiver.mIdentity.mPackageName + ")");
                            receiver.mCallerIdentity.mPackageName + ")");
                }
                continue;
            }

            if (mBlacklist.isBlacklisted(receiver.mIdentity.mPackageName)) {
            if (mBlacklist.isBlacklisted(receiver.mCallerIdentity.mPackageName)) {
                if (D) {
                    Log.d(TAG, "skipping loc update for blacklisted app: " +
                            receiver.mIdentity.mPackageName);
                            receiver.mCallerIdentity.mPackageName);
                }
                continue;
            }

            if (!reportLocationAccessNoThrow(
                    receiver.mIdentity.mPid,
                    receiver.mIdentity.mUid,
                    receiver.mIdentity.mPackageName,
                    receiver.mCallerIdentity.mPid,
                    receiver.mCallerIdentity.mUid,
                    receiver.mCallerIdentity.mPackageName,
                    receiver.mAllowedResolutionLevel)) {
                if (D) {
                    Log.d(TAG, "skipping loc update for no op app: " +
                            receiver.mIdentity.mPackageName);
                            receiver.mCallerIdentity.mPackageName);
                }
                continue;
            }
@@ -3425,14 +3413,16 @@ public class LocationManagerService extends ILocationManager.Stub {
                }
            }
            pw.println("  Active GnssMeasurement Listeners:");
            for (Identity identity : mGnssMeasurementsListeners.values()) {
                pw.println("    " + identity.mPid + " " + identity.mUid + " "
                        + identity.mPackageName + ": " + isThrottlingExemptLocked(identity));
            for (CallerIdentity callerIdentity : mGnssMeasurementsListeners.values()) {
                pw.println("    " + callerIdentity.mPid + " " + callerIdentity.mUid + " "
                        + callerIdentity.mPackageName + ": "
                        + isThrottlingExemptLocked(callerIdentity));
            }
            pw.println("  Active GnssNavigationMessage Listeners:");
            for (Identity identity : mGnssNavigationMessageListeners.values()) {
                pw.println("    " + identity.mPid + " " + identity.mUid + " "
                        + identity.mPackageName + ": " + isThrottlingExemptLocked(identity));
            for (CallerIdentity callerIdentity : mGnssNavigationMessageListeners.values()) {
                pw.println("    " + callerIdentity.mPid + " " + callerIdentity.mUid + " "
                        + callerIdentity.mPackageName + ": "
                        + isThrottlingExemptLocked(callerIdentity));
            }
            pw.println("  Overlay Provider Packages:");
            for (LocationProvider provider : mProviders) {
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.location;

/**
 * Represents the calling process's uid, pid, and package name.
 */
public class CallerIdentity {
    public final int mUid;
    public final int mPid;
    public final String mPackageName;

    public CallerIdentity(int uid, int pid, String packageName) {
        mUid = uid;
        mPid = pid;
        mPackageName = packageName;
    }
}
+14 −19
Original line number Diff line number Diff line
@@ -95,14 +95,10 @@ public abstract class GnssMeasurementsProvider
     */
    public void injectGnssMeasurementCorrections(
            GnssMeasurementCorrections measurementCorrections) {
        mHandler.post(
                new Runnable() {
                    @Override
                    public void run() {
        mHandler.post(() -> {
            if (!mNative.injectGnssMeasurementCorrections(measurementCorrections)) {
                Log.e(TAG, "Failure in injecting GNSS corrections.");
            }
                    }
        });
    }

@@ -115,11 +111,10 @@ public abstract class GnssMeasurementsProvider
    }

    public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
        foreach(
                (IGnssMeasurementsListener listener, int uid, String packageName) -> {
                    if (!hasPermission(uid, packageName)) {
        foreach((IGnssMeasurementsListener listener, CallerIdentity callerIdentity) -> {
            if (!hasPermission(mContext, callerIdentity)) {
                logPermissionDisabledEventNotReported(
                                TAG, packageName, "GNSS measurements");
                        TAG, callerIdentity.mPackageName, "GNSS measurements");
                return;
            }
            listener.onGnssMeasurementsReceived(event);
@@ -182,7 +177,7 @@ public abstract class GnssMeasurementsProvider

        @Override
        public void execute(IGnssMeasurementsListener listener,
                int uid, String packageName) throws RemoteException {
                CallerIdentity callerIdentity) throws RemoteException {
            listener.onStatusChanged(mStatus);
        }
    }
+2 −2
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ public abstract class GnssNavigationMessageProvider
    }

    public void onNavigationMessageAvailable(final GnssNavigationMessage event) {
        foreach((IGnssNavigationMessageListener listener, int uid, String packageName) -> {
        foreach((IGnssNavigationMessageListener listener, CallerIdentity callerIdentity) -> {
                    listener.onGnssNavigationMessageReceived(event);
                }
        );
@@ -136,7 +136,7 @@ public abstract class GnssNavigationMessageProvider

        @Override
        public void execute(IGnssNavigationMessageListener listener,
                int uid, String packageName) throws RemoteException {
                CallerIdentity callerIdentity) throws RemoteException {
            listener.onStatusChanged(mStatus);
        }
    }
+10 −9

File changed.

Preview size limit exceeded, changes collapsed.

Loading