blob: 42dc983792d203e8874245e3d6a014b5dcd0060f [file] [log] [blame]
Peng Xu9ff7d222016-02-11 13:02:05 -08001/*
2 * Copyright 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
17#include "context_hub.h"
18
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070019#define LOG_NDEBUG 0
20#define LOG_TAG "ContextHubService"
21
22#include <inttypes.h>
23#include <jni.h>
24#include <map>
25#include <queue>
Peng Xu9ff7d222016-02-11 13:02:05 -080026#include <string.h>
27#include <stdint.h>
28#include <stdio.h>
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070029#include <stdlib.h>
Peng Xu9ff7d222016-02-11 13:02:05 -080030
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070031#include <cutils/log.h>
32
Peng Xu9ff7d222016-02-11 13:02:05 -080033#include "JNIHelp.h"
34#include "core_jni_helpers.h"
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070035
36//static constexpr int OS_APP_ID=-1;
37
38static constexpr int MIN_APP_ID=1;
39static constexpr int MAX_APP_ID=128;
40
41static constexpr size_t MSG_HEADER_SIZE=4;
42static constexpr int HEADER_FIELD_MSG_TYPE=0;
43//static constexpr int HEADER_FIELD_MSG_VERSION=1;
44static constexpr int HEADER_FIELD_HUB_HANDLE=2;
45static constexpr int HEADER_FIELD_APP_INSTANCE=3;
Peng Xu9ff7d222016-02-11 13:02:05 -080046
47
48namespace android {
49
50namespace {
51
Peng Xu9ff7d222016-02-11 13:02:05 -080052/*
53 * Finds the length of a statically-sized array using template trickery that
54 * also prevents it from being applied to the wrong type.
55 */
56template <typename T, size_t N>
57constexpr size_t array_length(T (&)[N]) { return N; }
58
59struct jniInfo_s {
60 JavaVM *vm;
61 jclass contextHubInfoClass;
62 jclass contextHubServiceClass;
63 jclass memoryRegionsClass;
64
65 jobject jContextHubService;
66
67 jmethodID msgReceiptCallBack;
68
69 jmethodID contextHubInfoCtor;
70 jmethodID contextHubInfoSetId;
71 jmethodID contextHubInfoSetName;
72 jmethodID contextHubInfoSetVendor;
73 jmethodID contextHubInfoSetToolchain;
74 jmethodID contextHubInfoSetPlatformVersion;
75 jmethodID contextHubInfoSetStaticSwVersion;
76 jmethodID contextHubInfoSetToolchainVersion;
77 jmethodID contextHubInfoSetPeakMips;
78 jmethodID contextHubInfoSetStoppedPowerDrawMw;
79 jmethodID contextHubInfoSetSleepPowerDrawMw;
80 jmethodID contextHubInfoSetPeakPowerDrawMw;
81 jmethodID contextHubInfoSetSupportedSensors;
82 jmethodID contextHubInfoSetMemoryRegions;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070083 jmethodID contextHubInfoSetMaxPacketLenBytes;
Peng Xu9ff7d222016-02-11 13:02:05 -080084
85 jmethodID contextHubServiceMsgReceiptCallback;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070086 jmethodID contextHubServiceAddAppInstance;
Peng Xu9ff7d222016-02-11 13:02:05 -080087};
88
89struct context_hub_info_s {
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070090 uint32_t *cookies;
Peng Xu9ff7d222016-02-11 13:02:05 -080091 int numHubs;
92 const struct context_hub_t *hubs;
93 struct context_hub_module_t *contextHubModule;
94};
95
Ashutosh Joshib741e3b2016-03-29 09:19:56 -070096struct app_instance_info_s {
97 uint32_t hubHandle; // Id of the hub this app is on
98 int instanceId; // systemwide unique instance id - assigned
99 struct hub_app_info appInfo; // returned from the HAL
100 uint64_t truncName; // Possibly truncated name - logging
101};
102
Peng Xu9ff7d222016-02-11 13:02:05 -0800103struct contextHubServiceDb_s {
104 int initialized;
105 context_hub_info_s hubInfo;
106 jniInfo_s jniInfo;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700107 std::queue<int> freeIds;
108 std::map<int, app_instance_info_s *> appInstances;
Peng Xu9ff7d222016-02-11 13:02:05 -0800109};
110
111} // unnamed namespace
112
113static contextHubServiceDb_s db;
114
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700115int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
Peng Xu9ff7d222016-02-11 13:02:05 -0800116 void *cookie);
117
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700118const context_hub_t *get_hub_info(int hubHandle) {
119 if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) {
120 return &db.hubInfo.hubs[hubHandle];
121 }
122 return nullptr;
123}
124
125static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) {
126 const context_hub_t *info = get_hub_info(hubHandle);
127
128 if (info) {
129 return db.hubInfo.contextHubModule->send_message(info->hub_id, msg);
130 } else {
131 ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
132 return -1;
133 }
134}
135
136static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) {
137 const context_hub_t *info = get_hub_info(hubHandle);
138
139 if (info) {
140 msg->app = info->os_app_name;
141 return 0;
142 } else {
143 ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
144 return -1;
145 }
146}
147
148static int get_hub_id_for_app_instance(int id) {
149 if (db.appInstances.find(id) == db.appInstances.end()) {
150 ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
151 return -1;
152 }
153
154 int hubHandle = db.appInstances[id]->hubHandle;
155
156 return db.hubInfo.hubs[hubHandle].hub_id;
157}
158
159static int set_dest_app(hub_message_t *msg, int id) {
160 if (db.appInstances.find(id) == db.appInstances.end()) {
161 ALOGD("%s: Cannod find app for app instance %d", __FUNCTION__, id);
162 return -1;
163 }
164
165 msg->app = db.appInstances[id]->appInfo.name;
166 return 0;
167}
168
169static void send_query_for_apps() {
170 hub_message_t msg;
171
172 msg.message_type = CONTEXT_HUB_QUERY_APPS;
173 msg.message_len = 0;
174
175 for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
176 ALOGD("Sending query for apps to hub %d", i);
177 set_os_app_as_destination(&msg, i);
178 if (send_msg_to_hub(&msg, i) != 0) {
179 ALOGW("Could not query hub %i for apps", i);
180 }
181 }
182}
183
184static int return_id(int id) {
185 // Note : This method is not thread safe.
186 // id returned is guarenteed to be in use
187 db.freeIds.push(id);
188 return 0;
189}
190
191static int generate_id(void) {
192 // Note : This method is not thread safe.
193 int retVal = -1;
194
195 if (!db.freeIds.empty()) {
196 retVal = db.freeIds.front();
197 db.freeIds.pop();
198 }
199
200 return retVal;
201}
202
203int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) {
204 // Not checking if the apps are indeed distinct
205
206 app_instance_info_s *entry;
207 void *appName;
208 hub_app_name_t *name;
209
210 assert(appInfo && appInfo->name && appInfo->name->app_name);
211
212 entry = (app_instance_info_s *) malloc(sizeof(app_instance_info_s));
213 appName = malloc(appInfo->name->app_name_len);
214 name = (hub_app_name_t *) malloc(sizeof(hub_app_name_t));
215
216 int appInstanceHandle = generate_id();
217
218 if (appInstanceHandle < 0 || !appName || !entry || !name) {
219 ALOGE("Cannot find resources to add app instance %d, %p, %p",
220 appInstanceHandle, appName, entry);
221
222 free(appName);
223 free(entry);
224 free(name);
225
226 if (appInstanceHandle >= 0) {
227 return_id(appInstanceHandle);
228 }
229
230 return -1;
231 }
232
233 memcpy(&(entry->appInfo), appInfo, sizeof(entry->appInfo));
234 memcpy(appName, appInfo->name->app_name, appInfo->name->app_name_len);
235 name->app_name = appName;
236 name->app_name_len = appInfo->name->app_name_len;
237 entry->appInfo.name = name;
238 entry->truncName = 0;
239 memcpy(&(entry->truncName), name->app_name,
240 sizeof(entry->truncName) < name->app_name_len ?
241 sizeof(entry->truncName) : name->app_name_len);
242
243 // Not checking for sanity of hubId
244 entry->hubHandle = hubHandle;
245 entry->instanceId = appInstanceHandle;
246 db.appInstances[appInstanceHandle] = entry;
247
248 // Finally - let the service know of this app instance
249 env->CallIntMethod(db.jniInfo.jContextHubService,
250 db.jniInfo.contextHubServiceAddAppInstance,
251 hubHandle, entry->instanceId, entry->truncName,
252 entry->appInfo.version);
253
254 ALOGW("Added App 0x%" PRIx64 " on hub Handle %" PRId32
255 " as appInstance %d, original name_length %" PRId32, entry->truncName,
256 entry->hubHandle, appInstanceHandle, name->app_name_len);
257
258 return appInstanceHandle;
259}
260
261int delete_app_instance(int id) {
262 if (db.appInstances.find(id) == db.appInstances.end()) {
263 return -1;
264 }
265
266 return_id(id);
267
268 if (db.appInstances[id]) {
269 // Losing the const cast below. This is intentional.
270 free((void *)db.appInstances[id]->appInfo.name->app_name);
271 free((void *)db.appInstances[id]->appInfo.name);
272 free(db.appInstances[id]);
273 db.appInstances.erase(id);
274 }
275
276 return 0;
277}
278
279
Peng Xu9ff7d222016-02-11 13:02:05 -0800280static void initContextHubService() {
281 int err = 0;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700282 db.hubInfo.hubs = nullptr;
Peng Xu9ff7d222016-02-11 13:02:05 -0800283 db.hubInfo.numHubs = 0;
Peng Xu9ff7d222016-02-11 13:02:05 -0800284 int i;
285
286 err = hw_get_module(CONTEXT_HUB_MODULE_ID,
287 (hw_module_t const**)(&db.hubInfo.contextHubModule));
288
289 if (err) {
290 ALOGE("** Could not load %s module : err %s", CONTEXT_HUB_MODULE_ID,
291 strerror(-err));
292 }
293
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700294 // Prep for storing app info
295 for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
296 db.freeIds.push(i);
297 }
Ashutosh Joshiadf75e32016-03-29 09:19:56 -0700298
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700299 if (db.hubInfo.contextHubModule) {
300 int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
301 &db.hubInfo.hubs);
302 ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
303 db.hubInfo.numHubs = retNumHubs;
304
305 if (db.hubInfo.numHubs > 0) {
306 db.hubInfo.numHubs = retNumHubs;
307 db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs);
308
309 if (!db.hubInfo.cookies) {
310 ALOGW("Ran out of memory allocating cookies, bailing");
311 return;
312 }
313
314 for (i = 0; i < db.hubInfo.numHubs; i++) {
315 db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
316 if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
317 context_hub_callback,
318 &db.hubInfo.cookies[i]) == 0) {
319 }
320 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800321 }
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700322
323 send_query_for_apps();
324 } else {
325 ALOGW("No Context Hub Module present");
Peng Xu9ff7d222016-02-11 13:02:05 -0800326 }
327}
328
329static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
330 JNIEnv *env;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700331
332 if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
Peng Xu9ff7d222016-02-11 13:02:05 -0800333 return -1;
334 }
335
336 jbyteArray jmsg = env->NewByteArray(msgLen);
337 jintArray jheader = env->NewIntArray(headerLen);
338
339 env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
340 env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);
341
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700342 return (env->CallIntMethod(db.jniInfo.jContextHubService,
Peng Xu9ff7d222016-02-11 13:02:05 -0800343 db.jniInfo.contextHubServiceMsgReceiptCallback,
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700344 jheader, jmsg) != 0);
Peng Xu9ff7d222016-02-11 13:02:05 -0800345}
346
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700347int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) {
348 int i;
349 JNIEnv *env;
350 if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
351 return -1;
352 }
353
354 int numApps = msgLen/sizeof(hub_app_info);
355 hub_app_info *info = (hub_app_info *)malloc(msgLen); // handle possible alignment
356
357 if (!info) {
358 return -1;
359 }
360
361 memcpy(info, msg, msgLen);
362 for (i = 0; i < numApps; i++) {
363 add_app_instance(info, hubHandle, env);
364 info++;
365 }
366
367 free(info);
368
369 return 0;
370}
371
372
373int handle_os_message(uint32_t msgType, uint32_t hubHandle,
374 char *msg, int msgLen) {
375 int retVal;
376
377 switch(msgType) {
378 case CONTEXT_HUB_APPS_ENABLE:
379 retVal = 0;
380 break;
381
382 case CONTEXT_HUB_APPS_DISABLE:
383 retVal = 0;
384 break;
385
386 case CONTEXT_HUB_LOAD_APP:
387 retVal = 0;
388 break;
389
390 case CONTEXT_HUB_UNLOAD_APP:
391 retVal = 0;
392 break;
393
394 case CONTEXT_HUB_QUERY_APPS:
395 retVal = handle_query_apps_response(msg, msgLen, hubHandle);
396 break;
397
398 case CONTEXT_HUB_QUERY_MEMORY:
399 retVal = 0;
400 break;
401
402 case CONTEXT_HUB_LOAD_OS:
403 retVal = 0;
404 break;
405
406 default:
407 retVal = -1;
408 break;
409
410 }
411
412 return retVal;
413}
414
415static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
416 int *ptr = (int *)cookie;
417
418 if (!ptr || *ptr >= db.hubInfo.numHubs) {
419 return false;
420 }
421
422 if (db.hubInfo.hubs[*ptr].hub_id != hub_id) {
423 return false;
424 } else {
425 return true;
426 }
427}
428
429int context_hub_callback(uint32_t hubId,
430 const struct hub_message_t *msg,
Peng Xu9ff7d222016-02-11 13:02:05 -0800431 void *cookie) {
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700432 int msgHeader[MSG_HEADER_SIZE];
Peng Xu9ff7d222016-02-11 13:02:05 -0800433
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700434 if (!msg) {
435 return -1;
436 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800437
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700438 msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
439
440 if (!sanity_check_cookie(cookie, hubId)) {
441 ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
442 hubId, cookie);
443
444 return -1;
445 }
446
447 msgHeader[HEADER_FIELD_HUB_HANDLE] = *(uint32_t*)cookie;
448
449 if (msgHeader[HEADER_FIELD_MSG_TYPE] < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE &&
450 msgHeader[HEADER_FIELD_MSG_TYPE] != 0 ) {
451 handle_os_message(msgHeader[HEADER_FIELD_MSG_TYPE],
452 msgHeader[HEADER_FIELD_HUB_HANDLE],
453 (char *)msg->message,
454 msg->message_len);
455 } else {
456 onMessageReceipt(msgHeader, sizeof(msgHeader),
457 (char *)msg->message, msg->message_len);
458 }
459
460 return 0;
Peng Xu9ff7d222016-02-11 13:02:05 -0800461}
462
463static int init_jni(JNIEnv *env, jobject instance) {
464
465 if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700466 return -1;
Peng Xu9ff7d222016-02-11 13:02:05 -0800467 }
468
469 db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
470
471 db.jniInfo.contextHubInfoClass =
472 env->FindClass("android/hardware/location/ContextHubInfo");
473
474 db.jniInfo.contextHubServiceClass =
475 env->FindClass("android/hardware/location/ContextHubService");
476
477 db.jniInfo.memoryRegionsClass =
478 env->FindClass("android/hardware/location/MemoryRegion");
479
Peng Xu9ff7d222016-02-11 13:02:05 -0800480 db.jniInfo.contextHubInfoCtor =
481 env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
482 db.jniInfo.contextHubInfoSetId =
483 env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V");
484 db.jniInfo.contextHubInfoSetName =
485 env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
486 "(Ljava/lang/String;)V");
487
488 db.jniInfo.contextHubInfoSetVendor =
489 env->GetMethodID(db.jniInfo.contextHubInfoClass,
490 "setVendor", "(Ljava/lang/String;)V");
491 db.jniInfo.contextHubInfoSetToolchain =
492 env->GetMethodID(db.jniInfo.contextHubInfoClass,
493 "setToolchain", "(Ljava/lang/String;)V");
494 db.jniInfo.contextHubInfoSetPlatformVersion =
495 env->GetMethodID(db.jniInfo.contextHubInfoClass,
496 "setPlatformVersion", "(I)V");
497 db.jniInfo.contextHubInfoSetStaticSwVersion =
498 env->GetMethodID(db.jniInfo.contextHubInfoClass,
499 "setStaticSwVersion", "(I)V");
500 db.jniInfo.contextHubInfoSetToolchainVersion =
501 env->GetMethodID(db.jniInfo.contextHubInfoClass,
502 "setToolchainVersion", "(I)V");
503 db.jniInfo.contextHubInfoSetPeakMips =
504 env->GetMethodID(db.jniInfo.contextHubInfoClass,
505 "setPeakMips", "(F)V");
506 db.jniInfo.contextHubInfoSetStoppedPowerDrawMw =
507 env->GetMethodID(db.jniInfo.contextHubInfoClass,
508 "setStoppedPowerDrawMw", "(F)V");
509 db.jniInfo.contextHubInfoSetSleepPowerDrawMw =
510 env->GetMethodID(db.jniInfo.contextHubInfoClass,
511 "setSleepPowerDrawMw", "(F)V");
512 db.jniInfo.contextHubInfoSetPeakPowerDrawMw =
513 env->GetMethodID(db.jniInfo.contextHubInfoClass,
514 "setPeakPowerDrawMw", "(F)V");
515 db.jniInfo.contextHubInfoSetSupportedSensors =
516 env->GetMethodID(db.jniInfo.contextHubInfoClass,
517 "setSupportedSensors", "([I)V");
518 db.jniInfo.contextHubInfoSetMemoryRegions =
519 env->GetMethodID(db.jniInfo.contextHubInfoClass,
520 "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700521 db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
522 env->GetMethodID(db.jniInfo.contextHubInfoClass,
523 "setMaxPacketLenBytes", "(I)V");
Peng Xu9ff7d222016-02-11 13:02:05 -0800524
525
526 db.jniInfo.contextHubServiceMsgReceiptCallback =
527 env->GetMethodID(db.jniInfo.contextHubServiceClass, "onMessageReceipt",
528 "([I[B)I");
529 db.jniInfo.contextHubInfoSetName =
530 env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
531 "(Ljava/lang/String;)V");
532
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700533 db.jniInfo.contextHubServiceAddAppInstance =
534 env->GetMethodID(db.jniInfo.contextHubServiceClass,
535 "addAppInstance", "(IIJI)I");
536
537
Peng Xu9ff7d222016-02-11 13:02:05 -0800538
539 return 0;
540}
541
542static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t *hub) {
543 jstring jstrBuf;
544 jintArray jintBuf;
545 jobjectArray jmemBuf;
546
547 int dummyConnectedSensors[] = {1, 2, 3, 4, 5};
548
549 jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass,
550 db.jniInfo.contextHubInfoCtor);
551 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id);
552
553 jstrBuf = env->NewStringUTF(hub->name);
554 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf);
555
556 jstrBuf = env->NewStringUTF(hub->vendor);
557 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf);
558
559 jstrBuf = env->NewStringUTF(hub->toolchain);
560 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf);
561
562 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version);
563 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version);
564 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700565 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw,
566 hub->stopped_power_draw_mw);
567 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw,
568 hub->sleep_power_draw_mw);
569 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw,
570 hub->peak_power_draw_mw);
571 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
572 hub->max_supported_msg_len);
573
Peng Xu9ff7d222016-02-11 13:02:05 -0800574
575 // TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700576 // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
577 // hub->connected_sensors);
Peng Xu9ff7d222016-02-11 13:02:05 -0800578 jintBuf = env->NewIntArray(array_length(dummyConnectedSensors));
579 env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700580 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf);
Peng Xu9ff7d222016-02-11 13:02:05 -0800581
582 // We are not getting the memory regions from the CH Hal - change this when it is available
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700583 jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
Peng Xu9ff7d222016-02-11 13:02:05 -0800584 // Note the zero size above. We do not need to set any elements
585 env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
586
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700587
Peng Xu9ff7d222016-02-11 13:02:05 -0800588 return jHub;
589}
590
591static jobjectArray nativeInitialize(JNIEnv *env, jobject instance)
592{
593 jobject hub;
594 jobjectArray retArray;
595
Peng Xu9ff7d222016-02-11 13:02:05 -0800596 if (init_jni(env, instance) < 0) {
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700597 return nullptr;
Peng Xu9ff7d222016-02-11 13:02:05 -0800598 }
599
Peng Xu9ff7d222016-02-11 13:02:05 -0800600 initContextHubService();
601
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700602 if (db.hubInfo.numHubs > 1) {
603 ALOGW("Clamping the number of hubs to 1");
604 db.hubInfo.numHubs = 1;
605 }
606
607 retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);
Peng Xu9ff7d222016-02-11 13:02:05 -0800608
609 for(int i = 0; i < db.hubInfo.numHubs; i++) {
610 hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
611 env->SetObjectArrayElement(retArray, i, hub);
612 }
613
614 return retArray;
615}
616
617static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
618 jbyteArray data_) {
619 hub_message_t msg;
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700620 jint retVal = -1; // Default to failure
Peng Xu9ff7d222016-02-11 13:02:05 -0800621
622 jint *header = env->GetIntArrayElements(header_, 0);
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700623 unsigned int numHeaderElements = env->GetArrayLength(header_);
Peng Xu9ff7d222016-02-11 13:02:05 -0800624 jbyte *data = env->GetByteArrayElements(data_, 0);
625 int dataBufferLength = env->GetArrayLength(data_);
626
Ashutosh Joshib741e3b2016-03-29 09:19:56 -0700627 if (numHeaderElements >= MSG_HEADER_SIZE) {
628 if (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0) {
629 msg.message_type = header[HEADER_FIELD_MSG_TYPE];
630 msg.message_len = dataBufferLength;
631 msg.message = data;
632 retVal = db.hubInfo.contextHubModule->send_message(
633 get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]),
634 &msg);
635 } else {
636 ALOGD("Could not find app instance %d", header[HEADER_FIELD_APP_INSTANCE]);
637 }
638 } else {
639 ALOGD("Malformed header len");
640 }
Peng Xu9ff7d222016-02-11 13:02:05 -0800641
642 env->ReleaseIntArrayElements(header_, header, 0);
643 env->ReleaseByteArrayElements(data_, data, 0);
644
645 return retVal;
646}
647
648//--------------------------------------------------------------------------------------------------
649//
650static const JNINativeMethod gContextHubServiceMethods[] = {
651 {"nativeInitialize",
652 "()[Landroid/hardware/location/ContextHubInfo;",
653 (void*)nativeInitialize },
654 {"nativeSendMessage",
655 "([I[B)I",
656 (void*)nativeSendMessage }
657};
658
659}//namespace android
660
661using namespace android;
662
663int register_android_hardware_location_ContextHubService(JNIEnv *env)
664{
665 RegisterMethodsOrDie(env, "android/hardware/location/ContextHubService",
666 gContextHubServiceMethods, NELEM(gContextHubServiceMethods));
667
668 return 0;
669}