summaryrefslogtreecommitdiffstats
path: root/location/java/com
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-01-25 22:46:13 -0500
committerMike Lockwood <lockwood@android.com>2010-02-08 23:20:27 -0500
commit628fd6d9c11ed9806abebf34bc986247c106328f (patch)
tree402876b69159436587770bc8754f6a66d02326ed /location/java/com
parent53bd2522ca7767f46646606123b6e2689b811850 (diff)
downloadframeworks_base-628fd6d9c11ed9806abebf34bc986247c106328f.zip
frameworks_base-628fd6d9c11ed9806abebf34bc986247c106328f.tar.gz
frameworks_base-628fd6d9c11ed9806abebf34bc986247c106328f.tar.bz2
Network Location unbundling:
The network location and geocode provider services are now started on demand and their interfaces are now retrieved via bindService(). Remove obsolete LocationManager installLocationProvider() and installGeocodeProvider() methods. Add abstract class android.location.provider.GeocodeProvider to provide a public wrapper to the IGeocodeProvider Binder interface. Replaces the LocationManager.GeocodeProvider interface. Rename LocationProviderImpl to android.location.provider.LocationProvider. Move LocationManager.reportLocation() to android.location.provider.LocationProvider, so all methods related to external location providers are now all in one class. Avoid calling from the Location Manager Service into providers that are disabled so we do not start the network location service unnecessarily. Change-Id: If3ed2d5d62b83ba508006711d575cad09f4a0007 Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'location/java/com')
-rw-r--r--location/java/com/android/internal/location/GeocoderProxy.java105
-rw-r--r--location/java/com/android/internal/location/LocationProviderProxy.java354
2 files changed, 341 insertions, 118 deletions
diff --git a/location/java/com/android/internal/location/GeocoderProxy.java b/location/java/com/android/internal/location/GeocoderProxy.java
new file mode 100644
index 0000000..b06297b
--- /dev/null
+++ b/location/java/com/android/internal/location/GeocoderProxy.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.location;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.location.Address;
+import android.location.GeocoderParams;
+import android.location.IGeocodeProvider;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * A class for proxying IGeocodeProvider implementations.
+ *
+ * {@hide}
+ */
+public class GeocoderProxy {
+
+ private static final String TAG = "GeocoderProxy";
+
+ private final Context mContext;
+ private final Intent mIntent;
+ private final Connection mServiceConnection = new Connection();
+ private IGeocodeProvider mProvider;
+
+ public GeocoderProxy(Context context, String serviceName) {
+ mContext = context;
+ mIntent = new Intent(serviceName);
+ mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ private class Connection implements ServiceConnection {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ Log.d(TAG, "onServiceConnected " + className);
+ synchronized (this) {
+ mProvider = IGeocodeProvider.Stub.asInterface(service);
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ Log.d(TAG, "onServiceDisconnected " + className);
+ synchronized (this) {
+ mProvider = null;
+ }
+ }
+ }
+
+ public String getFromLocation(double latitude, double longitude, int maxResults,
+ GeocoderParams params, List<Address> addrs) {
+ IGeocodeProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ return provider.getFromLocation(latitude, longitude, maxResults,
+ params, addrs);
+ } catch (RemoteException e) {
+ Log.e(TAG, "getFromLocation failed", e);
+ }
+ }
+ return "Service not Available";
+ }
+
+ public String getFromLocationName(String locationName,
+ double lowerLeftLatitude, double lowerLeftLongitude,
+ double upperRightLatitude, double upperRightLongitude, int maxResults,
+ GeocoderParams params, List<Address> addrs) {
+ IGeocodeProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ return provider.getFromLocationName(locationName, lowerLeftLatitude,
+ lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
+ maxResults, params, addrs);
+ } catch (RemoteException e) {
+ Log.e(TAG, "getFromLocationName failed", e);
+ }
+ }
+ return "Service not Available";
+ }
+}
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index 2e0be89..361104f 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -16,155 +16,229 @@
package com.android.internal.location;
-import android.location.Address;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.location.ILocationProvider;
import android.location.Location;
-import android.location.LocationManager;
import android.net.NetworkInfo;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.util.Log;
-import java.util.List;
-
/**
- * A class for proxying remote ILocationProvider implementations.
+ * A class for proxying ILocationProvider implementations.
*
* {@hide}
*/
-public class LocationProviderProxy implements IBinder.DeathRecipient {
+public class LocationProviderProxy {
private static final String TAG = "LocationProviderProxy";
+ private final Context mContext;
private final String mName;
- private final ILocationProvider mProvider;
+ private ILocationProvider mProvider;
+ private Intent mIntent;
+ private Handler mHandler;
+ private final Connection mServiceConnection = new Connection();
+
+ // cached values set by the location manager
private boolean mLocationTracking = false;
private boolean mEnabled = false;
- private long mMinTime = 0;
- private boolean mDead;
+ private long mMinTime = -1;
+ private int mNetworkState;
+ private NetworkInfo mNetworkInfo;
- public LocationProviderProxy(String name, ILocationProvider provider) {
+ // 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;
- try {
- provider.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- Log.e(TAG, "linkToDeath failed", e);
- mDead = true;
- }
}
- public void unlinkProvider() {
- if (mProvider != null) {
- mProvider.asBinder().unlinkToDeath(this, 0);
+ // 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);
+ }
+
+ private class Connection implements ServiceConnection {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ Log.d(TAG, "LocationProviderProxy.onServiceConnected " + className);
+ synchronized (this) {
+ mProvider = ILocationProvider.Stub.asInterface(service);
+ if (mProvider != null) {
+ mHandler.post(mServiceConnectedTask);
+ }
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ Log.d(TAG, "LocationProviderProxy.onServiceDisconnected " + className);
+ synchronized (this) {
+ mProvider = null;
+ }
}
}
+ private Runnable mServiceConnectedTask = new Runnable() {
+ public void run() {
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ if (provider == null) {
+ return;
+ }
+ }
+
+ if (mCachedAttributes == null) {
+ try {
+ mCachedAttributes = new DummyLocationProvider(mName);
+ mCachedAttributes.setRequiresNetwork(provider.requiresNetwork());
+ mCachedAttributes.setRequiresSatellite(provider.requiresSatellite());
+ mCachedAttributes.setRequiresCell(provider.requiresCell());
+ mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost());
+ mCachedAttributes.setSupportsAltitude(provider.supportsAltitude());
+ mCachedAttributes.setSupportsSpeed(provider.supportsSpeed());
+ mCachedAttributes.setSupportsBearing(provider.supportsBearing());
+ mCachedAttributes.setPowerRequirement(provider.getPowerRequirement());
+ mCachedAttributes.setAccuracy(provider.getAccuracy());
+ } catch (RemoteException e) {
+ mCachedAttributes = null;
+ }
+ }
+
+ // resend previous values from the location manager if the service has restarted
+ try {
+ if (mEnabled) {
+ provider.enable();
+ }
+ if (mLocationTracking) {
+ provider.enableLocationTracking(true);
+ }
+ if (mMinTime >= 0) {
+ provider.setMinTime(mMinTime);
+ }
+ if (mNetworkInfo != null) {
+ provider.updateNetworkState(mNetworkState, mNetworkInfo);
+ }
+ } catch (RemoteException e) {
+ }
+ }
+ };
+
public String getName() {
return mName;
}
- public boolean isDead() {
- return mDead;
- }
-
public boolean requiresNetwork() {
- try {
- return mProvider.requiresNetwork();
- } catch (RemoteException e) {
- Log.e(TAG, "requiresNetwork failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.requiresNetwork();
+ } else {
return false;
}
}
public boolean requiresSatellite() {
- try {
- return mProvider.requiresSatellite();
- } catch (RemoteException e) {
- Log.e(TAG, "requiresSatellite failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.requiresSatellite();
+ } else {
return false;
}
}
public boolean requiresCell() {
- try {
- return mProvider.requiresCell();
- } catch (RemoteException e) {
- Log.e(TAG, "requiresCell failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.requiresCell();
+ } else {
return false;
}
}
public boolean hasMonetaryCost() {
- try {
- return mProvider.hasMonetaryCost();
- } catch (RemoteException e) {
- Log.e(TAG, "hasMonetaryCost failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.hasMonetaryCost();
+ } else {
return false;
}
}
public boolean supportsAltitude() {
- try {
- return mProvider.supportsAltitude();
- } catch (RemoteException e) {
- Log.e(TAG, "supportsAltitude failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.supportsAltitude();
+ } else {
return false;
}
}
public boolean supportsSpeed() {
- try {
- return mProvider.supportsSpeed();
- } catch (RemoteException e) {
- Log.e(TAG, "supportsSpeed failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.supportsSpeed();
+ } else {
return false;
}
}
public boolean supportsBearing() {
- try {
- return mProvider.supportsBearing();
- } catch (RemoteException e) {
- Log.e(TAG, "supportsBearing failed", e);
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.supportsBearing();
+ } else {
return false;
}
}
public int getPowerRequirement() {
- try {
- return mProvider.getPowerRequirement();
- } catch (RemoteException e) {
- Log.e(TAG, "getPowerRequirement failed", e);
- return 0;
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.getPowerRequirement();
+ } else {
+ return -1;
}
}
public int getAccuracy() {
- try {
- return mProvider.getAccuracy();
- } catch (RemoteException e) {
- Log.e(TAG, "getAccuracy failed", e);
- return 0;
+ if (mCachedAttributes != null) {
+ return mCachedAttributes.getAccuracy();
+ } else {
+ return -1;
}
}
public void enable() {
- try {
- mProvider.enable();
- mEnabled = true;
- } catch (RemoteException e) {
- Log.e(TAG, "enable failed", e);
+ mEnabled = true;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.enable();
+ } catch (RemoteException e) {
+ }
}
}
public void disable() {
- try {
- mProvider.disable();
- mEnabled = false;
- } catch (RemoteException e) {
- Log.e(TAG, "disable failed", e);
+ mEnabled = false;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.disable();
+ } catch (RemoteException e) {
+ }
}
}
@@ -173,22 +247,32 @@ public class LocationProviderProxy implements IBinder.DeathRecipient {
}
public int getStatus(Bundle extras) {
- try {
- return mProvider.getStatus(extras);
- } catch (RemoteException e) {
- Log.e(TAG, "getStatus failed", e);
- return 0;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
}
+ if (provider != null) {
+ try {
+ return provider.getStatus(extras);
+ } catch (RemoteException e) {
+ }
+ }
+ return 0;
}
public long getStatusUpdateTime() {
- try {
- return mProvider.getStatusUpdateTime();
- } catch (RemoteException e) {
- Log.e(TAG, "getStatusUpdateTime failed", e);
- return 0;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
}
- }
+ if (provider != null) {
+ try {
+ return provider.getStatusUpdateTime();
+ } catch (RemoteException e) {
+ }
+ }
+ return 0;
+ }
public boolean isLocationTracking() {
return mLocationTracking;
@@ -196,10 +280,18 @@ public class LocationProviderProxy implements IBinder.DeathRecipient {
public void enableLocationTracking(boolean enable) {
mLocationTracking = enable;
- try {
- mProvider.enableLocationTracking(enable);
- } catch (RemoteException e) {
- Log.e(TAG, "enableLocationTracking failed", e);
+ if (!enable) {
+ mMinTime = -1;
+ }
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.enableLocationTracking(enable);
+ } catch (RemoteException e) {
+ }
}
}
@@ -208,58 +300,84 @@ public class LocationProviderProxy implements IBinder.DeathRecipient {
}
public void setMinTime(long minTime) {
- mMinTime = minTime;
- try {
- mProvider.setMinTime(minTime);
- } catch (RemoteException e) {
- Log.e(TAG, "setMinTime failed", e);
+ mMinTime = minTime;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.setMinTime(minTime);
+ } catch (RemoteException e) {
+ }
}
}
public void updateNetworkState(int state, NetworkInfo info) {
- try {
- mProvider.updateNetworkState(state, info);
- } catch (RemoteException e) {
- Log.e(TAG, "updateNetworkState failed", e);
+ mNetworkState = state;
+ mNetworkInfo = info;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.updateNetworkState(state, info);
+ } catch (RemoteException e) {
+ }
}
}
public void updateLocation(Location location) {
- try {
- mProvider.updateLocation(location);
- } catch (RemoteException e) {
- Log.e(TAG, "updateLocation failed", e);
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.updateLocation(location);
+ } catch (RemoteException e) {
+ }
}
}
public boolean sendExtraCommand(String command, Bundle extras) {
- try {
- return mProvider.sendExtraCommand(command, extras);
- } catch (RemoteException e) {
- Log.e(TAG, "sendExtraCommand failed", e);
- return false;
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
}
+ if (provider != null) {
+ try {
+ provider.sendExtraCommand(command, extras);
+ } catch (RemoteException e) {
+ }
+ }
+ return false;
}
public void addListener(int uid) {
- try {
- mProvider.addListener(uid);
- } catch (RemoteException e) {
- Log.e(TAG, "addListener failed", e);
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.addListener(uid);
+ } catch (RemoteException e) {
+ }
}
}
public void removeListener(int uid) {
- try {
- mProvider.removeListener(uid);
- } catch (RemoteException e) {
- Log.e(TAG, "removeListener failed", e);
+ ILocationProvider provider;
+ synchronized (mServiceConnection) {
+ provider = mProvider;
+ }
+ if (provider != null) {
+ try {
+ provider.removeListener(uid);
+ } catch (RemoteException e) {
+ }
}
- }
-
- public void binderDied() {
- Log.w(TAG, "Location Provider " + mName + " died");
- mDead = true;
- mProvider.asBinder().unlinkToDeath(this, 0);
}
}