LocationProviderProxy.java revision 00b74270c9f136a8727c5f6cda0997a3a905f385
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.location; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.Intent; 22import android.content.ServiceConnection; 23import android.location.ILocationProvider; 24import android.location.Location; 25import android.net.NetworkInfo; 26import android.os.Bundle; 27import android.os.Handler; 28import android.os.IBinder; 29import android.os.RemoteException; 30import android.os.SystemClock; 31import android.util.Log; 32 33import com.android.internal.location.DummyLocationProvider; 34 35/** 36 * A class for proxying location providers implemented as services. 37 * 38 * {@hide} 39 */ 40public class LocationProviderProxy implements LocationProviderInterface { 41 42 private static final String TAG = "LocationProviderProxy"; 43 44 private final Context mContext; 45 private final String mName; 46 private ILocationProvider mProvider; 47 private Handler mHandler; 48 private final Connection mServiceConnection = new Connection(); 49 50 // cached values set by the location manager 51 private boolean mLocationTracking = false; 52 private boolean mEnabled = false; 53 private long mMinTime = -1; 54 private int mNetworkState; 55 private NetworkInfo mNetworkInfo; 56 57 // for caching requiresNetwork, requiresSatellite, etc. 58 private DummyLocationProvider mCachedAttributes; 59 60 // constructor for proxying location providers implemented in a separate service 61 public LocationProviderProxy(Context context, String name, String serviceName, 62 Handler handler) { 63 mContext = context; 64 mName = name; 65 mHandler = handler; 66 mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE); 67 } 68 69 private class Connection implements ServiceConnection { 70 public void onServiceConnected(ComponentName className, IBinder service) { 71 Log.d(TAG, "LocationProviderProxy.onServiceConnected " + className); 72 synchronized (this) { 73 mProvider = ILocationProvider.Stub.asInterface(service); 74 if (mProvider != null) { 75 mHandler.post(mServiceConnectedTask); 76 } 77 } 78 } 79 80 public void onServiceDisconnected(ComponentName className) { 81 Log.d(TAG, "LocationProviderProxy.onServiceDisconnected " + className); 82 synchronized (this) { 83 mProvider = null; 84 } 85 } 86 } 87 88 private Runnable mServiceConnectedTask = new Runnable() { 89 public void run() { 90 ILocationProvider provider; 91 synchronized (mServiceConnection) { 92 provider = mProvider; 93 if (provider == null) { 94 return; 95 } 96 } 97 98 if (mCachedAttributes == null) { 99 try { 100 mCachedAttributes = new DummyLocationProvider(mName); 101 mCachedAttributes.setRequiresNetwork(provider.requiresNetwork()); 102 mCachedAttributes.setRequiresSatellite(provider.requiresSatellite()); 103 mCachedAttributes.setRequiresCell(provider.requiresCell()); 104 mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost()); 105 mCachedAttributes.setSupportsAltitude(provider.supportsAltitude()); 106 mCachedAttributes.setSupportsSpeed(provider.supportsSpeed()); 107 mCachedAttributes.setSupportsBearing(provider.supportsBearing()); 108 mCachedAttributes.setPowerRequirement(provider.getPowerRequirement()); 109 mCachedAttributes.setAccuracy(provider.getAccuracy()); 110 } catch (RemoteException e) { 111 mCachedAttributes = null; 112 } 113 } 114 115 // resend previous values from the location manager if the service has restarted 116 try { 117 if (mEnabled) { 118 provider.enable(); 119 } 120 if (mLocationTracking) { 121 provider.enableLocationTracking(true); 122 } 123 if (mMinTime >= 0) { 124 provider.setMinTime(mMinTime); 125 } 126 if (mNetworkInfo != null) { 127 provider.updateNetworkState(mNetworkState, mNetworkInfo); 128 } 129 } catch (RemoteException e) { 130 } 131 } 132 }; 133 134 public String getName() { 135 return mName; 136 } 137 138 public boolean requiresNetwork() { 139 if (mCachedAttributes != null) { 140 return mCachedAttributes.requiresNetwork(); 141 } else { 142 return false; 143 } 144 } 145 146 public boolean requiresSatellite() { 147 if (mCachedAttributes != null) { 148 return mCachedAttributes.requiresSatellite(); 149 } else { 150 return false; 151 } 152 } 153 154 public boolean requiresCell() { 155 if (mCachedAttributes != null) { 156 return mCachedAttributes.requiresCell(); 157 } else { 158 return false; 159 } 160 } 161 162 public boolean hasMonetaryCost() { 163 if (mCachedAttributes != null) { 164 return mCachedAttributes.hasMonetaryCost(); 165 } else { 166 return false; 167 } 168 } 169 170 public boolean supportsAltitude() { 171 if (mCachedAttributes != null) { 172 return mCachedAttributes.supportsAltitude(); 173 } else { 174 return false; 175 } 176 } 177 178 public boolean supportsSpeed() { 179 if (mCachedAttributes != null) { 180 return mCachedAttributes.supportsSpeed(); 181 } else { 182 return false; 183 } 184 } 185 186 public boolean supportsBearing() { 187 if (mCachedAttributes != null) { 188 return mCachedAttributes.supportsBearing(); 189 } else { 190 return false; 191 } 192 } 193 194 public int getPowerRequirement() { 195 if (mCachedAttributes != null) { 196 return mCachedAttributes.getPowerRequirement(); 197 } else { 198 return -1; 199 } 200 } 201 202 public int getAccuracy() { 203 if (mCachedAttributes != null) { 204 return mCachedAttributes.getAccuracy(); 205 } else { 206 return -1; 207 } 208 } 209 210 public void enable() { 211 mEnabled = true; 212 ILocationProvider provider; 213 synchronized (mServiceConnection) { 214 provider = mProvider; 215 } 216 if (provider != null) { 217 try { 218 provider.enable(); 219 } catch (RemoteException e) { 220 } 221 } 222 } 223 224 public void disable() { 225 mEnabled = false; 226 ILocationProvider provider; 227 synchronized (mServiceConnection) { 228 provider = mProvider; 229 } 230 if (provider != null) { 231 try { 232 provider.disable(); 233 } catch (RemoteException e) { 234 } 235 } 236 } 237 238 public boolean isEnabled() { 239 return mEnabled; 240 } 241 242 public int getStatus(Bundle extras) { 243 ILocationProvider provider; 244 synchronized (mServiceConnection) { 245 provider = mProvider; 246 } 247 if (provider != null) { 248 try { 249 return provider.getStatus(extras); 250 } catch (RemoteException e) { 251 } 252 } 253 return 0; 254 } 255 256 public long getStatusUpdateTime() { 257 ILocationProvider provider; 258 synchronized (mServiceConnection) { 259 provider = mProvider; 260 } 261 if (provider != null) { 262 try { 263 return provider.getStatusUpdateTime(); 264 } catch (RemoteException e) { 265 } 266 } 267 return 0; 268 } 269 270 public String getInternalState() { 271 try { 272 return mProvider.getInternalState(); 273 } catch (RemoteException e) { 274 Log.e(TAG, "getInternalState failed", e); 275 return null; 276 } 277 } 278 279 public boolean isLocationTracking() { 280 return mLocationTracking; 281 } 282 283 public void enableLocationTracking(boolean enable) { 284 mLocationTracking = enable; 285 if (!enable) { 286 mMinTime = -1; 287 } 288 ILocationProvider provider; 289 synchronized (mServiceConnection) { 290 provider = mProvider; 291 } 292 if (provider != null) { 293 try { 294 provider.enableLocationTracking(enable); 295 } catch (RemoteException e) { 296 } 297 } 298 } 299 300 public long getMinTime() { 301 return mMinTime; 302 } 303 304 public void setMinTime(long minTime) { 305 mMinTime = minTime; 306 ILocationProvider provider; 307 synchronized (mServiceConnection) { 308 provider = mProvider; 309 } 310 if (provider != null) { 311 try { 312 provider.setMinTime(minTime); 313 } catch (RemoteException e) { 314 } 315 } 316 } 317 318 public void updateNetworkState(int state, NetworkInfo info) { 319 mNetworkState = state; 320 mNetworkInfo = info; 321 ILocationProvider provider; 322 synchronized (mServiceConnection) { 323 provider = mProvider; 324 } 325 if (provider != null) { 326 try { 327 provider.updateNetworkState(state, info); 328 } catch (RemoteException e) { 329 } 330 } 331 } 332 333 public void updateLocation(Location location) { 334 ILocationProvider provider; 335 synchronized (mServiceConnection) { 336 provider = mProvider; 337 } 338 if (provider != null) { 339 try { 340 provider.updateLocation(location); 341 } catch (RemoteException e) { 342 } 343 } 344 } 345 346 public boolean sendExtraCommand(String command, Bundle extras) { 347 ILocationProvider provider; 348 synchronized (mServiceConnection) { 349 provider = mProvider; 350 } 351 if (provider != null) { 352 try { 353 provider.sendExtraCommand(command, extras); 354 } catch (RemoteException e) { 355 } 356 } 357 return false; 358 } 359 360 public void addListener(int uid) { 361 ILocationProvider provider; 362 synchronized (mServiceConnection) { 363 provider = mProvider; 364 } 365 if (provider != null) { 366 try { 367 provider.addListener(uid); 368 } catch (RemoteException e) { 369 } 370 } 371 } 372 373 public void removeListener(int uid) { 374 ILocationProvider provider; 375 synchronized (mServiceConnection) { 376 provider = mProvider; 377 } 378 if (provider != null) { 379 try { 380 provider.removeListener(uid); 381 } catch (RemoteException e) { 382 } 383 } 384 } 385} 386