blob: b44087c07c16916763ef385b4c66e9026fd1b45e [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;
Jeff Sharkeyc06f1842016-11-09 12:25:44 -070020import java.io.IOException;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070021import java.io.PrintWriter;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070022
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;
Jeff Sharkeyc06f1842016-11-09 12:25:44 -070034import com.android.internal.os.TransferPipe;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070035import com.android.server.LocationManagerService;
36import com.android.server.ServiceWatcher;
Mike Lockwood00b74272010-03-26 10:41:48 -040037
Mike Lockwoode932f7f2009-04-06 10:51:26 -070038/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070039 * Proxy for ILocationProvider implementations.
Mike Lockwoode932f7f2009-04-06 10:51:26 -070040 */
Mike Lockwoodd03ff942010-02-09 08:46:14 -050041public class LocationProviderProxy implements LocationProviderInterface {
Mike Lockwoode932f7f2009-04-06 10:51:26 -070042 private static final String TAG = "LocationProviderProxy";
Nick Pelly6fa9ad42012-07-16 12:18:23 -070043 private static final boolean D = LocationManagerService.D;
Nick Pelly00355d52012-05-27 16:12:45 -070044
Mike Lockwood628fd6d2010-01-25 22:46:13 -050045 private final Context mContext;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -040046 private final String mName;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070047 private final ServiceWatcher mServiceWatcher;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050048
Nick Pelly6fa9ad42012-07-16 12:18:23 -070049 private Object mLock = new Object();
50
51 // cached values set by the location manager, synchronized on mLock
52 private ProviderProperties mProperties;
Mike Lockwood2cd543a2010-02-01 12:16:35 -050053 private boolean mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070054 private ProviderRequest mRequest = null;
55 private WorkSource mWorksource = new WorkSource();
Mike Lockwoode932f7f2009-04-06 10:51:26 -070056
Zhentao Sunc5fc9982013-04-17 17:47:53 -070057 public static LocationProviderProxy createAndBind(
58 Context context, String name, String action,
59 int overlaySwitchResId, int defaultServicePackageNameResId,
60 int initialPackageNamesResId, Handler handler) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -070061 LocationProviderProxy proxy = new LocationProviderProxy(context, name, action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070062 overlaySwitchResId, defaultServicePackageNameResId, initialPackageNamesResId,
63 handler);
Nick Pelly6fa9ad42012-07-16 12:18:23 -070064 if (proxy.bind()) {
65 return proxy;
66 } else {
67 return null;
68 }
69 }
70
71 private LocationProviderProxy(Context context, String name, String action,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070072 int overlaySwitchResId, int defaultServicePackageNameResId,
73 int initialPackageNamesResId, Handler handler) {
Mike Lockwood628fd6d2010-01-25 22:46:13 -050074 mContext = context;
75 mName = name;
Zhentao Sunc5fc9982013-04-17 17:47:53 -070076 mServiceWatcher = new ServiceWatcher(mContext, TAG + "-" + name, action, overlaySwitchResId,
77 defaultServicePackageNameResId, initialPackageNamesResId,
Victoria Lease03cdd3d2013-02-01 15:15:54 -080078 mNewServiceWork, handler);
Mike Lockwood628fd6d2010-01-25 22:46:13 -050079 }
80
Nick Pelly6fa9ad42012-07-16 12:18:23 -070081 private boolean bind () {
82 return mServiceWatcher.start();
Mike Lockwoode97ae402010-09-29 15:23:46 -040083 }
84
Nick Pelly6fa9ad42012-07-16 12:18:23 -070085 private ILocationProvider getService() {
86 return ILocationProvider.Stub.asInterface(mServiceWatcher.getBinder());
87 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070088
Nick Pelly6fa9ad42012-07-16 12:18:23 -070089 public String getConnectedPackageName() {
90 return mServiceWatcher.getBestPackageName();
91 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -070092
Nick Pelly6fa9ad42012-07-16 12:18:23 -070093 /**
94 * Work to apply current state to a newly connected provider.
95 * Remember we can switch the service that implements a providers
96 * at run-time, so need to apply current state.
97 */
98 private Runnable mNewServiceWork = new Runnable() {
99 @Override
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500100 public void run() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700101 if (D) Log.d(TAG, "applying state to connected service");
102
103 boolean enabled;
104 ProviderProperties properties = null;
105 ProviderRequest request;
106 WorkSource source;
107 ILocationProvider service;
108 synchronized (mLock) {
109 enabled = mEnabled;
110 request = mRequest;
111 source = mWorksource;
112 service = getService();
113 }
114
115 if (service == null) return;
116
117 try {
118 // load properties from provider
119 properties = service.getProperties();
120 if (properties == null) {
121 Log.e(TAG, mServiceWatcher.getBestPackageName() +
122 " has invalid locatino provider properties");
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500123 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500124
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700125 // apply current state to new service
126 if (enabled) {
127 service.enable();
128 if (request != null) {
129 service.setRequest(request, source);
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700130 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500131 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700132 } catch (RemoteException e) {
133 Log.w(TAG, e);
134 } catch (Exception e) {
135 // never let remote service crash system server
136 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
137 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500138
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700139 synchronized (mLock) {
140 mProperties = properties;
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500141 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700142 }
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500143 };
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700144
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700145 @Override
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400146 public String getName() {
147 return mName;
148 }
149
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700150 @Override
151 public ProviderProperties getProperties() {
152 synchronized (mLock) {
153 return mProperties;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700154 }
155 }
156
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700157 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700158 public void enable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700159 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700160 mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700161 }
162 ILocationProvider service = getService();
163 if (service == null) return;
164
165 try {
166 service.enable();
167 } catch (RemoteException e) {
168 Log.w(TAG, e);
169 } catch (Exception e) {
170 // never let remote service crash system server
171 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700172 }
173 }
174
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700175 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700176 public void disable() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700177 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700178 mEnabled = false;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700179 }
180 ILocationProvider service = getService();
181 if (service == null) return;
182
183 try {
184 service.disable();
185 } catch (RemoteException e) {
186 Log.w(TAG, e);
187 } catch (Exception e) {
188 // never let remote service crash system server
189 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700190 }
191 }
192
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700193 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700194 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700195 synchronized (mLock) {
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700196 return mEnabled;
197 }
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700198 }
199
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700200 @Override
201 public void setRequest(ProviderRequest request, WorkSource source) {
202 synchronized (mLock) {
203 mRequest = request;
204 mWorksource = source;
205 }
206 ILocationProvider service = getService();
207 if (service == null) return;
208
209 try {
210 service.setRequest(request, source);
211 } catch (RemoteException e) {
212 Log.w(TAG, e);
213 } catch (Exception e) {
214 // never let remote service crash system server
215 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
216 }
217 }
218
219 @Override
220 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
221 pw.append("REMOTE SERVICE");
222 pw.append(" name=").append(mName);
223 pw.append(" pkg=").append(mServiceWatcher.getBestPackageName());
224 pw.append(" version=").append("" + mServiceWatcher.getBestVersion());
225 pw.append('\n');
226
227 ILocationProvider service = getService();
228 if (service == null) {
229 pw.println("service down (null)");
230 return;
231 }
232 pw.flush();
233
234 try {
Jeff Sharkeyc06f1842016-11-09 12:25:44 -0700235 TransferPipe.dumpAsync(service.asBinder(), fd, args);
236 } catch (IOException | RemoteException e) {
237 pw.println("Failed to dump location provider: " + e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700238 }
239 }
240
241 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700242 public int getStatus(Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700243 ILocationProvider service = getService();
244 if (service == null) return LocationProvider.TEMPORARILY_UNAVAILABLE;
245
246 try {
247 return service.getStatus(extras);
248 } catch (RemoteException e) {
249 Log.w(TAG, e);
250 } catch (Exception e) {
251 // never let remote service crash system server
252 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700253 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700254 return LocationProvider.TEMPORARILY_UNAVAILABLE;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700255 }
256
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700257 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700258 public long getStatusUpdateTime() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700259 ILocationProvider service = getService();
260 if (service == null) return 0;
261
262 try {
263 return service.getStatusUpdateTime();
264 } catch (RemoteException e) {
265 Log.w(TAG, e);
266 } catch (Exception e) {
267 // never let remote service crash system server
268 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500269 }
270 return 0;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700271 }
272
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700273 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700274 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700275 ILocationProvider service = getService();
276 if (service == null) return false;
277
278 try {
279 return service.sendExtraCommand(command, extras);
280 } catch (RemoteException e) {
281 Log.w(TAG, e);
282 } catch (Exception e) {
283 // never let remote service crash system server
284 Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500285 }
286 return false;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700287 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700288 }