blob: 14db862065e3555918370935261b578f14a623ad [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
Nick Pelly6fa9ad42012-07-16 12:18:23 -070019import java.io.FileDescriptor;
20import java.io.PrintWriter;
21import java.util.List;
22
Mike Lockwood628fd6d2010-01-25 22:46:13 -050023import android.content.Context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070024import android.location.LocationProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070025import android.os.Bundle;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050026import android.os.Handler;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070027import android.os.RemoteException;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070028import android.os.WorkSource;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070029import android.util.Log;
30
Nick Pelly6fa9ad42012-07-16 12:18:23 -070031import com.android.internal.location.ProviderProperties;
32import com.android.internal.location.ILocationProvider;
33import com.android.internal.location.ProviderRequest;
34import com.android.server.LocationManagerService;
35import com.android.server.ServiceWatcher;
Mike Lockwood00b74272010-03-26 10:41:48 -040036
Mike Lockwoode932f7f2009-04-06 10:51:26 -070037/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070038 * Proxy for ILocationProvider implementations.
Mike Lockwoode932f7f2009-04-06 10:51:26 -070039 */
Mike Lockwoodd03ff942010-02-09 08:46:14 -050040public class LocationProviderProxy implements LocationProviderInterface {
Mike Lockwoode932f7f2009-04-06 10:51:26 -070041 private static final String TAG = "LocationProviderProxy";
Nick Pelly6fa9ad42012-07-16 12:18:23 -070042 private static final boolean D = LocationManagerService.D;
Nick Pelly00355d52012-05-27 16:12:45 -070043
Mike Lockwood628fd6d2010-01-25 22:46:13 -050044 private final Context mContext;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -040045 private final String mName;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070046 private final ServiceWatcher mServiceWatcher;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050047
Nick Pelly6fa9ad42012-07-16 12:18:23 -070048 private Object mLock = new Object();
49
50 // cached values set by the location manager, synchronized on mLock
51 private ProviderProperties mProperties;
Mike Lockwood2cd543a2010-02-01 12:16:35 -050052 private boolean mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070053 private ProviderRequest mRequest = null;
54 private WorkSource mWorksource = new WorkSource();
Mike Lockwoode932f7f2009-04-06 10:51:26 -070055
Zhentao Sunc5fc9982013-04-17 17:47:53 -070056 public static LocationProviderProxy createAndBind(
57 Context context, String name, String action,
58 int overlaySwitchResId, int defaultServicePackageNameResId,
59 int initialPackageNamesResId, Handler handler) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -070060 LocationProviderProxy proxy = new LocationProviderProxy(context, name, action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070061 overlaySwitchResId, defaultServicePackageNameResId, initialPackageNamesResId,
62 handler);
Nick Pelly6fa9ad42012-07-16 12:18:23 -070063 if (proxy.bind()) {
64 return proxy;
65 } else {
66 return null;
67 }
68 }
69
70 private LocationProviderProxy(Context context, String name, String action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070071 int overlaySwitchResId, int defaultServicePackageNameResId,
72 int initialPackageNamesResId, Handler handler) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050073 mContext = context;
74 mName = name;
Zhentao Sunc5fc9982013-04-17 17:47:53 -070075 mServiceWatcher = new ServiceWatcher(mContext, TAG + "-" + name, action, overlaySwitchResId,
76 defaultServicePackageNameResId, initialPackageNamesResId,
Victoria Lease03cdd3d2013-02-01 15:15:54 -080077 mNewServiceWork, handler);
Mike Lockwood628fd6d2010-01-25 22:46:13 -050078 }
79
Nick Pelly6fa9ad42012-07-16 12:18:23 -070080 private boolean bind () {
81 return mServiceWatcher.start();
Mike Lockwoode97ae402010-09-29 15:23:46 -040082 }
83
Nick Pelly6fa9ad42012-07-16 12:18:23 -070084 private ILocationProvider getService() {
85 return ILocationProvider.Stub.asInterface(mServiceWatcher.getBinder());
86 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070087
Nick Pelly6fa9ad42012-07-16 12:18:23 -070088 public String getConnectedPackageName() {
89 return mServiceWatcher.getBestPackageName();
90 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070091
Nick Pelly6fa9ad42012-07-16 12:18:23 -070092 /**
93 * Work to apply current state to a newly connected provider.
94 * Remember we can switch the service that implements a providers
95 * at run-time, so need to apply current state.
96 */
97 private Runnable mNewServiceWork = new Runnable() {
98 @Override
Mike Lockwood628fd6d2010-01-25 22:46:13 -050099 public void run() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700100 if (D) Log.d(TAG, "applying state to connected service");
101
102 boolean enabled;
103 ProviderProperties properties = null;
104 ProviderRequest request;
105 WorkSource source;
106 ILocationProvider service;
107 synchronized (mLock) {
108 enabled = mEnabled;
109 request = mRequest;
110 source = mWorksource;
111 service = getService();
112 }
113
114 if (service == null) return;
115
116 try {
117 // load properties from provider
118 properties = service.getProperties();
119 if (properties == null) {
120 Log.e(TAG, mServiceWatcher.getBestPackageName() +
121 " has invalid locatino provider properties");
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500122 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500123
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700124 // apply current state to new service
125 if (enabled) {
126 service.enable();
127 if (request != null) {
128 service.setRequest(request, source);
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700129 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500130 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700131 } catch (RemoteException e) {
132 Log.w(TAG, e);
133 } catch (Exception e) {
134 // never let remote service crash system server
135 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
136 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500137
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700138 synchronized (mLock) {
139 mProperties = properties;
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500140 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700141 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500142 };
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700143
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700144 @Override
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400145 public String getName() {
146 return mName;
147 }
148
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700149 @Override
150 public ProviderProperties getProperties() {
151 synchronized (mLock) {
152 return mProperties;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700153 }
154 }
155
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700156 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700157 public void enable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700158 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700159 mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700160 }
161 ILocationProvider service = getService();
162 if (service == null) return;
163
164 try {
165 service.enable();
166 } catch (RemoteException e) {
167 Log.w(TAG, e);
168 } catch (Exception e) {
169 // never let remote service crash system server
170 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700171 }
172 }
173
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700174 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700175 public void disable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700176 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700177 mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700178 }
179 ILocationProvider service = getService();
180 if (service == null) return;
181
182 try {
183 service.disable();
184 } catch (RemoteException e) {
185 Log.w(TAG, e);
186 } catch (Exception e) {
187 // never let remote service crash system server
188 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700189 }
190 }
191
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700192 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700193 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700194 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700195 return mEnabled;
196 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700197 }
198
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700199 @Override
200 public void setRequest(ProviderRequest request, WorkSource source) {
201 synchronized (mLock) {
202 mRequest = request;
203 mWorksource = source;
204 }
205 ILocationProvider service = getService();
206 if (service == null) return;
207
208 try {
209 service.setRequest(request, source);
210 } catch (RemoteException e) {
211 Log.w(TAG, e);
212 } catch (Exception e) {
213 // never let remote service crash system server
214 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
215 }
216 }
217
218 @Override
219 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
220 pw.append("REMOTE SERVICE");
221 pw.append(" name=").append(mName);
222 pw.append(" pkg=").append(mServiceWatcher.getBestPackageName());
223 pw.append(" version=").append("" + mServiceWatcher.getBestVersion());
224 pw.append('\n');
225
226 ILocationProvider service = getService();
227 if (service == null) {
228 pw.println("service down (null)");
229 return;
230 }
231 pw.flush();
232
233 try {
234 service.asBinder().dump(fd, args);
235 } catch (RemoteException e) {
236 pw.println("service down (RemoteException)");
237 Log.w(TAG, e);
238 } catch (Exception e) {
239 pw.println("service down (Exception)");
240 // never let remote service crash system server
241 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
242 }
243 }
244
245 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700246 public int getStatus(Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700247 ILocationProvider service = getService();
248 if (service == null) return LocationProvider.TEMPORARILY_UNAVAILABLE;
249
250 try {
251 return service.getStatus(extras);
252 } catch (RemoteException e) {
253 Log.w(TAG, e);
254 } catch (Exception e) {
255 // never let remote service crash system server
256 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700257 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700258 return LocationProvider.TEMPORARILY_UNAVAILABLE;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700259 }
260
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700261 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700262 public long getStatusUpdateTime() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700263 ILocationProvider service = getService();
264 if (service == null) return 0;
265
266 try {
267 return service.getStatusUpdateTime();
268 } catch (RemoteException e) {
269 Log.w(TAG, e);
270 } catch (Exception e) {
271 // never let remote service crash system server
272 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500273 }
274 return 0;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700275 }
276
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700277 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700278 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700279 ILocationProvider service = getService();
280 if (service == null) return false;
281
282 try {
283 return service.sendExtraCommand(command, extras);
284 } catch (RemoteException e) {
285 Log.w(TAG, e);
286 } catch (Exception e) {
287 // never let remote service crash system server
288 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500289 }
290 return false;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700291 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700292 }