location: Use ILocationProvider Binder interface for all location providers.
This change eliminates the LocationProviderImpl class which had been used
for location providers running in the system process.
Now the LocationProvider base class is only used to implement the
LocationManager.createProvider() method for retrieving provider information.
Added a new IGpsStatusProvider interface for providers that serve GPS status.
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/Android.mk b/Android.mk
index 82a8735..84d3317 100644
--- a/Android.mk
+++ b/Android.mk
@@ -116,6 +116,7 @@
im/java/android/im/IImPlugin.aidl \
location/java/android/location/IGeocodeProvider.aidl \
location/java/android/location/IGpsStatusListener.aidl \
+ location/java/android/location/IGpsStatusProvider.aidl \
location/java/android/location/ILocationCollector.aidl \
location/java/android/location/ILocationListener.aidl \
location/java/android/location/ILocationManager.aidl \
diff --git a/location/java/android/location/IGpsStatusProvider.aidl b/location/java/android/location/IGpsStatusProvider.aidl
new file mode 100644
index 0000000..cf277c8
--- /dev/null
+++ b/location/java/android/location/IGpsStatusProvider.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009 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 android.location;
+
+import android.location.IGpsStatusListener;
+
+/**
+ * An interface for location providers that provide GPS status information.
+ *
+ * {@hide}
+ */
+interface IGpsStatusProvider {
+ void addGpsStatusListener(IGpsStatusListener listener);
+ void removeGpsStatusListener(IGpsStatusListener listener);
+}
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index 82533a5..e3e374d 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -19,13 +19,11 @@
import android.os.Bundle;
/**
- * An interface for location providers implemented outside of the system process.
+ * Binder interface for location providers.
*
* {@hide}
*/
interface ILocationProvider {
-
- /* for LocationProvider */
boolean requiresNetwork();
boolean requiresSatellite();
boolean requiresCell();
@@ -35,8 +33,6 @@
boolean supportsBearing();
int getPowerRequirement();
int getAccuracy();
-
- /* for LocationProviderImpl */
void enable();
void disable();
boolean isEnabled();
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 57d3c53..693848b 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -22,7 +22,9 @@
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.IGpsStatusListener;
+import android.location.IGpsStatusProvider;
import android.location.ILocationManager;
+import android.location.ILocationProvider;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
@@ -54,7 +56,7 @@
*
* {@hide}
*/
-public class GpsLocationProvider extends LocationProviderImpl {
+public class GpsLocationProvider extends ILocationProvider.Stub {
private static final String TAG = "GpsLocationProvider";
@@ -142,7 +144,7 @@
private int mLocationFlags = LOCATION_INVALID;
// current status
- private int mStatus = TEMPORARILY_UNAVAILABLE;
+ private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
// time for last status update
private long mStatusUpdateTime = SystemClock.elapsedRealtime();
@@ -178,7 +180,8 @@
private Properties mProperties;
private String mNtpServer;
- private Context mContext;
+ private final Context mContext;
+ private final ILocationManager mLocationManager;
private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
private Bundle mLocationExtras = new Bundle();
private ArrayList<Listener> mListeners = new ArrayList<Listener>();
@@ -203,6 +206,57 @@
// current setting - 5 minutes
private static final long RETRY_INTERVAL = 5*60*1000;
+ private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() {
+ public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
+ if (listener == null) {
+ throw new NullPointerException("listener is null in addGpsStatusListener");
+ }
+
+ synchronized(mListeners) {
+ IBinder binder = listener.asBinder();
+ int size = mListeners.size();
+ for (int i = 0; i < size; i++) {
+ Listener test = mListeners.get(i);
+ if (binder.equals(test.mListener.asBinder())) {
+ // listener already added
+ return;
+ }
+ }
+
+ Listener l = new Listener(listener);
+ binder.linkToDeath(l, 0);
+ mListeners.add(l);
+ }
+ }
+
+ public void removeGpsStatusListener(IGpsStatusListener listener) {
+ if (listener == null) {
+ throw new NullPointerException("listener is null in addGpsStatusListener");
+ }
+
+ synchronized(mListeners) {
+ IBinder binder = listener.asBinder();
+ Listener l = null;
+ int size = mListeners.size();
+ for (int i = 0; i < size && l == null; i++) {
+ Listener test = mListeners.get(i);
+ if (binder.equals(test.mListener.asBinder())) {
+ l = test;
+ }
+ }
+
+ if (l != null) {
+ mListeners.remove(l);
+ binder.unlinkToDeath(l, 0);
+ }
+ }
+ }
+ };
+
+ public IGpsStatusProvider getGpsStatusProvider() {
+ return mGpsStatusProvider;
+ }
+
private class TelephonyBroadcastReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -231,8 +285,8 @@
}
public GpsLocationProvider(Context context, ILocationManager locationManager) {
- super(LocationManager.GPS_PROVIDER, locationManager);
mContext = context;
+ mLocationManager = locationManager;
TelephonyBroadcastReceiver receiver = new TelephonyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
@@ -270,7 +324,6 @@
* Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise.
*/
- @Override
public boolean requiresNetwork() {
// We want updateNetworkState() to get called when the network state changes
// for XTRA and NTP time injection support.
@@ -295,7 +348,6 @@
* satellite-based positioning system (e.g., GPS), false
* otherwise.
*/
- @Override
public boolean requiresSatellite() {
return true;
}
@@ -305,7 +357,6 @@
* cellular network (e.g., to make use of cell tower IDs), false
* otherwise.
*/
- @Override
public boolean requiresCell() {
return false;
}
@@ -315,7 +366,6 @@
* monetary charge to the user, false if use is free. It is up to
* each provider to give accurate information.
*/
- @Override
public boolean hasMonetaryCost() {
return false;
}
@@ -326,7 +376,6 @@
* under most circumstances but may occassionally not report it
* should return true.
*/
- @Override
public boolean supportsAltitude() {
return true;
}
@@ -337,7 +386,6 @@
* under most circumstances but may occassionally not report it
* should return true.
*/
- @Override
public boolean supportsSpeed() {
return true;
}
@@ -348,7 +396,6 @@
* under most circumstances but may occassionally not report it
* should return true.
*/
- @Override
public boolean supportsBearing() {
return true;
}
@@ -359,7 +406,6 @@
* @return the power requirement for this provider, as one of the
* constants Criteria.POWER_REQUIREMENT_*.
*/
- @Override
public int getPowerRequirement() {
return Criteria.POWER_HIGH;
}
@@ -370,7 +416,6 @@
* @return the accuracy of location from this provider, as one
* of the constants Criteria.ACCURACY_*.
*/
- @Override
public int getAccuracy() {
return Criteria.ACCURACY_FINE;
}
@@ -380,7 +425,6 @@
* must be handled. Hardware may be started up
* when the provider is enabled.
*/
- @Override
public synchronized void enable() {
if (Config.LOGD) Log.d(TAG, "enable");
if (mEnabled) return;
@@ -410,7 +454,6 @@
* need not be handled. Hardware may be shut
* down while the provider is disabled.
*/
- @Override
public synchronized void disable() {
if (Config.LOGD) Log.d(TAG, "disable");
if (!mEnabled) return;
@@ -443,12 +486,10 @@
native_cleanup();
}
- @Override
public boolean isEnabled() {
return mEnabled;
}
- @Override
public int getStatus(Bundle extras) {
if (extras != null) {
extras.putInt("satellites", mSvCount);
@@ -465,14 +506,11 @@
}
}
- @Override
public long getStatusUpdateTime() {
return mStatusUpdateTime;
}
- @Override
public void enableLocationTracking(boolean enable) {
- super.enableLocationTracking(enable);
if (enable) {
mFixRequestTime = System.currentTimeMillis();
mTTFF = 0;
@@ -483,9 +521,7 @@
}
}
- @Override
public void setMinTime(long minTime) {
- super.setMinTime(minTime);
if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime);
if (minTime >= 0) {
@@ -516,48 +552,12 @@
}
}
- public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException {
- if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener");
-
- synchronized(mListeners) {
- IBinder binder = listener.asBinder();
- int size = mListeners.size();
- for (int i = 0; i < size; i++) {
- Listener test = mListeners.get(i);
- if (binder.equals(test.mListener.asBinder())) {
- // listener already added
- return;
- }
- }
-
- Listener l = new Listener(listener);
- binder.linkToDeath(l, 0);
- mListeners.add(l);
- }
- }
-
- public void removeGpsStatusListener(IGpsStatusListener listener) {
- if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener");
-
- synchronized(mListeners) {
- IBinder binder = listener.asBinder();
- Listener l = null;
- int size = mListeners.size();
- for (int i = 0; i < size && l == null; i++) {
- Listener test = mListeners.get(i);
- if (binder.equals(test.mListener.asBinder())) {
- l = test;
- }
- }
-
- if (l != null) {
- mListeners.remove(l);
- binder.unlinkToDeath(l, 0);
- }
- }
+ public void wakeLockAcquired() {
}
- @Override
+ public void wakeLockReleased() {
+ }
+
public void addListener(int uid) {
mClientUids.put(uid, 0);
if (mNavigating) {
@@ -569,7 +569,6 @@
}
}
- @Override
public void removeListener(int uid) {
mClientUids.delete(uid);
if (mNavigating) {
@@ -581,7 +580,6 @@
}
}
- @Override
public boolean sendExtraCommand(String command, Bundle extras) {
if ("delete_aiding_data".equals(command)) {
@@ -632,7 +630,7 @@
}
// reset SV count to zero
- updateStatus(TEMPORARILY_UNAVAILABLE, 0);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
}
}
@@ -646,7 +644,7 @@
mLocationFlags = LOCATION_INVALID;
// reset SV count to zero
- updateStatus(TEMPORARILY_UNAVAILABLE, 0);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
}
}
@@ -709,15 +707,19 @@
mLocation.removeAccuracy();
}
- reportLocationChanged(mLocation);
+ try {
+ mLocationManager.setLocation(mLocation);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling reportLocation");
+ }
}
- if (mStarted && mStatus != AVAILABLE) {
+ if (mStarted && mStatus != LocationProvider.AVAILABLE) {
// send an intent to notify that the GPS is receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, true);
mContext.sendBroadcast(intent);
- updateStatus(AVAILABLE, mSvCount);
+ updateStatus(LocationProvider.AVAILABLE, mSvCount);
}
}
@@ -812,13 +814,13 @@
updateStatus(mStatus, svCount);
- if (mNavigating && mStatus == AVAILABLE && mLastFixTime > 0 &&
+ if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
// send an intent to notify that the GPS is no longer receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, false);
mContext.sendBroadcast(intent);
- updateStatus(TEMPORARILY_UNAVAILABLE, mSvCount);
+ updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
}
}
diff --git a/location/java/com/android/internal/location/LocationProviderImpl.java b/location/java/com/android/internal/location/LocationProviderImpl.java
deleted file mode 100644
index fc830f5..0000000
--- a/location/java/com/android/internal/location/LocationProviderImpl.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2007 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.LocationProvider;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * An abstract superclass for location provider implementations.
- * Location provider implementations are typically instantiated by the
- * location manager service in the system process, and location
- * information is made available to implementations via the manager.
- *
- * {@hide}
- */
-public abstract class LocationProviderImpl extends LocationProvider {
- private static final String TAG = "LocationProviderImpl";
-
- private static ArrayList<LocationProviderImpl> sProviders =
- new ArrayList<LocationProviderImpl>();
- private static HashMap<String, LocationProviderImpl> sProvidersByName
- = new HashMap<String, LocationProviderImpl>();
-
- private final ILocationManager mLocationManager;
- private boolean mLocationTracking = false;
- private long mMinTime = 0;
-
- protected LocationProviderImpl(String name, ILocationManager locationManager) {
- super(name);
- mLocationManager = locationManager;
- }
-
- public static void addProvider(LocationProviderImpl provider) {
- sProviders.add(provider);
- sProvidersByName.put(provider.getName(), provider);
- }
-
- public static void removeProvider(LocationProviderImpl provider) {
- sProviders.remove(provider);
- sProvidersByName.remove(provider.getName());
- }
-
- public static ArrayList<LocationProviderImpl> getProviders() {
- return sProviders;
- }
-
- public static LocationProviderImpl getProvider(String name) {
- return sProvidersByName.get(name);
- }
-
- public void reportLocationChanged(Location location) {
- try {
- mLocationManager.setLocation(location);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException calling ILocationManager.setLocation");
- }
- }
-
- /**
- * Enables this provider. When enabled, calls to {@link #getStatus()}
- * must be handled. Hardware may be started up
- * when the provider is enabled.
- */
- public abstract void enable();
-
- /**
- * Disables this provider. When disabled, calls to {@link #getStatus()}
- * need not be handled. Hardware may be shut
- * down while the provider is disabled.
- */
- public abstract void disable();
-
- /**
- * Returns true if this provider is enabled, false otherwise;
- */
- public abstract boolean isEnabled();
-
- /**
- * Returns a information on the status of this provider.
- * {@link #OUT_OF_SERVICE} is returned if the provider is
- * out of service, and this is not expected to change in the near
- * future; {@link #TEMPORARILY_UNAVAILABLE} is returned if
- * the provider is temporarily unavailable but is expected to be
- * available shortly; and {@link #AVAILABLE} is returned
- * if the provider is currently available.
- */
- public int getStatus() {
- return getStatus(null);
- }
-
- /**
- * Returns a information on the status of this provider.
- * {@link #OUT_OF_SERVICE} is returned if the provider is
- * out of service, and this is not expected to change in the near
- * future; {@link #TEMPORARILY_UNAVAILABLE} is returned if
- * the provider is temporarily unavailable but is expected to be
- * available shortly; and {@link #AVAILABLE} is returned
- * if the provider is currently available.
- *
- * <p> If extras is non-null, additional status information may be
- * added to it in the form of provider-specific key/value pairs.
- */
- public abstract int getStatus(Bundle extras);
-
- /**
- * Returns the time at which the status was last updated. It is the
- * responsibility of the provider to appropriately set this value
- * using {@link android.os.SystemClock.elapsedRealtime()} each time
- * there is a status update that it wishes to broadcast to all its
- * listeners. The provider should be careful not to broadcast
- * the same status again.
- *
- * @return time of last status update in millis since last reboot
- */
- public long getStatusUpdateTime() {
- return 0;
- }
-
- /**
- * Notifies the location provider that clients are listening for locations.
- * Called with enable set to true when the first client is added and
- * called with enable set to false when the last client is removed.
- * This allows the provider to prepare for receiving locations,
- * and to shut down when no clients are remaining.
- *
- * @param enable true if location tracking should be enabled.
- */
- public void enableLocationTracking(boolean enable) {
- mLocationTracking = enable;
- }
-
- /**
- * Returns true if the provider has any listeners
- *
- * @return true if provider is being tracked
- */
- public boolean isLocationTracking() {
- return mLocationTracking;
- }
-
- /**
- * Notifies the location provider of the smallest minimum time between updates amongst
- * all clients that are listening for locations. This allows the provider to reduce
- * the frequency of updates to match the requested frequency.
- *
- * @param minTime the smallest minTime value over all listeners for this provider.
- */
- public void setMinTime(long minTime) {
- mMinTime = minTime;
- }
-
- /**
- * Gets the smallest minimum time between updates amongst all the clients listening
- * for locations. By default this value is 0 (as frqeuently as possible)
- *
- * @return the smallest minTime value over all listeners for this provider
- */
- public long getMinTime() {
- return mMinTime;
- }
-
- /**
- * Updates the network state for the given provider. This function must
- * be overwritten if {@link #requiresNetwork} returns true. The state is
- * {@link #TEMPORARILY_UNAVAILABLE} (disconnected), OR {@link #AVAILABLE}
- * (connected or connecting).
- *
- * @param state data state
- */
- public void updateNetworkState(int state) {
- }
-
- /**
- * Implements addditional location provider specific additional commands.
- *
- * @param command name of the command to send to the provider.
- * @param extras optional arguments for the command (or null).
- * The provider may optionally fill the extras Bundle with results from the command.
- *
- * @return true if the command succeeds.
- */
- public boolean sendExtraCommand(String command, Bundle extras) {
- return false;
- }
-
- /**
- * Informs the location provider when a new client is listening for location information
- *
- * @param uid the uid of the client proces
- */
- public void addListener(int uid) {
- }
-
- /**
- * Informs the location provider when a client is no longer listening for location information
- *
- * @param uid the uid of the client proces
- */
- public void removeListener(int uid) {
- }
-
- /**
- * Informs the location provider when the location manager service has acquired its wake lock
- */
- public void wakeLockAcquired() {
- }
-
- /**
- * Informs the location provider when the location manager service has released its wake lock
- */
- public void wakeLockReleased() {
- }
-}
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index d3c86db..abca28f 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -17,7 +17,6 @@
package com.android.internal.location;
import android.location.Address;
-import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location;
import android.location.LocationManager;
@@ -32,19 +31,24 @@
*
* {@hide}
*/
-public class LocationProviderProxy extends LocationProviderImpl {
+public class LocationProviderProxy {
private static final String TAG = "LocationProviderProxy";
+ private final String mName;
private final ILocationProvider mProvider;
+ private boolean mLocationTracking = false;
+ private long mMinTime = 0;
- public LocationProviderProxy(String name, ILocationManager locationManager,
- ILocationProvider provider) {
- super(name, locationManager);
+ public LocationProviderProxy(String name, ILocationProvider provider) {
+ mName = name;
mProvider = provider;
}
- @Override
+ public String getName() {
+ return mName;
+ }
+
public boolean requiresNetwork() {
try {
return mProvider.requiresNetwork();
@@ -54,7 +58,6 @@
}
}
- @Override
public boolean requiresSatellite() {
try {
return mProvider.requiresSatellite();
@@ -64,7 +67,6 @@
}
}
- @Override
public boolean requiresCell() {
try {
return mProvider.requiresCell();
@@ -74,7 +76,6 @@
}
}
- @Override
public boolean hasMonetaryCost() {
try {
return mProvider.hasMonetaryCost();
@@ -84,7 +85,6 @@
}
}
- @Override
public boolean supportsAltitude() {
try {
return mProvider.supportsAltitude();
@@ -94,7 +94,6 @@
}
}
- @Override
public boolean supportsSpeed() {
try {
return mProvider.supportsSpeed();
@@ -104,8 +103,7 @@
}
}
- @Override
- public boolean supportsBearing() {
+ public boolean supportsBearing() {
try {
return mProvider.supportsBearing();
} catch (RemoteException e) {
@@ -114,7 +112,6 @@
}
}
- @Override
public int getPowerRequirement() {
try {
return mProvider.getPowerRequirement();
@@ -124,7 +121,6 @@
}
}
- @Override
public int getAccuracy() {
try {
return mProvider.getAccuracy();
@@ -134,7 +130,6 @@
}
}
- @Override
public void enable() {
try {
mProvider.enable();
@@ -143,7 +138,6 @@
}
}
- @Override
public void disable() {
try {
mProvider.disable();
@@ -152,7 +146,6 @@
}
}
- @Override
public boolean isEnabled() {
try {
return mProvider.isEnabled();
@@ -162,7 +155,6 @@
}
}
- @Override
public int getStatus(Bundle extras) {
try {
return mProvider.getStatus(extras);
@@ -172,7 +164,6 @@
}
}
- @Override
public long getStatusUpdateTime() {
try {
return mProvider.getStatusUpdateTime();
@@ -182,27 +173,32 @@
}
}
- @Override
+ public boolean isLocationTracking() {
+ return mLocationTracking;
+ }
+
public void enableLocationTracking(boolean enable) {
+ mLocationTracking = enable;
try {
- super.enableLocationTracking(enable);
mProvider.enableLocationTracking(enable);
} catch (RemoteException e) {
Log.e(TAG, "enableLocationTracking failed", e);
}
}
- @Override
+ public long getMinTime() {
+ return mMinTime;
+ }
+
public void setMinTime(long minTime) {
+ mMinTime = minTime;
try {
- super.setMinTime(minTime);
mProvider.setMinTime(minTime);
} catch (RemoteException e) {
Log.e(TAG, "setMinTime failed", e);
}
}
- @Override
public void updateNetworkState(int state) {
try {
mProvider.updateNetworkState(state);
@@ -211,7 +207,6 @@
}
}
- @Override
public boolean sendExtraCommand(String command, Bundle extras) {
try {
return mProvider.sendExtraCommand(command, extras);
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index 6336e2b..6fa2c29 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -17,8 +17,12 @@
package com.android.internal.location;
import android.location.ILocationManager;
+import android.location.ILocationProvider;
import android.location.Location;
+import android.location.LocationProvider;
import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
import android.util.PrintWriterPrinter;
import java.io.PrintWriter;
@@ -28,7 +32,9 @@
*
* {@hide}
*/
-public class MockProvider extends LocationProviderImpl {
+public class MockProvider extends ILocationProvider.Stub {
+ private final String mName;
+ private final ILocationManager mLocationManager;
private final boolean mRequiresNetwork;
private final boolean mRequiresSatellite;
private final boolean mRequiresCell;
@@ -46,12 +52,14 @@
private boolean mHasStatus;
private boolean mEnabled;
+ private static final String TAG = "MockProvider";
+
public MockProvider(String name, ILocationManager locationManager,
boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
- super(name, locationManager);
-
+ mName = name;
+ mLocationManager = locationManager;
mRequiresNetwork = requiresNetwork;
mRequiresSatellite = requiresSatellite;
mRequiresCell = requiresCell;
@@ -64,78 +72,64 @@
mLocation = new Location(name);
}
- @Override
public void disable() {
mEnabled = false;
}
- @Override
public void enable() {
mEnabled = true;
}
- @Override
public int getStatus(Bundle extras) {
if (mHasStatus) {
extras.clear();
extras.putAll(mExtras);
return mStatus;
} else {
- return AVAILABLE;
+ return LocationProvider.AVAILABLE;
}
}
- @Override
public long getStatusUpdateTime() {
return mStatusUpdateTime;
}
- @Override
public boolean isEnabled() {
return mEnabled;
}
- @Override
public int getAccuracy() {
return mAccuracy;
}
- @Override
public int getPowerRequirement() {
return mPowerRequirement;
}
- @Override
public boolean hasMonetaryCost() {
return mHasMonetaryCost;
}
- @Override
public boolean requiresCell() {
return mRequiresCell;
}
- @Override
public boolean requiresNetwork() {
return mRequiresNetwork;
}
- @Override
public boolean requiresSatellite() {
return mRequiresSatellite;
}
- @Override
public boolean supportsAltitude() {
return mSupportsAltitude;
}
- @Override
public boolean supportsBearing() {
return mSupportsBearing;
}
- @Override
public boolean supportsSpeed() {
return mSupportsSpeed;
}
@@ -143,7 +137,11 @@
public void setLocation(Location l) {
mLocation.set(l);
mHasLocation = true;
- reportLocationChanged(mLocation);
+ try {
+ mLocationManager.setLocation(mLocation);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling reportLocation");
+ }
}
public void clearLocation() {
@@ -165,8 +163,33 @@
mStatusUpdateTime = 0;
}
+ public void enableLocationTracking(boolean enable) {
+ }
+
+ public void setMinTime(long minTime) {
+ }
+
+ public void updateNetworkState(int state) {
+ }
+
+ public boolean sendExtraCommand(String command, Bundle extras) {
+ return false;
+ }
+
+ public void addListener(int uid) {
+ }
+
+ public void removeListener(int uid) {
+ }
+
+ public void wakeLockAcquired() {
+ }
+
+ public void wakeLockReleased() {
+ }
+
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + getName());
+ pw.println(prefix + mName);
pw.println(prefix + "mHasLocation=" + mHasLocation);
pw.println(prefix + "mLocation:");
mLocation.dump(new PrintWriterPrinter(pw), prefix + " ");
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 0e1e0d9..d44abaa 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -46,6 +46,7 @@
import android.location.Address;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
+import android.location.IGpsStatusProvider;
import android.location.ILocationCollector;
import android.location.ILocationListener;
import android.location.ILocationManager;
@@ -72,7 +73,6 @@
import android.util.SparseIntArray;
import com.android.internal.location.GpsLocationProvider;
-import com.android.internal.location.LocationProviderImpl;
import com.android.internal.location.LocationProviderProxy;
import com.android.internal.location.MockProvider;
import com.android.server.am.BatteryStatsService;
@@ -119,9 +119,10 @@
private static boolean sProvidersLoaded = false;
private final Context mContext;
- private GpsLocationProvider mGpsLocationProvider;
+ private LocationProviderProxy mGpsLocationProvider;
private LocationProviderProxy mNetworkLocationProvider;
private IGeocodeProvider mGeocodeProvider;
+ private IGpsStatusProvider mGpsStatusProvider;
private LocationWorkerHandler mLocationHandler;
// Handler messages
@@ -143,6 +144,15 @@
*/
private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>();
+
+ /**
+ * List of location providers.
+ */
+ private final ArrayList<LocationProviderProxy> mProviders =
+ new ArrayList<LocationProviderProxy>();
+ private final HashMap<String, LocationProviderProxy> mProvidersByName
+ = new HashMap<String, LocationProviderProxy>();
+
/**
* Object used internally for synchronization
*/
@@ -502,6 +512,16 @@
}
}
+ private void addProvider(LocationProviderProxy provider) {
+ mProviders.add(provider);
+ mProvidersByName.put(provider.getName(), provider);
+ }
+
+ private void removeProvider(LocationProviderProxy provider) {
+ mProviders.remove(provider);
+ mProvidersByName.remove(provider.getName());
+ }
+
/**
* Load providers from /data/location/<provider_name>/
* class
@@ -535,8 +555,11 @@
// Attempt to load "real" providers first
if (GpsLocationProvider.isSupported()) {
// Create a gps location provider
- mGpsLocationProvider = new GpsLocationProvider(mContext, this);
- LocationProviderImpl.addProvider(mGpsLocationProvider);
+ GpsLocationProvider provider = new GpsLocationProvider(mContext, this);
+ mGpsStatusProvider = provider.getGpsStatusProvider();
+ mGpsLocationProvider =
+ new LocationProviderProxy(LocationManager.GPS_PROVIDER, provider);
+ addProvider(mGpsLocationProvider);
}
updateProvidersLocked();
@@ -611,8 +634,8 @@
synchronized (mLock) {
mNetworkLocationProvider =
- new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, this, provider);
- LocationProviderImpl.addProvider(mNetworkLocationProvider);
+ new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, provider);
+ addProvider(mNetworkLocationProvider);
updateProvidersLocked();
// notify NetworkLocationProvider of any events it might have missed
@@ -703,10 +726,9 @@
if (LOCAL_LOGV) {
Log.v(TAG, "getAllProviders");
}
- ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- ArrayList<String> out = new ArrayList<String>(providers.size());
- for (int i = providers.size() - 1; i >= 0; i--) {
- LocationProviderImpl p = providers.get(i);
+ ArrayList<String> out = new ArrayList<String>(mProviders.size());
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ LocationProviderProxy p = mProviders.get(i);
out.add(p.getName());
}
return out;
@@ -729,10 +751,9 @@
if (LOCAL_LOGV) {
Log.v(TAG, "getProviders");
}
- ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- ArrayList<String> out = new ArrayList<String>(providers.size());
- for (int i = providers.size() - 1; i >= 0; i--) {
- LocationProviderImpl p = providers.get(i);
+ ArrayList<String> out = new ArrayList<String>(mProviders.size());
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ LocationProviderProxy p = mProviders.get(i);
String name = p.getName();
if (isAllowedProviderSafe(name)) {
if (enabledOnly && !isAllowedBySettingsLocked(name)) {
@@ -745,9 +766,8 @@
}
private void updateProvidersLocked() {
- ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- for (int i = providers.size() - 1; i >= 0; i--) {
- LocationProviderImpl p = providers.get(i);
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ LocationProviderProxy p = mProviders.get(i);
boolean isEnabled = p.isEnabled();
String name = p.getName();
boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
@@ -764,7 +784,7 @@
private void updateProviderListenersLocked(String provider, boolean enabled) {
int listeners = 0;
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) {
return;
}
@@ -966,8 +986,8 @@
Log.v(TAG, "_requestLocationUpdates: listener = " + receiver);
}
- LocationProviderImpl impl = LocationProviderImpl.getProvider(provider);
- if (impl == null) {
+ LocationProviderProxy proxy = mProvidersByName.get(provider);
+ if (proxy == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -985,14 +1005,14 @@
}
if (newUid) {
- impl.addListener(callingUid);
+ proxy.addListener(callingUid);
}
boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
if (isProviderEnabled) {
long minTimeForProvider = getMinTimeLocked(provider);
- impl.setMinTime(minTimeForProvider);
- impl.enableLocationTracking(true);
+ proxy.setMinTime(minTimeForProvider);
+ proxy.enableLocationTracking(true);
updateWakelockStatusLocked();
} else {
// Notify the listener that updates are currently disabled
@@ -1047,10 +1067,9 @@
// Call dispose() on the obsolete update records.
for (UpdateRecord record : oldRecords.values()) {
if (!providerHasListener(record.mProvider, callingUid, receiver)) {
- LocationProviderImpl impl =
- LocationProviderImpl.getProvider(record.mProvider);
- if (impl != null) {
- impl.removeListener(callingUid);
+ LocationProviderProxy proxy = mProvidersByName.get(record.mProvider);
+ if (proxy != null) {
+ proxy.removeListener(callingUid);
}
}
record.disposeLocked();
@@ -1074,7 +1093,7 @@
hasOtherListener = true;
}
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p != null) {
if (hasOtherListener) {
p.setMinTime(getMinTimeLocked(provider));
@@ -1091,7 +1110,7 @@
}
public boolean addGpsStatusListener(IGpsStatusListener listener) {
- if (mGpsLocationProvider == null) {
+ if (mGpsStatusProvider == null) {
return false;
}
if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) !=
@@ -1100,9 +1119,9 @@
}
try {
- mGpsLocationProvider.addGpsStatusListener(listener);
+ mGpsStatusProvider.addGpsStatusListener(listener);
} catch (RemoteException e) {
- Log.w(TAG, "RemoteException in addGpsStatusListener");
+ Log.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e);
return false;
}
return true;
@@ -1110,7 +1129,11 @@
public void removeGpsStatusListener(IGpsStatusListener listener) {
synchronized (mLock) {
- mGpsLocationProvider.removeGpsStatusListener(listener);
+ try {
+ mGpsStatusProvider.removeGpsStatusListener(listener);
+ } catch (Exception e) {
+ Log.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e);
+ }
}
}
@@ -1124,12 +1147,12 @@
}
synchronized (mLock) {
- LocationProviderImpl impl = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy proxy = mProvidersByName.get(provider);
if (provider == null) {
return false;
}
- return impl.sendExtraCommand(command, extras);
+ return proxy.sendExtraCommand(command, extras);
}
}
@@ -1359,14 +1382,12 @@
mProximityListener = new ProximityListener();
mProximityReceiver = new Receiver(mProximityListener);
- LocationProvider provider = LocationProviderImpl.getProvider(
- LocationManager.GPS_PROVIDER);
+ LocationProviderProxy provider = mProvidersByName.get(LocationManager.GPS_PROVIDER);
if (provider != null) {
requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
}
- provider =
- LocationProviderImpl.getProvider(LocationManager.NETWORK_PROVIDER);
+ provider = mProvidersByName.get(LocationManager.NETWORK_PROVIDER);
if (provider != null) {
requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
}
@@ -1417,7 +1438,7 @@
}
private Bundle _getProviderInfoLocked(String provider) {
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) {
return null;
}
@@ -1460,7 +1481,7 @@
private boolean _isProviderEnabledLocked(String provider) {
checkPermissionsSafe(provider);
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -1483,7 +1504,7 @@
private Location _getLastKnownLocationLocked(String provider) {
checkPermissionsSafe(provider);
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -1534,7 +1555,7 @@
return;
}
- LocationProviderImpl p = LocationProviderImpl.getProvider(provider);
+ LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) {
return;
}
@@ -1550,9 +1571,8 @@
if (LocationManager.NETWORK_PROVIDER.equals(p.getName())) {
mWakeLockNetworkReceived = true;
- } else if (p instanceof GpsLocationProvider) {
- // Gps location received signal is in NetworkStateBroadcastReceiver
}
+ // Gps location received signal is in NetworkStateBroadcastReceiver
// Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime();
@@ -1720,9 +1740,8 @@
// Notify location providers of current network state
synchronized (mLock) {
- ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders();
- for (int i = providers.size() - 1; i >= 0; i--) {
- LocationProviderImpl provider = providers.get(i);
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ LocationProviderProxy provider = mProviders.get(i);
if (provider.requiresNetwork()) {
provider.updateNetworkState(mNetworkState);
}
@@ -1930,10 +1949,10 @@
requiresNetwork, requiresSatellite,
requiresCell, hasMonetaryCost, supportsAltitude,
supportsSpeed, supportsBearing, powerRequirement, accuracy);
- if (LocationProviderImpl.getProvider(name) != null) {
+ if (mProvidersByName.get(name) != null) {
throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
}
- LocationProviderImpl.addProvider(provider);
+ addProvider(new LocationProviderProxy(name, provider));
mMockProviders.put(name, provider);
updateProvidersLocked();
}
@@ -1946,7 +1965,7 @@
if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
}
- LocationProviderImpl.removeProvider(mockProvider);
+ removeProvider(mProvidersByName.get(provider));
mMockProviders.remove(mockProvider);
updateProvidersLocked();
}
diff --git a/test-runner/android/test/TestLocationProvider.java b/test-runner/android/test/TestLocationProvider.java
index 0fc3d16..500786d 100644
--- a/test-runner/android/test/TestLocationProvider.java
+++ b/test-runner/android/test/TestLocationProvider.java
@@ -19,17 +19,19 @@
import android.location.Criteria;
import android.location.ILocationManager;
+import android.location.ILocationProvider;
import android.location.Location;
+import android.location.LocationProvider;
import android.os.Bundle;
+import android.os.RemoteException;
import android.os.SystemClock;
-
-import com.android.internal.location.LocationProviderImpl;
+import android.util.Log;
/**
* @hide - This is part of a framework that is under development and should not be used for
* active development.
*/
-public class TestLocationProvider extends LocationProviderImpl {
+public class TestLocationProvider extends ILocationProvider.Stub {
public static final String PROVIDER_NAME = "test";
public static final double LAT = 0;
@@ -37,9 +39,12 @@
public static final double ALTITUDE = 10000;
public static final float SPEED = 10;
public static final float BEARING = 1;
- public static final int STATUS = AVAILABLE;
+ public static final int STATUS = LocationProvider.AVAILABLE;
private static final long LOCATION_INTERVAL = 1000;
+ private static final String TAG = "TestLocationProvider";
+
+ private final ILocationManager mLocationManager;
private Location mLocation;
private boolean mEnabled;
private TestLocationProviderThread mThread;
@@ -75,59 +80,46 @@
}
public TestLocationProvider(ILocationManager locationManager) {
- super(PROVIDER_NAME, locationManager);
+ mLocationManager = locationManager;
mLocation = new Location(PROVIDER_NAME);
}
- //LocationProvider methods
-
- @Override
public int getAccuracy() {
return Criteria.ACCURACY_COARSE;
}
- @Override
public int getPowerRequirement() {
return Criteria.NO_REQUIREMENT;
}
- @Override
public boolean hasMonetaryCost() {
return false;
}
- @Override
public boolean requiresCell() {
return false;
}
- @Override
public boolean requiresNetwork() {
return false;
}
- @Override
public boolean requiresSatellite() {
return false;
}
- @Override
public boolean supportsAltitude() {
return true;
}
- @Override
public boolean supportsBearing() {
return true;
}
- @Override
public boolean supportsSpeed() {
return true;
}
- //LocationProviderImpl methods
- @Override
public synchronized void disable() {
mEnabled = false;
if (mThread != null) {
@@ -140,23 +132,49 @@
}
}
- @Override
public synchronized void enable() {
mEnabled = true;
mThread = new TestLocationProviderThread();
mThread.start();
}
- @Override
public boolean isEnabled() {
return mEnabled;
}
- @Override
public int getStatus(Bundle extras) {
return STATUS;
}
+ public long getStatusUpdateTime() {
+ return 0;
+ }
+
+ public void enableLocationTracking(boolean enable) {
+ }
+
+ public void setMinTime(long minTime) {
+ }
+
+ public void updateNetworkState(int state) {
+ }
+
+ public boolean sendExtraCommand(String command, Bundle extras) {
+ return false;
+ }
+
+ public void addListener(int uid) {
+ }
+
+ public void removeListener(int uid) {
+ }
+
+ public void wakeLockAcquired() {
+ }
+
+ public void wakeLockReleased() {
+ }
+
private void updateLocation() {
long time = SystemClock.uptimeMillis();
long multiplier = (time/5000)%500000;
@@ -170,7 +188,11 @@
extras.putInt("extraTest", 24);
mLocation.setExtras(extras);
mLocation.setTime(time);
- reportLocationChanged(mLocation);
+ try {
+ mLocationManager.setLocation(mLocation);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling updateLocation");
+ }
}
}