19ff7d2235427b211344fa58b608424805a21aa24Peng Xu/* 29ff7d2235427b211344fa58b608424805a21aa24Peng Xu * Copyright 2016, The Android Open Source Project 39ff7d2235427b211344fa58b608424805a21aa24Peng Xu * 49ff7d2235427b211344fa58b608424805a21aa24Peng Xu * Licensed under the Apache License, Version 2.0 (the "License"); 59ff7d2235427b211344fa58b608424805a21aa24Peng Xu * you may not use this file except in compliance with the License. 69ff7d2235427b211344fa58b608424805a21aa24Peng Xu * You may obtain a copy of the License at 79ff7d2235427b211344fa58b608424805a21aa24Peng Xu * 89ff7d2235427b211344fa58b608424805a21aa24Peng Xu * http://www.apache.org/licenses/LICENSE-2.0 99ff7d2235427b211344fa58b608424805a21aa24Peng Xu * 109ff7d2235427b211344fa58b608424805a21aa24Peng Xu * Unless required by applicable law or agreed to in writing, software 119ff7d2235427b211344fa58b608424805a21aa24Peng Xu * distributed under the License is distributed on an "AS IS" BASIS, 129ff7d2235427b211344fa58b608424805a21aa24Peng Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139ff7d2235427b211344fa58b608424805a21aa24Peng Xu * See the License for the specific language governing permissions and 149ff7d2235427b211344fa58b608424805a21aa24Peng Xu * limitations under the License. 159ff7d2235427b211344fa58b608424805a21aa24Peng Xu */ 169ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1785547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#undef LOG_NDEBUG 1885547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#undef LOG_TAG 19b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi#define LOG_NDEBUG 0 20b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi#define LOG_TAG "ContextHubService" 21b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 22b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi#include <inttypes.h> 23b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi#include <jni.h> 249ff7d2235427b211344fa58b608424805a21aa24Peng Xu#include <stdint.h> 259ff7d2235427b211344fa58b608424805a21aa24Peng Xu#include <stdio.h> 26b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi#include <stdlib.h> 2785547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#include <string.h> 286644c4547ce849327197786f02da7a045a860aceBrian Duddie#include <sys/endian.h> 29b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 3085547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#include <chrono> 3185547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#include <mutex> 3285547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#include <queue> 3385547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi#include <unordered_map> 346644c4547ce849327197786f02da7a045a860aceBrian Duddie#include <utility> 3585547d15e06b280e5fedc8a297f516cb414d43a3Ashutosh Joshi 3619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi#include <android-base/macros.h> 3719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi#include <android/hardware/contexthub/1.0/IContexthub.h> 3819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi#include <cutils/log.h> 39b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 4019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi#include "core_jni_helpers.h" 4119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi#include "JNIHelp.h" 4254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 438c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::AsyncEventType; 448c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::ContextHub; 458c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::ContextHubMsg; 468c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::HubAppInfo; 478c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::IContexthub; 488c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::IContexthubCallback; 496644c4547ce849327197786f02da7a045a860aceBrian Duddieusing android::hardware::contexthub::V1_0::NanoAppBinary; 508c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::Result; 518c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::contexthub::V1_0::TransactionResult; 52b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 538c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddieusing android::hardware::Return; 549ff7d2235427b211344fa58b608424805a21aa24Peng Xu 5529e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiserusing std::chrono::steady_clock; 568c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie 5719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// If a transaction takes longer than this, we'll allow it to be 5819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// canceled by a new transaction. Note we do _not_ automatically 5919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// cancel a transaction after this much time. We can have a 6019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// legal transaction which takes longer than this amount of time, 6119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// as long as no other new transactions are attempted after this 6219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi// time has expired. 6319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr auto kMinTransactionCancelTime = std::chrono::seconds(29); 6429e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiser 659ff7d2235427b211344fa58b608424805a21aa24Peng Xunamespace android { 669ff7d2235427b211344fa58b608424805a21aa24Peng Xu 676644c4547ce849327197786f02da7a045a860aceBrian Duddieconstexpr uint32_t kNanoAppBinaryHeaderVersion = 1; 686644c4547ce849327197786f02da7a045a860aceBrian Duddie 696644c4547ce849327197786f02da7a045a860aceBrian Duddie// Important: this header is explicitly defined as little endian byte order, and 706644c4547ce849327197786f02da7a045a860aceBrian Duddie// therefore may not match host endianness 716644c4547ce849327197786f02da7a045a860aceBrian Duddiestruct NanoAppBinaryHeader { 726644c4547ce849327197786f02da7a045a860aceBrian Duddie uint32_t headerVersion; // 0x1 for this version 736644c4547ce849327197786f02da7a045a860aceBrian Duddie uint32_t magic; // "NANO" (see NANOAPP_MAGIC in context_hub.h) 746644c4547ce849327197786f02da7a045a860aceBrian Duddie uint64_t appId; // App Id, contains vendor id 756644c4547ce849327197786f02da7a045a860aceBrian Duddie uint32_t appVersion; // Version of the app 766644c4547ce849327197786f02da7a045a860aceBrian Duddie uint32_t flags; // Signed, encrypted 776644c4547ce849327197786f02da7a045a860aceBrian Duddie uint64_t hwHubType; // Which hub type is this compiled for 786644c4547ce849327197786f02da7a045a860aceBrian Duddie uint8_t targetChreApiMajorVersion; // Which CHRE API version this is compiled for 796644c4547ce849327197786f02da7a045a860aceBrian Duddie uint8_t targetChreApiMinorVersion; 806644c4547ce849327197786f02da7a045a860aceBrian Duddie uint8_t reserved[6]; 816644c4547ce849327197786f02da7a045a860aceBrian Duddie} __attribute__((packed)); 826644c4547ce849327197786f02da7a045a860aceBrian Duddie 8319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshienum HubMessageType { 8419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_APPS_ENABLE = 1, // Enables loaded nano-app(s) 8519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_APPS_DISABLE = 2, // Disables loaded nano-app(s) 8619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_LOAD_APP = 3, // Load a supplied app 8719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_UNLOAD_APP = 4, // Unload a specified app 8819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_QUERY_APPS = 5, // Query for app(s) info on hub 8919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_QUERY_MEMORY = 6, // Query for memory info 9019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi CONTEXT_HUB_OS_REBOOT = 7, // Request to reboot context HUB OS 9119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 929ff7d2235427b211344fa58b608424805a21aa24Peng Xu 9319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr jint OS_APP_ID = -1; 9419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr jint INVALID_APP_ID = -2; 9519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 9619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr jint MIN_APP_ID = 1; 9719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr jint MAX_APP_ID = 128; 9819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 9919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t MSG_HEADER_SIZE = 4; 10019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_MSG_TYPE = 0; 10119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_MSG_VERSION = 1; 10219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_HUB_HANDLE = 2; 10319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_APP_INSTANCE = 3; 10419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 10519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE; 10619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1; 10719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconstexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2; 10819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 10919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijint getAppInstanceForAppId(uint64_t app_id); 11019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint onMessageReceipt(const uint32_t *header, 11119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t headerLen, 11219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const char *msg, 11319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t msgLen); 11419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid onHubReset(uint32_t hubId); 11519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid queryHubForApps(uint32_t hubId); 11619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid passOnOsResponse(uint32_t hubHandle, 11719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t msgType, 11819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TransactionResult result, 11919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const int8_t *additionalData, 12019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t additionalDataLen); 12119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 12219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshibool closeLoadTxn(bool success, jint *appInstanceHandle); 12319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid closeUnloadTxn(bool success); 12419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint handleQueryAppsResponse(const std::vector<HubAppInfo> apps, 12519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t hubHandle); 12619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 12719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshistruct JniInfo { 1289ff7d2235427b211344fa58b608424805a21aa24Peng Xu JavaVM *vm; 1299ff7d2235427b211344fa58b608424805a21aa24Peng Xu jclass contextHubInfoClass; 1309ff7d2235427b211344fa58b608424805a21aa24Peng Xu jclass contextHubServiceClass; 1319ff7d2235427b211344fa58b608424805a21aa24Peng Xu jclass memoryRegionsClass; 1329ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1339ff7d2235427b211344fa58b608424805a21aa24Peng Xu jobject jContextHubService; 1349ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1359ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID msgReceiptCallBack; 1369ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1379ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoCtor; 1389ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetId; 1399ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetName; 1409ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetVendor; 1419ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetToolchain; 1429ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetPlatformVersion; 1439ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetStaticSwVersion; 1449ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetToolchainVersion; 1459ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetPeakMips; 1469ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetStoppedPowerDrawMw; 1479ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetSleepPowerDrawMw; 1489ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetPeakPowerDrawMw; 1499ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetSupportedSensors; 1509ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubInfoSetMemoryRegions; 151b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi jmethodID contextHubInfoSetMaxPacketLenBytes; 1529ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1539ff7d2235427b211344fa58b608424805a21aa24Peng Xu jmethodID contextHubServiceMsgReceiptCallback; 154b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi jmethodID contextHubServiceAddAppInstance; 15554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi jmethodID contextHubServiceDeleteAppInstance; 1569ff7d2235427b211344fa58b608424805a21aa24Peng Xu}; 1579ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1589ff7d2235427b211344fa58b608424805a21aa24Peng Xu 15954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 16019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiclass TxnManager { 16119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshipublic: 16219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TxnManager() { 16319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mData = nullptr; 16419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mIsPending = false; 16519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 16629e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiser 16719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ~TxnManager() { 16819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi closeTxn(); 16919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 17029e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiser 17119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int addTxn(HubMessageType txnIdentifier, void *txnData) { 17219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::lock_guard<std::mutex>lock(mLock); 17319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (mIsPending) { 17419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Transaction already found pending when trying to add a new one."); 17519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return -1; 17619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 17719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mIsPending = true; 17819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mFirstTimeTxnCanBeCanceled = steady_clock::now() + kMinTransactionCancelTime; 17919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mData = txnData; 18019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mIdentifier = txnIdentifier; 181b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 18219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return 0; 18319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 1849ff7d2235427b211344fa58b608424805a21aa24Peng Xu 18519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int closeTxn() { 18619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::lock_guard<std::mutex>lock(mLock); 18719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi closeTxnUnlocked(); 18819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return 0; 18919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 1909ff7d2235427b211344fa58b608424805a21aa24Peng Xu 19119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi bool isTxnPending() { 19219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::lock_guard<std::mutex>lock(mLock); 19319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return mIsPending; 19419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 1959ff7d2235427b211344fa58b608424805a21aa24Peng Xu 19619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi void closeAnyStaleTxns() { 19719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::lock_guard<std::mutex>lock(mLock); 19819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (mIsPending && steady_clock::now() >= mFirstTimeTxnCanBeCanceled) { 19919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Stale transaction canceled"); 20019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi closeTxnUnlocked(); 20119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 20219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 20354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 20419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int fetchTxnData(HubMessageType *id, void **data) { 20519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (id == nullptr || data == nullptr) { 20619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Null Params isNull{id, data} {%d, %d}", 20719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi id == nullptr ? 1 : 0, 20819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi data == nullptr ? 1 : 0); 20919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return -1; 21019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 21154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 21219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::lock_guard<std::mutex>lock(mLock); 21319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (!mIsPending) { 21419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("No Transactions pending"); 21519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return -1; 21619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 21754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 21819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi *id = mIdentifier; 21919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi *data = mData; 22019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return 0; 22119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 22254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 22319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi private: 22419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi bool mIsPending; // Is a transaction pending 22519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::mutex mLock; // mutex for manager 22619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi HubMessageType mIdentifier; // What are we doing 22719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi void *mData; // Details 22819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi steady_clock::time_point mFirstTimeTxnCanBeCanceled; 22919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 23019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // Only call this if you hold the lock. 23119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi void closeTxnUnlocked() { 23219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mIsPending = false; 23319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi free(mData); 23419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mData = nullptr; 23519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 23619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 23754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 23854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 23919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshistruct ContextHubServiceCallback : IContexthubCallback { 24019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t mContextHubId; 24154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 24219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ContextHubServiceCallback(uint32_t hubId) { 24319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mContextHubId = hubId; 24419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 24554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 24619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi virtual Return<void> handleClientMsg(const ContextHubMsg &msg) { 24719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint appHandle = getAppInstanceForAppId(msg.appName); 24819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (appHandle < 0) { 24919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGE("Filtering out message due to invalid App Instance."); 25019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else { 25119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t msgHeader[MSG_HEADER_SIZE] = {}; 25219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msgHeader[HEADER_FIELD_MSG_TYPE] = msg.msgType; 25319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msgHeader[HEADER_FIELD_HUB_HANDLE] = mContextHubId; 25419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msgHeader[HEADER_FIELD_APP_INSTANCE] = appHandle; 25519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi onMessageReceipt(msgHeader, 25619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi MSG_HEADER_SIZE, 25719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi reinterpret_cast<const char *>(msg.msg.data()), 25819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msg.msg.size()); 25929e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiser } 26019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 26119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return android::hardware::Void(); 26229e868071d64ebbcf6191bb5b7542875ad6fcef8Greg Kaiser } 26354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 26419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi virtual Return<void> handleHubEvent(AsyncEventType evt) { 26519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (evt == AsyncEventType::RESTARTED) { 26619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Context Hub handle %d restarted", mContextHubId); 26719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi onHubReset(mContextHubId); 26819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else { 26919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Cannot handle event %u from hub %d", evt, mContextHubId); 27019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 27154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 27219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return android::hardware::Void(); 27354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 27454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 27519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi virtual Return<void> handleTxnResult(uint32_t txnId, 27619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TransactionResult result) { 27719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGI("Handle transaction result , hubId %" PRIu32 ", txnId %" PRIu32 ", result %" PRIu32, 27819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mContextHubId, 27919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi txnId, 28019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result); 28119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 28219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi switch(txnId) { 28319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi case CONTEXT_HUB_APPS_ENABLE: 28419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi case CONTEXT_HUB_APPS_DISABLE: 28519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi passOnOsResponse(mContextHubId, txnId, result, nullptr, 0); 28619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi break; 28754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 28819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi case CONTEXT_HUB_UNLOAD_APP: 28919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi closeUnloadTxn(result == TransactionResult::SUCCESS); 29019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi passOnOsResponse(mContextHubId, txnId, result, nullptr, 0); 29119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi break; 29254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 29319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi case CONTEXT_HUB_LOAD_APP: 29419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi { 29519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint appInstanceHandle = INVALID_APP_ID; 29619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi bool appRunningOnHub = (result == TransactionResult::SUCCESS); 29719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (!(closeLoadTxn(appRunningOnHub, &appInstanceHandle))) { 29819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (appRunningOnHub) { 29919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // Now we're in an odd situation. Our nanoapp 30019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // is up and running on the Context Hub. However, 30119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // something went wrong in our Service code so that 30219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // we're not able to properly track this nanoapp 30319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // in our Service code. If we tell the Java layer 30419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // things are good, it's a lie because the handle 30519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // we give them will fail when used with the Service. 30619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // If we tell the Java layer this failed, it's kind 30719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // of a lie as well, since this nanoapp is running. 30819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // 30919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // We leave a more robust fix for later, and for 31019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // now just tell the user things have failed. 31119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // 31219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // TODO(b/30835981): Make this situation better. 31319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result = TransactionResult::FAILURE; 31419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 31519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 31619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 31719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi passOnOsResponse(mContextHubId, 31819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi txnId, 31919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result, 32019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi reinterpret_cast<int8_t *>(&appInstanceHandle), 32119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi sizeof(appInstanceHandle)); 32219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi break; 32319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 3249ff7d2235427b211344fa58b608424805a21aa24Peng Xu 32519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi default: 32619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGI("unrecognized transction id %" PRIu32, txnId); 32719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi break; 32819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 32919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return android::hardware::Void(); 330b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 331b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 33219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi virtual Return<void> handleAppsInfo( 33319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const android::hardware::hidl_vec<HubAppInfo>& apps) { 3345c78ae3d1d511a8cccf2165b237b479db4fead9fAshutosh Joshi TransactionResult result = TransactionResult::SUCCESS; 33519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi handleQueryAppsResponse(apps,mContextHubId); 3365c78ae3d1d511a8cccf2165b237b479db4fead9fAshutosh Joshi passOnOsResponse(mContextHubId, CONTEXT_HUB_QUERY_APPS, result, nullptr, 0); 33719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return android::hardware::Void(); 338b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 339b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 340ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi virtual Return<void> handleAppAbort(uint64_t appId, uint32_t abortCode) { 341ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi ALOGI("Handle app aport called from %" PRIx64 " with abort code %" PRIu32, 342ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi appId, 343ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi abortCode); 344ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi 345ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi // TODO: Plumb this to the clients interested in this app 346ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi return android::hardware::Void(); 347ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi } 348ccb8e675257b729d0322461b09ad20effd3f5dc5Ashutosh Joshi 34919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi void setContextHubId(uint32_t id) { 35019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi mContextHubId = id; 35119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 352b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 35319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t getContextHubId() { 35419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return(mContextHubId); 355b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 35619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 357b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 35819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshistruct AppInstanceInfo { 35919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi HubAppInfo appInfo; // returned from the HAL 36019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint64_t truncName; // Possibly truncated name for logging 36119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t hubHandle; // Id of the hub this app is on 36219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint instanceId; // system wide unique instance id - assigned 36319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 36419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 36519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshistruct ContextHubInfo { 36619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int numHubs; 36719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi Vector<ContextHub> hubs; 36819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi sp<IContexthub> contextHub; 36919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 37019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 37119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshistruct ContextHubServiceDb { 37219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int initialized; 37319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ContextHubInfo hubInfo; 37419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi JniInfo jniInfo; 37519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::queue<jint> freeIds; 37619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::unordered_map<jint, AppInstanceInfo> appInstances; 37719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TxnManager txnManager; 37819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::vector<ContextHubServiceCallback *> regCallBacks; 37919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi}; 38019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 38119753cca3f49db2ca66106393d8302c0555fae79Ashutosh JoshiContextHubServiceDb db; 38219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 3838c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddiebool getHubIdForHubHandle(int hubHandle, uint32_t *hubId) { 3848c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie if (hubHandle < 0 || hubHandle >= db.hubInfo.numHubs || hubId == nullptr) { 3858c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie return false; 386cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi } else { 3878c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie *hubId = db.hubInfo.hubs[hubHandle].hubId; 3888c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie return true; 389cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi } 390cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi} 391cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi 39219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint getHubHandleForAppInstance(jint id) { 393ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov if (!db.appInstances.count(id)) { 394f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser ALOGD("%s: Cannot find app for app instance %" PRId32, 39519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi __FUNCTION__, 39619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi id); 397b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 398b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 399b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 40054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return db.appInstances[id].hubHandle; 40154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 40254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 40319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijint getAppInstanceForAppId(uint64_t app_id) { 4046469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa auto end = db.appInstances.end(); 4056469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa for (auto current = db.appInstances.begin(); current != end; ++current) { 40619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (current->second.appInfo.appId == app_id) { 4076469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa return current->first; 4086469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa } 4096469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa } 41019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGD("Cannot find app for app id %" PRIu64 ".", app_id); 4116469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa return -1; 4126469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa} 4136469c233fb9f7e617a5bc8b5d8348d7241d279c7destradaa 41419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiuint64_t getAppIdForAppInstance(jint id) { 415ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov if (!db.appInstances.count(id)) { 41619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return INVALID_APP_ID; 417b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 41819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return db.appInstances[id].appInfo.appId; 419b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 420b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 42119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid queryHubForApps(uint32_t hubId) { 42219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi Result r = db.hubInfo.contextHub->queryApps(hubId); 42319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGD("Sent query for apps to hub %" PRIu32 " with result %" PRIu32, hubId, r); 42454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 42554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 42619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid sendQueryForApps() { 427b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi for (int i = 0; i < db.hubInfo.numHubs; i++ ) { 42819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi queryHubForApps(db.hubInfo.hubs[i].hubId); 429b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 430b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 431b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 43219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint returnId(jint id) { 433b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Note : This method is not thread safe. 43454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi // id returned is guaranteed to be in use 43554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (id >= 0) { 43654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi db.freeIds.push(id); 43754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return 0; 43854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 43954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 44054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 441b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 442b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 44319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijint generateId() { 444b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Note : This method is not thread safe. 445f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser jint retVal = -1; 446b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 447b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi if (!db.freeIds.empty()) { 448b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi retVal = db.freeIds.front(); 449b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.freeIds.pop(); 450b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 451b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 452b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return retVal; 453b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 454b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 45519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijint addAppInstance(const HubAppInfo *appInfo, uint32_t hubHandle, 456f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser jint appInstanceHandle, JNIEnv *env) { 457b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Not checking if the apps are indeed distinct 45819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi AppInstanceInfo entry; 459ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov assert(appInfo); 460b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 461b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 462ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov entry.appInfo = *appInfo; 46354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 464ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov entry.instanceId = appInstanceHandle; 46519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi entry.truncName = appInfo->appId; 466ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov entry.hubHandle = hubHandle; 467b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.appInstances[appInstanceHandle] = entry; 468f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // Finally - let the service know of this app instance, to populate 469f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // the Java cache. 470b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallIntMethod(db.jniInfo.jContextHubService, 471b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.jniInfo.contextHubServiceAddAppInstance, 47219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hubHandle, entry.instanceId, 47319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi entry.truncName, 474ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov entry.appInfo.version); 475b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 47619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const char *action = (db.appInstances.count(appInstanceHandle) == 0) ? "Added" : "Updated"; 477f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser ALOGI("%s App 0x%" PRIx64 " on hub Handle %" PRId32 478fe6d4f518a34aa620eda9fe36365c2f750e6c67fGreg Kaiser " as appInstance %" PRId32, action, entry.truncName, 479ab2d44596b749f3095a262ca3dc3188238dd19d1Alexey Polyudov entry.hubHandle, appInstanceHandle); 480b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 481b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return appInstanceHandle; 482b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 483b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 48419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint deleteAppInstance(jint id, JNIEnv *env) { 4850d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser bool fullyDeleted = true; 486b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 4870d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser if (db.appInstances.count(id)) { 4880d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser db.appInstances.erase(id); 4890d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser } else { 490f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser ALOGW("Cannot delete App id (%" PRId32 ") from the JNI C++ cache", id); 4910d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser fullyDeleted = false; 4920d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser } 49319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi returnId(id); 4940d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser 4950d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser if ((env == nullptr) || 4960d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser (env->CallIntMethod(db.jniInfo.jContextHubService, 49754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi db.jniInfo.contextHubServiceDeleteAppInstance, 4980d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser id) != 0)) { 499f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser ALOGW("Cannot delete App id (%" PRId32 ") from Java cache", id); 5000d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser fullyDeleted = false; 50154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 50254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 5030d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser if (fullyDeleted) { 504f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser ALOGI("Deleted App id : %" PRId32, id); 5050d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser return 0; 5060d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser } 5070d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser return -1; 50854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 50954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 51019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint startLoadAppTxn(uint64_t appId, int hubHandle) { 51119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi AppInstanceInfo *txnInfo = new AppInstanceInfo(); 51219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint instanceId = generateId(); 51354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 51454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (!txnInfo || instanceId < 0) { 51519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi returnId(instanceId); 51654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi free(txnInfo); 51754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 51854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 51954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 52054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnInfo->truncName = appId; 52154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnInfo->hubHandle = hubHandle; 52254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnInfo->instanceId = instanceId; 52354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 52419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi txnInfo->appInfo.appId = appId; 52554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnInfo->appInfo.version = -1; // Awaited 52654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 52719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (db.txnManager.addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) { 52819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi returnId(instanceId); 52954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi free(txnInfo); 53054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 53154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 532b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 533b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 534b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 535b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 53619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint startUnloadAppTxn(jint appInstanceHandle) { 53719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint *txnData = new(jint); 53854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (!txnData) { 53954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Cannot allocate memory to start unload transaction"); 54054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 54154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 54254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 54354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi *txnData = appInstanceHandle; 54454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 54519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (db.txnManager.addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) { 54654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi free(txnData); 54754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Cannot start transaction to unload app"); 54854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 54954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 55054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 55154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return 0; 55254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 553b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 55419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid getHubsCb(const ::android::hardware::hidl_vec<ContextHub>& hubs) { 55519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi for (size_t i = 0; i < hubs.size(); i++) { 55619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.hubInfo.hubs.push_back(hubs[i]); 55719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 55819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi} 55919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 56019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid initContextHubService() { 5619ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.hubInfo.numHubs = 0; 5629ff7d2235427b211344fa58b608424805a21aa24Peng Xu 563de69003f072c0007679a6ad0c0e5f84fde6150d0Chris Phoenix db.hubInfo.contextHub = IContexthub::getService(); 5649ff7d2235427b211344fa58b608424805a21aa24Peng Xu 56519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (db.hubInfo.contextHub == nullptr) { 56619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGE("Could not load context hub hal"); 56719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else { 5684c43591588f69f80f21e5341cdf089cb5363d617Ashutosh Joshi ALOGI("Loaded context hub hal, isRemote %s", db.hubInfo.contextHub->isRemote() ? "TRUE" : "FALSE"); 5699ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 5709ff7d2235427b211344fa58b608424805a21aa24Peng Xu 571b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi // Prep for storing app info 572f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser for (jint i = MIN_APP_ID; i <= MAX_APP_ID; i++) { 573b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.freeIds.push(i); 574b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 575b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 57619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (db.hubInfo.contextHub != nullptr) { 57719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi std::function<void(const ::android::hardware::hidl_vec<ContextHub>& hubs)> f = getHubsCb; 57819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if(!db.hubInfo.contextHub->getHubs(f).isOk()) { 57919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("GetHubs Failed! transport error."); 58019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi return; 58119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi }; 58219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 58319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int retNumHubs = db.hubInfo.hubs.size(); 584b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi ALOGD("ContextHubModule returned %d hubs ", retNumHubs); 585b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.hubInfo.numHubs = retNumHubs; 586b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 58719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi for (int i = 0; i < db.hubInfo.numHubs; i++) { 58819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGI("Subscribing to hubHandle %d", i); 589b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 59019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ContextHubServiceCallback *callBackPtr = 59119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi new ContextHubServiceCallback(db.hubInfo.hubs[i].hubId); 59219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.hubInfo.contextHub->registerCallback(db.hubInfo.hubs[i].hubId, 59319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi callBackPtr); 59419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.regCallBacks.push_back(callBackPtr); 5952c697fb4a8b8f8c0a2acf1fb15027f363f74c2dcAshutosh Joshi } 596b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 597f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser sendQueryForApps(); 59819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 599b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } else { 600b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi ALOGW("No Context Hub Module present"); 6019ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 6029ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 6039ff7d2235427b211344fa58b608424805a21aa24Peng Xu 60419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid onHubReset(uint32_t hubId) { 60519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TransactionResult result = TransactionResult::SUCCESS; 60619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.txnManager.closeTxn(); 60719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // TODO : Expose this through an api 60819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi passOnOsResponse(hubId, CONTEXT_HUB_OS_REBOOT, result, nullptr, 0); 60919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi queryHubForApps(hubId); 61019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi} 61119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 61219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint onMessageReceipt(const uint32_t *header, 61319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t headerLen, 61419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const char *msg, 61519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t msgLen) { 6169ff7d2235427b211344fa58b608424805a21aa24Peng Xu JNIEnv *env; 617b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 618b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { 6199ff7d2235427b211344fa58b608424805a21aa24Peng Xu return -1; 6209ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 6219ff7d2235427b211344fa58b608424805a21aa24Peng Xu 6229ff7d2235427b211344fa58b608424805a21aa24Peng Xu jbyteArray jmsg = env->NewByteArray(msgLen); 623bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser if (jmsg == nullptr) { 624bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser ALOGW("Can't allocate %zu byte array", msgLen); 625bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser return -1; 626bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser } 6279ff7d2235427b211344fa58b608424805a21aa24Peng Xu jintArray jheader = env->NewIntArray(headerLen); 628bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser if (jheader == nullptr) { 629bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jmsg); 630bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser ALOGW("Can't allocate %zu int array", headerLen); 631bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser return -1; 632bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser } 6339ff7d2235427b211344fa58b608424805a21aa24Peng Xu 63419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->SetByteArrayRegion(jmsg, 0, msgLen, reinterpret_cast<const jbyte *>(msg)); 63519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->SetIntArrayRegion(jheader, 0, headerLen, reinterpret_cast<const jint *>(header)); 6369ff7d2235427b211344fa58b608424805a21aa24Peng Xu 637bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser int ret = (env->CallIntMethod(db.jniInfo.jContextHubService, 63819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.jniInfo.contextHubServiceMsgReceiptCallback, 63919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jheader, 64019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jmsg) != 0); 641bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jmsg); 642bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jheader); 643bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser 644bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser return ret; 645b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 646b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 64719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint handleQueryAppsResponse(const std::vector<HubAppInfo> apps, 64854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint32_t hubHandle) { 649b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi JNIEnv *env; 650b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { 651b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 652b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 653b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 65419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int numApps = apps.size(); 655b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 656f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // We use this information to sync our JNI and Java caches of nanoapp info. 657f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // We want to accomplish two things here: 658f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // 1) Remove entries from our caches which are stale, and pertained to 659f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // apps no longer running on Context Hub. 660f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // 2) Populate our caches with the latest information of all these apps. 661f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser 662f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // We make a couple of assumptions here: 663f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // A) The JNI and Java caches are in sync with each other (this isn't 664f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // necessarily true; any failure of a single call into Java land to 665f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // update its cache will leave that cache in a bad state. For NYC, 666f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // we're willing to tolerate this for now). 667f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // B) The total number of apps is relatively small, so horribly inefficent 668f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // algorithms aren't too painful. 669f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // C) We're going to call this relatively infrequently, so its inefficency 670f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // isn't a big impact. 671f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser 672f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser 673f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // (1). Looking for stale cache entries. Yes, this is O(N^2). See 674f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // assumption (B). Per assumption (A), it is sufficient to iterate 675f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // over just the JNI cache. 676f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser auto end = db.appInstances.end(); 677f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser for (auto current = db.appInstances.begin(); current != end; ) { 67819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi AppInstanceInfo cacheEntry = current->second; 679f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // We perform our iteration here because if we call 680f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // delete_app_instance() below, it will erase() this entry. 681f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser current++; 682f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser bool entryIsStale = true; 683f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser for (int i = 0; i < numApps; i++) { 68419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (apps[i].appId == cacheEntry.appInfo.appId) { 685f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // We found a match; this entry is current. 686f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser entryIsStale = false; 687f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser break; 688f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser } 689f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser } 69019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 691f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser if (entryIsStale) { 69219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi deleteAppInstance(cacheEntry.instanceId, env); 693f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser } 694f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser } 695f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser 696f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // (2). Update our caches with the latest. 697f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser for (int i = 0; i < numApps; i++) { 69854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi // We will only have one instance of the app 69954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi // TODO : Change this logic once we support multiple instances of the same app 70019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jint appInstance = getAppInstanceForAppId(apps[i].appId); 701f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser if (appInstance == -1) { 702f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // This is a previously unknown app, let's allocate an "id" for it. 70319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi appInstance = generateId(); 704f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser } 70519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi addAppInstance(&apps[i], hubHandle, appInstance, env); 706b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 707b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return 0; 708b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi} 709b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 710f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser// TODO(b/30807327): Do not use raw bytes for additional data. Use the 711f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser// JNI interfaces for the appropriate types. 71219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshivoid passOnOsResponse(uint32_t hubHandle, 71319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi uint32_t msgType, 71419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi TransactionResult result, 71519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi const int8_t *additionalData, 71619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi size_t additionalDataLen) { 71754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi JNIEnv *env; 718b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 71954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { 72019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32, 72119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msgType); 72254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return; 72354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 724b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 72554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint32_t header[MSG_HEADER_SIZE]; 72654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi memset(header, 0, sizeof(header)); 7276239cc6fe1d18ce4365c56346a09c7963dfa8f10Ashutosh Joshi 72854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (!additionalData) { 72954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi additionalDataLen = 0; // clamp 73054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 73154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi int msgLen = 1 + additionalDataLen; 732b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 73354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi int8_t *msg = new int8_t[msgLen]; 734b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 73554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (!msg) { 73654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Unexpected : Ran out of memory, cannot send response"); 73754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return; 73854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 73954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 74054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi header[HEADER_FIELD_MSG_TYPE] = msgType; 74154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi header[HEADER_FIELD_MSG_VERSION] = 0; 74254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi header[HEADER_FIELD_HUB_HANDLE] = hubHandle; 74354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID; 74454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 7456d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser // Due to API constraints, at the moment we can't change the fact that 7466d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser // we're changing our 4-byte response to a 1-byte value. But we can prevent 7476d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser // the possible change in sign (and thus meaning) that would happen from 7486d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser // a naive cast. Further, we can log when we're losing part of the value. 7496d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser // TODO(b/30918279): Don't truncate this result. 7506d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser int8_t truncatedResult; 75119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi truncatedResult = static_cast<int8_t>(result); 7526d9e7f669a6f03fa73abcae1ae36b529de1f6f3fGreg Kaiser msg[0] = truncatedResult; 75354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 75454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (additionalData) { 75554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi memcpy(&msg[1], additionalData, additionalDataLen); 75654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 75754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 75854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi jbyteArray jmsg = env->NewByteArray(msgLen); 7592e776ff893ba66fadf2977d51627c97d48d0a87eEvgenii Stepanov jintArray jheader = env->NewIntArray(arraysize(header)); 76054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 76119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->SetByteArrayRegion(jmsg, 0, msgLen, reinterpret_cast<jbyte *>(msg)); 76219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->SetIntArrayRegion(jheader, 0, arraysize(header), reinterpret_cast<jint *>(header)); 76354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 76454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32, 76519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi header[HEADER_FIELD_MSG_TYPE], 76619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi header[HEADER_FIELD_APP_INSTANCE], 76754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi header[HEADER_FIELD_HUB_HANDLE]); 76854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 76954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi env->CallIntMethod(db.jniInfo.jContextHubService, 77054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi db.jniInfo.contextHubServiceMsgReceiptCallback, 77119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jheader, 77219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jmsg); 77319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 774c35104535cf60fd0bb42640c4993172a62e83671Andrew Rossignol env->DeleteLocalRef(jmsg); 775c35104535cf60fd0bb42640c4993172a62e83671Andrew Rossignol env->DeleteLocalRef(jheader); 77654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 77754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi delete[] msg; 77854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 77954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 78054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshivoid closeUnloadTxn(bool success) { 78154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi void *txnData = nullptr; 78219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi HubMessageType txnId; 78354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 78419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (success && db.txnManager.fetchTxnData(&txnId, &txnData) == 0 && 78554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnId == CONTEXT_HUB_UNLOAD_APP) { 7860d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser JNIEnv *env; 7870d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { 7880d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser ALOGW("Could not attach to JVM !"); 7890d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser env = nullptr; 7900d052c95088190b37011f045a8443aaea28cd23bGreg Kaiser } 791f8210797adeb6527fe44dff6f8902d4744ad9540Greg Kaiser jint handle = *reinterpret_cast<jint *>(txnData); 79219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi deleteAppInstance(handle, env); 79354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 79419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Could not unload the app successfully ! success %d, txnData %p", 79519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi success, 79619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi txnData); 79754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 79854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 79919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.txnManager.closeTxn(); 80054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 80154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 80219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshibool closeLoadTxn(bool success, jint *appInstanceHandle) { 80354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi void *txnData; 80419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi HubMessageType txnId; 80554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 80619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (success && db.txnManager.fetchTxnData(&txnId, &txnData) == 0 && 80754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi txnId == CONTEXT_HUB_LOAD_APP) { 80819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi AppInstanceInfo *info = static_cast<AppInstanceInfo *>(txnData); 80954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi *appInstanceHandle = info->instanceId; 81054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 81154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi JNIEnv *env; 81254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) { 81319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi addAppInstance(&info->appInfo, info->hubHandle, info->instanceId, env); 81454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 81554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Could not attach to JVM !"); 8169d4d881cc5cd5e225f68c85050d99d60445edbcfGreg Kaiser success = false; 81754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 81819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // While we just called addAppInstance above, our info->appInfo was 819f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // incomplete (for example, the 'version' is hardcoded to -1). So we 820f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // trigger an additional query to the CHRE, so we'll be able to get 821f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // all the app "info", and have our JNI and Java caches with the 822f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser // full information. 823f16abd98c7ea8332e413d44a0baa8cb6eaa6669cGreg Kaiser sendQueryForApps(); 82454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 82554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Could not load the app successfully ! Unexpected failure"); 8269d4d881cc5cd5e225f68c85050d99d60445edbcfGreg Kaiser *appInstanceHandle = INVALID_APP_ID; 8279d4d881cc5cd5e225f68c85050d99d60445edbcfGreg Kaiser success = false; 82854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 82954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 83019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.txnManager.closeTxn(); 8319d4d881cc5cd5e225f68c85050d99d60445edbcfGreg Kaiser return success; 83254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi} 83354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 83419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiint initJni(JNIEnv *env, jobject instance) { 8359ff7d2235427b211344fa58b608424805a21aa24Peng Xu if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) { 836b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return -1; 8379ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 8389ff7d2235427b211344fa58b608424805a21aa24Peng Xu 8399ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.jContextHubService = env->NewGlobalRef(instance); 8409ff7d2235427b211344fa58b608424805a21aa24Peng Xu 8419ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoClass = 8429ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->FindClass("android/hardware/location/ContextHubInfo"); 8439ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubServiceClass = 844420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshi env->FindClass("com/android/server/location/ContextHubService"); 8459ff7d2235427b211344fa58b608424805a21aa24Peng Xu 8469ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.memoryRegionsClass = 8479ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->FindClass("android/hardware/location/MemoryRegion"); 8489ff7d2235427b211344fa58b608424805a21aa24Peng Xu 8499ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoCtor = 8509ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V"); 8519ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetId = 8529ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V"); 8539ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetName = 85419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", "(Ljava/lang/String;)V"); 8559ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetVendor = 8569ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 85719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setVendor", 85819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(Ljava/lang/String;)V"); 8599ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetToolchain = 8609ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 86119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setToolchain", 86219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(Ljava/lang/String;)V"); 8639ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetPlatformVersion = 8649ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 86519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setPlatformVersion", 86619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(I)V"); 8679ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetStaticSwVersion = 8689ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 86919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setStaticSwVersion", 87019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(I)V"); 8719ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetToolchainVersion = 8729ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 87319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setToolchainVersion", 87419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(I)V"); 8759ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetPeakMips = 8769ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 87719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setPeakMips", 87819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(F)V"); 8799ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetStoppedPowerDrawMw = 8809ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 88119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setStoppedPowerDrawMw", 88219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(F)V"); 8839ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetSleepPowerDrawMw = 8849ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 88519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setSleepPowerDrawMw", 88619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(F)V"); 8879ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetPeakPowerDrawMw = 8889ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 88919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setPeakPowerDrawMw", 89019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(F)V"); 8919ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetSupportedSensors = 8929ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 89319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setSupportedSensors", 89419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "([I)V"); 8959ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetMemoryRegions = 8969ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->GetMethodID(db.jniInfo.contextHubInfoClass, 89719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setMemoryRegions", 89819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "([Landroid/hardware/location/MemoryRegion;)V"); 899b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.jniInfo.contextHubInfoSetMaxPacketLenBytes = 900b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubInfoClass, 90119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setMaxPacketLenBytes", 90219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(I)V"); 9039ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubServiceMsgReceiptCallback = 90419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubServiceClass, 90519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "onMessageReceipt", 90619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "([I[B)I"); 9079ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoSetName = 90819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubInfoClass, 90919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "setName", 91019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(Ljava/lang/String;)V"); 911b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi db.jniInfo.contextHubServiceAddAppInstance = 912b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubServiceClass, 91319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "addAppInstance", 91419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(IIJI)I"); 91554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi db.jniInfo.contextHubServiceDeleteAppInstance = 91654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi env->GetMethodID(db.jniInfo.contextHubServiceClass, 91719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "deleteAppInstance", 91819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "(I)I"); 9199ff7d2235427b211344fa58b608424805a21aa24Peng Xu 9209ff7d2235427b211344fa58b608424805a21aa24Peng Xu return 0; 9219ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 9229ff7d2235427b211344fa58b608424805a21aa24Peng Xu 92319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijobject constructJContextHubInfo(JNIEnv *env, const ContextHub &hub) { 9249ff7d2235427b211344fa58b608424805a21aa24Peng Xu jstring jstrBuf; 9259ff7d2235427b211344fa58b608424805a21aa24Peng Xu jintArray jintBuf; 9269ff7d2235427b211344fa58b608424805a21aa24Peng Xu jobjectArray jmemBuf; 9279ff7d2235427b211344fa58b608424805a21aa24Peng Xu 9289ff7d2235427b211344fa58b608424805a21aa24Peng Xu jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass, 9299ff7d2235427b211344fa58b608424805a21aa24Peng Xu db.jniInfo.contextHubInfoCtor); 93019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub.hubId); 9319ff7d2235427b211344fa58b608424805a21aa24Peng Xu 93293945f2c6909289313ac7477b3eda0e71b0efac7Scott Randolph jstrBuf = env->NewStringUTF(hub.name.c_str()); 9339ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf); 934bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jstrBuf); 9359ff7d2235427b211344fa58b608424805a21aa24Peng Xu 93693945f2c6909289313ac7477b3eda0e71b0efac7Scott Randolph jstrBuf = env->NewStringUTF(hub.vendor.c_str()); 9379ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf); 938bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jstrBuf); 9399ff7d2235427b211344fa58b608424805a21aa24Peng Xu 94093945f2c6909289313ac7477b3eda0e71b0efac7Scott Randolph jstrBuf = env->NewStringUTF(hub.toolchain.c_str()); 9419ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf); 942bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jstrBuf); 9439ff7d2235427b211344fa58b608424805a21aa24Peng Xu 94419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub.platformVersion); 94519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub.toolchainVersion); 94619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub.peakMips); 947b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, 94819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hub.stoppedPowerDrawMw); 949b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, 95019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hub.sleepPowerDrawMw); 951b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, 95219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hub.peakPowerDrawMw); 953b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes, 95419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hub.maxSupportedMsgLen); 955b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 9569ff7d2235427b211344fa58b608424805a21aa24Peng Xu 95719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jintBuf = env->NewIntArray(hub.connectedSensors.size()); 95819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi int *connectedSensors = new int[hub.connectedSensors.size()]; 95954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 96054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (!connectedSensors) { 96154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Cannot allocate memory! Unexpected"); 96254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi assert(false); 96354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 96419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi for (unsigned int i = 0; i < hub.connectedSensors.size(); i++) { 96519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // TODO :: Populate connected sensors. 96619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi //connectedSensors[i] = hub.connectedSensors[i].sensorType; 96719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi connectedSensors[i] = 0; 96854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 96954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 97054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 97119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi env->SetIntArrayRegion(jintBuf, 0, hub.connectedSensors.size(), 97254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi connectedSensors); 97354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 974b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf); 975bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jintBuf); 9769ff7d2235427b211344fa58b608424805a21aa24Peng Xu 9779ff7d2235427b211344fa58b608424805a21aa24Peng Xu // We are not getting the memory regions from the CH Hal - change this when it is available 978b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr); 9799ff7d2235427b211344fa58b608424805a21aa24Peng Xu // Note the zero size above. We do not need to set any elements 9809ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf); 981bece5990c7ad14fff494204e68ca251f4c9c626bGreg Kaiser env->DeleteLocalRef(jmemBuf); 9829ff7d2235427b211344fa58b608424805a21aa24Peng Xu 983b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 98454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi delete[] connectedSensors; 9859ff7d2235427b211344fa58b608424805a21aa24Peng Xu return jHub; 9869ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 9879ff7d2235427b211344fa58b608424805a21aa24Peng Xu 98819753cca3f49db2ca66106393d8302c0555fae79Ashutosh JoshijobjectArray nativeInitialize(JNIEnv *env, jobject instance) { 9899ff7d2235427b211344fa58b608424805a21aa24Peng Xu jobject hub; 9909ff7d2235427b211344fa58b608424805a21aa24Peng Xu jobjectArray retArray; 9919ff7d2235427b211344fa58b608424805a21aa24Peng Xu 99219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (initJni(env, instance) < 0) { 993b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi return nullptr; 9949ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 9959ff7d2235427b211344fa58b608424805a21aa24Peng Xu 9962c697fb4a8b8f8c0a2acf1fb15027f363f74c2dcAshutosh Joshi initContextHubService(); 997adf75e31f52a7a935a66a884fb55631c7309ee75Ashutosh Joshi 998b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi if (db.hubInfo.numHubs > 1) { 99919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGW("Clamping the number of hubs to 1"); 100019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.hubInfo.numHubs = 1; 1001b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 1002b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi 1003b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr); 10049ff7d2235427b211344fa58b608424805a21aa24Peng Xu 10059ff7d2235427b211344fa58b608424805a21aa24Peng Xu for(int i = 0; i < db.hubInfo.numHubs; i++) { 100619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hub = constructJContextHubInfo(env, db.hubInfo.hubs[i]); 10079ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->SetObjectArrayElement(retArray, i, hub); 10089ff7d2235427b211344fa58b608424805a21aa24Peng Xu } 10099ff7d2235427b211344fa58b608424805a21aa24Peng Xu 10109ff7d2235427b211344fa58b608424805a21aa24Peng Xu return retArray; 10119ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 10129ff7d2235427b211344fa58b608424805a21aa24Peng Xu 10136644c4547ce849327197786f02da7a045a860aceBrian DuddieResult sendLoadNanoAppRequest(uint32_t hubId, 10146644c4547ce849327197786f02da7a045a860aceBrian Duddie jbyte *data, 10156644c4547ce849327197786f02da7a045a860aceBrian Duddie size_t dataBufferLength) { 10166644c4547ce849327197786f02da7a045a860aceBrian Duddie auto header = reinterpret_cast<const NanoAppBinaryHeader *>(data); 10176644c4547ce849327197786f02da7a045a860aceBrian Duddie Result result; 10186644c4547ce849327197786f02da7a045a860aceBrian Duddie 10196644c4547ce849327197786f02da7a045a860aceBrian Duddie if (dataBufferLength < sizeof(NanoAppBinaryHeader)) { 10206644c4547ce849327197786f02da7a045a860aceBrian Duddie ALOGE("Got short NanoApp, length %zu", dataBufferLength); 10216644c4547ce849327197786f02da7a045a860aceBrian Duddie result = Result::BAD_PARAMS; 10226644c4547ce849327197786f02da7a045a860aceBrian Duddie } else if (header->headerVersion != htole32(kNanoAppBinaryHeaderVersion)) { 10236644c4547ce849327197786f02da7a045a860aceBrian Duddie ALOGE("Got unexpected NanoApp header version %" PRIu32, 10246644c4547ce849327197786f02da7a045a860aceBrian Duddie letoh32(header->headerVersion)); 10256644c4547ce849327197786f02da7a045a860aceBrian Duddie result = Result::BAD_PARAMS; 10266644c4547ce849327197786f02da7a045a860aceBrian Duddie } else { 10276644c4547ce849327197786f02da7a045a860aceBrian Duddie NanoAppBinary nanoapp; 10286644c4547ce849327197786f02da7a045a860aceBrian Duddie 10296644c4547ce849327197786f02da7a045a860aceBrian Duddie // Data from the common nanoapp header goes into explicit fields 10306644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.appId = letoh64(header->appId); 10316644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.appVersion = letoh32(header->appVersion); 10326644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.flags = letoh32(header->flags); 10336644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.targetChreApiMajorVersion = header->targetChreApiMajorVersion; 10346644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.targetChreApiMinorVersion = header->targetChreApiMinorVersion; 10356644c4547ce849327197786f02da7a045a860aceBrian Duddie 10366644c4547ce849327197786f02da7a045a860aceBrian Duddie // Everything past the header goes in customBinary 10376644c4547ce849327197786f02da7a045a860aceBrian Duddie auto dataBytes = reinterpret_cast<const uint8_t *>(data); 10386644c4547ce849327197786f02da7a045a860aceBrian Duddie std::vector<uint8_t> customBinary( 10396644c4547ce849327197786f02da7a045a860aceBrian Duddie dataBytes + sizeof(NanoAppBinaryHeader), 10406644c4547ce849327197786f02da7a045a860aceBrian Duddie dataBytes + dataBufferLength); 10416644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp.customBinary = std::move(customBinary); 10426644c4547ce849327197786f02da7a045a860aceBrian Duddie 10436644c4547ce849327197786f02da7a045a860aceBrian Duddie ALOGW("Calling Load NanoApp on hub %d", hubId); 10446644c4547ce849327197786f02da7a045a860aceBrian Duddie result = db.hubInfo.contextHub->loadNanoApp(hubId, 10456644c4547ce849327197786f02da7a045a860aceBrian Duddie nanoapp, 10466644c4547ce849327197786f02da7a045a860aceBrian Duddie CONTEXT_HUB_LOAD_APP); 10476644c4547ce849327197786f02da7a045a860aceBrian Duddie } 10486644c4547ce849327197786f02da7a045a860aceBrian Duddie 10496644c4547ce849327197786f02da7a045a860aceBrian Duddie return result; 10506644c4547ce849327197786f02da7a045a860aceBrian Duddie} 10516644c4547ce849327197786f02da7a045a860aceBrian Duddie 105219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshijint nativeSendMessage(JNIEnv *env, 105319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jobject instance, 105419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jintArray header_, 105519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi jbyteArray data_) { 105619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // With the new binderized HAL definition, this function can be made much simpler. 105719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // All the magic can be removed. This is not however needed for the default implementation 105819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // TODO :: Change the JNI interface to conform to the new HAL interface and clean up this 105919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // function 1060b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi jint retVal = -1; // Default to failure 10619ff7d2235427b211344fa58b608424805a21aa24Peng Xu 10629ff7d2235427b211344fa58b608424805a21aa24Peng Xu jint *header = env->GetIntArrayElements(header_, 0); 10638c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie size_t numHeaderElements = env->GetArrayLength(header_); 10649ff7d2235427b211344fa58b608424805a21aa24Peng Xu jbyte *data = env->GetByteArrayElements(data_, 0); 10658c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie size_t dataBufferLength = env->GetArrayLength(data_); 10669ff7d2235427b211344fa58b608424805a21aa24Peng Xu 106754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (numHeaderElements < MSG_HEADER_SIZE) { 106854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Malformed header len"); 106954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 107054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 107154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 10728c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie jint appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE]; 107354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint32_t msgType = header[HEADER_FIELD_MSG_TYPE]; 107454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi int hubHandle = -1; 107554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint64_t appId; 107654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 107754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (msgType == CONTEXT_HUB_UNLOAD_APP) { 107819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hubHandle = getHubHandleForAppInstance(appInstanceHandle); 107954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else if (msgType == CONTEXT_HUB_LOAD_APP) { 108054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) { 108154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 108254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 108354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO]; 108454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI]; 108554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi appId = appIdHi << 32 | appIdLo; 108654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 108754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi hubHandle = header[HEADER_FIELD_HUB_HANDLE]; 108854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 108954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi hubHandle = header[HEADER_FIELD_HUB_HANDLE]; 109054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 109154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 10928c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie uint32_t hubId = -1; 10938c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie if (!getHubIdForHubHandle(hubHandle, &hubId)) { 109454787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGD("Invalid hub Handle %d", hubHandle); 109554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 109654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 109754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 109854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (msgType == CONTEXT_HUB_LOAD_APP || 109954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi msgType == CONTEXT_HUB_UNLOAD_APP) { 110054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 110119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.txnManager.closeAnyStaleTxns(); 110219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 110319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (db.txnManager.isTxnPending()) { 110419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi // TODO : There is a race conditio 110554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGW("Cannot load or unload app while a transaction is pending !"); 110654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 110719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else if (msgType == CONTEXT_HUB_LOAD_APP) { 110854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (startLoadAppTxn(appId, hubHandle) != 0) { 1109118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi ALOGW("Cannot Start Load Transaction"); 111054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 111154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 111254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { 111354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (startUnloadAppTxn(appInstanceHandle) != 0) { 1114118644056f3c442f0aa9451aaeac8e8b35dde3f8Ashutosh Joshi ALOGW("Cannot Start UnLoad Transaction"); 111554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi return -1; 111654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 111754787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 111854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 111954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 112019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi Result result; 112154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 112254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (msgType == CONTEXT_HUB_UNLOAD_APP) { 11238c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie ALOGW("Calling UnLoad NanoApp for app %" PRIx64 " on hub %" PRIu32, 112419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi db.appInstances[appInstanceHandle].appInfo.appId, 112519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hubId); 112619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result = db.hubInfo.contextHub->unloadNanoApp( 112719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hubId, db.appInstances[appInstanceHandle].appInfo.appId, CONTEXT_HUB_UNLOAD_APP); 112854787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else { 11298c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie if (appInstanceHandle == OS_APP_ID) { 113019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (msgType == CONTEXT_HUB_LOAD_APP) { 11316644c4547ce849327197786f02da7a045a860aceBrian Duddie result = sendLoadNanoAppRequest(hubId, data, dataBufferLength); 11320e5a2ab7c3ae3d798072fec0dd8407c50c862515Brian Duddie } else if (msgType == CONTEXT_HUB_QUERY_APPS) { 11330e5a2ab7c3ae3d798072fec0dd8407c50c862515Brian Duddie result = db.hubInfo.contextHub->queryApps(hubId); 113419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else { 113519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ALOGD("Dropping OS addresses message of type - %" PRIu32, msgType); 113619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result = Result::BAD_PARAMS; 113719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 1138cafdee9a72652354c5bde0b13c86dac3d88ac2aeAshutosh Joshi } else { 11398c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie appId = getAppIdForAppInstance(appInstanceHandle); 11408c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie if (appId == static_cast<uint64_t>(INVALID_APP_ID)) { 11418c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie ALOGD("Cannot find application instance %d", appInstanceHandle); 11428c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie result = Result::BAD_PARAMS; 11438c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie } else if (hubHandle != getHubHandleForAppInstance(appInstanceHandle)) { 11448c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie ALOGE("Given hubHandle (%d) doesn't match expected for app instance (%d)", 11458c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie hubHandle, 11468c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie getHubHandleForAppInstance(appInstanceHandle)); 11478c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie result = Result::BAD_PARAMS; 11488c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie } else { 114919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi ContextHubMsg msg; 115019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msg.appName = appId; 115119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msg.msgType = msgType; 115219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msg.msg.setToExternal((unsigned char *)data, dataBufferLength); 115319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi 11548c51b00e4c017dcd7bb24a51aa50f87ac3540208Brian Duddie ALOGW("Sending msg of type %" PRIu32 " len %zu to app %" PRIx64 " on hub %" PRIu32, 115519753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi msgType, 115619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi dataBufferLength, 115719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi appId, 115819753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi hubId); 115919753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi result = db.hubInfo.contextHub->sendMessageToHub(hubId, msg); 116019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 116119753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } 116254787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 116354787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi 116419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi if (result != Result::OK) { 116554787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi ALOGD("Send Message failure - %d", retVal); 116654787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi if (msgType == CONTEXT_HUB_LOAD_APP) { 1167ca9c676099aafaa371abeadffcdbb96d5ed3a674Greg Kaiser jint ignored; 1168ca9c676099aafaa371abeadffcdbb96d5ed3a674Greg Kaiser closeLoadTxn(false, &ignored); 116954787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { 117054787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi closeUnloadTxn(false); 117154787a5f9ffe7a15784049b00f664fac37c53b95Ashutosh Joshi } 117219753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi } else { 117319753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi retVal = 0; 1174b741e3b374e7eebf96e2104dec5caccf723b2a39Ashutosh Joshi } 11759ff7d2235427b211344fa58b608424805a21aa24Peng Xu 11769ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->ReleaseIntArrayElements(header_, header, 0); 11779ff7d2235427b211344fa58b608424805a21aa24Peng Xu env->ReleaseByteArrayElements(data_, data, 0); 11789ff7d2235427b211344fa58b608424805a21aa24Peng Xu 11799ff7d2235427b211344fa58b608424805a21aa24Peng Xu return retVal; 11809ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 11819ff7d2235427b211344fa58b608424805a21aa24Peng Xu 11829ff7d2235427b211344fa58b608424805a21aa24Peng Xu//-------------------------------------------------------------------------------------------------- 11839ff7d2235427b211344fa58b608424805a21aa24Peng Xu// 118419753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshiconst JNINativeMethod gContextHubServiceMethods[] = { 11859ff7d2235427b211344fa58b608424805a21aa24Peng Xu {"nativeInitialize", 118619753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi "()[Landroid/hardware/location/ContextHubInfo;", 118719753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi reinterpret_cast<void*>(nativeInitialize)}, 11889ff7d2235427b211344fa58b608424805a21aa24Peng Xu {"nativeSendMessage", 11899ff7d2235427b211344fa58b608424805a21aa24Peng Xu "([I[B)I", 119019753cca3f49db2ca66106393d8302c0555fae79Ashutosh Joshi reinterpret_cast<void*>(nativeSendMessage)} 11919ff7d2235427b211344fa58b608424805a21aa24Peng Xu}; 11929ff7d2235427b211344fa58b608424805a21aa24Peng Xu 1193420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshiint register_android_server_location_ContextHubService(JNIEnv *env) 11949ff7d2235427b211344fa58b608424805a21aa24Peng Xu{ 1195420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshi RegisterMethodsOrDie(env, "com/android/server/location/ContextHubService", 11969ff7d2235427b211344fa58b608424805a21aa24Peng Xu gContextHubServiceMethods, NELEM(gContextHubServiceMethods)); 11979ff7d2235427b211344fa58b608424805a21aa24Peng Xu 11989ff7d2235427b211344fa58b608424805a21aa24Peng Xu return 0; 11999ff7d2235427b211344fa58b608424805a21aa24Peng Xu} 1200420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshi 1201420e45e9cb004ea6c6e11f69adcdbf3dac5fc800Ashutosh Joshi}//namespace android 1202