Loading location/java/android/location/ILocationManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ interface ILocationManager in PendingIntent intent, String packageName); void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName); Location getLastLocation(in LocationRequest request); Location getLastLocation(in LocationRequest request, String packageName); boolean addGpsStatusListener(IGpsStatusListener listener); void removeGpsStatusListener(IGpsStatusListener listener); Loading location/java/android/location/LocationManager.java +5 −3 Original line number Diff line number Diff line Loading @@ -1174,8 +1174,10 @@ public class LocationManager { * @throws SecurityException if no suitable permission is present */ public Location getLastLocation() { String packageName = mContext.getPackageName(); try { return mService.getLastLocation(null); return mService.getLastLocation(null, packageName); } catch (RemoteException e) { Log.e(TAG, "RemoteException", e); return null; Loading Loading @@ -1204,12 +1206,12 @@ public class LocationManager { @Deprecated public Location getLastKnownLocation(String provider) { checkProvider(provider); String packageName = mContext.getPackageName(); LocationRequest request = LocationRequest.createFromDeprecatedProvider( provider, 0, 0, true); try { return mService.getLastLocation(request); return mService.getLastLocation(request, packageName); } catch (RemoteException e) { Log.e(TAG, "RemoteException", e); return null; Loading services/java/com/android/server/LocationManagerService.java +23 −5 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import com.android.internal.location.ProviderRequest; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GpsLocationProvider; import com.android.server.location.LocationBlacklist; import com.android.server.location.LocationFudger; import com.android.server.location.LocationProviderInterface; import com.android.server.location.LocationProviderProxy; Loading Loading @@ -132,8 +133,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs private IGpsStatusProvider mGpsStatusProvider; private INetInitiatedListener mNetInitiatedListener; private LocationWorkerHandler mLocationHandler; // track the passive provider for some special cases private PassiveProvider mPassiveProvider; private PassiveProvider mPassiveProvider; // track passive provider for special cases private LocationBlacklist mBlacklist; // --- fields below are protected by mWakeLock --- private int mPendingBroadcasts; Loading Loading @@ -208,7 +209,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs synchronized (mLock) { loadProvidersLocked(); } mGeofenceManager = new GeofenceManager(mContext); mBlacklist = new LocationBlacklist(mContext, mLocationHandler); mBlacklist.init(); mGeofenceManager = new GeofenceManager(mContext, mBlacklist); mLocationFudger = new LocationFudger(); // Register for Network (Wifi or Mobile) updates Loading Loading @@ -1063,10 +1066,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs } @Override public Location getLastLocation(LocationRequest request) { public Location getLastLocation(LocationRequest request, String packageName) { if (D) Log.d(TAG, "getLastLocation: " + request); if (request == null) request = DEFAULT_LOCATION_REQUEST; String perm = checkPermissionAndRequest(request); checkPackageName(packageName); if (mBlacklist.isBlacklisted(packageName)) { if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + packageName); return null; } synchronized (mLock) { // Figure out the provider. Either its explicitly request (deprecated API's), Loading Loading @@ -1325,6 +1335,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs for (UpdateRecord r : records) { Receiver receiver = r.mReceiver; boolean receiverDead = false; if (mBlacklist.isBlacklisted(receiver.mPackageName)) { if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + receiver.mPackageName); continue; } if (ACCESS_FINE_LOCATION.equals(receiver.mPermission)) { location = lastLocation; // use fine location } else { Loading Loading @@ -1716,8 +1733,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs for (String i : mDisabledProviders) { pw.println(" " + i); } } pw.append(" "); mBlacklist.dump(pw); if (mMockProviders.size() > 0) { pw.println(" Mock Providers:"); for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { Loading services/java/com/android/server/location/GeofenceManager.java +13 −1 Original line number Diff line number Diff line Loading @@ -34,9 +34,13 @@ import android.os.Bundle; import android.os.Looper; import android.os.PowerManager; import android.os.SystemClock; import android.util.Log; import com.android.server.LocationManagerService; public class GeofenceManager implements LocationListener, PendingIntent.OnFinished { private static final String TAG = "GeofenceManager"; private static final boolean D = LocationManagerService.D; /** * Assume a maximum land speed, as a heuristic to throttle location updates. Loading @@ -49,6 +53,7 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish private final LocationManager mLocationManager; private final PowerManager.WakeLock mWakeLock; private final Looper mLooper; // looper thread to take location updates on private final LocationBlacklist mBlacklist; private Object mLock = new Object(); Loading @@ -56,12 +61,13 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish private Location mLastLocation; private List<GeofenceState> mFences = new LinkedList<GeofenceState>(); public GeofenceManager(Context context) { public GeofenceManager(Context context, LocationBlacklist blacklist) { mContext = context; mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mLooper = Looper.myLooper(); mBlacklist = blacklist; LocationRequest request = new LocationRequest() .setQuality(LocationRequest.POWER_NONE) Loading Loading @@ -145,6 +151,12 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish removeExpiredFencesLocked(); for (GeofenceState state : mFences) { if (mBlacklist.isBlacklisted(state.mPackageName)) { if (D) Log.d(TAG, "skipping geofence processing for blacklisted app: " + state.mPackageName); continue; } int event = state.processLocation(location); if ((event & GeofenceState.FLAG_ENTER) != 0) { enterIntents.add(state.mIntent); Loading services/java/com/android/server/location/LocationBlacklist.java 0 → 100644 +135 −0 Original line number 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.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]; public LocationBlacklist(Context context, Handler handler) { super(handler); mContext = context; } public void init() { mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( BLACKLIST_CONFIG_NAME), false, this); // mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( // WHITELIST_CONFIG_NAME), false, this); reloadBlacklist(); } private void reloadBlacklist() { String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME); String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME); synchronized (mLock) { mWhitelist = whitelist; Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist)); mBlacklist = blacklist; Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist)); } } /** * 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(); } private String[] getStringArray(String key) { String flatString = Settings.Secure.getString(mContext.getContentResolver(), key); 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)); } } Loading
location/java/android/location/ILocationManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ interface ILocationManager in PendingIntent intent, String packageName); void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName); Location getLastLocation(in LocationRequest request); Location getLastLocation(in LocationRequest request, String packageName); boolean addGpsStatusListener(IGpsStatusListener listener); void removeGpsStatusListener(IGpsStatusListener listener); Loading
location/java/android/location/LocationManager.java +5 −3 Original line number Diff line number Diff line Loading @@ -1174,8 +1174,10 @@ public class LocationManager { * @throws SecurityException if no suitable permission is present */ public Location getLastLocation() { String packageName = mContext.getPackageName(); try { return mService.getLastLocation(null); return mService.getLastLocation(null, packageName); } catch (RemoteException e) { Log.e(TAG, "RemoteException", e); return null; Loading Loading @@ -1204,12 +1206,12 @@ public class LocationManager { @Deprecated public Location getLastKnownLocation(String provider) { checkProvider(provider); String packageName = mContext.getPackageName(); LocationRequest request = LocationRequest.createFromDeprecatedProvider( provider, 0, 0, true); try { return mService.getLastLocation(request); return mService.getLastLocation(request, packageName); } catch (RemoteException e) { Log.e(TAG, "RemoteException", e); return null; Loading
services/java/com/android/server/LocationManagerService.java +23 −5 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ import com.android.internal.location.ProviderRequest; import com.android.server.location.GeocoderProxy; import com.android.server.location.GeofenceManager; import com.android.server.location.GpsLocationProvider; import com.android.server.location.LocationBlacklist; import com.android.server.location.LocationFudger; import com.android.server.location.LocationProviderInterface; import com.android.server.location.LocationProviderProxy; Loading Loading @@ -132,8 +133,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs private IGpsStatusProvider mGpsStatusProvider; private INetInitiatedListener mNetInitiatedListener; private LocationWorkerHandler mLocationHandler; // track the passive provider for some special cases private PassiveProvider mPassiveProvider; private PassiveProvider mPassiveProvider; // track passive provider for special cases private LocationBlacklist mBlacklist; // --- fields below are protected by mWakeLock --- private int mPendingBroadcasts; Loading Loading @@ -208,7 +209,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs synchronized (mLock) { loadProvidersLocked(); } mGeofenceManager = new GeofenceManager(mContext); mBlacklist = new LocationBlacklist(mContext, mLocationHandler); mBlacklist.init(); mGeofenceManager = new GeofenceManager(mContext, mBlacklist); mLocationFudger = new LocationFudger(); // Register for Network (Wifi or Mobile) updates Loading Loading @@ -1063,10 +1066,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs } @Override public Location getLastLocation(LocationRequest request) { public Location getLastLocation(LocationRequest request, String packageName) { if (D) Log.d(TAG, "getLastLocation: " + request); if (request == null) request = DEFAULT_LOCATION_REQUEST; String perm = checkPermissionAndRequest(request); checkPackageName(packageName); if (mBlacklist.isBlacklisted(packageName)) { if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + packageName); return null; } synchronized (mLock) { // Figure out the provider. Either its explicitly request (deprecated API's), Loading Loading @@ -1325,6 +1335,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs for (UpdateRecord r : records) { Receiver receiver = r.mReceiver; boolean receiverDead = false; if (mBlacklist.isBlacklisted(receiver.mPackageName)) { if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + receiver.mPackageName); continue; } if (ACCESS_FINE_LOCATION.equals(receiver.mPermission)) { location = lastLocation; // use fine location } else { Loading Loading @@ -1716,8 +1733,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs for (String i : mDisabledProviders) { pw.println(" " + i); } } pw.append(" "); mBlacklist.dump(pw); if (mMockProviders.size() > 0) { pw.println(" Mock Providers:"); for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { Loading
services/java/com/android/server/location/GeofenceManager.java +13 −1 Original line number Diff line number Diff line Loading @@ -34,9 +34,13 @@ import android.os.Bundle; import android.os.Looper; import android.os.PowerManager; import android.os.SystemClock; import android.util.Log; import com.android.server.LocationManagerService; public class GeofenceManager implements LocationListener, PendingIntent.OnFinished { private static final String TAG = "GeofenceManager"; private static final boolean D = LocationManagerService.D; /** * Assume a maximum land speed, as a heuristic to throttle location updates. Loading @@ -49,6 +53,7 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish private final LocationManager mLocationManager; private final PowerManager.WakeLock mWakeLock; private final Looper mLooper; // looper thread to take location updates on private final LocationBlacklist mBlacklist; private Object mLock = new Object(); Loading @@ -56,12 +61,13 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish private Location mLastLocation; private List<GeofenceState> mFences = new LinkedList<GeofenceState>(); public GeofenceManager(Context context) { public GeofenceManager(Context context, LocationBlacklist blacklist) { mContext = context; mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); mLooper = Looper.myLooper(); mBlacklist = blacklist; LocationRequest request = new LocationRequest() .setQuality(LocationRequest.POWER_NONE) Loading Loading @@ -145,6 +151,12 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish removeExpiredFencesLocked(); for (GeofenceState state : mFences) { if (mBlacklist.isBlacklisted(state.mPackageName)) { if (D) Log.d(TAG, "skipping geofence processing for blacklisted app: " + state.mPackageName); continue; } int event = state.processLocation(location); if ((event & GeofenceState.FLAG_ENTER) != 0) { enterIntents.add(state.mIntent); Loading
services/java/com/android/server/location/LocationBlacklist.java 0 → 100644 +135 −0 Original line number 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.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]; public LocationBlacklist(Context context, Handler handler) { super(handler); mContext = context; } public void init() { mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( BLACKLIST_CONFIG_NAME), false, this); // mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor( // WHITELIST_CONFIG_NAME), false, this); reloadBlacklist(); } private void reloadBlacklist() { String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME); String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME); synchronized (mLock) { mWhitelist = whitelist; Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist)); mBlacklist = blacklist; Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist)); } } /** * 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(); } private String[] getStringArray(String key) { String flatString = Settings.Secure.getString(mContext.getContentResolver(), key); 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)); } }