Merge "Clean up interface between LocationManagerService and the location providers:"

This commit is contained in:
Mike Lockwood
2010-02-10 07:33:10 -08:00
committed by Android (Google) Code Review
8 changed files with 123 additions and 260 deletions

View File

@@ -22,7 +22,6 @@ import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
import android.location.ILocationListener;
import android.location.ILocationProvider;
import android.location.Location;
import android.os.Bundle;

View File

@@ -21,7 +21,7 @@ import android.net.NetworkInfo;
import android.os.Bundle;
/**
* Binder interface for location providers.
* Binder interface for services that implement location providers.
*
* {@hide}
*/

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.location;
import android.location.Location;
import android.net.NetworkInfo;
import android.os.Bundle;
/**
* Location Manager's interface for location providers.
*
* {@hide}
*/
public interface LocationProviderInterface {
String getName();
boolean requiresNetwork();
boolean requiresSatellite();
boolean requiresCell();
boolean hasMonetaryCost();
boolean supportsAltitude();
boolean supportsSpeed();
boolean supportsBearing();
int getPowerRequirement();
int getAccuracy();
boolean isEnabled();
void enable();
void disable();
int getStatus(Bundle extras);
long getStatusUpdateTime();
void enableLocationTracking(boolean enable);
void setMinTime(long minTime);
void updateNetworkState(int state, NetworkInfo info);
void updateLocation(Location location);
boolean sendExtraCommand(String command, Bundle extras);
void addListener(int uid);
void removeListener(int uid);
}

View File

