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

Commit ec37970c authored by David Christie's avatar David Christie Committed by Android (Google) Code Review
Browse files

Merge "Allow a particular LocationRequest to be excluded from AppOps...

Merge "Allow a particular LocationRequest to be excluded from AppOps monitoring as long as the client as the appropriate permission (UPDATE_DEVICE_STATS)."
parents 7d60f456 40e5782f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -147,6 +147,7 @@ public final class LocationRequest implements Parcelable {
    private int mNumUpdates = Integer.MAX_VALUE;  // no expiry
    private float mSmallestDisplacement = 0.0f;    // meters
    private WorkSource mWorkSource = new WorkSource();
    private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps

    private String mProvider = LocationManager.FUSED_PROVIDER;  // for deprecated APIs that explicitly request a provider

@@ -236,6 +237,7 @@ public final class LocationRequest implements Parcelable {
        mSmallestDisplacement = src.mSmallestDisplacement;
        mProvider = src.mProvider;
        mWorkSource = src.mWorkSource;
        mHideFromAppOps = src.mHideFromAppOps;
    }

    /**
@@ -506,6 +508,16 @@ public final class LocationRequest implements Parcelable {
        return mWorkSource;
    }

    /** @hide */
    public void setHideFromAppOps(boolean hideFromAppOps) {
        mHideFromAppOps = hideFromAppOps;
    }

    /** @hide */
    public boolean getHideFromAppOps() {
        return mHideFromAppOps;
    }

    private static void checkInterval(long millis) {
        if (millis < 0) {
            throw new IllegalArgumentException("invalid interval: " + millis);
@@ -549,6 +561,7 @@ public final class LocationRequest implements Parcelable {
            request.setExpireAt(in.readLong());
            request.setNumUpdates(in.readInt());
            request.setSmallestDisplacement(in.readFloat());
            request.setHideFromAppOps(in.readInt() != 0);
            String provider = in.readString();
            if (provider != null) request.setProvider(provider);
            WorkSource workSource = in.readParcelable(WorkSource.class.getClassLoader());
@@ -574,6 +587,7 @@ public final class LocationRequest implements Parcelable {
        parcel.writeLong(mExpireAt);
        parcel.writeInt(mNumUpdates);
        parcel.writeFloat(mSmallestDisplacement);
        parcel.writeInt(mHideFromAppOps ? 1 : 0);
        parcel.writeString(mProvider);
        parcel.writeParcelable(mWorkSource, 0);
    }
+31 −13
Original line number Diff line number Diff line
@@ -462,6 +462,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        final ILocationListener mListener;
        final PendingIntent mPendingIntent;
        final WorkSource mWorkSource; // WorkSource for battery blame, or null to assign to caller.
        final boolean mHideFromAppOps; // True if AppOps should not monitor this receiver.
        final Object mKey;

        final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
@@ -474,7 +475,7 @@ public class LocationManagerService extends ILocationManager.Stub {
        PowerManager.WakeLock mWakeLock;

        Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid,
                String packageName, WorkSource workSource) {
                String packageName, WorkSource workSource, boolean hideFromAppOps) {
            mListener = listener;
            mPendingIntent = intent;
            if (listener != null) {
@@ -490,6 +491,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                workSource = null;
            }
            mWorkSource = workSource;
            mHideFromAppOps = hideFromAppOps;

            updateMonitoring(true);

@@ -532,6 +534,10 @@ public class LocationManagerService extends ILocationManager.Stub {
        }

        public void updateMonitoring(boolean allow) {
            if (mHideFromAppOps) {
                return;
            }

            // First update monitoring of any location request (including high power).
            mOpMonitoring = updateMonitoring(allow, mOpMonitoring,
                    AppOpsManager.OP_MONITOR_LOCATION);
@@ -931,11 +937,16 @@ public class LocationManagerService extends ILocationManager.Stub {
     * Throw SecurityException if WorkSource use is not allowed (i.e. can't blame other packages
     * for battery).
     */
    private void checkWorkSourceAllowed() {
    private void checkDeviceStatsAllowed() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.UPDATE_DEVICE_STATS, null);
    }

    private void checkUpdateAppOpsAllowed() {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.UPDATE_APP_OPS_STATS, null);
    }

    public static int resolutionLevelToOp(int allowedResolutionLevel) {
        if (allowedResolutionLevel != RESOLUTION_LEVEL_NONE) {
            if (allowedResolutionLevel == RESOLUTION_LEVEL_COARSE) {
@@ -1260,11 +1271,12 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid,
            String packageName, WorkSource workSource) {
            String packageName, WorkSource workSource, boolean hideFromAppOps) {
        IBinder binder = listener.asBinder();
        Receiver receiver = mReceivers.get(binder);
        if (receiver == null) {
            receiver = new Receiver(listener, null, pid, uid, packageName, workSource);
            receiver = new Receiver(listener, null, pid, uid, packageName, workSource,
                    hideFromAppOps);
            mReceivers.put(binder, receiver);

            try {
@@ -1278,10 +1290,11 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName,
            WorkSource workSource) {
            WorkSource workSource, boolean hideFromAppOps) {
        Receiver receiver = mReceivers.get(intent);
        if (receiver == null) {
            receiver = new Receiver(null, intent, pid, uid, packageName, workSource);
            receiver = new Receiver(null, intent, pid, uid, packageName, workSource,
                    hideFromAppOps);
            mReceivers.put(intent, receiver);
        }
        return receiver;
@@ -1343,16 +1356,16 @@ public class LocationManagerService extends ILocationManager.Stub {
    }

    private Receiver checkListenerOrIntentLocked(ILocationListener listener, PendingIntent intent,
            int pid, int uid, String packageName, WorkSource workSource) {
            int pid, int uid, String packageName, WorkSource workSource, boolean hideFromAppOps) {
        if (intent == null && listener == null) {
            throw new IllegalArgumentException("need either listener or intent");
        } else if (intent != null && listener != null) {
            throw new IllegalArgumentException("cannot register both listener and intent");
        } else if (intent != null) {
            checkPendingIntent(intent);
            return getReceiverLocked(intent, pid, uid, packageName, workSource);
            return getReceiverLocked(intent, pid, uid, packageName, workSource, hideFromAppOps);
        } else {
            return getReceiverLocked(listener, pid, uid, packageName, workSource);
            return getReceiverLocked(listener, pid, uid, packageName, workSource, hideFromAppOps);
        }
    }

@@ -1366,7 +1379,11 @@ public class LocationManagerService extends ILocationManager.Stub {
                request.getProvider());
        WorkSource workSource = request.getWorkSource();
        if (workSource != null && workSource.size() > 0) {
            checkWorkSourceAllowed();
            checkDeviceStatsAllowed();
        }
        boolean hideFromAppOps = request.getHideFromAppOps();
        if (hideFromAppOps) {
            checkUpdateAppOpsAllowed();
        }
        LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel);

@@ -1381,7 +1398,7 @@ public class LocationManagerService extends ILocationManager.Stub {

            synchronized (mLock) {
                Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid,
                        packageName, workSource);
                        packageName, workSource, hideFromAppOps);
                requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName);
            }
        } finally {
@@ -1434,8 +1451,9 @@ public class LocationManagerService extends ILocationManager.Stub {

        synchronized (mLock) {
            WorkSource workSource = null;
            Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid, packageName,
                    workSource);
            boolean hideFromAppOps = false;
            Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid,
                    packageName, workSource, hideFromAppOps);

            // providers may use public location API's, need to clear identity
            long identity = Binder.clearCallingIdentity();