blob: bb86b4852fd512bfb42c0facba6a2116c2343a08 [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
Soonil Nagarkare731ca82018-11-02 13:55:51 -070019import android.annotation.Nullable;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050020import android.content.Context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070021import android.location.LocationProvider;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070022import android.os.Bundle;
Lifu Tang66f761c2017-11-13 15:51:54 -080023import android.os.IBinder;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070024import android.os.RemoteException;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070025import android.os.WorkSource;
Mike Lockwoode932f7f2009-04-06 10:51:26 -070026import android.util.Log;
27
Soonil Nagarkare731ca82018-11-02 13:55:51 -070028import com.android.internal.annotations.GuardedBy;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070029import com.android.internal.location.ILocationProvider;
Soonil Nagarkare731ca82018-11-02 13:55:51 -070030import com.android.internal.location.ProviderProperties;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070031import com.android.internal.location.ProviderRequest;
Soonil Nagarkare731ca82018-11-02 13:55:51 -070032import com.android.internal.os.BackgroundThread;
Jeff Sharkey850c83e2016-11-09 12:25:44 -070033import com.android.internal.os.TransferPipe;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070034import com.android.server.LocationManagerService;
35import com.android.server.ServiceWatcher;
Mike Lockwood00b74272010-03-26 10:41:48 -040036
Soonil Nagarkare731ca82018-11-02 13:55:51 -070037import java.io.FileDescriptor;
38import java.io.IOException;
39import java.io.PrintWriter;
40
Mike Lockwoode932f7f2009-04-06 10:51:26 -070041/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070042 * Proxy for ILocationProvider implementations.
Mike Lockwoode932f7f2009-04-06 10:51:26 -070043 */
Mike Lockwoodd03ff942010-02-09 08:46:14 -050044public class LocationProviderProxy implements LocationProviderInterface {
Mike Lockwoode932f7f2009-04-06 10:51:26 -070045 private static final String TAG = "LocationProviderProxy";
Nick Pelly6fa9ad42012-07-16 12:18:23 -070046 private static final boolean D = LocationManagerService.D;
Nick Pelly00355d52012-05-27 16:12:45 -070047
Nick Pelly6fa9ad42012-07-16 12:18:23 -070048 private final ServiceWatcher mServiceWatcher;
Mike Lockwood628fd6d2010-01-25 22:46:13 -050049
Soonil Nagarkare731ca82018-11-02 13:55:51 -070050 private final String mName;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070051
Soonil Nagarkare731ca82018-11-02 13:55:51 -070052 // used to ensure that updates to mRequest and mWorkSource are atomic
53 private final Object mRequestLock = new Object();
Mike Lockwoode932f7f2009-04-06 10:51:26 -070054
Soonil Nagarkare731ca82018-11-02 13:55:51 -070055
56 private volatile boolean mEnabled = false;
57 @Nullable
58 private volatile ProviderProperties mProperties;
59
60 @GuardedBy("mRequestLock")
61 @Nullable
62 private ProviderRequest mRequest;
63 @GuardedBy("mRequestLock")
64 private WorkSource mWorkSource;
65
66 /**
67 * Creates a new LocationProviderProxy and immediately begins binding to the best applicable
68 * service.
69 */
70 @Nullable
Zhentao Sunc5fc9982013-04-17 17:47:53 -070071 public static LocationProviderProxy createAndBind(
72 Context context, String name, String action,
73 int overlaySwitchResId, int defaultServicePackageNameResId,
Soonil Nagarkare731ca82018-11-02 13:55:51 -070074 int initialPackageNamesResId) {
75 LocationProviderProxy proxy = new LocationProviderProxy(context, name,
76 action, overlaySwitchResId, defaultServicePackageNameResId,
77 initialPackageNamesResId);
Nick Pelly6fa9ad42012-07-16 12:18:23 -070078 if (proxy.bind()) {
79 return proxy;
80 } else {
81 return null;
82 }
83 }
84
Soonil Nagarkare731ca82018-11-02 13:55:51 -070085 private LocationProviderProxy(Context context, String name,
86 String action, int overlaySwitchResId, int defaultServicePackageNameResId,
87 int initialPackageNamesResId) {
88
89 mServiceWatcher = new ServiceWatcher(context, TAG, action, overlaySwitchResId,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070090 defaultServicePackageNameResId, initialPackageNamesResId,
Soonil Nagarkare731ca82018-11-02 13:55:51 -070091 BackgroundThread.getHandler()) {
92 @Override
93 protected void onBind() {
94 runOnBinder(LocationProviderProxy.this::initializeService);
95 }
96 };
97 mName = name;
98
99 mProperties = null;
100 mRequest = null;
101 mWorkSource = new WorkSource();
Mike Lockwood628fd6d2010-01-25 22:46:13 -0500102 }
103
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700104 private boolean bind() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700105 return mServiceWatcher.start();
Mike Lockwoode97ae402010-09-29 15:23:46 -0400106 }
107
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700108 private void initializeService(IBinder binder) {
109 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
110 if (D) Log.d(TAG, "applying state to connected service");
111
112 ProviderProperties[] properties = new ProviderProperties[1];
113 ProviderRequest request;
114 WorkSource source;
115 synchronized (mRequestLock) {
116 request = mRequest;
117 source = mWorkSource;
118 }
119
120 try {
121 // load properties from provider
122 properties[0] = service.getProperties();
123 if (properties[0] == null) {
124 Log.e(TAG, mServiceWatcher.getCurrentPackageName()
125 + " has invalid location provider properties");
126 }
127
128 // apply current state to new service
129 if (mEnabled) {
130 service.enable();
131 if (request != null) {
132 service.setRequest(request, source);
133 }
134 }
135 } catch (RemoteException e) {
136 Log.w(TAG, e);
137 }
138
139 mProperties = properties[0];
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700140 }
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700141
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700142 public String getConnectedPackageName() {
143 return mServiceWatcher.getCurrentPackageName();
144 }
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -0700145
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700146 @Override
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400147 public String getName() {
148 return mName;
149 }
150
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700151 @Override
152 public ProviderProperties getProperties() {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700153 return mProperties;
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700154 }
155
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700156 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700157 public void enable() {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700158 mEnabled = true;
159 mServiceWatcher.runOnBinder(binder -> {
160 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
161 try {
162 service.enable();
163 } catch (RemoteException e) {
164 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800165 }
166 });
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700167 }
168
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700169 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700170 public void disable() {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700171 mEnabled = false;
172 mServiceWatcher.runOnBinder(binder -> {
173 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
174 try {
175 service.disable();
176 } catch (RemoteException e) {
177 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800178 }
179 });
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700180 }
181
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700182 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700183 public boolean isEnabled() {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700184 return mEnabled;
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700185 }
186
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700187 @Override
188 public void setRequest(ProviderRequest request, WorkSource source) {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700189 synchronized (mRequestLock) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700190 mRequest = request;
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700191 mWorkSource = source;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700192 }
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700193 mServiceWatcher.runOnBinder(binder -> {
194 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
195 try {
196 service.setRequest(request, source);
197 } catch (RemoteException e) {
198 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800199 }
200 });
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700201 }
202
203 @Override
204 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
205 pw.append("REMOTE SERVICE");
206 pw.append(" name=").append(mName);
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700207 pw.append(" pkg=").append(mServiceWatcher.getCurrentPackageName());
208 pw.append(" version=").append(Integer.toString(mServiceWatcher.getCurrentPackageVersion()));
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700209 pw.append('\n');
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700210 mServiceWatcher.runOnBinder(binder -> {
211 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
212 try {
213 TransferPipe.dumpAsync(service.asBinder(), fd, args);
214 } catch (IOException | RemoteException e) {
215 pw.println("Failed to dump location provider: " + e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800216 }
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700217 });
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700218 }
219
220 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700221 public int getStatus(Bundle extras) {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700222 int[] result = new int[]{LocationProvider.TEMPORARILY_UNAVAILABLE};
223 mServiceWatcher.runOnBinder(binder -> {
224 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
225 try {
226 result[0] = service.getStatus(extras);
227 } catch (RemoteException e) {
228 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800229 }
230 });
231 return result[0];
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700232 }
233
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700234 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700235 public long getStatusUpdateTime() {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700236 long[] result = new long[]{0L};
237 mServiceWatcher.runOnBinder(binder -> {
238 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
239 try {
240 result[0] = service.getStatusUpdateTime();
241 } catch (RemoteException e) {
242 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800243 }
244 });
245 return result[0];
Mark Vandevoorde8863c432010-10-04 14:23:24 -0700246 }
247
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700248 @Override
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700249 public boolean sendExtraCommand(String command, Bundle extras) {
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700250 boolean[] result = new boolean[]{false};
251 mServiceWatcher.runOnBinder(binder -> {
252 ILocationProvider service = ILocationProvider.Stub.asInterface(binder);
253 try {
254 result[0] = service.sendExtraCommand(command, extras);
255 } catch (RemoteException e) {
256 Log.w(TAG, e);
Lifu Tang66f761c2017-11-13 15:51:54 -0800257 }
258 });
259 return result[0];
Mike Lockwoode932f7f2009-04-06 10:51:26 -0700260 }
Soonil Nagarkare731ca82018-11-02 13:55:51 -0700261}