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>
This commit is contained in:
Mike Lockwood
2009-05-01 07:53:28 -04:00
parent a56b318cf2
commit 15e3d0f082
9 changed files with 281 additions and 428 deletions

View File

@ -116,6 +116,7 @@ LOCAL_SRC_FILES += \
im/java/android/im/IImPlugin.aidl \ im/java/android/im/IImPlugin.aidl \
location/java/android/location/IGeocodeProvider.aidl \ location/java/android/location/IGeocodeProvider.aidl \
location/java/android/location/IGpsStatusListener.aidl \ location/java/android/location/IGpsStatusListener.aidl \
location/java/android/location/IGpsStatusProvider.aidl \
location/java/android/location/ILocationCollector.aidl \ location/java/android/location/ILocationCollector.aidl \
location/java/android/location/ILocationListener.aidl \ location/java/android/location/ILocationListener.aidl \
location/java/android/location/ILocationManager.aidl \ location/java/android/location/ILocationManager.aidl \

View File

@ -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);
}

View File

@ -19,13 +19,11 @@ package android.location;
import android.os.Bundle; import android.os.Bundle;
/** /**
* An interface for location providers implemented outside of the system process. * Binder interface for location providers.
* *
* {@hide} * {@hide}
*/ */
interface ILocationProvider { interface ILocationProvider {
/* for LocationProvider */
boolean requiresNetwork(); boolean requiresNetwork();
boolean requiresSatellite(); boolean requiresSatellite();
boolean requiresCell(); boolean requiresCell();
@ -35,8 +33,6 @@ interface ILocationProvider {
boolean supportsBearing(); boolean supportsBearing();
int getPowerRequirement(); int getPowerRequirement();
int getAccuracy(); int getAccuracy();
/* for LocationProviderImpl */
void enable(); void enable();
void disable(); void disable();
boolean isEnabled(); boolean isEnabled();

View File

@ -22,7 +22,9 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.location.Criteria; import android.location.Criteria;
import android.location.IGpsStatusListener; import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
import android.location.ILocationManager; import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.location.LocationProvider; import android.location.LocationProvider;
@ -54,7 +56,7 @@ import java.util.Properties;
* *
* {@hide} * {@hide}
*/ */
public class GpsLocationProvider extends LocationProviderImpl { public class GpsLocationProvider extends ILocationProvider.Stub {
private static final String TAG = "GpsLocationProvider"; private static final String TAG = "GpsLocationProvider";
@ -142,7 +144,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
private int mLocationFlags = LOCATION_INVALID; private int mLocationFlags = LOCATION_INVALID;
// current status // current status
private int mStatus = TEMPORARILY_UNAVAILABLE; private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
// time for last status update // time for last status update
private long mStatusUpdateTime = SystemClock.elapsedRealtime(); private long mStatusUpdateTime = SystemClock.elapsedRealtime();
@ -178,7 +180,8 @@ public class GpsLocationProvider extends LocationProviderImpl {
private Properties mProperties; private Properties mProperties;
private String mNtpServer; private String mNtpServer;
private Context mContext; private final Context mContext;
private final ILocationManager mLocationManager;
private Location mLocation = new Location(LocationManager.GPS_PROVIDER); private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
private Bundle mLocationExtras = new Bundle(); private Bundle mLocationExtras = new Bundle();
private ArrayList<Listener> mListeners = new ArrayList<Listener>(); private ArrayList<Listener> mListeners = new ArrayList<Listener>();
@ -203,6 +206,57 @@ public class GpsLocationProvider extends LocationProviderImpl {
// current setting - 5 minutes // current setting - 5 minutes
private static final long RETRY_INTERVAL = 5*60*1000; 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 { private class TelephonyBroadcastReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) { @Override public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
@ -231,8 +285,8 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
public GpsLocationProvider(Context context, ILocationManager locationManager) { public GpsLocationProvider(Context context, ILocationManager locationManager) {
super(LocationManager.GPS_PROVIDER, locationManager);
mContext = context; mContext = context;
mLocationManager = locationManager;
TelephonyBroadcastReceiver receiver = new TelephonyBroadcastReceiver(); TelephonyBroadcastReceiver receiver = new TelephonyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
@ -270,7 +324,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* Returns true if the provider requires access to a * Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise. * data network (e.g., the Internet), false otherwise.
*/ */
@Override
public boolean requiresNetwork() { public boolean requiresNetwork() {
// We want updateNetworkState() to get called when the network state changes // We want updateNetworkState() to get called when the network state changes
// for XTRA and NTP time injection support. // for XTRA and NTP time injection support.
@ -295,7 +348,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* satellite-based positioning system (e.g., GPS), false * satellite-based positioning system (e.g., GPS), false
* otherwise. * otherwise.
*/ */
@Override
public boolean requiresSatellite() { public boolean requiresSatellite() {
return true; return true;
} }
@ -305,7 +357,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* cellular network (e.g., to make use of cell tower IDs), false * cellular network (e.g., to make use of cell tower IDs), false
* otherwise. * otherwise.
*/ */
@Override
public boolean requiresCell() { public boolean requiresCell() {
return false; return false;
} }
@ -315,7 +366,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* monetary charge to the user, false if use is free. It is up to * monetary charge to the user, false if use is free. It is up to
* each provider to give accurate information. * each provider to give accurate information.
*/ */
@Override
public boolean hasMonetaryCost() { public boolean hasMonetaryCost() {
return false; return false;
} }
@ -326,7 +376,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* under most circumstances but may occassionally not report it * under most circumstances but may occassionally not report it
* should return true. * should return true.
*/ */
@Override
public boolean supportsAltitude() { public boolean supportsAltitude() {
return true; return true;
} }
@ -337,7 +386,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* under most circumstances but may occassionally not report it * under most circumstances but may occassionally not report it
* should return true. * should return true.
*/ */
@Override
public boolean supportsSpeed() { public boolean supportsSpeed() {
return true; return true;
} }
@ -348,7 +396,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* under most circumstances but may occassionally not report it * under most circumstances but may occassionally not report it
* should return true. * should return true.
*/ */
@Override
public boolean supportsBearing() { public boolean supportsBearing() {
return true; return true;
} }
@ -359,7 +406,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* @return the power requirement for this provider, as one of the * @return the power requirement for this provider, as one of the
* constants Criteria.POWER_REQUIREMENT_*. * constants Criteria.POWER_REQUIREMENT_*.
*/ */
@Override
public int getPowerRequirement() { public int getPowerRequirement() {
return Criteria.POWER_HIGH; return Criteria.POWER_HIGH;
} }
@ -370,7 +416,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* @return the accuracy of location from this provider, as one * @return the accuracy of location from this provider, as one
* of the constants Criteria.ACCURACY_*. * of the constants Criteria.ACCURACY_*.
*/ */
@Override
public int getAccuracy() { public int getAccuracy() {
return Criteria.ACCURACY_FINE; return Criteria.ACCURACY_FINE;
} }
@ -380,7 +425,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* must be handled. Hardware may be started up * must be handled. Hardware may be started up
* when the provider is enabled. * when the provider is enabled.
*/ */
@Override
public synchronized void enable() { public synchronized void enable() {
if (Config.LOGD) Log.d(TAG, "enable"); if (Config.LOGD) Log.d(TAG, "enable");
if (mEnabled) return; if (mEnabled) return;
@ -410,7 +454,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
* need not be handled. Hardware may be shut * need not be handled. Hardware may be shut
* down while the provider is disabled. * down while the provider is disabled.
*/ */
@Override
public synchronized void disable() { public synchronized void disable() {
if (Config.LOGD) Log.d(TAG, "disable"); if (Config.LOGD) Log.d(TAG, "disable");
if (!mEnabled) return; if (!mEnabled) return;
@ -443,12 +486,10 @@ public class GpsLocationProvider extends LocationProviderImpl {
native_cleanup(); native_cleanup();
} }
@Override
public boolean isEnabled() { public boolean isEnabled() {
return mEnabled; return mEnabled;
} }
@Override
public int getStatus(Bundle extras) { public int getStatus(Bundle extras) {
if (extras != null) { if (extras != null) {
extras.putInt("satellites", mSvCount); extras.putInt("satellites", mSvCount);
@ -465,14 +506,11 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
} }
@Override
public long getStatusUpdateTime() { public long getStatusUpdateTime() {
return mStatusUpdateTime; return mStatusUpdateTime;
} }
@Override
public void enableLocationTracking(boolean enable) { public void enableLocationTracking(boolean enable) {
super.enableLocationTracking(enable);
if (enable) { if (enable) {
mFixRequestTime = System.currentTimeMillis(); mFixRequestTime = System.currentTimeMillis();
mTTFF = 0; mTTFF = 0;
@ -483,9 +521,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
} }
@Override
public void setMinTime(long minTime) { public void setMinTime(long minTime) {
super.setMinTime(minTime);
if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime); if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime);
if (minTime >= 0) { if (minTime >= 0) {
@ -516,48 +552,12 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
} }
public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { public void wakeLockAcquired() {
if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener"); }
synchronized(mListeners) { public void wakeLockReleased() {
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);
}
}
} }
@Override
public void addListener(int uid) { public void addListener(int uid) {
mClientUids.put(uid, 0); mClientUids.put(uid, 0);
if (mNavigating) { if (mNavigating) {
@ -569,7 +569,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
} }
@Override
public void removeListener(int uid) { public void removeListener(int uid) {
mClientUids.delete(uid); mClientUids.delete(uid);
if (mNavigating) { if (mNavigating) {
@ -581,7 +580,6 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
} }
@Override
public boolean sendExtraCommand(String command, Bundle extras) { public boolean sendExtraCommand(String command, Bundle extras) {
if ("delete_aiding_data".equals(command)) { if ("delete_aiding_data".equals(command)) {
@ -632,7 +630,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
} }
// reset SV count to zero // reset SV count to zero
updateStatus(TEMPORARILY_UNAVAILABLE, 0); updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
} }
} }
@ -646,7 +644,7 @@ public class GpsLocationProvider extends LocationProviderImpl {
mLocationFlags = LOCATION_INVALID; mLocationFlags = LOCATION_INVALID;
// reset SV count to zero // reset SV count to zero
updateStatus(TEMPORARILY_UNAVAILABLE, 0); updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0);
} }
} }
@ -709,15 +707,19 @@ public class GpsLocationProvider extends LocationProviderImpl {
mLocation.removeAccuracy(); 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. // send an intent to notify that the GPS is receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, true); intent.putExtra(EXTRA_ENABLED, true);
mContext.sendBroadcast(intent); mContext.sendBroadcast(intent);
updateStatus(AVAILABLE, mSvCount); updateStatus(LocationProvider.AVAILABLE, mSvCount);
} }
} }
@ -812,13 +814,13 @@ public class GpsLocationProvider extends LocationProviderImpl {
updateStatus(mStatus, svCount); updateStatus(mStatus, svCount);
if (mNavigating && mStatus == AVAILABLE && mLastFixTime > 0 && if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
// send an intent to notify that the GPS is no longer receiving fixes. // send an intent to notify that the GPS is no longer receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, false); intent.putExtra(EXTRA_ENABLED, false);
mContext.sendBroadcast(intent); mContext.sendBroadcast(intent);
updateStatus(TEMPORARILY_UNAVAILABLE, mSvCount); updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount);
} }
} }

View File

@ -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() {
}
}

View File

@ -17,7 +17,6 @@
package com.android.internal.location; package com.android.internal.location;
import android.location.Address; import android.location.Address;
import android.location.ILocationManager;
import android.location.ILocationProvider; import android.location.ILocationProvider;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
@ -32,19 +31,24 @@ import java.util.List;
* *
* {@hide} * {@hide}
*/ */
public class LocationProviderProxy extends LocationProviderImpl { public class LocationProviderProxy {
private static final String TAG = "LocationProviderProxy"; private static final String TAG = "LocationProviderProxy";
private final String mName;
private final ILocationProvider mProvider; private final ILocationProvider mProvider;
private boolean mLocationTracking = false;
private long mMinTime = 0;
public LocationProviderProxy(String name, ILocationManager locationManager, public LocationProviderProxy(String name, ILocationProvider provider) {
ILocationProvider provider) { mName = name;
super(name, locationManager);
mProvider = provider; mProvider = provider;
} }
@Override public String getName() {
return mName;
}
public boolean requiresNetwork() { public boolean requiresNetwork() {
try { try {
return mProvider.requiresNetwork(); return mProvider.requiresNetwork();
@ -54,7 +58,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean requiresSatellite() { public boolean requiresSatellite() {
try { try {
return mProvider.requiresSatellite(); return mProvider.requiresSatellite();
@ -64,7 +67,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean requiresCell() { public boolean requiresCell() {
try { try {
return mProvider.requiresCell(); return mProvider.requiresCell();
@ -74,7 +76,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean hasMonetaryCost() { public boolean hasMonetaryCost() {
try { try {
return mProvider.hasMonetaryCost(); return mProvider.hasMonetaryCost();
@ -84,7 +85,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean supportsAltitude() { public boolean supportsAltitude() {
try { try {
return mProvider.supportsAltitude(); return mProvider.supportsAltitude();
@ -94,7 +94,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean supportsSpeed() { public boolean supportsSpeed() {
try { try {
return mProvider.supportsSpeed(); return mProvider.supportsSpeed();
@ -104,8 +103,7 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override public boolean supportsBearing() {
public boolean supportsBearing() {
try { try {
return mProvider.supportsBearing(); return mProvider.supportsBearing();
} catch (RemoteException e) { } catch (RemoteException e) {
@ -114,7 +112,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public int getPowerRequirement() { public int getPowerRequirement() {
try { try {
return mProvider.getPowerRequirement(); return mProvider.getPowerRequirement();
@ -124,7 +121,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public int getAccuracy() { public int getAccuracy() {
try { try {
return mProvider.getAccuracy(); return mProvider.getAccuracy();
@ -134,7 +130,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public void enable() { public void enable() {
try { try {
mProvider.enable(); mProvider.enable();
@ -143,7 +138,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public void disable() { public void disable() {
try { try {
mProvider.disable(); mProvider.disable();
@ -152,7 +146,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean isEnabled() { public boolean isEnabled() {
try { try {
return mProvider.isEnabled(); return mProvider.isEnabled();
@ -162,7 +155,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public int getStatus(Bundle extras) { public int getStatus(Bundle extras) {
try { try {
return mProvider.getStatus(extras); return mProvider.getStatus(extras);
@ -172,7 +164,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public long getStatusUpdateTime() { public long getStatusUpdateTime() {
try { try {
return mProvider.getStatusUpdateTime(); return mProvider.getStatusUpdateTime();
@ -182,27 +173,32 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override public boolean isLocationTracking() {
return mLocationTracking;
}
public void enableLocationTracking(boolean enable) { public void enableLocationTracking(boolean enable) {
mLocationTracking = enable;
try { try {
super.enableLocationTracking(enable);
mProvider.enableLocationTracking(enable); mProvider.enableLocationTracking(enable);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "enableLocationTracking failed", e); Log.e(TAG, "enableLocationTracking failed", e);
} }
} }
@Override public long getMinTime() {
return mMinTime;
}
public void setMinTime(long minTime) { public void setMinTime(long minTime) {
mMinTime = minTime;
try { try {
super.setMinTime(minTime);
mProvider.setMinTime(minTime); mProvider.setMinTime(minTime);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "setMinTime failed", e); Log.e(TAG, "setMinTime failed", e);
} }
} }
@Override
public void updateNetworkState(int state) { public void updateNetworkState(int state) {
try { try {
mProvider.updateNetworkState(state); mProvider.updateNetworkState(state);
@ -211,7 +207,6 @@ public class LocationProviderProxy extends LocationProviderImpl {
} }
} }
@Override
public boolean sendExtraCommand(String command, Bundle extras) { public boolean sendExtraCommand(String command, Bundle extras) {
try { try {
return mProvider.sendExtraCommand(command, extras); return mProvider.sendExtraCommand(command, extras);

View File

@ -17,8 +17,12 @@
package com.android.internal.location; package com.android.internal.location;
import android.location.ILocationManager; import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location; import android.location.Location;
import android.location.LocationProvider;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.util.PrintWriterPrinter; import android.util.PrintWriterPrinter;
import java.io.PrintWriter; import java.io.PrintWriter;
@ -28,7 +32,9 @@ import java.io.PrintWriter;
* *
* {@hide} * {@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 mRequiresNetwork;
private final boolean mRequiresSatellite; private final boolean mRequiresSatellite;
private final boolean mRequiresCell; private final boolean mRequiresCell;
@ -46,12 +52,14 @@ public class MockProvider extends LocationProviderImpl {
private boolean mHasStatus; private boolean mHasStatus;
private boolean mEnabled; private boolean mEnabled;
private static final String TAG = "MockProvider";
public MockProvider(String name, ILocationManager locationManager, public MockProvider(String name, ILocationManager locationManager,
boolean requiresNetwork, boolean requiresSatellite, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
super(name, locationManager); mName = name;
mLocationManager = locationManager;
mRequiresNetwork = requiresNetwork; mRequiresNetwork = requiresNetwork;
mRequiresSatellite = requiresSatellite; mRequiresSatellite = requiresSatellite;
mRequiresCell = requiresCell; mRequiresCell = requiresCell;
@ -64,78 +72,64 @@ public class MockProvider extends LocationProviderImpl {
mLocation = new Location(name); mLocation = new Location(name);
} }
@Override
public void disable() { public void disable() {
mEnabled = false; mEnabled = false;
} }
@Override
public void enable() { public void enable() {
mEnabled = true; mEnabled = true;
} }
@Override
public int getStatus(Bundle extras) { public int getStatus(Bundle extras) {
if (mHasStatus) { if (mHasStatus) {
extras.clear(); extras.clear();
extras.putAll(mExtras); extras.putAll(mExtras);
return mStatus; return mStatus;
} else { } else {
return AVAILABLE; return LocationProvider.AVAILABLE;
} }
} }
@Override
public long getStatusUpdateTime() { public long getStatusUpdateTime() {
return mStatusUpdateTime; return mStatusUpdateTime;
} }
@Override
public boolean isEnabled() { public boolean isEnabled() {
return mEnabled; return mEnabled;
} }
@Override
public int getAccuracy() { public int getAccuracy() {
return mAccuracy; return mAccuracy;
} }
@Override
public int getPowerRequirement() { public int getPowerRequirement() {
return mPowerRequirement; return mPowerRequirement;
} }
@Override
public boolean hasMonetaryCost() { public boolean hasMonetaryCost() {
return mHasMonetaryCost; return mHasMonetaryCost;
} }
@Override
public boolean requiresCell() { public boolean requiresCell() {
return mRequiresCell; return mRequiresCell;
} }
@Override
public boolean requiresNetwork() { public boolean requiresNetwork() {
return mRequiresNetwork; return mRequiresNetwork;
} }
@Override
public boolean requiresSatellite() { public boolean requiresSatellite() {
return mRequiresSatellite; return mRequiresSatellite;
} }
@Override
public boolean supportsAltitude() { public boolean supportsAltitude() {
return mSupportsAltitude; return mSupportsAltitude;
} }
@Override
public boolean supportsBearing() { public boolean supportsBearing() {
return mSupportsBearing; return mSupportsBearing;
} }
@Override
public boolean supportsSpeed() { public boolean supportsSpeed() {
return mSupportsSpeed; return mSupportsSpeed;
} }
@ -143,7 +137,11 @@ public class MockProvider extends LocationProviderImpl {
public void setLocation(Location l) { public void setLocation(Location l) {
mLocation.set(l); mLocation.set(l);
mHasLocation = true; mHasLocation = true;
reportLocationChanged(mLocation); try {
mLocationManager.setLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}
} }
public void clearLocation() { public void clearLocation() {
@ -165,8 +163,33 @@ public class MockProvider extends LocationProviderImpl {
mStatusUpdateTime = 0; 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) { public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + getName()); pw.println(prefix + mName);
pw.println(prefix + "mHasLocation=" + mHasLocation); pw.println(prefix + "mHasLocation=" + mHasLocation);
pw.println(prefix + "mLocation:"); pw.println(prefix + "mLocation:");
mLocation.dump(new PrintWriterPrinter(pw), prefix + " "); mLocation.dump(new PrintWriterPrinter(pw), prefix + " ");

View File

@ -46,6 +46,7 @@ import android.database.Cursor;
import android.location.Address; import android.location.Address;
import android.location.IGeocodeProvider; import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener; import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
import android.location.ILocationCollector; import android.location.ILocationCollector;
import android.location.ILocationListener; import android.location.ILocationListener;
import android.location.ILocationManager; import android.location.ILocationManager;
@ -72,7 +73,6 @@ import android.util.PrintWriterPrinter;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.android.internal.location.GpsLocationProvider; import com.android.internal.location.GpsLocationProvider;
import com.android.internal.location.LocationProviderImpl;
import com.android.internal.location.LocationProviderProxy; import com.android.internal.location.LocationProviderProxy;
import com.android.internal.location.MockProvider; import com.android.internal.location.MockProvider;
import com.android.server.am.BatteryStatsService; import com.android.server.am.BatteryStatsService;
@ -119,9 +119,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private static boolean sProvidersLoaded = false; private static boolean sProvidersLoaded = false;
private final Context mContext; private final Context mContext;
private GpsLocationProvider mGpsLocationProvider; private LocationProviderProxy mGpsLocationProvider;
private LocationProviderProxy mNetworkLocationProvider; private LocationProviderProxy mNetworkLocationProvider;
private IGeocodeProvider mGeocodeProvider; private IGeocodeProvider mGeocodeProvider;
private IGpsStatusProvider mGpsStatusProvider;
private LocationWorkerHandler mLocationHandler; private LocationWorkerHandler mLocationHandler;
// Handler messages // Handler messages
@ -143,6 +144,15 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
*/ */
private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 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 * Object used internally for synchronization
*/ */
@ -502,6 +512,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
} }
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>/ * Load providers from /data/location/<provider_name>/
* class * class
@ -535,8 +555,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Attempt to load "real" providers first // Attempt to load "real" providers first
if (GpsLocationProvider.isSupported()) { if (GpsLocationProvider.isSupported()) {
// Create a gps location provider // Create a gps location provider
mGpsLocationProvider = new GpsLocationProvider(mContext, this); GpsLocationProvider provider = new GpsLocationProvider(mContext, this);
LocationProviderImpl.addProvider(mGpsLocationProvider); mGpsStatusProvider = provider.getGpsStatusProvider();
mGpsLocationProvider =
new LocationProviderProxy(LocationManager.GPS_PROVIDER, provider);
addProvider(mGpsLocationProvider);
} }
updateProvidersLocked(); updateProvidersLocked();
@ -611,8 +634,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
synchronized (mLock) { synchronized (mLock) {
mNetworkLocationProvider = mNetworkLocationProvider =
new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, this, provider); new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, provider);
LocationProviderImpl.addProvider(mNetworkLocationProvider); addProvider(mNetworkLocationProvider);
updateProvidersLocked(); updateProvidersLocked();
// notify NetworkLocationProvider of any events it might have missed // notify NetworkLocationProvider of any events it might have missed
@ -703,10 +726,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (LOCAL_LOGV) { if (LOCAL_LOGV) {
Log.v(TAG, "getAllProviders"); Log.v(TAG, "getAllProviders");
} }
ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); ArrayList<String> out = new ArrayList<String>(mProviders.size());
ArrayList<String> out = new ArrayList<String>(providers.size()); for (int i = mProviders.size() - 1; i >= 0; i--) {
for (int i = providers.size() - 1; i >= 0; i--) { LocationProviderProxy p = mProviders.get(i);
LocationProviderImpl p = providers.get(i);
out.add(p.getName()); out.add(p.getName());
} }
return out; return out;
@ -729,10 +751,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (LOCAL_LOGV) { if (LOCAL_LOGV) {
Log.v(TAG, "getProviders"); Log.v(TAG, "getProviders");
} }
ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); ArrayList<String> out = new ArrayList<String>(mProviders.size());
ArrayList<String> out = new ArrayList<String>(providers.size()); for (int i = mProviders.size() - 1; i >= 0; i--) {
for (int i = providers.size() - 1; i >= 0; i--) { LocationProviderProxy p = mProviders.get(i);
LocationProviderImpl p = providers.get(i);
String name = p.getName(); String name = p.getName();
if (isAllowedProviderSafe(name)) { if (isAllowedProviderSafe(name)) {
if (enabledOnly && !isAllowedBySettingsLocked(name)) { if (enabledOnly && !isAllowedBySettingsLocked(name)) {
@ -745,9 +766,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
private void updateProvidersLocked() { private void updateProvidersLocked() {
ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); for (int i = mProviders.size() - 1; i >= 0; i--) {
for (int i = providers.size() - 1; i >= 0; i--) { LocationProviderProxy p = mProviders.get(i);
LocationProviderImpl p = providers.get(i);
boolean isEnabled = p.isEnabled(); boolean isEnabled = p.isEnabled();
String name = p.getName(); String name = p.getName();
boolean shouldBeEnabled = isAllowedBySettingsLocked(name); boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
@ -764,7 +784,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private void updateProviderListenersLocked(String provider, boolean enabled) { private void updateProviderListenersLocked(String provider, boolean enabled) {
int listeners = 0; int listeners = 0;
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) { if (p == null) {
return; return;
} }
@ -966,8 +986,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
Log.v(TAG, "_requestLocationUpdates: listener = " + receiver); Log.v(TAG, "_requestLocationUpdates: listener = " + receiver);
} }
LocationProviderImpl impl = LocationProviderImpl.getProvider(provider); LocationProviderProxy proxy = mProvidersByName.get(provider);
if (impl == null) { if (proxy == null) {
throw new IllegalArgumentException("provider=" + provider); throw new IllegalArgumentException("provider=" + provider);
} }
@ -985,14 +1005,14 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
if (newUid) { if (newUid) {
impl.addListener(callingUid); proxy.addListener(callingUid);
} }
boolean isProviderEnabled = isAllowedBySettingsLocked(provider); boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
if (isProviderEnabled) { if (isProviderEnabled) {
long minTimeForProvider = getMinTimeLocked(provider); long minTimeForProvider = getMinTimeLocked(provider);
impl.setMinTime(minTimeForProvider); proxy.setMinTime(minTimeForProvider);
impl.enableLocationTracking(true); proxy.enableLocationTracking(true);
updateWakelockStatusLocked(); updateWakelockStatusLocked();
} else { } else {
// Notify the listener that updates are currently disabled // Notify the listener that updates are currently disabled
@ -1047,10 +1067,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Call dispose() on the obsolete update records. // Call dispose() on the obsolete update records.
for (UpdateRecord record : oldRecords.values()) { for (UpdateRecord record : oldRecords.values()) {
if (!providerHasListener(record.mProvider, callingUid, receiver)) { if (!providerHasListener(record.mProvider, callingUid, receiver)) {
LocationProviderImpl impl = LocationProviderProxy proxy = mProvidersByName.get(record.mProvider);
LocationProviderImpl.getProvider(record.mProvider); if (proxy != null) {
if (impl != null) { proxy.removeListener(callingUid);
impl.removeListener(callingUid);
} }
} }
record.disposeLocked(); record.disposeLocked();
@ -1074,7 +1093,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
hasOtherListener = true; hasOtherListener = true;
} }
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p != null) { if (p != null) {
if (hasOtherListener) { if (hasOtherListener) {
p.setMinTime(getMinTimeLocked(provider)); p.setMinTime(getMinTimeLocked(provider));
@ -1091,7 +1110,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
public boolean addGpsStatusListener(IGpsStatusListener listener) { public boolean addGpsStatusListener(IGpsStatusListener listener) {
if (mGpsLocationProvider == null) { if (mGpsStatusProvider == null) {
return false; return false;
} }
if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) != if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) !=
@ -1100,9 +1119,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
try { try {
mGpsLocationProvider.addGpsStatusListener(listener); mGpsStatusProvider.addGpsStatusListener(listener);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "RemoteException in addGpsStatusListener"); Log.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e);
return false; return false;
} }
return true; return true;
@ -1110,7 +1129,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
public void removeGpsStatusListener(IGpsStatusListener listener) { public void removeGpsStatusListener(IGpsStatusListener listener) {
synchronized (mLock) { synchronized (mLock) {
mGpsLocationProvider.removeGpsStatusListener(listener); try {
mGpsStatusProvider.removeGpsStatusListener(listener);
} catch (Exception e) {
Log.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e);
}
} }
} }
@ -1124,12 +1147,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
synchronized (mLock) { synchronized (mLock) {
LocationProviderImpl impl = LocationProviderImpl.getProvider(provider); LocationProviderProxy proxy = mProvidersByName.get(provider);
if (provider == null) { if (provider == null) {
return false; return false;
} }
return impl.sendExtraCommand(command, extras); return proxy.sendExtraCommand(command, extras);
} }
} }
@ -1359,14 +1382,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mProximityListener = new ProximityListener(); mProximityListener = new ProximityListener();
mProximityReceiver = new Receiver(mProximityListener); mProximityReceiver = new Receiver(mProximityListener);
LocationProvider provider = LocationProviderImpl.getProvider( LocationProviderProxy provider = mProvidersByName.get(LocationManager.GPS_PROVIDER);
LocationManager.GPS_PROVIDER);
if (provider != null) { if (provider != null) {
requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver); requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
} }
provider = provider = mProvidersByName.get(LocationManager.NETWORK_PROVIDER);
LocationProviderImpl.getProvider(LocationManager.NETWORK_PROVIDER);
if (provider != null) { if (provider != null) {
requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver); requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
} }
@ -1417,7 +1438,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
} }
private Bundle _getProviderInfoLocked(String provider) { private Bundle _getProviderInfoLocked(String provider) {
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) { if (p == null) {
return null; return null;
} }
@ -1460,7 +1481,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private boolean _isProviderEnabledLocked(String provider) { private boolean _isProviderEnabledLocked(String provider) {
checkPermissionsSafe(provider); checkPermissionsSafe(provider);
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) { if (p == null) {
throw new IllegalArgumentException("provider=" + provider); throw new IllegalArgumentException("provider=" + provider);
} }
@ -1483,7 +1504,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private Location _getLastKnownLocationLocked(String provider) { private Location _getLastKnownLocationLocked(String provider) {
checkPermissionsSafe(provider); checkPermissionsSafe(provider);
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) { if (p == null) {
throw new IllegalArgumentException("provider=" + provider); throw new IllegalArgumentException("provider=" + provider);
} }
@ -1534,7 +1555,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return; return;
} }
LocationProviderImpl p = LocationProviderImpl.getProvider(provider); LocationProviderProxy p = mProvidersByName.get(provider);
if (p == null) { if (p == null) {
return; return;
} }
@ -1550,9 +1571,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (LocationManager.NETWORK_PROVIDER.equals(p.getName())) { if (LocationManager.NETWORK_PROVIDER.equals(p.getName())) {
mWakeLockNetworkReceived = true; 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 // Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime(); long newStatusUpdateTime = p.getStatusUpdateTime();
@ -1720,9 +1740,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Notify location providers of current network state // Notify location providers of current network state
synchronized (mLock) { synchronized (mLock) {
ArrayList<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); for (int i = mProviders.size() - 1; i >= 0; i--) {
for (int i = providers.size() - 1; i >= 0; i--) { LocationProviderProxy provider = mProviders.get(i);
LocationProviderImpl provider = providers.get(i);
if (provider.requiresNetwork()) { if (provider.requiresNetwork()) {
provider.updateNetworkState(mNetworkState); provider.updateNetworkState(mNetworkState);
} }
@ -1930,10 +1949,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
requiresNetwork, requiresSatellite, requiresNetwork, requiresSatellite,
requiresCell, hasMonetaryCost, supportsAltitude, requiresCell, hasMonetaryCost, supportsAltitude,
supportsSpeed, supportsBearing, powerRequirement, accuracy); supportsSpeed, supportsBearing, powerRequirement, accuracy);
if (LocationProviderImpl.getProvider(name) != null) { if (mProvidersByName.get(name) != null) {
throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
} }
LocationProviderImpl.addProvider(provider); addProvider(new LocationProviderProxy(name, provider));
mMockProviders.put(name, provider); mMockProviders.put(name, provider);
updateProvidersLocked(); updateProvidersLocked();
} }
@ -1946,7 +1965,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (mockProvider == null) { if (mockProvider == null) {
throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
} }
LocationProviderImpl.removeProvider(mockProvider); removeProvider(mProvidersByName.get(provider));
mMockProviders.remove(mockProvider); mMockProviders.remove(mockProvider);
updateProvidersLocked(); updateProvidersLocked();
} }

View File

@ -19,17 +19,19 @@ package android.test;
import android.location.Criteria; import android.location.Criteria;
import android.location.ILocationManager; import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location; import android.location.Location;
import android.location.LocationProvider;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log;
import com.android.internal.location.LocationProviderImpl;
/** /**
* @hide - This is part of a framework that is under development and should not be used for * @hide - This is part of a framework that is under development and should not be used for
* active development. * active development.
*/ */
public class TestLocationProvider extends LocationProviderImpl { public class TestLocationProvider extends ILocationProvider.Stub {
public static final String PROVIDER_NAME = "test"; public static final String PROVIDER_NAME = "test";
public static final double LAT = 0; public static final double LAT = 0;
@ -37,9 +39,12 @@ public class TestLocationProvider extends LocationProviderImpl {
public static final double ALTITUDE = 10000; public static final double ALTITUDE = 10000;
public static final float SPEED = 10; public static final float SPEED = 10;
public static final float BEARING = 1; 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 long LOCATION_INTERVAL = 1000;
private static final String TAG = "TestLocationProvider";
private final ILocationManager mLocationManager;
private Location mLocation; private Location mLocation;
private boolean mEnabled; private boolean mEnabled;
private TestLocationProviderThread mThread; private TestLocationProviderThread mThread;
@ -75,59 +80,46 @@ public class TestLocationProvider extends LocationProviderImpl {
} }
public TestLocationProvider(ILocationManager locationManager) { public TestLocationProvider(ILocationManager locationManager) {
super(PROVIDER_NAME, locationManager); mLocationManager = locationManager;
mLocation = new Location(PROVIDER_NAME); mLocation = new Location(PROVIDER_NAME);
} }
//LocationProvider methods
@Override
public int getAccuracy() { public int getAccuracy() {
return Criteria.ACCURACY_COARSE; return Criteria.ACCURACY_COARSE;
} }
@Override
public int getPowerRequirement() { public int getPowerRequirement() {
return Criteria.NO_REQUIREMENT; return Criteria.NO_REQUIREMENT;
} }
@Override
public boolean hasMonetaryCost() { public boolean hasMonetaryCost() {
return false; return false;
} }
@Override
public boolean requiresCell() { public boolean requiresCell() {
return false; return false;
} }
@Override
public boolean requiresNetwork() { public boolean requiresNetwork() {
return false; return false;
} }
@Override
public boolean requiresSatellite() { public boolean requiresSatellite() {
return false; return false;
} }
@Override
public boolean supportsAltitude() { public boolean supportsAltitude() {
return true; return true;
} }
@Override
public boolean supportsBearing() { public boolean supportsBearing() {
return true; return true;
} }
@Override
public boolean supportsSpeed() { public boolean supportsSpeed() {
return true; return true;
} }
//LocationProviderImpl methods
@Override
public synchronized void disable() { public synchronized void disable() {
mEnabled = false; mEnabled = false;
if (mThread != null) { if (mThread != null) {
@ -140,23 +132,49 @@ public class TestLocationProvider extends LocationProviderImpl {
} }
} }
@Override
public synchronized void enable() { public synchronized void enable() {
mEnabled = true; mEnabled = true;
mThread = new TestLocationProviderThread(); mThread = new TestLocationProviderThread();
mThread.start(); mThread.start();
} }
@Override
public boolean isEnabled() { public boolean isEnabled() {
return mEnabled; return mEnabled;
} }
@Override
public int getStatus(Bundle extras) { public int getStatus(Bundle extras) {
return STATUS; 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() { private void updateLocation() {
long time = SystemClock.uptimeMillis(); long time = SystemClock.uptimeMillis();
long multiplier = (time/5000)%500000; long multiplier = (time/5000)%500000;
@ -170,7 +188,11 @@ public class TestLocationProvider extends LocationProviderImpl {
extras.putInt("extraTest", 24); extras.putInt("extraTest", 24);
mLocation.setExtras(extras); mLocation.setExtras(extras);
mLocation.setTime(time); mLocation.setTime(time);
reportLocationChanged(mLocation); try {
mLocationManager.setLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling updateLocation");
}
} }
} }