blob: ef2056b58a87636fa38b6a37f1a9cc61956940c2 [file] [log] [blame]
Mike Lockwoode932f7f2009-04-06 10:51:26 -07001/*
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
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070018
Mike Lockwood628fd6d2010-01-25 22:46:13 -050019import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.ServiceConnection;
Mike Lockwood03ca2162010-04-01 08:10:09 -070023import android.location.Criteria;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070024import android.location.ILocationProvider;
25import android.location.Location;
Mike Lockwood03d24672009-10-08 15:45:03 -040026import android.net.NetworkInfo;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070027import android.os.Bundle;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050028import android.os.Handler;
Mike Lockwood3681f262009-05-12 10:52:03 -040029import android.os.IBinder;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070030import android.os.RemoteException;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050031import android.os.SystemClock;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070032import android.os.WorkSource;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070033import android.util.Log;
34
Mike Lockwood00b74272010-03-26 10:41:48 -040035import com.android.internal.location.DummyLocationProvider;
36
Mike Lockwoode932f7f2009-04-06 10:51:26 -070037/**
Mike Lockwoodd03ff942010-02-09 08:46:14 -050038 * A class for proxying location providers implemented as services.
Mike Lockwoode932f7f2009-04-06 10:51:26 -070039 *
40 * {@hide}
41 */
Mike Lockwoodd03ff942010-02-09 08:46:14 -050042public class LocationProviderProxy implements LocationProviderInterface {
Mike Lockwoode932f7f2009-04-06 10:51:26 -070043
44 private static final String TAG = "LocationProviderProxy";
45
Mike Lockwood628fd6d2010-01-25 22:46:13 -050046 private final Context mContext;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -040047 private final String mName;
Mike Lockwoode97ae402010-09-29 15:23:46 -040048 private final String mServiceName;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050049 private ILocationProvider mProvider;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050050 private Handler mHandler;
51 private final Connection mServiceConnection = new Connection();
52
53 // cached values set by the location manager
Mike Lockwood15e3d0f2009-05-01 07:53:28 -040054 private boolean mLocationTracking = false;
Mike Lockwood2cd543a2010-02-01 12:16:35 -050055 private boolean mEnabled = false;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050056 private long mMinTime = -1;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070057 private WorkSource mMinTimeSource = new WorkSource();
Mike Lockwood628fd6d2010-01-25 22:46:13 -050058 private int mNetworkState;
59 private NetworkInfo mNetworkInfo;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070060
Mike Lockwood628fd6d2010-01-25 22:46:13 -050061 // for caching requiresNetwork, requiresSatellite, etc.
62 private DummyLocationProvider mCachedAttributes;
63
Mike Lockwood628fd6d2010-01-25 22:46:13 -050064 // constructor for proxying location providers implemented in a separate service
65 public LocationProviderProxy(Context context, String name, String serviceName,
66 Handler handler) {
67 mContext = context;
68 mName = name;
Mike Lockwoode97ae402010-09-29 15:23:46 -040069 mServiceName = serviceName;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050070 mHandler = handler;
Mike Lockwoodd03ff942010-02-09 08:46:14 -050071 mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE);
Mike Lockwood628fd6d2010-01-25 22:46:13 -050072 }
73
Mike Lockwoode97ae402010-09-29 15:23:46 -040074 public void reconnect() {
75 synchronized (mServiceConnection) {
76 // unbind first
77 mContext.unbindService(mServiceConnection);
78 mContext.bindService(new Intent(mServiceName), mServiceConnection,
79 Context.BIND_AUTO_CREATE);
80 }
81 }
82
Mike Lockwood628fd6d2010-01-25 22:46:13 -050083 private class Connection implements ServiceConnection {
84 public void onServiceConnected(ComponentName className, IBinder service) {
85 Log.d(TAG, "LocationProviderProxy.onServiceConnected " + className);
Mike Lockwoode97ae402010-09-29 15:23:46 -040086 synchronized (mServiceConnection) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050087 mProvider = ILocationProvider.Stub.asInterface(service);
88 if (mProvider != null) {
89 mHandler.post(mServiceConnectedTask);
90 }
91 }
92 }
93
94 public void onServiceDisconnected(ComponentName className) {
95 Log.d(TAG, "LocationProviderProxy.onServiceDisconnected " + className);
Mike Lockwoode97ae402010-09-29 15:23:46 -040096 synchronized (mServiceConnection) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050097 mProvider = null;
98 }
Mike Lockwood3681f262009-05-12 10:52:03 -040099 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700100 }
101
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500102 private Runnable mServiceConnectedTask = new Runnable() {
103 public void run() {
104 ILocationProvider provider;
105 synchronized (mServiceConnection) {
106 provider = mProvider;
107 if (provider == null) {
108 return;
109 }
110 }
111
112 if (mCachedAttributes == null) {
113 try {
Mike Lockwood03ca2162010-04-01 08:10:09 -0700114 mCachedAttributes = new DummyLocationProvider(mName, null);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500115 mCachedAttributes.setRequiresNetwork(provider.requiresNetwork());
116 mCachedAttributes.setRequiresSatellite(provider.requiresSatellite());
117 mCachedAttributes.setRequiresCell(provider.requiresCell());
118 mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost());
119 mCachedAttributes.setSupportsAltitude(provider.supportsAltitude());
120 mCachedAttributes.setSupportsSpeed(provider.supportsSpeed());
121 mCachedAttributes.setSupportsBearing(provider.supportsBearing());
122 mCachedAttributes.setPowerRequirement(provider.getPowerRequirement());
123 mCachedAttributes.setAccuracy(provider.getAccuracy());
124 } catch (RemoteException e) {
125 mCachedAttributes = null;
126 }
127 }
128
129 // resend previous values from the location manager if the service has restarted
130 try {
131 if (mEnabled) {
132 provider.enable();
133 }
134 if (mLocationTracking) {
135 provider.enableLocationTracking(true);
136 }
137 if (mMinTime >= 0) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700138 provider.setMinTime(mMinTime, mMinTimeSource);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500139 }
140 if (mNetworkInfo != null) {
141 provider.updateNetworkState(mNetworkState, mNetworkInfo);
142 }
143 } catch (RemoteException e) {
144 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700145 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500146 };
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700147
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400148 public String getName() {
149 return mName;
150 }
151
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700152 public boolean requiresNetwork() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500153 if (mCachedAttributes != null) {
154 return mCachedAttributes.requiresNetwork();
155 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700156 return false;
157 }
158 }
159
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700160 public boolean requiresSatellite() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500161 if (mCachedAttributes != null) {
162 return mCachedAttributes.requiresSatellite();
163 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700164 return false;
165 }
166 }
167
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700168 public boolean requiresCell() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500169 if (mCachedAttributes != null) {
170 return mCachedAttributes.requiresCell();
171 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700172 return false;
173 }
174 }
175
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700176 public boolean hasMonetaryCost() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500177 if (mCachedAttributes != null) {
178 return mCachedAttributes.hasMonetaryCost();
179 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700180 return false;
181 }
182 }
183
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700184 public boolean supportsAltitude() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500185 if (mCachedAttributes != null) {
186 return mCachedAttributes.supportsAltitude();
187 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700188 return false;
189 }
190 }
191
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700192 public boolean supportsSpeed() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500193 if (mCachedAttributes != null) {
194 return mCachedAttributes.supportsSpeed();
195 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700196 return false;
197 }
198 }
199
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400200 public boolean supportsBearing() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500201 if (mCachedAttributes != null) {
202 return mCachedAttributes.supportsBearing();
203 } else {
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700204 return false;
205 }
206 }
207
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700208 public int getPowerRequirement() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500209 if (mCachedAttributes != null) {
210 return mCachedAttributes.getPowerRequirement();
211 } else {
212 return -1;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700213 }
214 }
215
Mike Lockwood03ca2162010-04-01 08:10:09 -0700216 public boolean meetsCriteria(Criteria criteria) {
217 ILocationProvider provider;
218 synchronized (mServiceConnection) {
219 provider = mProvider;
220 }
221 if (provider != null) {
222 try {
223 return provider.meetsCriteria(criteria);
224 } catch (RemoteException e) {
225 }
226 }
227 // default implementation if we lost connection to the provider
228 if ((criteria.getAccuracy() != Criteria.NO_REQUIREMENT) &&
229 (criteria.getAccuracy() < getAccuracy())) {
230 return false;
231 }
232 int criteriaPower = criteria.getPowerRequirement();
233 if ((criteriaPower != Criteria.NO_REQUIREMENT) &&
234 (criteriaPower < getPowerRequirement())) {
235 return false;
236 }
237 if (criteria.isAltitudeRequired() && !supportsAltitude()) {
238 return false;
239 }
240 if (criteria.isSpeedRequired() && !supportsSpeed()) {
241 return false;
242 }
243 if (criteria.isBearingRequired() && !supportsBearing()) {
244 return false;
245 }
246 return true;
247 }
248
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700249 public int getAccuracy() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500250 if (mCachedAttributes != null) {
251 return mCachedAttributes.getAccuracy();
252 } else {
253 return -1;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700254 }
255 }
256
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700257 public void enable() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500258 mEnabled = true;
259 ILocationProvider provider;
260 synchronized (mServiceConnection) {
261 provider = mProvider;
262 }
263 if (provider != null) {
264 try {
265 provider.enable();
266 } catch (RemoteException e) {
267 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700268 }
269 }
270
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700271 public void disable() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500272 mEnabled = false;
273 ILocationProvider provider;
274 synchronized (mServiceConnection) {
275 provider = mProvider;
276 }
277 if (provider != null) {
278 try {
279 provider.disable();
280 } catch (RemoteException e) {
281 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700282 }
283 }
284
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700285 public boolean isEnabled() {
Mike Lockwood2cd543a2010-02-01 12:16:35 -0500286 return mEnabled;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700287 }
288
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700289 public int getStatus(Bundle extras) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500290 ILocationProvider provider;
291 synchronized (mServiceConnection) {
292 provider = mProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700293 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500294 if (provider != null) {
295 try {
296 return provider.getStatus(extras);
297 } catch (RemoteException e) {
298 }
299 }
300 return 0;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700301 }
302
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700303 public long getStatusUpdateTime() {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500304 ILocationProvider provider;
305 synchronized (mServiceConnection) {
306 provider = mProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700307 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500308 if (provider != null) {
309 try {
310 return provider.getStatusUpdateTime();
311 } catch (RemoteException e) {
312 }
313 }
314 return 0;
315 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700316
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -0600317 public String getInternalState() {
318 try {
319 return mProvider.getInternalState();
320 } catch (RemoteException e) {
321 Log.e(TAG, "getInternalState failed", e);
322 return null;
323 }
324 }
325
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400326 public boolean isLocationTracking() {
327 return mLocationTracking;
328 }
329
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700330 public void enableLocationTracking(boolean enable) {
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400331 mLocationTracking = enable;
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500332 if (!enable) {
333 mMinTime = -1;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700334 mMinTimeSource.clear();
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500335 }
336 ILocationProvider provider;
337 synchronized (mServiceConnection) {
338 provider = mProvider;
339 }
340 if (provider != null) {
341 try {
342 provider.enableLocationTracking(enable);
343 } catch (RemoteException e) {
344 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700345 }
346 }
347
Mike Lockwood03ca2162010-04-01 08:10:09 -0700348 public boolean requestSingleShotFix() {
349 return false;
350 }
351
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400352 public long getMinTime() {
353 return mMinTime;
354 }
355
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700356 public void setMinTime(long minTime, WorkSource ws) {
357 mMinTime = minTime;
358 mMinTimeSource.set(ws);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500359 ILocationProvider provider;
360 synchronized (mServiceConnection) {
361 provider = mProvider;
362 }
363 if (provider != null) {
364 try {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700365 provider.setMinTime(minTime, ws);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500366 } catch (RemoteException e) {
367 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700368 }
369 }
370
Mike Lockwood03d24672009-10-08 15:45:03 -0400371 public void updateNetworkState(int state, NetworkInfo info) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500372 mNetworkState = state;
373 mNetworkInfo = info;
374 ILocationProvider provider;
375 synchronized (mServiceConnection) {
376 provider = mProvider;
377 }
378 if (provider != null) {
379 try {
380 provider.updateNetworkState(state, info);
381 } catch (RemoteException e) {
382 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700383 }
384 }
385
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400386 public void updateLocation(Location location) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500387 ILocationProvider provider;
388 synchronized (mServiceConnection) {
389 provider = mProvider;
390 }
391 if (provider != null) {
392 try {
393 provider.updateLocation(location);
394 } catch (RemoteException e) {
395 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400396 }
397 }
398
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700399 public boolean sendExtraCommand(String command, Bundle extras) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500400 ILocationProvider provider;
401 synchronized (mServiceConnection) {
402 provider = mProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700403 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500404 if (provider != null) {
405 try {
406 provider.sendExtraCommand(command, extras);
407 } catch (RemoteException e) {
408 }
409 }
410 return false;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700411 }
412
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400413 public void addListener(int uid) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500414 ILocationProvider provider;
415 synchronized (mServiceConnection) {
416 provider = mProvider;
417 }
418 if (provider != null) {
419 try {
420 provider.addListener(uid);
421 } catch (RemoteException e) {
422 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700423 }
424 }
425
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400426 public void removeListener(int uid) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500427 ILocationProvider provider;
428 synchronized (mServiceConnection) {
429 provider = mProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700430 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500431 if (provider != null) {
432 try {
433 provider.removeListener(uid);
434 } catch (RemoteException e) {
435 }
436 }
Mike Lockwood3681f262009-05-12 10:52:03 -0400437 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700438}