blob: 7faf72c33284bf74a0cd7684bc341a7e228973bc [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
Nick Pelly6fa9ad42012-07-16 12:18:23 -070056 public static LocationProviderProxy createAndBind(Context context, String name, String action,
57 List<String> initialPackageNames, Handler handler) {
58 LocationProviderProxy proxy = new LocationProviderProxy(context, name, action,
59 initialPackageNames, handler);
60 if (proxy.bind()) {
61 return proxy;
62 } else {
63 return null;
64 }
65 }
66
67 private LocationProviderProxy(Context context, String name, String action,
68 List<String> initialPackageNames, Handler handler) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050069 mContext = context;
70 mName = name;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070071 mServiceWatcher = new ServiceWatcher(mContext, TAG, action, initialPackageNames,
72 mNewServiceWork, handler);
Mike Lockwood628fd6d2010-01-25 22:46:13 -050073 }
74
Nick Pelly6fa9ad42012-07-16 12:18:23 -070075 private boolean bind () {
76 return mServiceWatcher.start();
Mike Lockwoode97ae402010-09-29 15:23:46 -040077 }
78
Nick Pelly6fa9ad42012-07-16 12:18:23 -070079 private ILocationProvider getService() {
80 return ILocationProvider.Stub.asInterface(mServiceWatcher.getBinder());
81 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070082
Nick Pelly6fa9ad42012-07-16 12:18:23 -070083 public String getConnectedPackageName() {
84 return mServiceWatcher.getBestPackageName();
85 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070086
Nick Pelly6fa9ad42012-07-16 12:18:23 -070087 /**
88 * Work to apply current state to a newly connected provider.
89 * Remember we can switch the service that implements a providers
90 * at run-time, so need to apply current state.
91 */
92 private Runnable mNewServiceWork = new Runnable() {
93 @Override
Mike Lockwood628fd6d2010-01-25 22:46:13 -050094 public void run() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -070095 if (D) Log.d(TAG, "applying state to connected service");
96
97 boolean enabled;
98 ProviderProperties properties = null;
99 ProviderRequest request;
100 WorkSource source;
101 ILocationProvider service;
102 synchronized (mLock) {
103 enabled = mEnabled;
104 request = mRequest;
105 source = mWorksource;
106 service = getService();
107 }
108
109 if (service == null) return;
110
111 try {
112 // load properties from provider
113 properties = service.getProperties();
114 if (properties == null) {
115 Log.e(TAG, mServiceWatcher.getBestPackageName() +
116 " has invalid locatino provider properties");
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500117 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500118
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700119 // apply current state to new service
120 if (enabled) {
121 service.enable();
122 if (request != null) {
123 service.setRequest(request, source);
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700124 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500125 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700126 } catch (RemoteException e) {
127 Log.w(TAG, e);
128 } catch (Exception e) {
129 // never let remote service crash system server
130 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
131 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500132
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700133 synchronized (mLock) {
134 mProperties = properties;
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500135 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700136 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500137 };
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700138
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700139 @Override
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400140 public String getName() {
141 return mName;
142 }
143
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700144 @Override
145 public ProviderProperties getProperties() {
146 synchronized (mLock) {
147 return mProperties;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700148 }
149 }
150
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700151 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700152 public void enable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700153 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700154 mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700155 }
156 ILocationProvider service = getService();
157 if (service == null) return;
158
159 try {
160 service.enable();
161 } catch (RemoteException e) {
162 Log.w(TAG, e);
163 } catch (Exception e) {
164 // never let remote service crash system server
165 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700166 }
167 }
168
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700169 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700170 public void disable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700171 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700172 mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700173 }
174 ILocationProvider service = getService();
175 if (service == null) return;
176
177 try {
178 service.disable();
179 } catch (RemoteException e) {
180 Log.w(TAG, e);
181 } catch (Exception e) {
182 // never let remote service crash system server
183 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700184 }
185 }
186
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700187 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700188 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700189 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700190 return mEnabled;
191 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700192 }
193
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700194 @Override
195 public void setRequest(ProviderRequest request, WorkSource source) {
196 synchronized (mLock) {
197 mRequest = request;
198 mWorksource = source;
199 }
200 ILocationProvider service = getService();
201 if (service == null) return;
202
203 try {
204 service.setRequest(request, source);
205 } catch (RemoteException e) {
206 Log.w(TAG, e);
207 } catch (Exception e) {
208 // never let remote service crash system server
209 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
210 }
211 }
212
213 @Override
214 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
215 pw.append("REMOTE SERVICE");
216 pw.append(" name=").append(mName);
217 pw.append(" pkg=").append(mServiceWatcher.getBestPackageName());
218 pw.append(" version=").append("" + mServiceWatcher.getBestVersion());
219 pw.append('\n');
220
221 ILocationProvider service = getService();
222 if (service == null) {
223 pw.println("service down (null)");
224 return;
225 }
226 pw.flush();
227
228 try {
229 service.asBinder().dump(fd, args);
230 } catch (RemoteException e) {
231 pw.println("service down (RemoteException)");
232 Log.w(TAG, e);
233 } catch (Exception e) {
234 pw.println("service down (Exception)");
235 // never let remote service crash system server
236 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
237 }
238 }
239
240 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700241 public int getStatus(Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700242 ILocationProvider service = getService();
243 if (service == null) return LocationProvider.TEMPORARILY_UNAVAILABLE;
244
245 try {
246 return service.getStatus(extras);
247 } catch (RemoteException e) {
248 Log.w(TAG, e);
249 } catch (Exception e) {
250 // never let remote service crash system server
251 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700252 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700253 return LocationProvider.TEMPORARILY_UNAVAILABLE;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700254 }
255
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700256 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700257 public long getStatusUpdateTime() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700258 ILocationProvider service = getService();
259 if (service == null) return 0;
260
261 try {
262 return service.getStatusUpdateTime();
263 } catch (RemoteException e) {
264 Log.w(TAG, e);
265 } catch (Exception e) {
266 // never let remote service crash system server
267 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500268 }
269 return 0;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700270 }
271
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700272 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700273 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700274 ILocationProvider service = getService();
275 if (service == null) return false;
276
277 try {
278 return service.sendExtraCommand(command, extras);
279 } catch (RemoteException e) {
280 Log.w(TAG, e);
281 } catch (Exception e) {
282 // never let remote service crash system server
283 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500284 }
285 return false;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700286 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700287 }