diff options
Diffstat (limited to 'location/java/com')
-rw-r--r-- | location/java/com/android/internal/location/GeocoderProxy.java | 105 | ||||
-rw-r--r-- | location/java/com/android/internal/location/LocationProviderProxy.java | 354 |
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); } } |