@@ -26,11 +26,11 @@ import android.location.Criteria;
import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.INetInitiatedListener;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationProviderInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.SntpClient;
@@ -65,7 +65,7 @@ import java.util.Map.Entry;
*
* {@hide}
*/
public class GpsLocationProvider extends ILocationProvider.Stub {
public class GpsLocationProvider implements LocationProviderInterface {
private static final String TAG = "GpsLocationProvider";
@@ -373,6 +373,13 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
}
}
/**
* Returns the name of this provider.
*/
public String getName() {
return LocationManager.GPS_PROVIDER;
}
/**
* Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise.
@@ -576,6 +583,10 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
}
}
public boolean isEnabled() {
return mEnabled;
}
public int getStatus(Bundle extras) {
if (extras != null) {
extras.putInt("satellites", mSvCount);

View File

@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.location.ILocationProvider;
import android.location.Location;
import android.location.LocationProviderInterface;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
@@ -31,18 +32,17 @@ import android.os.SystemClock;
import android.util.Log;
/**
* A class for proxying ILocationProvider implementations.
* A class for proxying location providers implemented as services.
*
* {@hide}
*/
public class LocationProviderProxy {
public class LocationProviderProxy implements LocationProviderInterface {
private static final String TAG = "LocationProviderProxy";
private final Context mContext;
private final String mName;
private ILocationProvider mProvider;
private Intent mIntent;
private Handler mHandler;
private final Connection mServiceConnection = new Connection();
@@ -56,21 +56,13 @@ public class LocationProviderProxy {
// for caching requiresNetwork, requiresSatellite, etc.
private DummyLocationProvider mCachedAttributes;
// constructor for proxying built-in location providers
public LocationProviderProxy(Context context, String name, ILocationProvider provider) {
mContext = context;
mName = name;
mProvider = provider;
}
// constructor for proxying location providers implemented in a separate service
public LocationProviderProxy(Context context, String name, String serviceName,
Handler handler) {
mContext = context;
mName = name;
mIntent = new Intent(serviceName);
mHandler = handler;
mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE);
}
private class Connection implements ServiceConnection {

View File

@@ -17,9 +17,9 @@
package com.android.internal.location;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location;
import android.location.LocationProvider;
import android.location.LocationProviderInterface;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.RemoteException;
@@ -33,7 +33,7 @@ import java.io.PrintWriter;
*
* {@hide}
*/
public class MockProvider extends ILocationProvider.Stub {
public class MockProvider implements LocationProviderInterface {
private final String mName;
private final ILocationManager mLocationManager;
private final boolean mRequiresNetwork;
@@ -73,6 +73,10 @@ public class MockProvider extends ILocationProvider.Stub {
mLocation = new Location(name);
}
public String getName() {
return mName;
}
public void disable() {
mEnabled = false;
}
@@ -81,6 +85,10 @@ public class MockProvider extends ILocationProvider.Stub {
mEnabled = true;
}
public boolean isEnabled() {
return mEnabled;
}
public int getStatus(Bundle extras) {
if (mHasStatus) {
extras.clear();

View File

@@ -45,11 +45,11 @@ import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
import android.location.ILocationListener;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.INetInitiatedListener;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationProviderInterface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
@@ -114,8 +114,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private LocationWorkerHandler mLocationHandler;
// Cache the real providers for use in addTestProvider() and removeTestProvider()
LocationProviderProxy mNetworkLocationProvider;
LocationProviderProxy mGpsLocationProvider;
LocationProviderInterface mNetworkLocationProvider;
LocationProviderInterface mGpsLocationProvider;
// Handler messages
private static final int MESSAGE_LOCATION_CHANGED = 1;
@@ -134,10 +134,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
/**
* List of location providers.
*/
private final ArrayList<LocationProviderProxy> mProviders =
new ArrayList<LocationProviderProxy>();
private final HashMap<String, LocationProviderProxy> mProvidersByName
= new HashMap<String, LocationProviderProxy>();
private final ArrayList<LocationProviderInterface> mProviders =
new ArrayList<LocationProviderInterface>();
private final HashMap<String, LocationProviderInterface> mProvidersByName
= new HashMap<String, LocationProviderInterface>();
/**
* Object used internally for synchronization
@@ -411,12 +411,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
private void addProvider(LocationProviderProxy provider) {
private void addProvider(LocationProviderInterface provider) {
mProviders.add(provider);
mProvidersByName.put(provider.getName(), provider);
}
private void removeProvider(LocationProviderProxy provider) {
private void removeProvider(LocationProviderInterface provider) {
mProviders.remove(provider);
mProvidersByName.remove(provider.getName());
}
@@ -445,13 +445,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Attempt to load "real" providers first
if (GpsLocationProvider.isSupported()) {
// Create a gps location provider
GpsLocationProvider provider = new GpsLocationProvider(mContext, this);
mGpsStatusProvider = provider.getGpsStatusProvider();
mNetInitiatedListener = provider.getNetInitiatedListener();
LocationProviderProxy proxy =
new LocationProviderProxy(mContext, LocationManager.GPS_PROVIDER, provider);
addProvider(proxy);
mGpsLocationProvider = proxy;
GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this);
mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
addProvider(gpsProvider);
mGpsLocationProvider = gpsProvider;
}
// initialize external network location and geocoder services
@@ -591,7 +589,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
ArrayList<String> out = new ArrayList<String>(mProviders.size());
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy p = mProviders.get(i);
LocationProviderInterface p = mProviders.get(i);
out.add(p.getName());
}
return out;
@@ -616,7 +614,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
ArrayList<String> out = new ArrayList<String>(mProviders.size());
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy p = mProviders.get(i);
LocationProviderInterface p = mProviders.get(i);
String name = p.getName();
if (isAllowedProviderSafe(name)) {
if (enabledOnly && !isAllowedBySettingsLocked(name)) {
@@ -630,7 +628,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private void updateProvidersLocked() {
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy p = mProviders.get(i);
LocationProviderInterface p = mProviders.get(i);
boolean isEnabled = p.isEnabled();
String name = p.getName();
boolean shouldBeEnabled = isAllowedBySettingsLocked(name);
@@ -647,7 +645,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private void updateProviderListenersLocked(String provider, boolean enabled) {
int listeners = 0;
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
return;
}
@@ -837,8 +835,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
Log.v(TAG, "_requestLocationUpdates: listener = " + receiver);
}
LocationProviderProxy proxy = mProvidersByName.get(provider);
if (proxy == null) {
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -856,14 +854,14 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
if (newUid) {
proxy.addListener(callingUid);
p.addListener(callingUid);
}
boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
if (isProviderEnabled) {
long minTimeForProvider = getMinTimeLocked(provider);
proxy.setMinTime(minTimeForProvider);
proxy.enableLocationTracking(true);
p.setMinTime(minTimeForProvider);
p.enableLocationTracking(true);
} else {
// Notify the listener that updates are currently disabled
receiver.callProviderEnabledLocked(provider, false);
@@ -923,9 +921,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Call dispose() on the obsolete update records.
for (UpdateRecord record : oldRecords.values()) {
if (!providerHasListener(record.mProvider, callingUid, receiver)) {
LocationProviderProxy proxy = mProvidersByName.get(record.mProvider);
if (proxy != null) {
proxy.removeListener(callingUid);
LocationProviderInterface p = mProvidersByName.get(record.mProvider);
if (p != null) {
p.removeListener(callingUid);
}
}
record.disposeLocked();
@@ -949,7 +947,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
hasOtherListener = true;
}
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p != null) {
if (hasOtherListener) {
p.setMinTime(getMinTimeLocked(provider));
@@ -1006,12 +1004,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
synchronized (mLock) {
LocationProviderProxy proxy = mProvidersByName.get(provider);
if (proxy == null) {
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
return false;
}
return proxy.sendExtraCommand(command, extras);
return p.sendExtraCommand(command, extras);
}
}
@@ -1261,7 +1259,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
mProximityReceiver = new Receiver(mProximityListener);
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy provider = mProviders.get(i);
LocationProviderInterface provider = mProviders.get(i);
requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver);
}
}
@@ -1311,7 +1309,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
private Bundle _getProviderInfoLocked(String provider) {
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null || !p.isEnabled()) {
return null;
}
@@ -1359,7 +1357,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private boolean _isProviderEnabledLocked(String provider) {
checkPermissionsSafe(provider);
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -1382,7 +1380,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private Location _getLastKnownLocationLocked(String provider) {
checkPermissionsSafe(provider);
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
throw new IllegalArgumentException("provider=" + provider);
}
@@ -1424,7 +1422,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
return;
}
LocationProviderProxy p = mProvidersByName.get(provider);
LocationProviderInterface p = mProvidersByName.get(provider);
if (p == null) {
return;
}
@@ -1507,9 +1505,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// notify other providers of the new location
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy proxy = mProviders.get(i);
if (!provider.equals(proxy.getName())) {
proxy.updateLocation(location);
LocationProviderInterface p = mProviders.get(i);
if (!provider.equals(p.getName())) {
p.updateLocation(location);
}
}
@@ -1597,7 +1595,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Notify location providers of current network state
synchronized (mLock) {
for (int i = mProviders.size() - 1; i >= 0; i--) {
LocationProviderProxy provider = mProviders.get(i);
LocationProviderInterface provider = mProviders.get(i);
if (provider.isEnabled() && provider.requiresNetwork()) {
provider.updateNetworkState(mNetworkState, info);
}
@@ -1698,16 +1696,16 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// remove the real provider if we are replacing GPS or network provider
if (LocationManager.GPS_PROVIDER.equals(name)
|| LocationManager.NETWORK_PROVIDER.equals(name)) {
LocationProviderProxy proxy = mProvidersByName.get(name);
if (proxy != null) {
proxy.enableLocationTracking(false);
removeProvider(proxy);
LocationProviderInterface p = mProvidersByName.get(name);
if (p != null) {
p.enableLocationTracking(false);
removeProvider(p);
}
}
if (mProvidersByName.get(name) != null) {
throw new IllegalArgumentException("Provider \"" + name + "\" already exists");
}
addProvider(new LocationProviderProxy(mContext, name, provider));
addProvider(provider);
mMockProviders.put(name, provider);
mLastKnownLocation.put(name, null);
updateProvidersLocked();

View File

@@ -1,196 +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 android.test;
import android.location.Criteria;
import android.location.ILocationManager;
import android.location.ILocationProvider;
import android.location.Location;
import android.location.LocationProvider;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
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 ILocationProvider.Stub {
public static final String PROVIDER_NAME = "test";
public static final double LAT = 0;
public static final double LON = 1;
public static final double ALTITUDE = 10000;
public static final float SPEED = 10;
public static final float BEARING = 1;
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;
private class TestLocationProviderThread extends Thread {
private boolean mDone = false;
public TestLocationProviderThread() {
super("TestLocationProviderThread");
}
public void run() {
// thread exits after disable() is called
synchronized (this) {
while (!mDone) {
try {
wait(LOCATION_INTERVAL);
} catch (InterruptedException e) {
}
if (!mDone) {
TestLocationProvider.this.updateLocation();
}
}
}
}
synchronized void setDone() {
mDone = true;
notify();
}
}
public TestLocationProvider(ILocationManager locationManager) {
mLocationManager = locationManager;
mLocation = new Location(PROVIDER_NAME);
}
public int getAccuracy() {
return Criteria.ACCURACY_COARSE;
}
public int getPowerRequirement() {
return Criteria.NO_REQUIREMENT;
}
public boolean hasMonetaryCost() {
return false;
}
public boolean requiresCell() {
return false;
}
public boolean requiresNetwork() {
return false;
}
public boolean requiresSatellite() {
return false;
}
public boolean supportsAltitude() {
return true;
}
public boolean supportsBearing() {
return true;
}
public boolean supportsSpeed() {
return true;
}
public synchronized void disable() {
mEnabled = false;
if (mThread != null) {
mThread.setDone();
try {
mThread.join();
} catch (InterruptedException e) {
}
mThread = null;
}
}
public synchronized void enable() {
mEnabled = true;
mThread = new TestLocationProviderThread();
mThread.start();
}
public boolean isEnabled() {
return mEnabled;
}
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, NetworkInfo info) {
}
public void updateLocation(Location location) {
}
public boolean sendExtraCommand(String command, Bundle extras) {
return false;
}
public void addListener(int uid) {
}
public void removeListener(int uid) {
}
private void updateLocation() {
long time = SystemClock.uptimeMillis();
long multiplier = (time/5000)%500000;
mLocation.setLatitude(LAT*multiplier);
mLocation.setLongitude(LON*multiplier);
mLocation.setAltitude(ALTITUDE);
mLocation.setSpeed(SPEED);
mLocation.setBearing(BEARING*multiplier);
Bundle extras = new Bundle();
extras.putInt("extraTest", 24);
mLocation.setExtras(extras);
mLocation.setTime(time);
try {
mLocationManager.reportLocation(mLocation);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling updateLocation");
}
}
}