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

Commit b8466b76 authored by Soonil Nagarkar's avatar Soonil Nagarkar
Browse files

Pull out Settings usage into utility

Centralizes all settings usages so it can more easily be mocked from
unit tests.

Bug: 143471007
Test: manual
Change-Id: Ie8b59b903d131b5abd180805794b596f503d6d4b
parent 235a9b30
Loading
Loading
Loading
Loading
+63 −168
Original line number Original line Diff line number Diff line
@@ -43,7 +43,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.pm.Signature;
import android.content.res.Resources;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.location.ActivityRecognitionHardware;
import android.hardware.location.ActivityRecognitionHardware;
import android.location.Address;
import android.location.Address;
import android.location.Criteria;
import android.location.Criteria;
@@ -79,7 +78,6 @@ import android.os.WorkSource.WorkChain;
import android.provider.Settings;
import android.provider.Settings;
import android.stats.location.LocationStatsEnums;
import android.stats.location.LocationStatsEnums;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.EventLog;
import android.util.Log;
import android.util.Log;
import android.util.Slog;
import android.util.Slog;
@@ -99,12 +97,12 @@ import com.android.server.location.CallerIdentity;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeofenceManager;
import com.android.server.location.GeofenceManager;
import com.android.server.location.GeofenceProxy;
import com.android.server.location.GeofenceProxy;
import com.android.server.location.LocationBlacklist;
import com.android.server.location.LocationFudger;
import com.android.server.location.LocationFudger;
import com.android.server.location.LocationProviderProxy;
import com.android.server.location.LocationProviderProxy;
import com.android.server.location.LocationRequestStatistics;
import com.android.server.location.LocationRequestStatistics;
import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
import com.android.server.location.LocationRequestStatistics.PackageStatistics;
import com.android.server.location.LocationRequestStatistics.PackageStatistics;
import com.android.server.location.LocationSettingsStore;
import com.android.server.location.MockProvider;
import com.android.server.location.MockProvider;
import com.android.server.location.PassiveProvider;
import com.android.server.location.PassiveProvider;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -183,13 +181,6 @@ public class LocationManagerService extends ILocationManager.Stub {
    private static final int FOREGROUND_IMPORTANCE_CUTOFF
    private static final int FOREGROUND_IMPORTANCE_CUTOFF
            = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
            = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;


    // default background throttling interval if not overriden in settings
    private static final long DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 60 * 1000;

    // Default value for maximum age of last location returned to applications with foreground-only
    // location permissions.
    private static final long DEFAULT_LAST_LOCATION_MAX_AGE_MS = 20 * 60 * 1000;

    // Location Providers may sometimes deliver location updates
    // Location Providers may sometimes deliver location updates
    // slightly faster that requested - provide grace period so
    // slightly faster that requested - provide grace period so
    // we don't unnecessarily filter events that are otherwise on
    // we don't unnecessarily filter events that are otherwise on
@@ -208,13 +199,14 @@ public class LocationManagerService extends ILocationManager.Stub {
    private ActivityManager mActivityManager;
    private ActivityManager mActivityManager;
    private UserManager mUserManager;
    private UserManager mUserManager;


    private LocationSettingsStore mSettingsStore;

    private GeofenceManager mGeofenceManager;
    private GeofenceManager mGeofenceManager;
    private LocationFudger mLocationFudger;
    private LocationFudger mLocationFudger;
    private GeocoderProxy mGeocodeProvider;
    private GeocoderProxy mGeocodeProvider;
    @Nullable
    @Nullable
    private GnssManagerService mGnssManagerService;
    private GnssManagerService mGnssManagerService;
    private PassiveProvider mPassiveProvider; // track passive provider for special cases
    private PassiveProvider mPassiveProvider; // track passive provider for special cases
    private LocationBlacklist mBlacklist;
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private String mExtraLocationControllerPackage;
    private String mExtraLocationControllerPackage;
    private boolean mExtraLocationControllerPackageEnabled;
    private boolean mExtraLocationControllerPackageEnabled;
@@ -245,10 +237,6 @@ public class LocationManagerService extends ILocationManager.Stub {
    private final HashMap<String, Location> mLastLocationCoarseInterval =
    private final HashMap<String, Location> mLastLocationCoarseInterval =
            new HashMap<>();
            new HashMap<>();


    private final ArraySet<String> mBackgroundThrottlePackageWhitelist = new ArraySet<>();

    private final ArraySet<String> mIgnoreSettingsPackageWhitelist = new ArraySet<>();

    // current active user on the device - other users are denied location data
    // current active user on the device - other users are denied location data
    private int mCurrentUserId = UserHandle.USER_SYSTEM;
    private int mCurrentUserId = UserHandle.USER_SYSTEM;
    private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM};
    private int[] mCurrentUserProfiles = new int[]{UserHandle.USER_SYSTEM};
@@ -287,16 +275,19 @@ public class LocationManagerService extends ILocationManager.Stub {


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void initializeLocked() {
    private void initializeLocked() {
        mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        mPackageManager = mContext.getPackageManager();
        mPackageManager = mContext.getPackageManager();
        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mAppOps = mContext.getSystemService(AppOpsManager.class);
        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        mPowerManager = mContext.getSystemService(PowerManager.class);
        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        mActivityManager = mContext.getSystemService(ActivityManager.class);
        mUserManager = mContext.getSystemService(UserManager.class);

        mSettingsStore = new LocationSettingsStore(mContext, mHandler);


        mLocationFudger = new LocationFudger(mContext, mHandler);
        mLocationFudger = new LocationFudger(mContext, mHandler);
        mBlacklist = new LocationBlacklist(mContext, mHandler);
        mGeofenceManager = new GeofenceManager(mContext, mSettingsStore);
        mBlacklist.init();

        mGeofenceManager = new GeofenceManager(mContext, mBlacklist);
        PowerManagerInternal localPowerManager =
                LocalServices.getService(PowerManagerInternal.class);


        // prepare providers
        // prepare providers
        initializeProvidersLocked();
        initializeProvidersLocked();
@@ -327,7 +318,6 @@ public class LocationManagerService extends ILocationManager.Stub {
                        }
                        }
                    });
                    });
                });
                });

        mActivityManager.addOnUidImportanceListener(
        mActivityManager.addOnUidImportanceListener(
                (uid, importance) -> {
                (uid, importance) -> {
                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
@@ -339,72 +329,43 @@ public class LocationManagerService extends ILocationManager.Stub {
                    });
                    });
                },
                },
                FOREGROUND_IMPORTANCE_CUTOFF);
                FOREGROUND_IMPORTANCE_CUTOFF);
        mContext.getContentResolver().registerContentObserver(

                Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE), true,
        localPowerManager.registerLowPowerModeObserver(ServiceType.LOCATION,
                new ContentObserver(mHandler) {
                state -> {
                    @Override
                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
                    public void onChange(boolean selfChange) {
                    // ui thread
                    mHandler.post(() -> {
                        synchronized (mLock) {
                        synchronized (mLock) {
                            onLocationModeChangedLocked(true);
                            onBatterySaverModeChangedLocked(state.locationMode);
                        }
                        }
                    });
                });
        mBatterySaverMode = mPowerManager.getLocationPowerSaveMode();

        mSettingsStore.addOnLocationEnabledChangedListener(() -> {
            synchronized (mLock) {
                onLocationModeChangedLocked(true);
            }
            }
                }, UserHandle.USER_ALL);
        });
        mContext.getContentResolver().registerContentObserver(
        mSettingsStore.addOnLocationProvidersAllowedChangedListener(() -> {
                Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,
                new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
            synchronized (mLock) {
            synchronized (mLock) {
                onProviderAllowedChangedLocked();
                onProviderAllowedChangedLocked();
            }
            }
                    }
        });
                }, UserHandle.USER_ALL);
        mSettingsStore.addOnBackgroundThrottleIntervalChangedListener(() -> {
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS),
                true,
                new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
            synchronized (mLock) {
            synchronized (mLock) {
                onBackgroundThrottleIntervalChangedLocked();
                onBackgroundThrottleIntervalChangedLocked();
            }
            }
                    }
        });
                }, UserHandle.USER_ALL);
        mSettingsStore.addOnBackgroundThrottlePackageWhitelistChangedListener(() -> {
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(
                        Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST),
                true,
                new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
            synchronized (mLock) {
            synchronized (mLock) {
                onBackgroundThrottleWhitelistChangedLocked();
                onBackgroundThrottleWhitelistChangedLocked();
            }
            }
                    }
        });
                }, UserHandle.USER_ALL);
        mSettingsStore.addOnIgnoreSettingsPackageWhitelistChangedListener(() -> {
        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(
                        Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST),
                true,
                new ContentObserver(mHandler) {
                    @Override
                    public void onChange(boolean selfChange) {
            synchronized (mLock) {
            synchronized (mLock) {
                onIgnoreSettingsWhitelistChangedLocked();
                onIgnoreSettingsWhitelistChangedLocked();
            }
            }
                    }
                }, UserHandle.USER_ALL);
        PowerManagerInternal localPowerManager =
                LocalServices.getService(PowerManagerInternal.class);
        localPowerManager.registerLowPowerModeObserver(ServiceType.LOCATION,
                state -> {
                    // listener invoked on ui thread, move to our thread to reduce risk of blocking
                    // ui thread
                    mHandler.post(() -> {
                        synchronized (mLock) {
                            onBatterySaverModeChangedLocked(state.locationMode);
                        }
                    });
        });
        });


        new PackageMonitor() {
        new PackageMonitor() {
@@ -453,11 +414,6 @@ public class LocationManagerService extends ILocationManager.Stub {
        // provider initialization, and propagates changes until a steady state is reached
        // provider initialization, and propagates changes until a steady state is reached
        mCurrentUserId = UserHandle.USER_NULL;
        mCurrentUserId = UserHandle.USER_NULL;
        onUserChangedLocked(ActivityManager.getCurrentUser());
        onUserChangedLocked(ActivityManager.getCurrentUser());

        // initialize in-memory settings values
        onBackgroundThrottleWhitelistChangedLocked();
        onIgnoreSettingsWhitelistChangedLocked();
        onBatterySaverModeChangedLocked(mPowerManager.getLocationPowerSaveMode());
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
@@ -479,6 +435,10 @@ public class LocationManagerService extends ILocationManager.Stub {


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void onBatterySaverModeChangedLocked(int newLocationMode) {
    private void onBatterySaverModeChangedLocked(int newLocationMode) {
        if (mBatterySaverMode == newLocationMode) {
            return;
        }

        if (D) {
        if (D) {
            Slog.d(TAG,
            Slog.d(TAG,
                    "Battery Saver location mode changed from "
                    "Battery Saver location mode changed from "
@@ -486,11 +446,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                            + locationPowerSaveModeToString(newLocationMode));
                            + locationPowerSaveModeToString(newLocationMode));
        }
        }


        if (mBatterySaverMode == newLocationMode) {
            return;
        }

        mBatterySaverMode = newLocationMode;
        mBatterySaverMode = newLocationMode;

        for (LocationProvider p : mProviders) {
        for (LocationProvider p : mProviders) {
            applyRequirementsLocked(p);
            applyRequirementsLocked(p);
        }
        }
@@ -588,17 +545,6 @@ public class LocationManagerService extends ILocationManager.Stub {


    @GuardedBy("mLock")
    @GuardedBy("mLock")
    private void onBackgroundThrottleWhitelistChangedLocked() {
    private void onBackgroundThrottleWhitelistChangedLocked() {
        mBackgroundThrottlePackageWhitelist.clear();
        mBackgroundThrottlePackageWhitelist.addAll(
                SystemConfig.getInstance().getAllowUnthrottledLocation());

        String setting = Settings.Global.getString(
                mContext.getContentResolver(),
                Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
        if (!TextUtils.isEmpty(setting)) {
            mBackgroundThrottlePackageWhitelist.addAll(Arrays.asList(setting.split(",")));
        }

        for (LocationProvider p : mProviders) {
        for (LocationProvider p : mProviders) {
            applyRequirementsLocked(p);
            applyRequirementsLocked(p);
        }
        }
@@ -606,17 +552,6 @@ public class LocationManagerService extends ILocationManager.Stub {


    @GuardedBy("lock")
    @GuardedBy("lock")
    private void onIgnoreSettingsWhitelistChangedLocked() {
    private void onIgnoreSettingsWhitelistChangedLocked() {
        mIgnoreSettingsPackageWhitelist.clear();
        mIgnoreSettingsPackageWhitelist.addAll(
                SystemConfig.getInstance().getAllowIgnoreLocationSettings());

        String setting = Settings.Global.getString(
                mContext.getContentResolver(),
                Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST);
        if (!TextUtils.isEmpty(setting)) {
            mIgnoreSettingsPackageWhitelist.addAll(Arrays.asList(setting.split(",")));
        }

        for (LocationProvider p : mProviders) {
        for (LocationProvider p : mProviders) {
            applyRequirementsLocked(p);
            applyRequirementsLocked(p);
        }
        }
@@ -859,8 +794,6 @@ public class LocationManagerService extends ILocationManager.Stub {
        mCurrentUserId = userId;
        mCurrentUserId = userId;
        onUserProfilesChangedLocked();
        onUserProfilesChangedLocked();


        mBlacklist.switchUser(userId);

        // if the user changes, per-user settings may also have changed
        // if the user changes, per-user settings may also have changed
        onLocationModeChangedLocked(false);
        onLocationModeChangedLocked(false);
        onProviderAllowedChangedLocked();
        onProviderAllowedChangedLocked();
@@ -1083,11 +1016,8 @@ public class LocationManagerService extends ILocationManager.Stub {
        @GuardedBy("mLock")
        @GuardedBy("mLock")
        public void onAllowedChangedLocked() {
        public void onAllowedChangedLocked() {
            if (mIsManagedBySettings) {
            if (mIsManagedBySettings) {
                String allowedProviders = Settings.Secure.getStringForUser(
                boolean allowed = mSettingsStore.getLocationProvidersAllowed(
                        mContext.getContentResolver(),
                        mCurrentUserId).contains(mName);
                        Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                        mCurrentUserId);
                boolean allowed = TextUtils.delimitedStringContains(allowedProviders, ',', mName);


                if (allowed == mAllowed) {
                if (allowed == mAllowed) {
                    return;
                    return;
@@ -1909,10 +1839,7 @@ public class LocationManagerService extends ILocationManager.Stub {


            long identity = Binder.clearCallingIdentity();
            long identity = Binder.clearCallingIdentity();
            try {
            try {
                backgroundThrottleInterval = Settings.Global.getLong(
                backgroundThrottleInterval = mSettingsStore.getBackgroundThrottleIntervalMs();
                        mContext.getContentResolver(),
                        Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
                        DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS);
            } finally {
            } finally {
                Binder.restoreCallingIdentity(identity);
                Binder.restoreCallingIdentity(identity);
            }
            }
@@ -2032,16 +1959,12 @@ public class LocationManagerService extends ILocationManager.Stub {


    @Override
    @Override
    public String[] getBackgroundThrottlingWhitelist() {
    public String[] getBackgroundThrottlingWhitelist() {
        synchronized (mLock) {
        return mSettingsStore.getBackgroundThrottlePackageWhitelist().toArray(new String[0]);
            return mBackgroundThrottlePackageWhitelist.toArray(new String[0]);
        }
    }
    }


    @Override
    @Override
    public String[] getIgnoreSettingsWhitelist() {
    public String[] getIgnoreSettingsWhitelist() {
        synchronized (mLock) {
        return mSettingsStore.getIgnoreSettingsPackageWhitelist().toArray(new String[0]);
            return mIgnoreSettingsPackageWhitelist.toArray(new String[0]);
        }
    }
    }


    @GuardedBy("mLock")
    @GuardedBy("mLock")
@@ -2050,7 +1973,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            return true;
            return true;
        }
        }


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


@@ -2064,7 +1988,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            return false;
            return false;
        }
        }


        if (mIgnoreSettingsPackageWhitelist.contains(
        if (mSettingsStore.getIgnoreSettingsPackageWhitelist().contains(
                record.mReceiver.mCallerIdentity.mPackageName)) {
                record.mReceiver.mCallerIdentity.mPackageName)) {
            return true;
            return true;
        }
        }
@@ -2472,7 +2396,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            final int uid = Binder.getCallingUid();
            final int uid = Binder.getCallingUid();
            final long identity = Binder.clearCallingIdentity();
            final long identity = Binder.clearCallingIdentity();
            try {
            try {
                if (mBlacklist.isBlacklisted(packageName)) {
                if (mSettingsStore.isLocationPackageBlacklisted(UserHandle.getUserId(uid),
                        packageName)) {
                    if (D) {
                    if (D) {
                        Log.d(TAG, "not returning last loc for blacklisted app: "
                        Log.d(TAG, "not returning last loc for blacklisted app: "
                                + packageName);
                                + packageName);
@@ -2513,10 +2438,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                String op = resolutionLevelToOpStr(allowedResolutionLevel);
                String op = resolutionLevelToOpStr(allowedResolutionLevel);
                long locationAgeMs = TimeUnit.NANOSECONDS.toMillis(
                long locationAgeMs = TimeUnit.NANOSECONDS.toMillis(
                        SystemClock.elapsedRealtime() - location.getElapsedRealtimeNanos());
                        SystemClock.elapsedRealtime() - location.getElapsedRealtimeNanos());
                if ((locationAgeMs > Settings.Global.getLong(
                if (locationAgeMs > mSettingsStore.getMaxLastLocationAgeMs()
                        mContext.getContentResolver(),
                        Settings.Global.LOCATION_LAST_LOCATION_MAX_AGE_MILLIS,
                        DEFAULT_LAST_LOCATION_MAX_AGE_MS))
                        && (mAppOps.unsafeCheckOp(op, uid, packageName)
                        && (mAppOps.unsafeCheckOp(op, uid, packageName)
                        == AppOpsManager.MODE_FOREGROUND)) {
                        == AppOpsManager.MODE_FOREGROUND)) {
                    return null;
                    return null;
@@ -2575,11 +2497,7 @@ public class LocationManagerService extends ILocationManager.Stub {
                boolean foreground = LocationManagerServiceUtils.isImportanceForeground(
                boolean foreground = LocationManagerServiceUtils.isImportanceForeground(
                        mActivityManager.getPackageImportance(packageName));
                        mActivityManager.getPackageImportance(packageName));
                if (!foreground) {
                if (!foreground) {
                    long backgroundThrottleIntervalMs = Settings.Global.getLong(
                    if (locationAgeMs < mSettingsStore.getBackgroundThrottleIntervalMs()) {
                            mContext.getContentResolver(),
                            Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
                            DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS);
                    if (locationAgeMs < backgroundThrottleIntervalMs) {
                        // not allowed to request new locations, so we can't return anything
                        // not allowed to request new locations, so we can't return anything
                        return false;
                        return false;
                    }
                    }
@@ -2910,11 +2828,7 @@ public class LocationManagerService extends ILocationManager.Stub {


        long identity = Binder.clearCallingIdentity();
        long identity = Binder.clearCallingIdentity();
        try {
        try {
            return Settings.Secure.getIntForUser(
            return mSettingsStore.isLocationEnabled(userId);
                    mContext.getContentResolver(),
                    Settings.Secure.LOCATION_MODE,
                    Settings.Secure.LOCATION_MODE_OFF,
                    userId) != Settings.Secure.LOCATION_MODE_OFF;
        } finally {
        } finally {
            Binder.restoreCallingIdentity(identity);
            Binder.restoreCallingIdentity(identity);
        }
        }
@@ -3050,7 +2964,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                continue;
                continue;
            }
            }


            if (mBlacklist.isBlacklisted(receiver.mCallerIdentity.mPackageName)) {
            if (mSettingsStore.isLocationPackageBlacklisted(receiverUserId,
                    receiver.mCallerIdentity.mPackageName)) {
                if (D) {
                if (D) {
                    Log.d(TAG, "skipping loc update for blacklisted app: " +
                    Log.d(TAG, "skipping loc update for blacklisted app: " +
                            receiver.mCallerIdentity.mPackageName);
                            receiver.mCallerIdentity.mPackageName);
@@ -3392,33 +3307,11 @@ public class LocationManagerService extends ILocationManager.Stub {
                ipw.decreaseIndent();
                ipw.decreaseIndent();
            }
            }


            if (mBlacklist != null) {
                mBlacklist.dump(ipw);
            }

            if (mExtraLocationControllerPackage != null) {
            if (mExtraLocationControllerPackage != null) {
                ipw.println("Location Controller Extra Package: " + mExtraLocationControllerPackage
                ipw.println("Location Controller Extra Package: " + mExtraLocationControllerPackage
                        + (mExtraLocationControllerPackageEnabled ? " [enabled]" : "[disabled]"));
                        + (mExtraLocationControllerPackageEnabled ? " [enabled]" : "[disabled]"));
            }
            }


            if (!mBackgroundThrottlePackageWhitelist.isEmpty()) {
                ipw.println("Throttling Whitelisted Packages:");
                ipw.increaseIndent();
                for (String packageName : mBackgroundThrottlePackageWhitelist) {
                    ipw.println(packageName);
                }
                ipw.decreaseIndent();
            }

            if (!mIgnoreSettingsPackageWhitelist.isEmpty()) {
                ipw.println("Bypass Whitelisted Packages:");
                ipw.increaseIndent();
                for (String packageName : mIgnoreSettingsPackageWhitelist) {
                    ipw.println(packageName);
                }
                ipw.decreaseIndent();
            }

            if (mLocationFudger != null) {
            if (mLocationFudger != null) {
                ipw.println("Location Fudger:");
                ipw.println("Location Fudger:");
                ipw.increaseIndent();
                ipw.increaseIndent();
@@ -3426,6 +3319,8 @@ public class LocationManagerService extends ILocationManager.Stub {
                ipw.decreaseIndent();
                ipw.decreaseIndent();
            }
            }


            mSettingsStore.dump(fd, pw, args);

            ipw.println("Location Providers:");
            ipw.println("Location Providers:");
            ipw.increaseIndent();
            ipw.increaseIndent();
            for (LocationProvider provider : mProviders) {
            for (LocationProvider provider : mProviders) {
+33 −59

File changed.

Preview size limit exceeded, changes collapsed.

+0 −151
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2012 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;

import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;

import com.android.server.LocationManagerService;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Allows applications to be blacklisted from location updates at run-time.
 *
 * This is a silent blacklist. Applications can still call Location Manager
 * API's, but they just won't receive any locations.
 */
public final class LocationBlacklist extends ContentObserver {
    private static final String TAG = "LocationBlacklist";
    private static final boolean D = LocationManagerService.D;
    private static final String BLACKLIST_CONFIG_NAME = "locationPackagePrefixBlacklist";
    private static final String WHITELIST_CONFIG_NAME = "locationPackagePrefixWhitelist";

    private final Context mContext;
    private final Object mLock = new Object();

    // all fields below synchronized on mLock
    private String[] mWhitelist = new String[0];
    private String[] mBlacklist = new String[0];

    private int mCurrentUserId = UserHandle.USER_SYSTEM;
    
    public LocationBlacklist(Context context, Handler handler) {
        super(handler);
        mContext = context;
    }

    public void init() {
        mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
                BLACKLIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
//        mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
//                WHITELIST_CONFIG_NAME), false, this, UserHandle.USER_ALL);
        reloadBlacklist();
    }

    private void reloadBlacklistLocked() {
        mWhitelist = getStringArrayLocked(WHITELIST_CONFIG_NAME);
        if (D) Slog.d(TAG, "whitelist: " + Arrays.toString(mWhitelist));
        mBlacklist = getStringArrayLocked(BLACKLIST_CONFIG_NAME);
        if (D) Slog.d(TAG, "blacklist: " + Arrays.toString(mBlacklist));
    }

    private void reloadBlacklist() {
        synchronized (mLock) {
            reloadBlacklistLocked();
        }
    }

    /**
     * Return true if in blacklist
     * (package name matches blacklist, and does not match whitelist)
     */
    public boolean isBlacklisted(String packageName) {
        synchronized (mLock) {
            for (String black : mBlacklist) {
                if (packageName.startsWith(black)) {
                    if (inWhitelist(packageName)) {
                        continue;
                    } else {
                        if (D) Log.d(TAG, "dropping location (blacklisted): "
                                + packageName + " matches " + black);
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Return true if any of packages are in whitelist
     */
    private boolean inWhitelist(String pkg) {
        synchronized (mLock) {
            for (String white : mWhitelist) {
                if (pkg.startsWith(white)) return true;
            }
        }
        return false;
    }

    @Override
    public void onChange(boolean selfChange) {
        reloadBlacklist();
    }

    public void switchUser(int userId) {
        synchronized(mLock) {
            mCurrentUserId = userId;
            reloadBlacklistLocked();
        }
    }

    private String[] getStringArrayLocked(String key) {
        String flatString;
        synchronized(mLock) {
            flatString = Settings.Secure.getStringForUser(mContext.getContentResolver(), key,
                    mCurrentUserId);
        }
        if (flatString == null) {
            return new String[0];
        }
        String[] splitStrings = flatString.split(",");
        ArrayList<String> result = new ArrayList<String>();
        for (String pkg : splitStrings) {
            pkg = pkg.trim();
            if (pkg.isEmpty()) {
                continue;
            }
            result.add(pkg);
        }
        return result.toArray(new String[result.size()]);
    }

    public void dump(PrintWriter pw) {
        pw.println("mWhitelist=" + Arrays.toString(mWhitelist) + " mBlacklist=" +
                Arrays.toString(mBlacklist));
    }
}
+461 −0

File added.

Preview size limit exceeded, changes collapsed.