am 1af5ac1b: Merge "DO NOT MERGE. Add package-name-prefix blacklist for location updates." into jb-dev
* commit '1af5ac1b6801c4da2ef689449fd1fd2eba1ff48e': DO NOT MERGE. Add package-name-prefix blacklist for location updates.
This commit is contained in:
@@ -361,10 +361,10 @@ class ContextImpl extends Context {
|
|||||||
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
|
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
|
||||||
}});
|
}});
|
||||||
|
|
||||||
registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
|
registerService(LOCATION_SERVICE, new ServiceFetcher() {
|
||||||
public Object createStaticService() {
|
public Object createService(ContextImpl ctx) {
|
||||||
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
|
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
|
||||||
return new LocationManager(ILocationManager.Stub.asInterface(b));
|
return new LocationManager(ctx, ILocationManager.Stub.asInterface(b));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
|
registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ interface ILocationManager
|
|||||||
boolean providerMeetsCriteria(String provider, in Criteria criteria);
|
boolean providerMeetsCriteria(String provider, in Criteria criteria);
|
||||||
|
|
||||||
void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
|
void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
|
||||||
boolean singleShot, in ILocationListener listener);
|
boolean singleShot, in ILocationListener listener, String packageName);
|
||||||
void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
|
void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
|
||||||
boolean singleShot, in PendingIntent intent);
|
boolean singleShot, in PendingIntent intent, String packageName);
|
||||||
void removeUpdates(in ILocationListener listener);
|
void removeUpdates(in ILocationListener listener, String packageName);
|
||||||
void removeUpdatesPI(in PendingIntent intent);
|
void removeUpdatesPI(in PendingIntent intent, String packageName);
|
||||||
|
|
||||||
boolean addGpsStatusListener(IGpsStatusListener listener);
|
boolean addGpsStatusListener(IGpsStatusListener listener);
|
||||||
void removeGpsStatusListener(IGpsStatusListener listener);
|
void removeGpsStatusListener(IGpsStatusListener listener);
|
||||||
@@ -54,13 +54,13 @@ interface ILocationManager
|
|||||||
boolean sendExtraCommand(String provider, String command, inout Bundle extras);
|
boolean sendExtraCommand(String provider, String command, inout Bundle extras);
|
||||||
|
|
||||||
void addProximityAlert(double latitude, double longitude, float distance,
|
void addProximityAlert(double latitude, double longitude, float distance,
|
||||||
long expiration, in PendingIntent intent);
|
long expiration, in PendingIntent intent, String packageName);
|
||||||
void removeProximityAlert(in PendingIntent intent);
|
void removeProximityAlert(in PendingIntent intent);
|
||||||
|
|
||||||
Bundle getProviderInfo(String provider);
|
Bundle getProviderInfo(String provider);
|
||||||
boolean isProviderEnabled(String provider);
|
boolean isProviderEnabled(String provider);
|
||||||
|
|
||||||
Location getLastKnownLocation(String provider);
|
Location getLastKnownLocation(String provider, String packageName);
|
||||||
|
|
||||||
// Used by location providers to tell the location manager when it has a new location.
|
// Used by location providers to tell the location manager when it has a new location.
|
||||||
// Passive is true if the location is coming from the passive provider, in which case
|
// Passive is true if the location is coming from the passive provider, in which case
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package android.location;
|
package android.location;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -160,6 +161,8 @@ public class LocationManager {
|
|||||||
*/
|
*/
|
||||||
public static final String EXTRA_GPS_ENABLED = "enabled";
|
public static final String EXTRA_GPS_ENABLED = "enabled";
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
// Map from LocationListeners to their associated ListenerTransport objects
|
// Map from LocationListeners to their associated ListenerTransport objects
|
||||||
private HashMap<LocationListener,ListenerTransport> mListeners =
|
private HashMap<LocationListener,ListenerTransport> mListeners =
|
||||||
new HashMap<LocationListener,ListenerTransport>();
|
new HashMap<LocationListener,ListenerTransport>();
|
||||||
@@ -260,8 +263,9 @@ public class LocationManager {
|
|||||||
* right way to create an instance of this class is using the
|
* right way to create an instance of this class is using the
|
||||||
* factory Context.getSystemService.
|
* factory Context.getSystemService.
|
||||||
*/
|
*/
|
||||||
public LocationManager(ILocationManager service) {
|
public LocationManager(Context context, ILocationManager service) {
|
||||||
mService = service;
|
mService = service;
|
||||||
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocationProvider createProvider(String name, Bundle info) {
|
private LocationProvider createProvider(String name, Bundle info) {
|
||||||
@@ -657,7 +661,8 @@ public class LocationManager {
|
|||||||
transport = new ListenerTransport(listener, looper);
|
transport = new ListenerTransport(listener, looper);
|
||||||
}
|
}
|
||||||
mListeners.put(listener, transport);
|
mListeners.put(listener, transport);
|
||||||
mService.requestLocationUpdates(provider, criteria, minTime, minDistance, singleShot, transport);
|
mService.requestLocationUpdates(provider, criteria, minTime, minDistance,
|
||||||
|
singleShot, transport, mContext.getPackageName());
|
||||||
}
|
}
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "requestLocationUpdates: DeadObjectException", ex);
|
Log.e(TAG, "requestLocationUpdates: DeadObjectException", ex);
|
||||||
@@ -837,7 +842,8 @@ public class LocationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mService.requestLocationUpdatesPI(provider, criteria, minTime, minDistance, singleShot, intent);
|
mService.requestLocationUpdatesPI(provider, criteria, minTime, minDistance, singleShot,
|
||||||
|
intent, mContext.getPackageName());
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "requestLocationUpdates: RemoteException", ex);
|
Log.e(TAG, "requestLocationUpdates: RemoteException", ex);
|
||||||
}
|
}
|
||||||
@@ -1005,7 +1011,7 @@ public class LocationManager {
|
|||||||
try {
|
try {
|
||||||
ListenerTransport transport = mListeners.remove(listener);
|
ListenerTransport transport = mListeners.remove(listener);
|
||||||
if (transport != null) {
|
if (transport != null) {
|
||||||
mService.removeUpdates(transport);
|
mService.removeUpdates(transport, mContext.getPackageName());
|
||||||
}
|
}
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "removeUpdates: DeadObjectException", ex);
|
Log.e(TAG, "removeUpdates: DeadObjectException", ex);
|
||||||
@@ -1028,7 +1034,7 @@ public class LocationManager {
|
|||||||
Log.d(TAG, "removeUpdates: intent = " + intent);
|
Log.d(TAG, "removeUpdates: intent = " + intent);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mService.removeUpdatesPI(intent);
|
mService.removeUpdatesPI(intent, mContext.getPackageName());
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "removeUpdates: RemoteException", ex);
|
Log.e(TAG, "removeUpdates: RemoteException", ex);
|
||||||
}
|
}
|
||||||
@@ -1087,7 +1093,7 @@ public class LocationManager {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mService.addProximityAlert(latitude, longitude, radius,
|
mService.addProximityAlert(latitude, longitude, radius,
|
||||||
expiration, intent);
|
expiration, intent, mContext.getPackageName());
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "addProximityAlert: RemoteException", ex);
|
Log.e(TAG, "addProximityAlert: RemoteException", ex);
|
||||||
}
|
}
|
||||||
@@ -1153,7 +1159,7 @@ public class LocationManager {
|
|||||||
throw new IllegalArgumentException("provider==null");
|
throw new IllegalArgumentException("provider==null");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return mService.getLastKnownLocation(provider);
|
return mService.getLastKnownLocation(provider, mContext.getPackageName());
|
||||||
} catch (RemoteException ex) {
|
} catch (RemoteException ex) {
|
||||||
Log.e(TAG, "getLastKnowLocation: RemoteException", ex);
|
Log.e(TAG, "getLastKnowLocation: RemoteException", ex);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.content.pm.ResolveInfo;
|
|||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
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.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.location.Address;
|
import android.location.Address;
|
||||||
import android.location.Criteria;
|
import android.location.Criteria;
|
||||||
@@ -79,6 +80,8 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
@@ -109,6 +112,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
private static final String INSTALL_LOCATION_PROVIDER =
|
private static final String INSTALL_LOCATION_PROVIDER =
|
||||||
android.Manifest.permission.INSTALL_LOCATION_PROVIDER;
|
android.Manifest.permission.INSTALL_LOCATION_PROVIDER;
|
||||||
|
|
||||||
|
private static final String BLACKLIST_CONFIG_NAME = "locationPackagePrefixBlacklist";
|
||||||
|
private static final String WHITELIST_CONFIG_NAME = "locationPackagePrefixWhitelist";
|
||||||
|
|
||||||
// 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
|
||||||
@@ -193,6 +199,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
|
|
||||||
private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
||||||
|
|
||||||
|
// for prefix blacklist
|
||||||
|
private String[] mWhitelist = new String[0];
|
||||||
|
private String[] mBlacklist = new String[0];
|
||||||
|
|
||||||
// for Settings change notification
|
// for Settings change notification
|
||||||
private ContentQueryMap mSettings;
|
private ContentQueryMap mSettings;
|
||||||
|
|
||||||
@@ -205,20 +215,23 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
final PendingIntent mPendingIntent;
|
final PendingIntent mPendingIntent;
|
||||||
final Object mKey;
|
final Object mKey;
|
||||||
final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
|
final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
|
||||||
|
final String mPackageName;
|
||||||
|
|
||||||
int mPendingBroadcasts;
|
int mPendingBroadcasts;
|
||||||
String mRequiredPermissions;
|
String mRequiredPermissions;
|
||||||
|
|
||||||
Receiver(ILocationListener listener) {
|
Receiver(ILocationListener listener, String packageName) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
mPendingIntent = null;
|
mPendingIntent = null;
|
||||||
mKey = listener.asBinder();
|
mKey = listener.asBinder();
|
||||||
|
mPackageName = packageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Receiver(PendingIntent intent) {
|
Receiver(PendingIntent intent, String packageName) {
|
||||||
mPendingIntent = intent;
|
mPendingIntent = intent;
|
||||||
mListener = null;
|
mListener = null;
|
||||||
mKey = intent;
|
mKey = intent;
|
||||||
|
mPackageName = packageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -601,6 +614,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
|
|
||||||
// Load providers
|
// Load providers
|
||||||
loadProviders();
|
loadProviders();
|
||||||
|
loadBlacklist();
|
||||||
|
|
||||||
// Register for Network (Wifi or Mobile) updates
|
// Register for Network (Wifi or Mobile) updates
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
@@ -1110,11 +1124,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Receiver getReceiver(ILocationListener listener) {
|
private Receiver getReceiver(ILocationListener listener, String packageName) {
|
||||||
IBinder binder = listener.asBinder();
|
IBinder binder = listener.asBinder();
|
||||||
Receiver receiver = mReceivers.get(binder);
|
Receiver receiver = mReceivers.get(binder);
|
||||||
if (receiver == null) {
|
if (receiver == null) {
|
||||||
receiver = new Receiver(listener);
|
receiver = new Receiver(listener, packageName);
|
||||||
mReceivers.put(binder, receiver);
|
mReceivers.put(binder, receiver);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1129,10 +1143,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
return receiver;
|
return receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Receiver getReceiver(PendingIntent intent) {
|
private Receiver getReceiver(PendingIntent intent, String packageName) {
|
||||||
Receiver receiver = mReceivers.get(intent);
|
Receiver receiver = mReceivers.get(intent);
|
||||||
if (receiver == null) {
|
if (receiver == null) {
|
||||||
receiver = new Receiver(intent);
|
receiver = new Receiver(intent, packageName);
|
||||||
mReceivers.put(intent, receiver);
|
mReceivers.put(intent, receiver);
|
||||||
}
|
}
|
||||||
return receiver;
|
return receiver;
|
||||||
@@ -1157,7 +1171,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void requestLocationUpdates(String provider, Criteria criteria,
|
public void requestLocationUpdates(String provider, Criteria criteria,
|
||||||
long minTime, float minDistance, boolean singleShot, ILocationListener listener) {
|
long minTime, float minDistance, boolean singleShot, ILocationListener listener,
|
||||||
|
String packageName) {
|
||||||
|
checkPackageName(Binder.getCallingUid(), packageName);
|
||||||
if (criteria != null) {
|
if (criteria != null) {
|
||||||
// FIXME - should we consider using multiple providers simultaneously
|
// FIXME - should we consider using multiple providers simultaneously
|
||||||
// rather than only the best one?
|
// rather than only the best one?
|
||||||
@@ -1170,7 +1186,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
requestLocationUpdatesLocked(provider, minTime, minDistance, singleShot,
|
requestLocationUpdatesLocked(provider, minTime, minDistance, singleShot,
|
||||||
getReceiver(listener));
|
getReceiver(listener, packageName));
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1194,7 +1210,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void requestLocationUpdatesPI(String provider, Criteria criteria,
|
public void requestLocationUpdatesPI(String provider, Criteria criteria,
|
||||||
long minTime, float minDistance, boolean singleShot, PendingIntent intent) {
|
long minTime, float minDistance, boolean singleShot, PendingIntent intent,
|
||||||
|
String packageName) {
|
||||||
|
checkPackageName(Binder.getCallingUid(), packageName);
|
||||||
validatePendingIntent(intent);
|
validatePendingIntent(intent);
|
||||||
if (criteria != null) {
|
if (criteria != null) {
|
||||||
// FIXME - should we consider using multiple providers simultaneously
|
// FIXME - should we consider using multiple providers simultaneously
|
||||||
@@ -1208,7 +1226,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
requestLocationUpdatesLocked(provider, minTime, minDistance, singleShot,
|
requestLocationUpdatesLocked(provider, minTime, minDistance, singleShot,
|
||||||
getReceiver(intent));
|
getReceiver(intent, packageName));
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1270,10 +1288,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeUpdates(ILocationListener listener) {
|
public void removeUpdates(ILocationListener listener, String packageName) {
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
removeUpdatesLocked(getReceiver(listener));
|
removeUpdatesLocked(getReceiver(listener, packageName));
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1284,10 +1302,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeUpdatesPI(PendingIntent intent) {
|
public void removeUpdatesPI(PendingIntent intent, String packageName) {
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
removeUpdatesLocked(getReceiver(intent));
|
removeUpdatesLocked(getReceiver(intent, packageName));
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1446,15 +1464,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
final long mExpiration;
|
final long mExpiration;
|
||||||
final PendingIntent mIntent;
|
final PendingIntent mIntent;
|
||||||
final Location mLocation;
|
final Location mLocation;
|
||||||
|
final String mPackageName;
|
||||||
|
|
||||||
public ProximityAlert(int uid, double latitude, double longitude,
|
public ProximityAlert(int uid, double latitude, double longitude,
|
||||||
float radius, long expiration, PendingIntent intent) {
|
float radius, long expiration, PendingIntent intent, String packageName) {
|
||||||
mUid = uid;
|
mUid = uid;
|
||||||
mLatitude = latitude;
|
mLatitude = latitude;
|
||||||
mLongitude = longitude;
|
mLongitude = longitude;
|
||||||
mRadius = radius;
|
mRadius = radius;
|
||||||
mExpiration = expiration;
|
mExpiration = expiration;
|
||||||
mIntent = intent;
|
mIntent = intent;
|
||||||
|
mPackageName = packageName;
|
||||||
|
|
||||||
mLocation = new Location("");
|
mLocation = new Location("");
|
||||||
mLocation.setLatitude(latitude);
|
mLocation.setLatitude(latitude);
|
||||||
@@ -1522,6 +1542,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
PendingIntent intent = alert.getIntent();
|
PendingIntent intent = alert.getIntent();
|
||||||
long expiration = alert.getExpiration();
|
long expiration = alert.getExpiration();
|
||||||
|
|
||||||
|
if (inBlacklist(alert.mPackageName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((expiration == -1) || (now <= expiration)) {
|
if ((expiration == -1) || (now <= expiration)) {
|
||||||
boolean entered = mProximitiesEntered.contains(alert);
|
boolean entered = mProximitiesEntered.contains(alert);
|
||||||
boolean inProximity =
|
boolean inProximity =
|
||||||
@@ -1632,11 +1656,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addProximityAlert(double latitude, double longitude,
|
public void addProximityAlert(double latitude, double longitude,
|
||||||
float radius, long expiration, PendingIntent intent) {
|
float radius, long expiration, PendingIntent intent, String packageName) {
|
||||||
validatePendingIntent(intent);
|
validatePendingIntent(intent);
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
addProximityAlertLocked(latitude, longitude, radius, expiration, intent);
|
addProximityAlertLocked(latitude, longitude, radius, expiration, intent,
|
||||||
|
packageName);
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1648,7 +1673,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addProximityAlertLocked(double latitude, double longitude,
|
private void addProximityAlertLocked(double latitude, double longitude,
|
||||||
float radius, long expiration, PendingIntent intent) {
|
float radius, long expiration, PendingIntent intent, String packageName) {
|
||||||
if (LOCAL_LOGV) {
|
if (LOCAL_LOGV) {
|
||||||
Slog.v(TAG, "addProximityAlert: latitude = " + latitude +
|
Slog.v(TAG, "addProximityAlert: latitude = " + latitude +
|
||||||
", longitude = " + longitude +
|
", longitude = " + longitude +
|
||||||
@@ -1656,6 +1681,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
", intent = " + intent);
|
", intent = " + intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkPackageName(Binder.getCallingUid(), packageName);
|
||||||
|
|
||||||
// Require ability to access all providers for now
|
// Require ability to access all providers for now
|
||||||
if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) ||
|
if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) ||
|
||||||
!isAllowedProviderSafe(LocationManager.NETWORK_PROVIDER)) {
|
!isAllowedProviderSafe(LocationManager.NETWORK_PROVIDER)) {
|
||||||
@@ -1666,12 +1693,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
expiration += System.currentTimeMillis();
|
expiration += System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(),
|
ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(),
|
||||||
latitude, longitude, radius, expiration, intent);
|
latitude, longitude, radius, expiration, intent, packageName);
|
||||||
mProximityAlerts.put(intent, alert);
|
mProximityAlerts.put(intent, alert);
|
||||||
|
|
||||||
if (mProximityReceiver == null) {
|
if (mProximityReceiver == null) {
|
||||||
mProximityListener = new ProximityListener();
|
mProximityListener = new ProximityListener();
|
||||||
mProximityReceiver = new Receiver(mProximityListener);
|
mProximityReceiver = new Receiver(mProximityListener, packageName);
|
||||||
|
|
||||||
for (int i = mProviders.size() - 1; i >= 0; i--) {
|
for (int i = mProviders.size() - 1; i >= 0; i--) {
|
||||||
LocationProviderInterface provider = mProviders.get(i);
|
LocationProviderInterface provider = mProviders.get(i);
|
||||||
@@ -1787,13 +1814,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
return isAllowedBySettingsLocked(provider);
|
return isAllowedBySettingsLocked(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getLastKnownLocation(String provider) {
|
public Location getLastKnownLocation(String provider, String packageName) {
|
||||||
if (LOCAL_LOGV) {
|
if (LOCAL_LOGV) {
|
||||||
Slog.v(TAG, "getLastKnownLocation: " + provider);
|
Slog.v(TAG, "getLastKnownLocation: " + provider);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
return _getLastKnownLocationLocked(provider);
|
return _getLastKnownLocationLocked(provider, packageName);
|
||||||
}
|
}
|
||||||
} catch (SecurityException se) {
|
} catch (SecurityException se) {
|
||||||
throw se;
|
throw se;
|
||||||
@@ -1803,8 +1830,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Location _getLastKnownLocationLocked(String provider) {
|
private Location _getLastKnownLocationLocked(String provider, String packageName) {
|
||||||
checkPermissionsSafe(provider, null);
|
checkPermissionsSafe(provider, null);
|
||||||
|
checkPackageName(Binder.getCallingUid(), packageName);
|
||||||
|
|
||||||
LocationProviderInterface p = mProvidersByName.get(provider);
|
LocationProviderInterface p = mProvidersByName.get(provider);
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
@@ -1815,6 +1843,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inBlacklist(packageName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return mLastKnownLocation.get(provider);
|
return mLastKnownLocation.get(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1877,6 +1909,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
Receiver receiver = r.mReceiver;
|
Receiver receiver = r.mReceiver;
|
||||||
boolean receiverDead = false;
|
boolean receiverDead = false;
|
||||||
|
|
||||||
|
if (inBlacklist(receiver.mPackageName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Location lastLoc = r.mLastFixBroadcast;
|
Location lastLoc = r.mLastFixBroadcast;
|
||||||
if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) {
|
if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) {
|
||||||
if (lastLoc == null) {
|
if (lastLoc == null) {
|
||||||
@@ -2315,6 +2351,113 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BlacklistObserver extends ContentObserver {
|
||||||
|
public BlacklistObserver(Handler handler) {
|
||||||
|
super(handler);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
reloadBlacklist();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadBlacklist() {
|
||||||
|
// Register for changes
|
||||||
|
BlacklistObserver observer = new BlacklistObserver(mLocationHandler);
|
||||||
|
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
|
||||||
|
BLACKLIST_CONFIG_NAME), false, observer);
|
||||||
|
mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
|
||||||
|
WHITELIST_CONFIG_NAME), false, observer);
|
||||||
|
reloadBlacklist();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reloadBlacklist() {
|
||||||
|
String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME);
|
||||||
|
String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME);
|
||||||
|
synchronized (mLock) {
|
||||||
|
mWhitelist = whitelist;
|
||||||
|
Slog.i(TAG, "whitelist: " + arrayToString(mWhitelist));
|
||||||
|
mBlacklist = blacklist;
|
||||||
|
Slog.i(TAG, "blacklist: " + arrayToString(mBlacklist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String arrayToString(String[] array) {
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
s.append('[');
|
||||||
|
boolean first = true;
|
||||||
|
for (String a : array) {
|
||||||
|
if (!first) s.append(',');
|
||||||
|
first = false;
|
||||||
|
s.append(a);
|
||||||
|
}
|
||||||
|
s.append(']');
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
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()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if in blacklist, and not in whitelist.
|
||||||
|
*/
|
||||||
|
private boolean inBlacklist(String packageName) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
for (String black : mBlacklist) {
|
||||||
|
if (packageName.startsWith(black)) {
|
||||||
|
if (inWhitelist(packageName)) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (LOCAL_LOGV) 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPackageName(int uid, String packageName) {
|
||||||
|
if (packageName == null) {
|
||||||
|
throw new SecurityException("packageName cannot be null");
|
||||||
|
}
|
||||||
|
String[] packages = mPackageManager.getPackagesForUid(uid);
|
||||||
|
if (packages == null) {
|
||||||
|
throw new SecurityException("invalid UID " + uid);
|
||||||
|
}
|
||||||
|
for (String pkg : packages) {
|
||||||
|
if (packageName.equals(pkg)) return;
|
||||||
|
}
|
||||||
|
throw new SecurityException("invalid package name");
|
||||||
|
}
|
||||||
|
|
||||||
private void log(String log) {
|
private void log(String log) {
|
||||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||||
Slog.d(TAG, log);
|
Slog.d(TAG, log);
|
||||||
@@ -2346,6 +2489,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
|
|||||||
j.getValue().dump(pw, " ");
|
j.getValue().dump(pw, " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pw.println(" Package blacklist:" + arrayToString(mBlacklist));
|
||||||
|
pw.println(" Package whitelist:" + arrayToString(mWhitelist));
|
||||||
pw.println(" Records by Provider:");
|
pw.println(" Records by Provider:");
|
||||||
for (Map.Entry<String, ArrayList<UpdateRecord>> i
|
for (Map.Entry<String, ArrayList<UpdateRecord>> i
|
||||||
: mRecordsByProvider.entrySet()) {
|
: mRecordsByProvider.entrySet()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user