blob: dc95d41090b2af07d4d7c7a8b5684506ce3bfb65 [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
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080019import android.content.Context;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070020import android.hardware.contexthub.V1_0.AsyncEventType;
21import android.hardware.contexthub.V1_0.ContextHub;
22import android.hardware.contexthub.V1_0.ContextHubMsg;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070023import android.hardware.contexthub.V1_0.HubAppInfo;
24import android.hardware.contexthub.V1_0.IContexthub;
25import android.hardware.contexthub.V1_0.IContexthubCallback;
26import android.hardware.contexthub.V1_0.Result;
27import android.hardware.contexthub.V1_0.TransactionResult;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080028import android.hardware.location.ContextHubInfo;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080029import android.hardware.location.ContextHubMessage;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080030import android.hardware.location.ContextHubTransaction;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080031import android.hardware.location.IContextHubCallback;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080032import android.hardware.location.IContextHubClient;
33import android.hardware.location.IContextHubClientCallback;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070034import android.hardware.location.IContextHubService;
35import android.hardware.location.IContextHubTransactionCallback;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080036import android.hardware.location.NanoApp;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070037import android.hardware.location.NanoAppBinary;
38import android.hardware.location.NanoAppFilter;
Ashutosh Joshi420e45e2016-12-20 16:34:41 -080039import android.hardware.location.NanoAppInstanceInfo;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080040import android.hardware.location.NanoAppMessage;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070041import android.hardware.location.NanoAppState;
destradaa78cebca2016-04-14 18:40:14 -070042import android.os.RemoteCallbackList;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080043import android.os.RemoteException;
44import android.util.Log;
45
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060046import com.android.internal.util.DumpUtils;
47
Ashutosh Joshi6239cc62016-04-04 16:19:29 -070048import java.io.FileDescriptor;
49import java.io.PrintWriter;
Ashutosh Joshi19753cc2016-11-23 13:56:39 -080050import java.nio.ByteBuffer;
51import java.nio.ByteOrder;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080052import java.util.ArrayList;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070053import java.util.Collections;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080054import java.util.HashMap;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070055import java.util.List;
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080056import java.util.Map;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070057import java.util.NoSuchElementException;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080058
59/**
60 * @hide
61 */
Peng Xu9ff7d222016-02-11 13:02:05 -080062public class ContextHubService extends IContextHubService.Stub {
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080063 private static final String TAG = "ContextHubService";
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080064
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070065 /*
66 * Constants for the type of transaction that is defined by ContextHubService.
67 * This is used to report the transaction callback to clients, and is different from
68 * ContextHubTransaction.Type.
69 */
70 public static final int MSG_ENABLE_NANO_APP = 1;
71 public static final int MSG_DISABLE_NANO_APP = 2;
72 public static final int MSG_LOAD_NANO_APP = 3;
Ashutosh Joshicafdee92016-04-04 16:19:29 -070073 public static final int MSG_UNLOAD_NANO_APP = 4;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070074 public static final int MSG_QUERY_NANO_APPS = 5;
75 public static final int MSG_QUERY_MEMORY = 6;
76 public static final int MSG_HUB_RESET = 7;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070077
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070078 private static final int OS_APP_INSTANCE = -1;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080079
Peng Xu9ff7d222016-02-11 13:02:05 -080080 private final Context mContext;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070081
Arthur Ishiguroab7113d2017-12-15 14:32:51 -080082 private final Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
Arthur Ishigurofdbbd462017-11-27 16:33:36 -080083 private final List<ContextHubInfo> mContextHubInfoList;
destradaa78cebca2016-04-14 18:40:14 -070084 private final RemoteCallbackList<IContextHubCallback> mCallbacksList =
85 new RemoteCallbackList<>();
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -080086
Arthur Ishiguro7a23a962017-11-01 10:52:28 -070087 // Proxy object to communicate with the Context Hub HAL
88 private final IContexthub mContextHubProxy;
89
90 // The manager for transaction queue
91 private final ContextHubTransactionManager mTransactionManager;
92
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -080093 // The manager for sending messages to/from clients
94 private final ContextHubClientManager mClientManager;
95
Arthur Ishiguroebb0e862017-11-17 14:55:32 -080096 // The default client for old API clients
97 private final Map<Integer, IContextHubClient> mDefaultClientMap;
98
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -080099 // The manager for the internal nanoapp state cache
100 private final NanoAppStateManager mNanoAppStateManager = new NanoAppStateManager();
101
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700102 /**
103 * Class extending the callback to register with a Context Hub.
104 */
105 private class ContextHubServiceCallback extends IContexthubCallback.Stub {
106 private final int mContextHubId;
107
108 ContextHubServiceCallback(int contextHubId) {
109 mContextHubId = contextHubId;
110 }
111
112 @Override
113 public void handleClientMsg(ContextHubMsg message) {
114 handleClientMessageCallback(mContextHubId, message);
115 }
116
117 @Override
118 public void handleTxnResult(int transactionId, int result) {
119 handleTransactionResultCallback(mContextHubId, transactionId, result);
120 }
121
122 @Override
123 public void handleHubEvent(int eventType) {
124 handleHubEventCallback(mContextHubId, eventType);
125 }
126
127 @Override
128 public void handleAppAbort(long nanoAppId, int abortCode) {
129 handleAppAbortCallback(mContextHubId, nanoAppId, abortCode);
130 }
131
132 @Override
133 public void handleAppsInfo(ArrayList<HubAppInfo> nanoAppInfoList) {
134 handleQueryAppsCallback(mContextHubId, nanoAppInfoList);
135 }
136 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700137
Peng Xu9ff7d222016-02-11 13:02:05 -0800138 public ContextHubService(Context context) {
139 mContext = context;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700140
141 mContextHubProxy = getContextHubProxy();
142 if (mContextHubProxy == null) {
143 mTransactionManager = null;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800144 mClientManager = null;
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800145 mDefaultClientMap = Collections.emptyMap();
146 mContextHubIdToInfoMap = Collections.emptyMap();
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800147 mContextHubInfoList = Collections.emptyList();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700148 return;
149 }
150
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800151 mClientManager = new ContextHubClientManager(mContext, mContextHubProxy);
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800152 mTransactionManager = new ContextHubTransactionManager(
153 mContextHubProxy, mClientManager, mNanoAppStateManager);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700154
155 List<ContextHub> hubList;
156 try {
157 hubList = mContextHubProxy.getHubs();
158 } catch (RemoteException e) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800159 Log.e(TAG, "RemoteException while getting Context Hub info", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700160 hubList = Collections.emptyList();
161 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800162 mContextHubIdToInfoMap = Collections.unmodifiableMap(
163 ContextHubServiceUtil.createContextHubInfoMap(hubList));
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800164 mContextHubInfoList = new ArrayList<>(mContextHubIdToInfoMap.values());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700165
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800166 HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800167 for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800168 IContextHubClient client = mClientManager.registerClient(
169 createDefaultClientCallback(contextHubId), contextHubId);
170 defaultClientMap.put(contextHubId, client);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800171
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700172 try {
173 mContextHubProxy.registerCallback(
174 contextHubId, new ContextHubServiceCallback(contextHubId));
175 } catch (RemoteException e) {
176 Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800177 + contextHubId + ")", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700178 }
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700179
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800180 // Do a query to initialize the service cache list of nanoapps
181 // TODO(b/69270990): Remove this when old API is deprecated
182 queryNanoAppsInternal(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700183 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800184 mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);
Peng Xu9ff7d222016-02-11 13:02:05 -0800185 }
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800186
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700187 /**
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800188 * Creates a default client callback for old API clients.
189 *
190 * @param contextHubId the ID of the hub to attach this client to
191 * @return the internal callback interface
192 */
193 private IContextHubClientCallback createDefaultClientCallback(int contextHubId) {
194 return new IContextHubClientCallback.Stub() {
195 @Override
196 public void onMessageFromNanoApp(NanoAppMessage message) {
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800197 int nanoAppHandle = mNanoAppStateManager.getNanoAppHandle(
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800198 contextHubId, message.getNanoAppId());
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800199
200 onMessageReceiptOldApi(
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800201 message.getMessageType(), contextHubId, nanoAppHandle,
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800202 message.getMessageBody());
203 }
204
205 @Override
206 public void onHubReset() {
Arthur Ishiguro6d47c542017-11-17 15:49:07 -0800207 byte[] data = {TransactionResult.SUCCESS};
208 onMessageReceiptOldApi(MSG_HUB_RESET, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800209 }
210
211 @Override
212 public void onNanoAppAborted(long nanoAppId, int abortCode) {
213 }
214
215 @Override
216 public void onNanoAppLoaded(long nanoAppId) {
217 }
218
219 @Override
220 public void onNanoAppUnloaded(long nanoAppId) {
221 }
222
223 @Override
224 public void onNanoAppEnabled(long nanoAppId) {
225 }
226
227 @Override
228 public void onNanoAppDisabled(long nanoAppId) {
229 }
230 };
231 }
232
233 /**
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700234 * @return the IContexthub proxy interface
235 */
236 private IContexthub getContextHubProxy() {
237 IContexthub proxy = null;
238 try {
239 proxy = IContexthub.getService(true /* retry */);
240 } catch (RemoteException e) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800241 Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700242 } catch (NoSuchElementException e) {
243 Log.i(TAG, "Context Hub HAL service not found");
244 }
245
246 return proxy;
247 }
248
Peng Xu9ff7d222016-02-11 13:02:05 -0800249 @Override
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700250 public int registerCallback(IContextHubCallback callback) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700251 checkPermissions();
destradaa78cebca2016-04-14 18:40:14 -0700252 mCallbacksList.register(callback);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800253
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800254 Log.d(TAG, "Added callback, total callbacks " +
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700255 mCallbacksList.getRegisteredCallbackCount());
Peng Xu9ff7d222016-02-11 13:02:05 -0800256 return 0;
257 }
258
259 @Override
260 public int[] getContextHubHandles() throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700261 checkPermissions();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800262 return ContextHubServiceUtil.createPrimitiveIntArray(mContextHubIdToInfoMap.keySet());
Peng Xu9ff7d222016-02-11 13:02:05 -0800263 }
264
265 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800266 public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700267 checkPermissions();
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800268 if (!mContextHubIdToInfoMap.containsKey(contextHubHandle)) {
269 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in getContextHubInfo");
270 return null;
Peng Xu9ff7d222016-02-11 13:02:05 -0800271 }
272
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800273 return mContextHubIdToInfoMap.get(contextHubHandle);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700274 }
275
276 /**
Arthur Ishigurofdbbd462017-11-27 16:33:36 -0800277 * Returns a List of ContextHubInfo object describing the available hubs.
278 *
279 * @return the List of ContextHubInfo objects
280 */
281 @Override
282 public List<ContextHubInfo> getContextHubs() throws RemoteException {
283 checkPermissions();
284 return mContextHubInfoList;
285 }
286
287 /**
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700288 * Creates an internal load transaction callback to be used for old API clients
289 *
290 * @param contextHubId the ID of the hub to load the binary
291 * @param nanoAppBinary the binary to load
292 * @return the callback interface
293 */
294 private IContextHubTransactionCallback createLoadTransactionCallback(
295 int contextHubId, NanoAppBinary nanoAppBinary) {
296 return new IContextHubTransactionCallback.Stub() {
297 @Override
298 public void onTransactionComplete(int result) {
299 handleLoadResponseOldApi(contextHubId, result, nanoAppBinary);
300 }
301
302 @Override
303 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
304 }
305 };
306 }
307
308 /**
309 * Creates an internal unload transaction callback to be used for old API clients
310 *
311 * @param contextHubId the ID of the hub to unload the nanoapp
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700312 * @return the callback interface
313 */
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800314 private IContextHubTransactionCallback createUnloadTransactionCallback(int contextHubId) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700315 return new IContextHubTransactionCallback.Stub() {
316 @Override
317 public void onTransactionComplete(int result) {
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800318 handleUnloadResponseOldApi(contextHubId, result);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700319 }
320
321 @Override
322 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
323 }
324 };
325 }
326
327 /**
328 * Creates an internal query transaction callback to be used for old API clients
329 *
330 * @param contextHubId the ID of the hub to query
331 * @return the callback interface
332 */
333 private IContextHubTransactionCallback createQueryTransactionCallback(int contextHubId) {
334 return new IContextHubTransactionCallback.Stub() {
335 @Override
336 public void onTransactionComplete(int result) {
337 }
338
339 @Override
340 public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
341 byte[] data = {(byte) result};
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800342 onMessageReceiptOldApi(MSG_QUERY_NANO_APPS, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700343 }
344 };
345 }
346
Peng Xu9ff7d222016-02-11 13:02:05 -0800347 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800348 public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700349 checkPermissions();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700350 if (mContextHubProxy == null) {
351 return -1;
352 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800353 if (!isValidContextHubId(contextHubHandle)) {
354 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in loadNanoApp");
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700355 return -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800356 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800357 if (nanoApp == null) {
358 Log.e(TAG, "NanoApp cannot be null in loadNanoApp");
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600359 return -1;
360 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800361
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700362 // Create an internal IContextHubTransactionCallback for the old API clients
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800363 NanoAppBinary nanoAppBinary = new NanoAppBinary(nanoApp.getAppBinary());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700364 IContextHubTransactionCallback onCompleteCallback =
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800365 createLoadTransactionCallback(contextHubHandle, nanoAppBinary);
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700366
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700367 ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800368 contextHubHandle, nanoAppBinary, onCompleteCallback);
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700369
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800370 mTransactionManager.addTransaction(transaction);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700371 return 0;
Peng Xu9ff7d222016-02-11 13:02:05 -0800372 }
373
destradaa8bad3fe2016-03-15 12:33:40 -0700374 @Override
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800375 public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700376 checkPermissions();
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700377 if (mContextHubProxy == null) {
378 return -1;
379 }
380
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800381 NanoAppInstanceInfo info =
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800382 mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
Peng Xu9ff7d222016-02-11 13:02:05 -0800383 if (info == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800384 Log.e(TAG, "Invalid nanoapp handle " + nanoAppHandle + " in unloadNanoApp");
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800385 return -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800386 }
387
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700388 int contextHubId = info.getContexthubId();
389 long nanoAppId = info.getAppId();
390 IContextHubTransactionCallback onCompleteCallback =
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800391 createUnloadTransactionCallback(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700392 ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
393 contextHubId, nanoAppId, onCompleteCallback);
Peng Xu9ff7d222016-02-11 13:02:05 -0800394
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800395 mTransactionManager.addTransaction(transaction);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700396 return 0;
destradaa8bad3fe2016-03-15 12:33:40 -0700397 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800398
399 @Override
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800400 public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700401 checkPermissions();
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800402
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800403 return mNanoAppStateManager.getNanoAppInstanceInfo(nanoAppHandle);
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800404 }
405
406 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800407 public int[] findNanoAppOnHub(
408 int contextHubHandle, NanoAppFilter filter) throws RemoteException {
destradaa8bad3fe2016-03-15 12:33:40 -0700409 checkPermissions();
Peng Xu9ff7d222016-02-11 13:02:05 -0800410
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800411 ArrayList<Integer> foundInstances = new ArrayList<>();
412 for (NanoAppInstanceInfo info : mNanoAppStateManager.getNanoAppInstanceInfoCollection()) {
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700413 if (filter.testMatch(info)) {
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800414 foundInstances.add(info.getHandle());
Peng Xu9ff7d222016-02-11 13:02:05 -0800415 }
416 }
417
418 int[] retArray = new int[foundInstances.size()];
419 for (int i = 0; i < foundInstances.size(); i++) {
420 retArray[i] = foundInstances.get(i).intValue();
421 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800422 return retArray;
Ashutosh Joshi1d1ac542016-01-18 17:19:27 -0800423 }
424
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700425 /**
426 * Performs a query at the specified hub.
427 *
428 * This method should only be invoked internally by the service, either to update the service
429 * cache or as a result of an explicit query requested by a client through the sendMessage API.
430 *
431 * @param contextHubId the ID of the hub to do the query
432 * @return the result of the query
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800433 *
434 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700435 */
436 private int queryNanoAppsInternal(int contextHubId) {
437 if (mContextHubProxy == null) {
438 return Result.UNKNOWN_FAILURE;
439 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700440
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700441 IContextHubTransactionCallback onCompleteCallback =
442 createQueryTransactionCallback(contextHubId);
443 ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
444 contextHubId, onCompleteCallback);
445
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800446 mTransactionManager.addTransaction(transaction);
447 return Result.OK;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700448 }
449
450 @Override
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800451 public int sendMessage(int contextHubHandle, int nanoAppHandle, ContextHubMessage msg)
452 throws RemoteException {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700453 checkPermissions();
454 if (mContextHubProxy == null) {
455 return -1;
456 }
457 if (msg == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800458 Log.e(TAG, "ContextHubMessage cannot be null in sendMessage");
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700459 return -1;
460 }
461 if (msg.getData() == null) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800462 Log.e(TAG, "ContextHubMessage message body cannot be null in sendMessage");
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800463 return -1;
464 }
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800465 if (!isValidContextHubId(contextHubHandle)) {
466 Log.e(TAG, "Invalid Context Hub handle " + contextHubHandle + " in sendMessage");
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600467 return -1;
468 }
469
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800470 boolean success = false;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700471 if (nanoAppHandle == OS_APP_INSTANCE) {
472 if (msg.getMsgType() == MSG_QUERY_NANO_APPS) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800473 success = (queryNanoAppsInternal(contextHubHandle) == Result.OK);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700474 } else {
475 Log.e(TAG, "Invalid OS message params of type " + msg.getMsgType());
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700476 }
477 } else {
478 NanoAppInstanceInfo info = getNanoAppInstanceInfo(nanoAppHandle);
479 if (info != null) {
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800480 NanoAppMessage message = NanoAppMessage.createMessageToNanoApp(
481 info.getAppId(), msg.getMsgType(), msg.getData());
Peng Xu9ff7d222016-02-11 13:02:05 -0800482
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800483 IContextHubClient client = mDefaultClientMap.get(contextHubHandle);
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800484 success = (client.sendMessageToNanoApp(message) ==
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800485 ContextHubTransaction.RESULT_SUCCESS);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700486 } else {
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800487 Log.e(TAG, "Failed to send nanoapp message - nanoapp with handle "
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700488 + nanoAppHandle + " does not exist.");
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700489 }
490 }
491
Arthur Ishiguroebb0e862017-11-17 14:55:32 -0800492 return success ? 0 : -1;
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700493 }
494
495 /**
496 * Handles a unicast or broadcast message from a nanoapp.
497 *
498 * @param contextHubId the ID of the hub the message came from
499 * @param message the message contents
500 */
501 private void handleClientMessageCallback(int contextHubId, ContextHubMsg message) {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800502 mClientManager.onMessageFromNanoApp(contextHubId, message);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700503 }
504
505 /**
506 * A helper function to handle a load response from the Context Hub for the old API.
507 *
508 * TODO(b/69270990): Remove this once the old APIs are obsolete.
509 */
510 private void handleLoadResponseOldApi(
511 int contextHubId, int result, NanoAppBinary nanoAppBinary) {
512 if (nanoAppBinary == null) {
513 Log.e(TAG, "Nanoapp binary field was null for a load transaction");
514 return;
515 }
516
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700517 byte[] data = new byte[5];
518 data[0] = (byte) result;
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800519 int nanoAppHandle = mNanoAppStateManager.getNanoAppHandle(
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800520 contextHubId, nanoAppBinary.getNanoAppId());
Arthur Ishiguro2fc5a4b2017-12-11 15:15:44 -0800521 ByteBuffer.wrap(data, 1, 4).order(ByteOrder.nativeOrder()).putInt(nanoAppHandle);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700522
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800523 onMessageReceiptOldApi(MSG_LOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700524 }
525
526 /**
527 * A helper function to handle an unload response from the Context Hub for the old API.
528 *
529 * TODO(b/69270990): Remove this once the old APIs are obsolete.
530 */
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800531 private void handleUnloadResponseOldApi(int contextHubId, int result) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700532 byte[] data = new byte[1];
533 data[0] = (byte) result;
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800534 onMessageReceiptOldApi(MSG_UNLOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700535 }
536
537 /**
538 * Handles a transaction response from a Context Hub.
539 *
540 * @param contextHubId the ID of the hub the response came from
541 * @param transactionId the ID of the transaction
542 * @param result the result of the transaction reported by the hub
543 */
544 private void handleTransactionResultCallback(int contextHubId, int transactionId, int result) {
545 mTransactionManager.onTransactionResponse(transactionId, result);
546 }
547
548 /**
549 * Handles an asynchronous event from a Context Hub.
550 *
551 * @param contextHubId the ID of the hub the response came from
552 * @param eventType the type of the event as defined in Context Hub HAL AsyncEventType
553 */
554 private void handleHubEventCallback(int contextHubId, int eventType) {
555 if (eventType == AsyncEventType.RESTARTED) {
556 mTransactionManager.onHubReset();
557 queryNanoAppsInternal(contextHubId);
558
Arthur Ishiguro6d47c542017-11-17 15:49:07 -0800559 mClientManager.onHubReset(contextHubId);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700560 } else {
561 Log.i(TAG, "Received unknown hub event (hub ID = " + contextHubId + ", type = "
562 + eventType + ")");
563 }
564 }
565
566 /**
567 * Handles an asynchronous abort event of a nanoapp.
568 *
569 * @param contextHubId the ID of the hub that the nanoapp aborted in
570 * @param nanoAppId the ID of the aborted nanoapp
571 * @param abortCode the nanoapp-specific abort code
572 */
573 private void handleAppAbortCallback(int contextHubId, long nanoAppId, int abortCode) {
Arthur Ishiguro02ff50b2017-12-18 10:02:35 -0800574 mClientManager.onNanoAppAborted(contextHubId, nanoAppId, abortCode);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700575 }
576
577 /**
578 * Handles a query response from a Context Hub.
579 *
580 * @param contextHubId the ID of the hub of the response
581 * @param nanoAppInfoList the list of loaded nanoapps
582 */
583 private void handleQueryAppsCallback(int contextHubId, List<HubAppInfo> nanoAppInfoList) {
584 List<NanoAppState> nanoAppStateList =
585 ContextHubServiceUtil.createNanoAppStateList(nanoAppInfoList);
586
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800587 mNanoAppStateManager.updateCache(contextHubId, nanoAppInfoList);
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700588 mTransactionManager.onQueryResponse(nanoAppStateList);
589 }
590
591 /**
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800592 * @param contextHubId the hub ID to validate
593 * @return {@code true} if the ID represents that of an available hub, {@code false} otherwise
594 */
595 private boolean isValidContextHubId(int contextHubId) {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800596 return mContextHubIdToInfoMap.containsKey(contextHubId);
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800597 }
598
599 /**
600 * Creates and registers a client at the service for the specified Context Hub.
601 *
602 * @param clientCallback the client interface to register with the service
603 * @param contextHubId the ID of the hub this client is attached to
604 * @return the generated client interface, null if registration was unsuccessful
605 *
606 * @throws IllegalArgumentException if contextHubId is not a valid ID
607 * @throws IllegalStateException if max number of clients have already registered
608 * @throws NullPointerException if clientCallback is null
609 */
610 @Override
611 public IContextHubClient createClient(
612 IContextHubClientCallback clientCallback, int contextHubId) throws RemoteException {
613 checkPermissions();
614 if (!isValidContextHubId(contextHubId)) {
615 throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
616 }
617 if (clientCallback == null) {
618 throw new NullPointerException("Cannot register client with null callback");
619 }
620
621 return mClientManager.registerClient(clientCallback, contextHubId);
622 }
623
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800624 /**
625 * Loads a nanoapp binary at the specified Context hub.
626 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800627 * @param contextHubId the ID of the hub to load the binary
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800628 * @param transactionCallback the client-facing transaction callback interface
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800629 * @param nanoAppBinary the binary to load
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800630 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800631 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800632 */
633 @Override
634 public void loadNanoAppOnHub(
635 int contextHubId, IContextHubTransactionCallback transactionCallback,
636 NanoAppBinary nanoAppBinary) throws RemoteException {
637 checkPermissions();
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800638 if (!checkHalProxyAndContextHubId(
639 contextHubId, transactionCallback, ContextHubTransaction.TYPE_LOAD_NANOAPP)) {
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800640 return;
641 }
642 if (nanoAppBinary == null) {
643 Log.e(TAG, "NanoAppBinary cannot be null in loadNanoAppOnHub");
644 transactionCallback.onTransactionComplete(
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800645 ContextHubTransaction.RESULT_FAILED_BAD_PARAMS);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800646 return;
647 }
648
649 ContextHubServiceTransaction transaction = mTransactionManager.createLoadTransaction(
650 contextHubId, nanoAppBinary, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800651 mTransactionManager.addTransaction(transaction);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800652 }
653
654 /**
655 * Unloads a nanoapp from the specified Context Hub.
656 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800657 * @param contextHubId the ID of the hub to unload the nanoapp
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800658 * @param transactionCallback the client-facing transaction callback interface
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800659 * @param nanoAppId the ID of the nanoapp to unload
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800660 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800661 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800662 */
663 @Override
664 public void unloadNanoAppFromHub(
665 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
666 throws RemoteException {
667 checkPermissions();
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800668 if (!checkHalProxyAndContextHubId(
669 contextHubId, transactionCallback, ContextHubTransaction.TYPE_UNLOAD_NANOAPP)) {
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800670 return;
671 }
672
673 ContextHubServiceTransaction transaction = mTransactionManager.createUnloadTransaction(
674 contextHubId, nanoAppId, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800675 mTransactionManager.addTransaction(transaction);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800676 }
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800677
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800678 /**
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800679 * Enables a nanoapp at the specified Context Hub.
680 *
681 * @param contextHubId the ID of the hub to enable the nanoapp
682 * @param transactionCallback the client-facing transaction callback interface
683 * @param nanoAppId the ID of the nanoapp to enable
684 *
685 * @throws IllegalStateException if the transaction queue is full
686 */
687 @Override
688 public void enableNanoApp(
689 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
690 throws RemoteException {
691 checkPermissions();
692 if (!checkHalProxyAndContextHubId(
693 contextHubId, transactionCallback, ContextHubTransaction.TYPE_ENABLE_NANOAPP)) {
694 return;
695 }
696
697 ContextHubServiceTransaction transaction = mTransactionManager.createEnableTransaction(
698 contextHubId, nanoAppId, transactionCallback);
699 mTransactionManager.addTransaction(transaction);
700 }
701
702 /**
Arthur Ishiguro54e1a892017-12-12 15:09:31 -0800703 * Disables a nanoapp at the specified Context Hub.
704 *
705 * @param contextHubId the ID of the hub to disable the nanoapp
706 * @param transactionCallback the client-facing transaction callback interface
707 * @param nanoAppId the ID of the nanoapp to disable
708 *
709 * @throws IllegalStateException if the transaction queue is full
710 */
711 @Override
712 public void disableNanoApp(
713 int contextHubId, IContextHubTransactionCallback transactionCallback, long nanoAppId)
714 throws RemoteException {
715 checkPermissions();
716 if (!checkHalProxyAndContextHubId(
717 contextHubId, transactionCallback, ContextHubTransaction.TYPE_DISABLE_NANOAPP)) {
718 return;
719 }
720
721 ContextHubServiceTransaction transaction = mTransactionManager.createDisableTransaction(
722 contextHubId, nanoAppId, transactionCallback);
723 mTransactionManager.addTransaction(transaction);
724 }
725
726 /**
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800727 * Queries for a list of nanoapps from the specified Context hub.
728 *
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800729 * @param contextHubId the ID of the hub to query
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800730 * @param transactionCallback the client-facing transaction callback interface
731 *
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800732 * @throws IllegalStateException if the transaction queue is full
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800733 */
734 @Override
735 public void queryNanoApps(int contextHubId, IContextHubTransactionCallback transactionCallback)
736 throws RemoteException {
737 checkPermissions();
738 if (!checkHalProxyAndContextHubId(
739 contextHubId, transactionCallback, ContextHubTransaction.TYPE_QUERY_NANOAPPS)) {
740 return;
741 }
742
Arthur Ishiguro0ed545c2017-12-12 15:01:32 -0800743 ContextHubServiceTransaction transaction = mTransactionManager.createQueryTransaction(
744 contextHubId, transactionCallback);
Arthur Ishiguroe60f91a2017-11-30 09:48:00 -0800745 mTransactionManager.addTransaction(transaction);
Arthur Ishiguroe1ade432017-11-27 10:45:33 -0800746 }
747
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700748 @Override
749 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600750 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700751
752 pw.println("Dumping ContextHub Service");
753
754 pw.println("");
755 // dump ContextHubInfo
756 pw.println("=================== CONTEXT HUBS ====================");
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800757 for (ContextHubInfo hubInfo : mContextHubIdToInfoMap.values()) {
758 pw.println(hubInfo);
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700759 }
760 pw.println("");
761 pw.println("=================== NANOAPPS ====================");
762 // Dump nanoAppHash
Arthur Ishigurofb9e4c72017-11-21 15:33:21 -0800763 for (NanoAppInstanceInfo info : mNanoAppStateManager.getNanoAppInstanceInfoCollection()) {
764 pw.println(info);
Ashutosh Joshi6239cc62016-04-04 16:19:29 -0700765 }
766
767 // dump eventLog
768 }
769
destradaa8bad3fe2016-03-15 12:33:40 -0700770 private void checkPermissions() {
Arthur Ishiguro4e39aa12017-11-14 14:59:08 -0800771 ContextHubServiceUtil.checkPermissions(mContext);
destradaa8bad3fe2016-03-15 12:33:40 -0700772 }
Ashutosh Joshi2c697fb2016-04-01 20:48:13 +0000773
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800774 private int onMessageReceiptOldApi(
775 int msgType, int contextHubHandle, int appInstance, byte[] data) {
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700776 if (data == null) {
777 return -1;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700778 }
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800779
Arthur Ishiguro7a23a962017-11-01 10:52:28 -0700780 int msgVersion = 0;
destradaa78cebca2016-04-14 18:40:14 -0700781 int callbacksCount = mCallbacksList.beginBroadcast();
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800782 Log.d(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle " +
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800783 contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
784 + callbacksCount);
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800785
destradaa78cebca2016-04-14 18:40:14 -0700786 if (callbacksCount < 1) {
787 Log.v(TAG, "No message callbacks registered.");
788 return 0;
789 }
Ashutosh Joshi54787a52016-04-27 11:19:16 -0700790
Ashutosh Joshi1d941812017-03-09 15:21:24 -0800791 ContextHubMessage msg = new ContextHubMessage(msgType, msgVersion, data);
destradaa78cebca2016-04-14 18:40:14 -0700792 for (int i = 0; i < callbacksCount; ++i) {
793 IContextHubCallback callback = mCallbacksList.getBroadcastItem(i);
794 try {
Arthur Ishiguroab7113d2017-12-15 14:32:51 -0800795 callback.onMessageReceipt(contextHubHandle, appInstance, msg);
destradaa78cebca2016-04-14 18:40:14 -0700796 } catch (RemoteException e) {
797 Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
798 continue;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700799 }
800 }
destradaa78cebca2016-04-14 18:40:14 -0700801 mCallbacksList.finishBroadcast();
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700802 return 0;
803 }
804
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800805 /**
806 * Validates the HAL proxy state and context hub ID to see if we can start the transaction.
807 *
808 * @param contextHubId the ID of the hub to start the transaction
809 * @param callback the client transaction callback interface
810 * @param transactionType the type of the transaction
811 *
812 * @return {@code true} if mContextHubProxy and contextHubId is valid, {@code false} otherwise
813 */
814 private boolean checkHalProxyAndContextHubId(
815 int contextHubId, IContextHubTransactionCallback callback,
816 @ContextHubTransaction.Type int transactionType) {
817 if (mContextHubProxy == null) {
818 try {
819 callback.onTransactionComplete(
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800820 ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800821 } catch (RemoteException e) {
822 Log.e(TAG, "RemoteException while calling onTransactionComplete", e);
823 }
824 return false;
825 }
826 if (!isValidContextHubId(contextHubId)) {
827 Log.e(TAG, "Cannot start "
828 + ContextHubTransaction.typeToString(transactionType, false /* upperCase */)
829 + " transaction for invalid hub ID " + contextHubId);
830 try {
Arthur Ishiguro6100aa72017-12-20 09:35:00 -0800831 callback.onTransactionComplete(ContextHubTransaction.RESULT_FAILED_BAD_PARAMS);
Arthur Ishiguro4493e142017-11-27 16:26:34 -0800832 } catch (RemoteException e) {
833 Log.e(TAG, "RemoteException while calling onTransactionComplete", e);
834 }
835 return false;
836 }
837
838 return true;
839 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700840}