blob: 787a8007920d3d3f03fbbb7f87108f7967e7c390 [file] [log] [blame]
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -08001/*
2 * Copyright (C) 2016 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
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080017package com.android.server.location;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080018
Arthur Ishiguro82ed3af2018-11-09 13:20:30 -080019import android.app.PendingIntent;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080020import android.content.Context;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070021import android.hardware.contexthub.V1_0.AsyncEventType;
22import android.hardware.contexthub.V1_0.ContextHub;
23import android.hardware.contexthub.V1_0.ContextHubMsg;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070024import android.hardware.contexthub.V1_0.HubAppInfo;
25import android.hardware.contexthub.V1_0.IContexthub;
26import android.hardware.contexthub.V1_0.IContexthubCallback;
27import android.hardware.contexthub.V1_0.Result;
28import android.hardware.contexthub.V1_0.TransactionResult;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080029import android.hardware.location.ContextHubInfo;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080030import android.hardware.location.ContextHubMessage;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080031import android.hardware.location.ContextHubTransaction;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080032import android.hardware.location.IContextHubCallback;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080033import android.hardware.location.IContextHubClient;
34import android.hardware.location.IContextHubClientCallback;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070035import android.hardware.location.IContextHubService;
36import android.hardware.location.IContextHubTransactionCallback;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080037import android.hardware.location.NanoApp;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070038import android.hardware.location.NanoAppBinary;
39import android.hardware.location.NanoAppFilter;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080040import android.hardware.location.NanoAppInstanceInfo;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080041import android.hardware.location.NanoAppMessage;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070042import android.hardware.location.NanoAppState;
destradaa78cebca2016-04-14 18:40:14 -070043import android.os.RemoteCallbackList;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080044import android.os.RemoteException;
45import android.util.Log;
46
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060047import com.android.internal.util.DumpUtils;
48
Ashutosh Joshi6239cc62016-04-04 16:19:29 -070049import java.io.FileDescriptor;
50import java.io.PrintWriter;
Ashutosh Joshi19753cc2016-11-23 13:56:39 -080051import java.nio.ByteBuffer;
52import java.nio.ByteOrder;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080053import java.util.ArrayList;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070054import java.util.Collections;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080055import java.util.HashMap;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070056import java.util.List;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080057import java.util.Map;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070058import java.util.NoSuchElementException;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080059
60/**
61 * @hide
62 */
Peng Xu9ff7d222016-02-11 13:02:05 -080063public class ContextHubService extends IContextHubService.Stub {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080064 private static final String TAG = "ContextHubService";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080065
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070066 /*
67 * Constants for the type of transaction that is defined by ContextHubService.
68 * This is used to report the transaction callback to clients, and is different from
69 * ContextHubTransaction.Type.
70 */
71 public static final int MSG_ENABLE_NANO_APP = 1;
72 public static final int MSG_DISABLE_NANO_APP = 2;
73 public static final int MSG_LOAD_NANO_APP = 3;
Ashutosh Joshicafdee92016-04-04 16:19:29 -070074 public static final int MSG_UNLOAD_NANO_APP = 4;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070075 public static final int MSG_QUERY_NANO_APPS = 5;
76 public static final int MSG_QUERY_MEMORY = 6;
77 public static final int MSG_HUB_RESET = 7;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070078
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070079 private static final int OS_APP_INSTANCE = -1;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080080
Arthur Ishigurob4f59872018-07-31 16:38:08 -070081 /*
82 * Local flag to enable debug logging.
83 */
84 private static final boolean DEBUG_LOG_ENABLED = false;
85
Peng Xu9ff7d222016-02-11 13:02:05 -080086 private final Context mContext;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070087
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080088 private final Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
Arthur Ishigurofdbbd462017-11-27 16:33:36 -080089 private final List<ContextHubInfo> mContextHubInfoList;
destradaa78cebca2016-04-14 18:40:14 -070090 private final RemoteCallbackList<IContextHubCallback> mCallbacksList =
91 new RemoteCallbackList<>();
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080092
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070093 // Proxy object to communicate with the Context Hub HAL
94 private final IContexthub mContextHubProxy;
95
96 // The manager for transaction queue
97 private final ContextHubTransactionManager mTransactionManager;
98
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080099 // The manager for sending messages to/from clients
100 private final ContextHubClientManager mClientManager;
101
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800102 // The default client for old API clients
103 private final Map<Integer, IContextHubClient> mDefaultClientMap;
104
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800105 // The manager for the internal nanoapp state cache
106 private final NanoAppStateManager mNanoAppStateManager = new NanoAppStateManager();
107
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700108 /**
109 * Class extending the callback to register with a Context Hub.
110 */
111 private class ContextHubServiceCallback extends IContexthubCallback.Stub {
112 private final int mContextHubId;
113
114 ContextHubServiceCallback(int contextHubId) {
115 mContextHubId = contextHubId;
116 }
117
118 @Override
119 public void handleClientMsg(ContextHubMsg message) {
120 handleClientMessageCallback(mContextHubId, message);
121 }
122
123 @Override
124 public void handleTxnResult(int transactionId, int result) {
125 handleTransactionResultCallback(mContextHubId, transactionId, result);
126 }
127
128 @Override
129 public void handleHubEvent(int eventType) {
130 handleHubEventCallback(mContextHubId, eventType);
131 }
132
133 @Override
134 public void handleAppAbort(long nanoAppId, int abortCode) {
135 handleAppAbortCallback(mContextHubId, nanoAppId, abortCode);
136 }
137
138 @Override
139 public void handleAppsInfo(ArrayList<HubAppInfo> nanoAppInfoList) {
140 handleQueryAppsCallback(mContextHubId, nanoAppInfoList);
141 }
142 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700143
Peng Xu9ff7d222016-02-11 13:02:05 -0800144 public ContextHubService(Context context) {
145 mContext = context;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700146
147 mContextHubProxy = getContextHubProxy();
148 if (mContextHubProxy == null) {
149 mTransactionManager = null;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800150 mClientManager = null;
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800151 mDefaultClientMap = Collections.emptyMap();
152 mContextHubIdToInfoMap = Collections.emptyMap();
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800153 mContextHubInfoList = Collections.emptyList();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700154 return;
155 }
156
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800157 mClientManager = new ContextHubClientManager(mContext, mContextHubProxy);
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800158 mTransactionManager = new ContextHubTransactionManager(
159 mContextHubProxy, mClientManager, mNanoAppStateManager);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700160
161 List<ContextHub> hubList;
162 try {
163 hubList = mContextHubProxy.getHubs();
164 } catch (RemoteException e) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800165 Log.e(TAG, "RemoteException while getting Context Hub info", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700166 hubList = Collections.emptyList();
167 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800168 mContextHubIdToInfoMap = Collections.unmodifiableMap(
169 ContextHubServiceUtil.createContextHubInfoMap(hubList));
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800170 mContextHubInfoList = new ArrayList<>(mContextHubIdToInfoMap.values());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700171
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800172 HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800173 for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
Arthur Ishiguro622ebcb2018-10-17 14:02:27 -0700174 ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800175 IContextHubClient client = mClientManager.registerClient(
Arthur Ishiguro793d3d12018-11-15 13:10:24 -0800176 contextHubInfo, createDefaultClientCallback(contextHubId));
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800177 defaultClientMap.put(contextHubId, client);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800178
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700179 try {
180 mContextHubProxy.registerCallback(
181 contextHubId, new ContextHubServiceCallback(contextHubId));
182 } catch (RemoteException e) {
183 Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800184 + contextHubId + ")", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700185 }
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700186
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800187 // Do a query to initialize the service cache list of nanoapps
188 // TODO(b/69270990): Remove this when old API is deprecated
189 queryNanoAppsInternal(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700190 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800191 mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);
Peng Xu9ff7d222016-02-11 13:02:05 -0800192 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800193
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700194 /**
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800195 * Creates a default client callback for old API clients.
196 *
197 * @param contextHubId the ID of the hub to attach this client to
198 * @return the internal callback interface
199 */
200 private IContextHubClientCallback createDefaultClientCallback(int contextHubId) {
201 return new IContextHubClientCallback.Stub() {
202 @Override
203 public void onMessageFromNanoApp(NanoAppMessage message) {
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800204 int nanoAppHandle = mNanoAppStateManager.getNanoAppHandle(
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800205 contextHubId, message.getNanoAppId());
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800206
207 onMessageReceiptOldApi(
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800208 message.getMessageType(), contextHubId, nanoAppHandle,
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800209 message.getMessageBody());
210 }
211
212 @Override
213 public void onHubReset() {
Arthur Ishiguro6d47c542017-11-17 15:49:07 -0800214 byte[] data = {TransactionResult.SUCCESS};
215 onMessageReceiptOldApi(MSG_HUB_RESET, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800216 }
217
218 @Override
219 public void onNanoAppAborted(long nanoAppId, int abortCode) {
220 }
221
222 @Override
223 public void onNanoAppLoaded(long nanoAppId) {
224 }
225
226 @Override
227 public void onNanoAppUnloaded(long nanoAppId) {
228 }
229
230 @Override
231 public void onNanoAppEnabled(long nanoAppId) {
232 }
233
234 @Override
235 public void onNanoAppDisabled(long nanoAppId) {
236 }
237 };
238 }
239
240 /**
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700241 * @return the IContexthub proxy interface
242 */
243 private IContexthub getContextHubProxy() {
244 IContexthub proxy = null;
245 try {
246 proxy = IContexthub.getService(true /* retry */);
247 } catch (RemoteException e) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800248 Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700249 } catch (NoSuchElementException e) {
250 Log.i(TAG, "Context Hub HAL service not found");
251 }
252
253 return proxy;
254 }
255
Peng Xu9ff7d222016-02-11 13:02:05 -0800256 @Override
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700257 public int registerCallback(IContextHubCallback callback) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700258 checkPermissions();
destradaa78cebca2016-04-14 18:40:14 -0700259 mCallbacksList.register(callback);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800260
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800261 Log.d(TAG, "Added callback, total callbacks " +
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700262 mCallbacksList.getRegisteredCallbackCount());
Peng Xu9ff7d222016-02-11 13:02:05 -0800263 return 0;
264 }
265
266 @Override
267 public int[] getContextHubHandles() throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700268 checkPermissions();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800269 return ContextHubServiceUtil.createPrimitiveIntArray(mContextHubIdToInfoMap.keySet());
Peng Xu9ff7d222016-02-11 13:02:05 -0800270 }
271
272 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800273 public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700274 checkPermissions();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800275 if (!mContextHubIdToInfoMap.containsKey(contextHubHandle)) {
276 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in getContextHubInfo");
277 return null;
Peng Xu9ff7d222016-02-11 13:02:05 -0800278 }
279
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800280 return mContextHubIdToInfoMap.get(contextHubHandle);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700281 }
282
283 /**
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800284 * Returns a List of ContextHubInfo object describing the available hubs.
285 *
286 * @return the List of ContextHubInfo objects
287 */
288 @Override
289 public List<ContextHubInfo> getContextHubs() throws RemoteException {
290 checkPermissions();
291 return mContextHubInfoList;
292 }
293
294 /**
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700295 * Creates an internal load transaction callback to be used for old API clients
296 *
297 * @param contextHubId the ID of the hub to load the binary
298 * @param nanoAppBinary the binary to load
299 * @return the callback interface
300 */
301 private IContextHubTransactionCallback createLoadTransactionCallback(
302 int contextHubId, NanoAppBinary nanoAppBinary) {
303 return new IContextHubTransactionCallback.Stub() {
304 @Override
305 public void onTransactionComplete(int result) {
306 handleLoadResponseOldApi(contextHubId, result, nanoAppBinary);
307 }
308
309 @Override
310 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
311 }
312 };
313 }
314
315 /**
316 * Creates an internal unload transaction callback to be used for old API clients
317 *
318 * @param contextHubId the ID of the hub to unload the nanoapp
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700319 * @return the callback interface
320 */
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800321 private IContextHubTransactionCallback createUnloadTransactionCallback(int contextHubId) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700322 return new IContextHubTransactionCallback.Stub() {
323 @Override
324 public void onTransactionComplete(int result) {
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800325 handleUnloadResponseOldApi(contextHubId, result);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700326 }
327
328 @Override
329 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
330 }
331 };
332 }
333
334 /**
335 * Creates an internal query transaction callback to be used for old API clients
336 *
337 * @param contextHubId the ID of the hub to query
338 * @return the callback interface
339 */
340 private IContextHubTransactionCallback createQueryTransactionCallback(int contextHubId) {
341 return new IContextHubTransactionCallback.Stub() {
342 @Override
343 public void onTransactionComplete(int result) {
344 }
345
346 @Override
347 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
348 byte[] data = {(byte) result};
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800349 onMessageReceiptOldApi(MSG_QUERY_NANO_APPS, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700350 }
351 };
352 }
353
Peng Xu9ff7d222016-02-11 13:02:05 -0800354 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800355 public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700356 checkPermissions();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700357 if (mContextHubProxy == null) {
358 return -1;
359 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800360 if (!isValidContextHubId(contextHubHandle)) {
361 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in loadNanoApp");
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700362 return -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800363 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800364 if (nanoApp == null) {
365 Log.e(TAG, "NanoApp cannot be null in loadNanoApp");
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600366 return -1;
367 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800368
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700369 // Create an internal IContextHubTransactionCallback for the old API clients
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800370 NanoAppBinary nanoAppBinary = new NanoAppBinary(nanoApp.getAppBinary());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700371 IContextHubTransactionCallback onCompleteCallback =
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800372 createLoadTransactionCallback(contextHubHandle, nanoAppBinary);
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700373
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700374 ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800375 contextHubHandle, nanoAppBinary, onCompleteCallback);
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700376
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800377 mTransactionManager.addTransaction(transaction);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700378 return 0;
Peng Xu9ff7d222016-02-11 13:02:05 -0800379 }
380
destradaa8bad3fe2016-03-15 12:33:40 -0700381 @Override
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800382 public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700383 checkPermissions();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700384 if (mContextHubProxy == null) {
385 return -1;
386 }
387
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800388 NanoAppInstanceInfo info =
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800389 mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
Peng Xu9ff7d222016-02-11 13:02:05 -0800390 if (info == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800391 Log.e(TAG, "Invalid nanoapp handle " + nanoAppHandle + " in unloadNanoApp");
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800392 return -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800393 }
394
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700395 int contextHubId = info.getContexthubId();
396 long nanoAppId = info.getAppId();
397 IContextHubTransactionCallback onCompleteCallback =
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800398 createUnloadTransactionCallback(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700399 ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
400 contextHubId, nanoAppId, onCompleteCallback);
Peng Xu9ff7d222016-02-11 13:02:05 -0800401
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800402 mTransactionManager.addTransaction(transaction);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700403 return 0;
destradaa8bad3fe2016-03-15 12:33:40 -0700404 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800405
406 @Override
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800407 public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700408 checkPermissions();
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800409
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800410 return mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800411 }
412
413 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800414 public int[] findNanoAppOnHub(
415 int contextHubHandle, NanoAppFilter filter) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700416 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800417
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800418 ArrayList<Integer> foundInstances = new ArrayList<>();
Arthur Ishiguro11946342018-10-30 09:29:09 -0700419 if (filter != null) {
420 mNanoAppStateManager.foreachNanoAppInstanceInfo((info) -> {
421 if (filter.testMatch(info)) {
422 foundInstances.add(info.getHandle());
423 }
424 });
Peng Xu9ff7d222016-02-11 13:02:05 -0800425 }
426
427 int[] retArray = new int[foundInstances.size()];
428 for (int i = 0; i < foundInstances.size(); i++) {
429 retArray[i] = foundInstances.get(i).intValue();
430 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800431 return retArray;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800432 }
433
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700434 /**
435 * Performs a query at the specified hub.
436 *
437 * This method should only be invoked internally by the service, either to update the service
438 * cache or as a result of an explicit query requested by a client through the sendMessage API.
439 *
440 * @param contextHubId the ID of the hub to do the query
441 * @return the result of the query
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800442 *
443 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700444 */
445 private int queryNanoAppsInternal(int contextHubId) {
446 if (mContextHubProxy == null) {
447 return Result.UNKNOWN_FAILURE;
448 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700449
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700450 IContextHubTransactionCallback onCompleteCallback =
451 createQueryTransactionCallback(contextHubId);
452 ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
453 contextHubId, onCompleteCallback);
454
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800455 mTransactionManager.addTransaction(transaction);
456 return Result.OK;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700457 }
458
459 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800460 public int sendMessage(int contextHubHandle, int nanoAppHandle, ContextHubMessage msg)
461 throws RemoteException {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700462 checkPermissions();
463 if (mContextHubProxy == null) {
464 return -1;
465 }
466 if (msg == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800467 Log.e(TAG, "ContextHubMessage cannot be null in sendMessage");
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700468 return -1;
469 }
470 if (msg.getData() == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800471 Log.e(TAG, "ContextHubMessage message body cannot be null in sendMessage");
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800472 return -1;
473 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800474 if (!isValidContextHubId(contextHubHandle)) {
475 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in sendMessage");
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600476 return -1;
477 }
478
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800479 boolean success = false;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700480 if (nanoAppHandle == OS_APP_INSTANCE) {
481 if (msg.getMsgType() == MSG_QUERY_NANO_APPS) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800482 success = (queryNanoAppsInternal(contextHubHandle) == Result.OK);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700483 } else {
484 Log.e(TAG, "Invalid OS message params of type " + msg.getMsgType());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700485 }
486 } else {
487 NanoAppInstanceInfo info = getNanoAppInstanceInfo(nanoAppHandle);
488 if (info != null) {
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800489 NanoAppMessage message = NanoAppMessage.createMessageToNanoApp(
490 info.getAppId(), msg.getMsgType(), msg.getData());
Peng Xu9ff7d222016-02-11 13:02:05 -0800491
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800492 IContextHubClient client = mDefaultClientMap.get(contextHubHandle);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800493 success = (client.sendMessageToNanoApp(message) ==
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800494 ContextHubTransaction.RESULT_SUCCESS);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700495 } else {
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800496 Log.e(TAG, "Failed to send nanoapp message - nanoapp with handle "
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700497 + nanoAppHandle + " does not exist.");
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700498 }
499 }
500
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800501 return success ? 0 : -1;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700502 }
503
504 /**
505 * Handles a unicast or broadcast message from a nanoapp.
506 *
507 * @param contextHubId the ID of the hub the message came from
508 * @param message the message contents
509 */
510 private void handleClientMessageCallback(int contextHubId, ContextHubMsg message) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800511 mClientManager.onMessageFromNanoApp(contextHubId, message);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700512 }
513
514 /**
515 * A helper function to handle a load response from the Context Hub for the old API.
516 *
517 * TODO(b/69270990): Remove this once the old APIs are obsolete.
518 */
519 private void handleLoadResponseOldApi(
520 int contextHubId, int result, NanoAppBinary nanoAppBinary) {
521 if (nanoAppBinary == null) {
522 Log.e(TAG, "Nanoapp binary field was null for a load transaction");
523 return;
524 }
525
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700526 byte[] data = new byte[5];
527 data[0] = (byte) result;
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800528 int nanoAppHandle = mNanoAppStateManager.getNanoAppHandle(
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800529 contextHubId, nanoAppBinary.getNanoAppId());
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800530 ByteBuffer.wrap(data, 1, 4).order(ByteOrder.nativeOrder()).putInt(nanoAppHandle);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700531
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800532 onMessageReceiptOldApi(MSG_LOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700533 }
534
535 /**
536 * A helper function to handle an unload response from the Context Hub for the old API.
537 *
538 * TODO(b/69270990): Remove this once the old APIs are obsolete.
539 */
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800540 private void handleUnloadResponseOldApi(int contextHubId, int result) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700541 byte[] data = new byte[1];
542 data[0] = (byte) result;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800543 onMessageReceiptOldApi(MSG_UNLOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700544 }
545
546 /**
547 * Handles a transaction response from a Context Hub.
548 *
549 * @param contextHubId the ID of the hub the response came from
550 * @param transactionId the ID of the transaction
551 * @param result the result of the transaction reported by the hub
552 */
553 private void handleTransactionResultCallback(int contextHubId, int transactionId, int result) {
554 mTransactionManager.onTransactionResponse(transactionId, result);
555 }
556
557 /**
558 * Handles an asynchronous event from a Context Hub.
559 *
560 * @param contextHubId the ID of the hub the response came from
561 * @param eventType the type of the event as defined in Context Hub HAL AsyncEventType
562 */
563 private void handleHubEventCallback(int contextHubId, int eventType) {
564 if (eventType == AsyncEventType.RESTARTED) {
565 mTransactionManager.onHubReset();
566 queryNanoAppsInternal(contextHubId);
567
Arthur Ishiguro6d47c542017-11-17 15:49:07 -0800568 mClientManager.onHubReset(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700569 } else {
570 Log.i(TAG, "Received unknown hub event (hub ID = " + contextHubId + ", type = "
571 + eventType + ")");
572 }
573 }
574
575 /**
576 * Handles an asynchronous abort event of a nanoapp.
577 *
578 * @param contextHubId the ID of the hub that the nanoapp aborted in
579 * @param nanoAppId the ID of the aborted nanoapp
580 * @param abortCode the nanoapp-specific abort code
581 */
582 private void handleAppAbortCallback(int contextHubId, long nanoAppId, int abortCode) {
Arthur Ishiguro02ff50b2017-12-18 10:02:35 -0800583 mClientManager.onNanoAppAborted(contextHubId, nanoAppId, abortCode);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700584 }
585
586 /**
587 * Handles a query response from a Context Hub.
588 *
589 * @param contextHubId the ID of the hub of the response
590 * @param nanoAppInfoList the list of loaded nanoapps
591 */
592 private void handleQueryAppsCallback(int contextHubId, List<HubAppInfo> nanoAppInfoList) {
593 List<NanoAppState> nanoAppStateList =
594 ContextHubServiceUtil.createNanoAppStateList(nanoAppInfoList);
595
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800596 mNanoAppStateManager.updateCache(contextHubId, nanoAppInfoList);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700597 mTransactionManager.onQueryResponse(nanoAppStateList);
598 }
599
600 /**
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800601 * @param contextHubId the hub ID to validate
602 * @return {@code true} if the ID represents that of an available hub, {@code false} otherwise
603 */
604 private boolean isValidContextHubId(int contextHubId) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800605 return mContextHubIdToInfoMap.containsKey(contextHubId);
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800606 }
607
608 /**
609 * Creates and registers a client at the service for the specified Context Hub.
610 *
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800611 * @param contextHubId the ID of the hub this client is attached to
Arthur Ishiguro793d3d12018-11-15 13:10:24 -0800612 * @param clientCallback the client interface to register with the service
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800613 * @return the generated client interface, null if registration was unsuccessful
614 *
615 * @throws IllegalArgumentException if contextHubId is not a valid ID
616 * @throws IllegalStateException if max number of clients have already registered
617 * @throws NullPointerException if clientCallback is null
618 */
619 @Override
620 public IContextHubClient createClient(
Arthur Ishiguro793d3d12018-11-15 13:10:24 -0800621 int contextHubId, IContextHubClientCallback clientCallback) throws RemoteException {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800622 checkPermissions();
623 if (!isValidContextHubId(contextHubId)) {
624 throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
625 }
626 if (clientCallback == null) {
627 throw new NullPointerException("Cannot register client with null callback");
628 }
629
Arthur Ishiguro622ebcb2018-10-17 14:02:27 -0700630 ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
Arthur Ishiguro793d3d12018-11-15 13:10:24 -0800631 return mClientManager.registerClient(contextHubInfo, clientCallback);
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800632 }
633
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800634 /**
Arthur Ishiguro82ed3af2018-11-09 13:20:30 -0800635 * Creates and registers a PendingIntent client at the service for the specified Context Hub.
636 *
637 * @param contextHubId the ID of the hub this client is attached to
638 * @param pendingIntent the PendingIntent associated with this client
639 * @param nanoAppId the ID of the nanoapp PendingIntent events will be sent for
640 * @return the generated client interface
641 *
642 * @throws IllegalArgumentException if hubInfo does not represent a valid hub
643 * @throws IllegalStateException if there were too many registered clients at the service
644 */
645 @Override
646 public IContextHubClient createPendingIntentClient(
647 int contextHubId, PendingIntent pendingIntent, long nanoAppId) throws RemoteException {
648 checkPermissions();
649 if (!isValidContextHubId(contextHubId)) {
650 throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
651 }
652
653 ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
654 return mClientManager.registerClient(contextHubInfo, pendingIntent, nanoAppId);
655 }
656
657 /**
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800658 * Loads a nanoapp binary at the specified Context hub.
659 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800660 * @param contextHubId the ID of the hub to load the binary
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800661 * @param transactionCallback the client-facing transaction callback interface
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800662 * @param nanoAppBinary the binary to load
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800663 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800664 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800665 */
666 @Override
667 public void loadNanoAppOnHub(
668 int contextHubId, IContextHubTransactionCallback transactionCallback,
669 NanoAppBinary nanoAppBinary) throws RemoteException {
670 checkPermissions();
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800671 if (!checkHalProxyAndContextHubId(
672 contextHubId, transactionCallback, ContextHubTransaction.TYPE_LOAD_NANOAPP)) {
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800673 return;
674 }
675 if (nanoAppBinary == null) {
676 Log.e(TAG, "NanoAppBinary cannot be null in loadNanoAppOnHub");
677 transactionCallback.onTransactionComplete(
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800678 ContextHubTransaction.RESULT_FAILED_BAD_PARAMS);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800679 return;
680 }
681
682 ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
683 contextHubId, nanoAppBinary, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800684 mTransactionManager.addTransaction(transaction);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800685 }
686
687 /**
688 * Unloads a nanoapp from the specified Context Hub.
689 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800690 * @param contextHubId the ID of the hub to unload the nanoapp
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800691 * @param transactionCallback the client-facing transaction callback interface
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800692 * @param nanoAppId the ID of the nanoapp to unload
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800693 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800694 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800695 */
696 @Override
697 public void unloadNanoAppFromHub(
698 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
699 throws RemoteException {
700 checkPermissions();
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800701 if (!checkHalProxyAndContextHubId(
702 contextHubId, transactionCallback, ContextHubTransaction.TYPE_UNLOAD_NANOAPP)) {
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800703 return;
704 }
705
706 ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
707 contextHubId, nanoAppId, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800708 mTransactionManager.addTransaction(transaction);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800709 }
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800710
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800711 /**
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800712 * Enables a nanoapp at the specified Context Hub.
713 *
714 * @param contextHubId the ID of the hub to enable the nanoapp
715 * @param transactionCallback the client-facing transaction callback interface
716 * @param nanoAppId the ID of the nanoapp to enable
717 *
718 * @throws IllegalStateException if the transaction queue is full
719 */
720 @Override
721 public void enableNanoApp(
722 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
723 throws RemoteException {
724 checkPermissions();
725 if (!checkHalProxyAndContextHubId(
726 contextHubId, transactionCallback, ContextHubTransaction.TYPE_ENABLE_NANOAPP)) {
727 return;
728 }
729
730 ContextHubServiceTransaction transaction = mTransactionManager.createEnableTransaction(
731 contextHubId, nanoAppId, transactionCallback);
732 mTransactionManager.addTransaction(transaction);
733 }
734
735 /**
Arthur Ishiguro54e1a892017-12-12 15:09:31 -0800736 * Disables a nanoapp at the specified Context Hub.
737 *
738 * @param contextHubId the ID of the hub to disable the nanoapp
739 * @param transactionCallback the client-facing transaction callback interface
740 * @param nanoAppId the ID of the nanoapp to disable
741 *
742 * @throws IllegalStateException if the transaction queue is full
743 */
744 @Override
745 public void disableNanoApp(
746 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
747 throws RemoteException {
748 checkPermissions();
749 if (!checkHalProxyAndContextHubId(
750 contextHubId, transactionCallback, ContextHubTransaction.TYPE_DISABLE_NANOAPP)) {
751 return;
752 }
753
754 ContextHubServiceTransaction transaction = mTransactionManager.createDisableTransaction(
755 contextHubId, nanoAppId, transactionCallback);
756 mTransactionManager.addTransaction(transaction);
757 }
758
759 /**
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800760 * Queries for a list of nanoapps from the specified Context hub.
761 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800762 * @param contextHubId the ID of the hub to query
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800763 * @param transactionCallback the client-facing transaction callback interface
764 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800765 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800766 */
767 @Override
768 public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback)
769 throws RemoteException {
770 checkPermissions();
771 if (!checkHalProxyAndContextHubId(
772 contextHubId, transactionCallback, ContextHubTransaction.TYPE_QUERY_NANOAPPS)) {
773 return;
774 }
775
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800776 ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
777 contextHubId, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800778 mTransactionManager.addTransaction(transaction);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800779 }
780
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700781 @Override
782 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600783 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700784
785 pw.println("Dumping ContextHub Service");
786
787 pw.println("");
788 // dump ContextHubInfo
789 pw.println("=================== CONTEXT HUBS ====================");
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800790 for (ContextHubInfo hubInfo : mContextHubIdToInfoMap.values()) {
791 pw.println(hubInfo);
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700792 }
793 pw.println("");
794 pw.println("=================== NANOAPPS ====================");
795 // Dump nanoAppHash
Arthur Ishiguro11946342018-10-30 09:29:09 -0700796 mNanoAppStateManager.foreachNanoAppInstanceInfo((info) -> pw.println(info));
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700797
Arthur Ishiguro672d8a72019-12-02 15:16:08 -0800798 pw.println("");
799 pw.println("=================== CLIENTS ====================");
800 pw.println(mClientManager);
801
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700802 // dump eventLog
803 }
804
destradaa8bad3fe2016-03-15 12:33:40 -0700805 private void checkPermissions() {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800806 ContextHubServiceUtil.checkPermissions(mContext);
destradaa8bad3fe2016-03-15 12:33:40 -0700807 }
Ashutosh Joshi2c697fb2016-04-01 20:48:13 +0000808
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800809 private int onMessageReceiptOldApi(
810 int msgType, int contextHubHandle, int appInstance, byte[] data) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700811 if (data == null) {
812 return -1;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700813 }
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800814
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700815 int msgVersion = 0;
destradaa78cebca2016-04-14 18:40:14 -0700816 int callbacksCount = mCallbacksList.beginBroadcast();
Arthur Ishigurob4f59872018-07-31 16:38:08 -0700817 if (DEBUG_LOG_ENABLED) {
818 Log.v(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle "
819 + contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
820 + callbacksCount);
821 }
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800822
destradaa78cebca2016-04-14 18:40:14 -0700823 if (callbacksCount < 1) {
Arthur Ishigurob4f59872018-07-31 16:38:08 -0700824 if (DEBUG_LOG_ENABLED) {
825 Log.v(TAG, "No message callbacks registered.");
826 }
destradaa78cebca2016-04-14 18:40:14 -0700827 return 0;
828 }
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700829
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800830 ContextHubMessage msg = new ContextHubMessage(msgType, msgVersion, data);
destradaa78cebca2016-04-14 18:40:14 -0700831 for (int i = 0; i < callbacksCount; ++i) {
832 IContextHubCallback callback = mCallbacksList.getBroadcastItem(i);
833 try {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800834 callback.onMessageReceipt(contextHubHandle, appInstance, msg);
destradaa78cebca2016-04-14 18:40:14 -0700835 } catch (RemoteException e) {
836 Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
837 continue;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700838 }
839 }
destradaa78cebca2016-04-14 18:40:14 -0700840 mCallbacksList.finishBroadcast();
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700841 return 0;
842 }
843
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800844 /**
845 * Validates the HAL proxy state and context hub ID to see if we can start the transaction.
846 *
847 * @param contextHubId the ID of the hub to start the transaction
848 * @param callback the client transaction callback interface
849 * @param transactionType the type of the transaction
850 *
851 * @return {@code true} if mContextHubProxy and contextHubId is valid, {@code false} otherwise
852 */
853 private boolean checkHalProxyAndContextHubId(
854 int contextHubId, IContextHubTransactionCallback callback,
855 @ContextHubTransaction.Type int transactionType) {
856 if (mContextHubProxy == null) {
857 try {
858 callback.onTransactionComplete(
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800859 ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800860 } catch (RemoteException e) {
861 Log.e(TAG, "RemoteException while calling onTransactionComplete", e);
862 }
863 return false;
864 }
865 if (!isValidContextHubId(contextHubId)) {
866 Log.e(TAG, "Cannot start "
867 + ContextHubTransaction.typeToString(transactionType, false /* upperCase */)
868 + " transaction for invalid hub ID " + contextHubId);
869 try {
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800870 callback.onTransactionComplete(ContextHubTransaction.RESULT_FAILED_BAD_PARAMS);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800871 } catch (RemoteException e) {
872 Log.e(TAG, "RemoteException while calling onTransactionComplete", e);
873 }
874 return false;
875 }
876
877 return true;
878 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700879}