blob: 5eb06ed20b42c4cefd87ac12bc6ff46798f53756 [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;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070021
Mike Lockwood628fd6d2010-01-25 22:46:13 -050022import android.content.Context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070023import android.location.LocationProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070024import android.os.Bundle;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050025import android.os.Handler;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070026import android.os.RemoteException;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070027import android.os.WorkSource;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070028import android.util.Log;
29
Nick Pelly6fa9ad42012-07-16 12:18:23 -070030import com.android.internal.location.ProviderProperties;
31import com.android.internal.location.ILocationProvider;
32import com.android.internal.location.ProviderRequest;
33import com.android.server.LocationManagerService;
34import com.android.server.ServiceWatcher;
Mike Lockwood00b74272010-03-26 10:41:48 -040035
Mike Lockwoode932f7f2009-04-06 10:51:26 -070036/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070037 * Proxy for ILocationProvider implementations.
Mike Lockwoode932f7f2009-04-06 10:51:26 -070038 */
Mike Lockwoodd03ff942010-02-09 08:46:14 -050039public class LocationProviderProxy implements LocationProviderInterface {
Mike Lockwoode932f7f2009-04-06 10:51:26 -070040 private static final String TAG = "LocationProviderProxy";
Nick Pelly6fa9ad42012-07-16 12:18:23 -070041 private static final boolean D = LocationManagerService.D;
Nick Pelly00355d52012-05-27 16:12:45 -070042
Mike Lockwood628fd6d2010-01-25 22:46:13 -050043 private final Context mContext;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -040044 private final String mName;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070045 private final ServiceWatcher mServiceWatcher;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050046
Nick Pelly6fa9ad42012-07-16 12:18:23 -070047 private Object mLock = new Object();
48
49 // cached values set by the location manager, synchronized on mLock
50 private ProviderProperties mProperties;
Mike Lockwood2cd543a2010-02-01 12:16:35 -050051 private boolean mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070052 private ProviderRequest mRequest = null;
53 private WorkSource mWorksource = new WorkSource();
Mike Lockwoode932f7f2009-04-06 10:51:26 -070054
Zhentao Sunc5fc9982013-04-17 17:47:53 -070055 public static LocationProviderProxy createAndBind(
56 Context context, String name, String action,
57 int overlaySwitchResId, int defaultServicePackageNameResId,
58 int initialPackageNamesResId, Handler handler) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -070059 LocationProviderProxy proxy = new LocationProviderProxy(context, name, action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070060 overlaySwitchResId, defaultServicePackageNameResId, initialPackageNamesResId,
61 handler);
Nick Pelly6fa9ad42012-07-16 12:18:23 -070062 if (proxy.bind()) {
63 return proxy;
64 } else {
65 return null;
66 }
67 }
68
69 private LocationProviderProxy(Context context, String name, String action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070070 int overlaySwitchResId, int defaultServicePackageNameResId,
71 int initialPackageNamesResId, Handler handler) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050072 mContext = context;
73 mName = name;
Zhentao Sunc5fc9982013-04-17 17:47:53 -070074 mServiceWatcher = new ServiceWatcher(mContext, TAG + "-" + name, action, overlaySwitchResId,
75 defaultServicePackageNameResId, initialPackageNamesResId,
Victoria Lease03cdd3d2013-02-01 15:15:54 -080076 mNewServiceWork, handler);
Mike Lockwood628fd6d2010-01-25 22:46:13 -050077 }
78
Nick Pelly6fa9ad42012-07-16 12:18:23 -070079 private boolean bind () {
80 return mServiceWatcher.start();
Mike Lockwoode97ae402010-09-29 15:23:46 -040081 }
82
Nick Pelly6fa9ad42012-07-16 12:18:23 -070083 private ILocationProvider getService() {
84 return ILocationProvider.Stub.asInterface(mServiceWatcher.getBinder());
85 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070086
Nick Pelly6fa9ad42012-07-16 12:18:23 -070087 public String getConnectedPackageName() {
88 return mServiceWatcher.getBestPackageName();
89 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070090
Nick Pelly6fa9ad42012-07-16 12:18:23 -070091 /**
92 * Work to apply current state to a newly connected provider.
93 * Remember we can switch the service that implements a providers
94 * at run-time, so need to apply current state.
95 */
96 private Runnable mNewServiceWork = new Runnable() {
97 @Override
Mike Lockwood628fd6d2010-01-25 22:46:13 -050098 public void run() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -070099 if (D) Log.d(TAG, "applying state to connected service");
100
101 boolean enabled;
102 ProviderProperties properties = null;
103 ProviderRequest request;
104 WorkSource source;
105 ILocationProvider service;
106 synchronized (mLock) {
107 enabled = mEnabled;
108 request = mRequest;
109 source = mWorksource;
110 service = getService();
111 }
112
113 if (service == null) return;
114
115 try {
116 // load properties from provider
117 properties = service.getProperties();
118 if (properties == null) {
119 Log.e(TAG, mServiceWatcher.getBestPackageName() +
120 " has invalid locatino provider properties");
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500121 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500122
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700123 // apply current state to new service
124 if (enabled) {
125 service.enable();
126 if (request != null) {
127 service.setRequest(request, source);
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700128 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500129 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700130 } catch (RemoteException e) {
131 Log.w(TAG, e);
132 } catch (Exception e) {
133 // never let remote service crash system server
134 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
135 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500136
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700137 synchronized (mLock) {
138 mProperties = properties;
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500139 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700140 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500141 };
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700142
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700143 @Override
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400144 public String getName() {
145 return mName;
146 }
147
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700148 @Override
149 public ProviderProperties getProperties() {
150 synchronized (mLock) {
151 return mProperties;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700152 }
153 }
154
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700155 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700156 public void enable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700157 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700158 mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700159 }
160 ILocationProvider service = getService();
161 if (service == null) return;
162
163 try {
164 service.enable();
165 } catch (RemoteException e) {
166 Log.w(TAG, e);
167 } catch (Exception e) {
168 // never let remote service crash system server
169 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700170 }
171 }
172
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700173 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700174 public void disable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700175 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700176 mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700177 }
178 ILocationProvider service = getService();
179 if (service == null) return;
180
181 try {
182 service.disable();
183 } catch (RemoteException e) {
184 Log.w(TAG, e);
185 } catch (Exception e) {
186 // never let remote service crash system server
187 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700188 }
189 }
190
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700191 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700192 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700193 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700194 return mEnabled;
195 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700196 }
197
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700198 @Override
199 public void setRequest(ProviderRequest request, WorkSource source) {
200 synchronized (mLock) {
201 mRequest = request;
202 mWorksource = source;
203 }
204 ILocationProvider service = getService();
205 if (service == null) return;
206
207 try {
208 service.setRequest(request, source);
209 } catch (RemoteException e) {
210 Log.w(TAG, e);
211 } catch (Exception e) {
212 // never let remote service crash system server
213 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
214 }
215 }
216
217 @Override
218 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
219 pw.append("REMOTE SERVICE");
220 pw.append(" name=").append(mName);
221 pw.append(" pkg=").append(mServiceWatcher.getBestPackageName());
222 pw.append(" version=").append("" + mServiceWatcher.getBestVersion());
223 pw.append('\n');
224
225 ILocationProvider service = getService();
226 if (service == null) {
227 pw.println("service down (null)");
228 return;
229 }
230 pw.flush();
231
232 try {
233 service.asBinder().dump(fd, args);
234 } catch (RemoteException e) {
235 pw.println("service down (RemoteException)");
236 Log.w(TAG, e);
237 } catch (Exception e) {
238 pw.println("service down (Exception)");
239 // never let remote service crash system server
240 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
241 }
242 }
243
244 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700245 public int getStatus(Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700246 ILocationProvider service = getService();
247 if (service == null) return LocationProvider.TEMPORARILY_UNAVAILABLE;
248
249 try {
250 return service.getStatus(extras);
251 } catch (RemoteException e) {
252 Log.w(TAG, e);
253 } catch (Exception e) {
254 // never let remote service crash system server
255 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700256 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700257 return LocationProvider.TEMPORARILY_UNAVAILABLE;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700258 }
259
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700260 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700261 public long getStatusUpdateTime() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700262 ILocationProvider service = getService();
263 if (service == null) return 0;
264
265 try {
266 return service.getStatusUpdateTime();
267 } catch (RemoteException e) {
268 Log.w(TAG, e);
269 } catch (Exception e) {
270 // never let remote service crash system server
271 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500272 }
273 return 0;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700274 }
275
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700276 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700277 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700278 ILocationProvider service = getService();
279 if (service == null) return false;
280
281 try {
282 return service.sendExtraCommand(command, extras);
283 } catch (RemoteException e) {
284 Log.w(TAG, e);
285 } catch (Exception e) {
286 // never let remote service crash system server
287 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500288 }
289 return false;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700290 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700291 }