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

Commit a08b2419 authored by Steve Kondik's avatar Steve Kondik
Browse files

privacy guard: Use LocationBlacklist for location filtering

 * Google has built a per-package blacklist into the location service.
 * Let's use this to handle Privacy Guard instead of our one-off code
   which has a bunch of edge cases and can leave apps in a weird state.

Change-Id: I2f2ecd0b75ff51b44b1a6035189355d7bd63eaf4
parent faf55695
Loading
Loading
Loading
Loading
+1 −57
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package com.android.server;
package com.android.server;


import android.app.ActivityManagerNative;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentResolver;
@@ -665,20 +664,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        mProvidersByName.remove(provider.getName());
        mProvidersByName.remove(provider.getName());
    }
    }


    private boolean isPrivacyGuardEnabled(int pid) {
        try {
            if (ActivityManagerNative.getDefault().isPrivacyGuardEnabledForProcess(pid)) {
                Slog.i(TAG, "Location services unavailable under privacy guard for process pid=" + pid);
                return true;
            }
        } catch (RemoteException e) {
            // nothing
        }
        return false;
    }


    private boolean isAllowedBySettingsLocked(String provider, int userId) {
    private boolean isAllowedBySettingsLocked(String provider, int userId) {

        if (userId != mCurrentUserId) {
        if (userId != mCurrentUserId) {
            return false;
            return false;
        }
        }
@@ -839,9 +826,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
     */
     */
    @Override
    @Override
    public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
    public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return new ArrayList<String>(0);
        }
        int allowedResolutionLevel = getCallerAllowedResolutionLevel();
        int allowedResolutionLevel = getCallerAllowedResolutionLevel();
        ArrayList<String> out;
        ArrayList<String> out;
        int callingUserId = UserHandle.getCallingUserId();
        int callingUserId = UserHandle.getCallingUserId();
@@ -1240,7 +1224,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        }
        }


        boolean isProviderEnabled = isAllowedBySettingsLocked(name, UserHandle.getUserId(uid));
        boolean isProviderEnabled = isAllowedBySettingsLocked(name, UserHandle.getUserId(uid));
        if (isProviderEnabled && !isPrivacyGuardEnabled(pid)) {
        if (isProviderEnabled) {
            applyRequirementsLocked(name);
            applyRequirementsLocked(name);
        } else {
        } else {
            // Notify the listener that updates are currently disabled
            // Notify the listener that updates are currently disabled
@@ -1254,9 +1238,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        checkPackageName(packageName);
        checkPackageName(packageName);


        final int pid = Binder.getCallingPid();
        final int pid = Binder.getCallingPid();
        if (isPrivacyGuardEnabled(pid)) {
            return;
        }
        final int uid = Binder.getCallingUid();
        final int uid = Binder.getCallingUid();
        Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName);
        Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName);


@@ -1316,9 +1297,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
        checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel,
                request.getProvider());
                request.getProvider());
        // no need to sanitize this request, as only the provider name is used
        // no need to sanitize this request, as only the provider name is used
        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return null;
        }


        long identity = Binder.clearCallingIdentity();
        long identity = Binder.clearCallingIdentity();
        try {
        try {
@@ -1371,13 +1349,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run


        if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent);
        if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent);


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return;
        }

        // geo-fence manager uses the public location API, need to clear identity
        // geo-fence manager uses the public location API, need to clear identity
        int uid = Binder.getCallingUid();
        int uid = Binder.getCallingUid();

        if (UserHandle.getUserId(uid) != UserHandle.USER_OWNER) {
        if (UserHandle.getUserId(uid) != UserHandle.USER_OWNER) {
            // temporary measure until geofences work for secondary users
            // temporary measure until geofences work for secondary users
            Log.w(TAG, "proximity alerts are currently available only to the primary user");
            Log.w(TAG, "proximity alerts are currently available only to the primary user");
@@ -1399,10 +1372,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run


        if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent);
        if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent);


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return;
        }

        // geo-fence manager uses the public location API, need to clear identity
        // geo-fence manager uses the public location API, need to clear identity
        long identity = Binder.clearCallingIdentity();
        long identity = Binder.clearCallingIdentity();
        try {
        try {
@@ -1421,10 +1390,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
                LocationManager.GPS_PROVIDER);
                LocationManager.GPS_PROVIDER);


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return false;
        }

        try {
        try {
            mGpsStatusProvider.addGpsStatusListener(listener);
            mGpsStatusProvider.addGpsStatusListener(listener);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -1436,10 +1401,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run


    @Override
    @Override
    public void removeGpsStatusListener(IGpsStatusListener listener) {
    public void removeGpsStatusListener(IGpsStatusListener listener) {
        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return;
        }

        synchronized (mLock) {
        synchronized (mLock) {
            try {
            try {
                mGpsStatusProvider.removeGpsStatusListener(listener);
                mGpsStatusProvider.removeGpsStatusListener(listener);
@@ -1458,10 +1419,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
                provider);
                provider);


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return false;
        }

        // and check for ACCESS_LOCATION_EXTRA_COMMANDS
        // and check for ACCESS_LOCATION_EXTRA_COMMANDS
        if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
        if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
                != PackageManager.PERMISSION_GRANTED)) {
                != PackageManager.PERMISSION_GRANTED)) {
@@ -1482,11 +1439,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
            throw new SecurityException(
            throw new SecurityException(
                    "calling sendNiResponse from outside of the system is not allowed");
                    "calling sendNiResponse from outside of the system is not allowed");
        }
        }

        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return false;
        }

        try {
        try {
            return mNetInitiatedListener.sendNiResponse(notifId, userResponse);
            return mNetInitiatedListener.sendNiResponse(notifId, userResponse);
        } catch (RemoteException e) {
        } catch (RemoteException e) {
@@ -1509,10 +1461,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
        checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
                provider);
                provider);


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return null;
        }

        LocationProviderInterface p;
        LocationProviderInterface p;
        synchronized (mLock) {
        synchronized (mLock) {
            p = mProvidersByName.get(provider);
            p = mProvidersByName.get(provider);
@@ -1528,10 +1476,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
                provider);
                provider);
        if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;
        if (LocationManager.FUSED_PROVIDER.equals(provider)) return false;


        if (isPrivacyGuardEnabled(Binder.getCallingPid())) {
            return false;
        }

        long identity = Binder.clearCallingIdentity();
        long identity = Binder.clearCallingIdentity();
        try {
        try {
            synchronized (mLock) {
            synchronized (mLock) {
+10 −0
Original line number Original line Diff line number Diff line
@@ -17,9 +17,11 @@


package com.android.server.location;
package com.android.server.location;


import android.app.AppGlobals;
import android.content.Context;
import android.content.Context;
import android.database.ContentObserver;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.util.Log;
import android.util.Log;
@@ -84,6 +86,14 @@ public final class LocationBlacklist extends ContentObserver {
     */
     */
    public boolean isBlacklisted(String packageName) {
    public boolean isBlacklisted(String packageName) {
        synchronized (mLock) {
        synchronized (mLock) {
            try {
                if (AppGlobals.getPackageManager().getPrivacyGuardSetting(packageName, mCurrentUserId)) {
                    Log.d(TAG, "dropping location due to privacy guard package=" + packageName);
                    return true;
                }
            } catch (RemoteException e) {
                // nothing
            }
            for (String black : mBlacklist) {
            for (String black : mBlacklist) {
                if (packageName.startsWith(black)) {
                if (packageName.startsWith(black)) {
                    if (inWhitelist(packageName)) {
                    if (inWhitelist(packageName)) {