summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml11
-rw-r--r--location/java/android/location/ILocationManager.aidl6
-rw-r--r--location/java/android/location/LocationManager.java13
-rw-r--r--location/java/android/location/LocationProvider.java4
-rw-r--r--location/java/android/location/provider/LocationProvider.java2
-rwxr-xr-xlocation/java/com/android/internal/location/GpsLocationProvider.java2
-rw-r--r--location/java/com/android/internal/location/MockProvider.java2
-rw-r--r--location/java/com/android/internal/location/PassiveProvider.java139
-rw-r--r--services/java/com/android/server/LocationManagerService.java37
9 files changed, 200 insertions, 16 deletions
diff --git a/api/current.xml b/api/current.xml
index c3a7b26..444b002 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -78725,6 +78725,17 @@
visibility="public"
>
</field>
+<field name="PASSIVE_PROVIDER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;passive&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="LocationProvider"
extends="java.lang.Object"
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 8c24ee1..2c0399e 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -59,8 +59,10 @@ interface ILocationManager
Location getLastKnownLocation(String provider);
- /* used by location providers to tell the location manager when it has a new location */
- void reportLocation(in Location 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
+ // it need not be shared with other providers.
+ void reportLocation(in Location location, boolean passive);
String getFromLocation(double latitude, double longitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 9027fc2..da760a1 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -81,6 +81,19 @@ public class LocationManager {
public static final String GPS_PROVIDER = "gps";
/**
+ * A special location provider for receiving locations without actually initiating
+ * a location fix. This provider can be used to passively receive location updates
+ * when other applications or services request them without actually requesting
+ * the locations yourself. This provider will return locations generated by other
+ * providers. You can query the {@link Location#getProvider()} method to determine
+ * the origin of the location update.
+ *
+ * Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS
+ * is not enabled this provider might only return coarse fixes.
+ */
+ public static final String PASSIVE_PROVIDER = "passive";
+
+ /**
* Key used for the Bundle extra holding a boolean indicating whether
* a proximity alert is entering (true) or exiting (false)..
*/
diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java
index 3faba58..bb3e2a5 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -71,6 +71,10 @@ public abstract class LocationProvider {
* false otherwise.
*/
public boolean meetsCriteria(Criteria criteria) {
+ // We do not want to match the special passive provider based on criteria.
+ if (LocationManager.PASSIVE_PROVIDER.equals(mName)) {
+ return false;
+ }
if ((criteria.getAccuracy() != Criteria.NO_REQUIREMENT) &&
(criteria.getAccuracy() < getAccuracy())) {
return false;
diff --git a/location/java/android/location/provider/LocationProvider.java b/location/java/android/location/provider/LocationProvider.java
index 0d028c0..4163def 100644
--- a/location/java/android/location/provider/LocationProvider.java
+++ b/location/java/android/location/provider/LocationProvider.java
@@ -156,7 +156,7 @@ public abstract class LocationProvider {
*/
public void reportLocation(Location location) {
try {
- mLocationManager.reportLocation(location);
+ mLocationManager.reportLocation(location, false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in reportLocation: ", e);
}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index dce3b27..8e84106 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -863,7 +863,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
}
try {
- mLocationManager.reportLocation(mLocation);
+ mLocationManager.reportLocation(mLocation, false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index 2f6fdee..bc1893e 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -143,7 +143,7 @@ public class MockProvider implements LocationProviderInterface {
mLocation.set(l);
mHasLocation = true;
try {
- mLocationManager.reportLocation(mLocation);
+ mLocationManager.reportLocation(mLocation, false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}
diff --git a/location/java/com/android/internal/location/PassiveProvider.java b/location/java/com/android/internal/location/PassiveProvider.java
new file mode 100644
index 0000000..7eb711d
--- /dev/null
+++ b/location/java/com/android/internal/location/PassiveProvider.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 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.internal.location;
+
+import android.location.ILocationManager;
+import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.location.LocationProviderInterface;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A passive location provider reports locations received from other providers
+ * for clients that want to listen passively without actually triggering
+ * location updates.
+ *
+ * {@hide}
+ */
+public class PassiveProvider implements LocationProviderInterface {
+
+ private static final String TAG = "PassiveProvider";
+
+ private final ILocationManager mLocationManager;
+ private boolean mTracking;
+
+ public PassiveProvider(ILocationManager locationManager) {
+ mLocationManager = locationManager;
+ }
+
+ public String getName() {
+ return LocationManager.PASSIVE_PROVIDER;
+ }
+
+ public boolean requiresNetwork() {
+ return false;
+ }
+
+ public boolean requiresSatellite() {
+ return false;
+ }
+
+ public boolean requiresCell() {
+ return false;
+ }
+
+ public boolean hasMonetaryCost() {
+ return false;
+ }
+
+ public boolean supportsAltitude() {
+ return false;
+ }
+
+ public boolean supportsSpeed() {
+ return false;
+ }
+
+ public boolean supportsBearing() {
+ return false;
+ }
+
+ public int getPowerRequirement() {
+ return -1;
+ }
+
+ public int getAccuracy() {
+ return -1;
+ }
+
+ public boolean isEnabled() {
+ return true;
+ }
+
+ public void enable() {
+ }
+
+ public void disable() {
+ }
+
+ public int getStatus(Bundle extras) {
+ if (mTracking) {
+ return LocationProvider.AVAILABLE;
+ } else {
+ return LocationProvider.TEMPORARILY_UNAVAILABLE;
+ }
+ }
+
+ public long getStatusUpdateTime() {
+ return -1;
+ }
+
+ public void enableLocationTracking(boolean enable) {
+ mTracking = enable;
+ }
+
+ public void setMinTime(long minTime) {
+ }
+
+ public void updateNetworkState(int state, NetworkInfo info) {
+ }
+
+ public void updateLocation(Location location) {
+ if (mTracking) {
+ try {
+ // pass the location back to the location manager
+ mLocationManager.reportLocation(location, true);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling reportLocation");
+ }
+ }
+ }
+
+ public boolean sendExtraCommand(String command, Bundle extras) {
+ return false;
+ }
+
+ public void addListener(int uid) {
+ }
+
+ public void removeListener(int uid) {
+ }
+}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index e12f2e1..9068966 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -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();
-
- // 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);
+ boolean passive = (msg.arg1 == 1);
+
+ 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,