Add passive location provider.

The passive location provider allows receiving location updates without
actually triggering them.  This allows an application to receive location
updates that are being generated due to other clients of the location manager.

Change-Id: Ibf7a96b089c56875d4f62d3210252ae8d9f32768
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2010-02-17 06:42:23 -05:00
parent c6a0a9cb67
commit a4903f254b
9 changed files with 199 additions and 15 deletions

View File

@@ -71,6 +71,7 @@ import com.android.internal.location.GpsLocationProvider;
import com.android.internal.location.GpsNetInitiatedHandler;
import com.android.internal.location.LocationProviderProxy;
import com.android.internal.location.MockProvider;
import com.android.internal.location.PassiveProvider;
/**
* The service class that manages LocationProviders and issues location
@@ -452,6 +453,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mGpsLocationProvider = gpsProvider;
}
// create a passive location provider, which is always enabled
PassiveProvider passiveProvider = new PassiveProvider(this);
addProvider(passiveProvider);
mEnabledProviders.add(passiveProvider.getName());
// initialize external network location and geocoder services
Resources resources = mContext.getResources();
String serviceName = resources.getString(
@@ -538,7 +544,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
private void checkPermissionsSafe(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider)
if ((LocationManager.GPS_PROVIDER.equals(provider)
|| LocationManager.PASSIVE_PROVIDER.equals(provider))
&& (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
@@ -1343,7 +1350,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
public void reportLocation(Location location) {
public void reportLocation(Location location, boolean passive) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission");
@@ -1351,6 +1358,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location);
Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location);
m.arg1 = (passive ? 1 : 0);
mLocationHandler.sendMessageAtFrontOfQueue(m);
}
@@ -1415,8 +1423,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return true;
}
private void handleLocationChangedLocked(Location location) {
String provider = location.getProvider();
private void handleLocationChangedLocked(Location location, boolean passive) {
String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider());
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
if (records == null || records.size() == 0) {
return;
@@ -1502,17 +1510,20 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
synchronized (mLock) {
Location location = (Location) msg.obj;
String provider = location.getProvider();
boolean passive = (msg.arg1 == 1);
// notify other providers of the new location
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderInterface p = mProviders.get(i);
if (!provider.equals(p.getName())) {
p.updateLocation(location);
if (!passive) {
// notify other providers of the new location
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderInterface p = mProviders.get(i);
if (!provider.equals(p.getName())) {
p.updateLocation(location);
}
}
}
if (isAllowedBySettingsLocked(provider)) {
handleLocationChangedLocked(location);
handleLocationChangedLocked(location, passive);
}
}
}
@@ -1687,6 +1698,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
checkMockPermissionsSafe();
if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
throw new IllegalArgumentException("Cannot mock the passive location provider");
}
long identity = Binder.clearCallingIdentity();
synchronized (mLock) {
MockProvider provider = new MockProvider(name, this,