Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016, The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include "context_hub.h" |
| 18 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 19 | #define LOG_NDEBUG 0 |
| 20 | #define LOG_TAG "ContextHubService" |
| 21 | |
| 22 | #include <inttypes.h> |
| 23 | #include <jni.h> |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 24 | #include <mutex> |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 25 | #include <string.h> |
| 26 | #include <stdint.h> |
| 27 | #include <stdio.h> |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 28 | #include <stdlib.h> |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 29 | #include <unordered_map> |
| 30 | #include <queue> |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 31 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 32 | #include <cutils/log.h> |
| 33 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 34 | #include "JNIHelp.h" |
| 35 | #include "core_jni_helpers.h" |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 36 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 37 | static constexpr int OS_APP_ID = -1; |
| 38 | static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 39 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 40 | static constexpr int MIN_APP_ID = 1; |
| 41 | static constexpr int MAX_APP_ID = 128; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 42 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 43 | static constexpr size_t MSG_HEADER_SIZE = 4; |
| 44 | static constexpr size_t HEADER_FIELD_MSG_TYPE = 0; |
| 45 | static constexpr size_t HEADER_FIELD_MSG_VERSION = 1; |
| 46 | static constexpr size_t HEADER_FIELD_HUB_HANDLE = 2; |
| 47 | static constexpr size_t HEADER_FIELD_APP_INSTANCE = 3; |
| 48 | |
| 49 | static constexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE; |
| 50 | static constexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1; |
| 51 | static constexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 52 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 53 | namespace android { |
| 54 | |
| 55 | namespace { |
| 56 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 57 | /* |
| 58 | * Finds the length of a statically-sized array using template trickery that |
| 59 | * also prevents it from being applied to the wrong type. |
| 60 | */ |
| 61 | template <typename T, size_t N> |
| 62 | constexpr size_t array_length(T (&)[N]) { return N; } |
| 63 | |
| 64 | struct jniInfo_s { |
| 65 | JavaVM *vm; |
| 66 | jclass contextHubInfoClass; |
| 67 | jclass contextHubServiceClass; |
| 68 | jclass memoryRegionsClass; |
| 69 | |
| 70 | jobject jContextHubService; |
| 71 | |
| 72 | jmethodID msgReceiptCallBack; |
| 73 | |
| 74 | jmethodID contextHubInfoCtor; |
| 75 | jmethodID contextHubInfoSetId; |
| 76 | jmethodID contextHubInfoSetName; |
| 77 | jmethodID contextHubInfoSetVendor; |
| 78 | jmethodID contextHubInfoSetToolchain; |
| 79 | jmethodID contextHubInfoSetPlatformVersion; |
| 80 | jmethodID contextHubInfoSetStaticSwVersion; |
| 81 | jmethodID contextHubInfoSetToolchainVersion; |
| 82 | jmethodID contextHubInfoSetPeakMips; |
| 83 | jmethodID contextHubInfoSetStoppedPowerDrawMw; |
| 84 | jmethodID contextHubInfoSetSleepPowerDrawMw; |
| 85 | jmethodID contextHubInfoSetPeakPowerDrawMw; |
| 86 | jmethodID contextHubInfoSetSupportedSensors; |
| 87 | jmethodID contextHubInfoSetMemoryRegions; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 88 | jmethodID contextHubInfoSetMaxPacketLenBytes; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 89 | |
| 90 | jmethodID contextHubServiceMsgReceiptCallback; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 91 | jmethodID contextHubServiceAddAppInstance; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 92 | jmethodID contextHubServiceDeleteAppInstance; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 93 | }; |
| 94 | |
| 95 | struct context_hub_info_s { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 96 | uint32_t *cookies; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 97 | int numHubs; |
| 98 | const struct context_hub_t *hubs; |
| 99 | struct context_hub_module_t *contextHubModule; |
| 100 | }; |
| 101 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 102 | struct app_instance_info_s { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 103 | uint64_t truncName; // Possibly truncated name for logging |
| 104 | uint32_t hubHandle; // Id of the hub this app is on |
| 105 | int instanceId; // system wide unique instance id - assigned |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 106 | struct hub_app_info appInfo; // returned from the HAL |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 107 | }; |
| 108 | |
| 109 | /* |
| 110 | * TODO(ashutoshj): From original code review: |
| 111 | * |
| 112 | * So, I feel like we could possible do a better job of organizing this code, |
| 113 | * and being more C++-y. Consider something like this: |
| 114 | * class TxnManager { |
| 115 | * public: |
| 116 | * TxnManager(); |
| 117 | * ~TxnManager(); |
| 118 | * int add(hub_message_e identifier, void *data); |
| 119 | * int close(); |
| 120 | * bool isPending() const; |
| 121 | * int fetchData(hub_message_e *identifier, void **data) const; |
| 122 | * |
| 123 | * private: |
| 124 | * bool mPending; |
| 125 | * mutable std::mutex mLock; |
| 126 | * hub_message_e mIdentifier; |
| 127 | * void *mData; |
| 128 | * }; |
| 129 | * |
| 130 | * And then, for example, we'd have things like: |
| 131 | * TxnManager::TxnManager() : mPending(false), mLock(), mIdentifier(), mData(nullptr) {} |
| 132 | * int TxnManager::add(hub_message_e identifier, void *data) { |
| 133 | * std::lock_guard<std::mutex> lock(mLock); |
| 134 | * mPending = true; |
| 135 | * mData = txnData; |
| 136 | * mIdentifier = txnIdentifier; |
| 137 | * return 0; |
| 138 | * } |
| 139 | * And then calling code would look like: |
| 140 | * if (!db.txnManager.add(CONTEXT_HUB_LOAD_APP, txnInfo)) { |
| 141 | * |
| 142 | * This would make it clearer the nothing is manipulating any state within TxnManager |
| 143 | * unsafely and outside of these couple of calls. |
| 144 | */ |
| 145 | struct txnManager_s { |
| 146 | bool txnPending; // Is a transaction pending |
| 147 | std::mutex m; // mutex for manager |
| 148 | hub_messages_e txnIdentifier; // What are we doing |
| 149 | void *txnData; // Details |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 150 | }; |
| 151 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 152 | struct contextHubServiceDb_s { |
| 153 | int initialized; |
| 154 | context_hub_info_s hubInfo; |
| 155 | jniInfo_s jniInfo; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 156 | std::queue<int> freeIds; |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 157 | std::unordered_map<int, app_instance_info_s> appInstances; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 158 | txnManager_s txnManager; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 159 | }; |
| 160 | |
| 161 | } // unnamed namespace |
| 162 | |
| 163 | static contextHubServiceDb_s db; |
| 164 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 165 | static bool initTxnManager() { |
| 166 | txnManager_s *mgr = &db.txnManager; |
| 167 | |
| 168 | mgr->txnData = nullptr; |
| 169 | mgr->txnPending = false; |
| 170 | return true; |
| 171 | } |
| 172 | |
| 173 | static int addTxn(hub_messages_e txnIdentifier, void *txnData) { |
| 174 | txnManager_s *mgr = &db.txnManager; |
| 175 | |
| 176 | std::lock_guard<std::mutex>lock(mgr->m); |
| 177 | |
| 178 | mgr->txnPending = true; |
| 179 | mgr->txnData = txnData; |
| 180 | mgr->txnIdentifier = txnIdentifier; |
| 181 | |
| 182 | return 0; |
| 183 | } |
| 184 | |
| 185 | static int closeTxn() { |
| 186 | txnManager_s *mgr = &db.txnManager; |
| 187 | std::lock_guard<std::mutex>lock(mgr->m); |
| 188 | mgr->txnPending = false; |
| 189 | free(mgr->txnData); |
| 190 | mgr->txnData = nullptr; |
| 191 | |
| 192 | return 0; |
| 193 | } |
| 194 | |
| 195 | static bool isTxnPending() { |
| 196 | txnManager_s *mgr = &db.txnManager; |
| 197 | std::lock_guard<std::mutex>lock(mgr->m); |
| 198 | return mgr->txnPending; |
| 199 | } |
| 200 | |
| 201 | static int fetchTxnData(hub_messages_e *id, void **data) { |
| 202 | txnManager_s *mgr = &db.txnManager; |
| 203 | |
| 204 | if (!id || !data) { |
| 205 | ALOGW("Null params id %p, data %p", id, data); |
| 206 | return -1; |
| 207 | } |
| 208 | |
| 209 | std::lock_guard<std::mutex>lock(mgr->m); |
| 210 | if (!mgr->txnPending) { |
| 211 | ALOGW("No Transactions pending"); |
| 212 | return -1; |
| 213 | } |
| 214 | |
| 215 | // else |
| 216 | *id = mgr->txnIdentifier; |
| 217 | *data = mgr->txnData; |
| 218 | return 0; |
| 219 | } |
| 220 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 221 | int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg, |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 222 | void *cookie); |
| 223 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 224 | const context_hub_t *get_hub_info(int hubHandle) { |
| 225 | if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) { |
| 226 | return &db.hubInfo.hubs[hubHandle]; |
| 227 | } |
| 228 | return nullptr; |
| 229 | } |
| 230 | |
| 231 | static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) { |
| 232 | const context_hub_t *info = get_hub_info(hubHandle); |
| 233 | |
| 234 | if (info) { |
| 235 | return db.hubInfo.contextHubModule->send_message(info->hub_id, msg); |
| 236 | } else { |
| 237 | ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle); |
| 238 | return -1; |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) { |
| 243 | const context_hub_t *info = get_hub_info(hubHandle); |
| 244 | |
| 245 | if (info) { |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 246 | msg->app_name = info->os_app_name; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 247 | return 0; |
| 248 | } else { |
| 249 | ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle); |
| 250 | return -1; |
| 251 | } |
| 252 | } |
| 253 | |
Ashutosh Joshi | cafdee9 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 254 | static int get_hub_id_for_hub_handle(int hubHandle) { |
| 255 | if (hubHandle < 0 || hubHandle >= db.hubInfo.numHubs) { |
| 256 | return -1; |
| 257 | } else { |
| 258 | return db.hubInfo.hubs[hubHandle].hub_id; |
| 259 | } |
| 260 | } |
| 261 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 262 | static int get_hub_handle_for_app_instance(int id) { |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 263 | if (!db.appInstances.count(id)) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 264 | ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id); |
| 265 | return -1; |
| 266 | } |
| 267 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 268 | return db.appInstances[id].hubHandle; |
| 269 | } |
| 270 | |
| 271 | static int get_hub_id_for_app_instance(int id) { |
| 272 | int hubHandle = get_hub_handle_for_app_instance(id); |
| 273 | |
| 274 | if (hubHandle < 0) { |
| 275 | return -1; |
| 276 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 277 | |
| 278 | return db.hubInfo.hubs[hubHandle].hub_id; |
| 279 | } |
| 280 | |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 281 | static int get_app_instance_for_app_id(uint64_t app_id) { |
| 282 | auto end = db.appInstances.end(); |
| 283 | for (auto current = db.appInstances.begin(); current != end; ++current) { |
| 284 | if (current->second.appInfo.app_name.id == app_id) { |
| 285 | return current->first; |
| 286 | } |
| 287 | } |
destradaa | 3cd7305 | 2016-04-29 13:11:33 -0700 | [diff] [blame] | 288 | ALOGD("Cannot find app for app instance %" PRIu64 ".", app_id); |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 289 | return -1; |
| 290 | } |
| 291 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 292 | static int set_dest_app(hub_message_t *msg, int id) { |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 293 | if (!db.appInstances.count(id)) { |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 294 | ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 295 | return -1; |
| 296 | } |
| 297 | |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 298 | msg->app_name = db.appInstances[id].appInfo.app_name; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 299 | return 0; |
| 300 | } |
| 301 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 302 | static void query_hub_for_apps(uint64_t appId, uint32_t hubHandle) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 303 | hub_message_t msg; |
Ashutosh Joshi | 848c8c4 | 2016-07-06 13:54:28 -0700 | [diff] [blame] | 304 | query_apps_request_t queryMsg; |
| 305 | |
| 306 | queryMsg.app_name.id = NANOAPP_VENDOR_ALL_APPS; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 307 | |
| 308 | msg.message_type = CONTEXT_HUB_QUERY_APPS; |
Ashutosh Joshi | 848c8c4 | 2016-07-06 13:54:28 -0700 | [diff] [blame] | 309 | msg.message_len = sizeof(queryMsg); |
| 310 | msg.message = &queryMsg; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 311 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 312 | ALOGD("Sending query for apps to hub %" PRIu32, hubHandle); |
| 313 | set_os_app_as_destination(&msg, hubHandle); |
| 314 | if (send_msg_to_hub(&msg, hubHandle) != 0) { |
| 315 | ALOGW("Could not query hub %" PRIu32 " for apps", hubHandle); |
| 316 | } |
| 317 | } |
| 318 | |
| 319 | static void sendQueryForApps(uint64_t appId) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 320 | for (int i = 0; i < db.hubInfo.numHubs; i++ ) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 321 | query_hub_for_apps(appId, i); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 322 | } |
| 323 | } |
| 324 | |
| 325 | static int return_id(int id) { |
| 326 | // Note : This method is not thread safe. |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 327 | // id returned is guaranteed to be in use |
| 328 | if (id >= 0) { |
| 329 | db.freeIds.push(id); |
| 330 | return 0; |
| 331 | } |
| 332 | |
| 333 | return -1; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 334 | } |
| 335 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 336 | static int generate_id() { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 337 | // Note : This method is not thread safe. |
| 338 | int retVal = -1; |
| 339 | |
| 340 | if (!db.freeIds.empty()) { |
| 341 | retVal = db.freeIds.front(); |
| 342 | db.freeIds.pop(); |
| 343 | } |
| 344 | |
| 345 | return retVal; |
| 346 | } |
| 347 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 348 | |
| 349 | static int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, |
| 350 | int appInstanceHandle, JNIEnv *env) { |
| 351 | |
| 352 | ALOGI("Loading App"); |
| 353 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 354 | // Not checking if the apps are indeed distinct |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 355 | app_instance_info_s entry; |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 356 | assert(appInfo); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 357 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 358 | if (db.appInstances.count(appInstanceHandle) == 0) { |
| 359 | appInstanceHandle = generate_id(); |
| 360 | if (appInstanceHandle < 0) { |
| 361 | ALOGE("Cannot find resources to add app instance %d", |
| 362 | appInstanceHandle); |
| 363 | return -1; |
| 364 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 365 | } |
| 366 | |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 367 | entry.appInfo = *appInfo; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 368 | |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 369 | entry.instanceId = appInstanceHandle; |
| 370 | entry.truncName = appInfo->app_name.id; |
| 371 | entry.hubHandle = hubHandle; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 372 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 373 | db.appInstances[appInstanceHandle] = entry; |
| 374 | |
| 375 | // Finally - let the service know of this app instance |
| 376 | env->CallIntMethod(db.jniInfo.jContextHubService, |
| 377 | db.jniInfo.contextHubServiceAddAppInstance, |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 378 | hubHandle, entry.instanceId, entry.truncName, |
| 379 | entry.appInfo.version); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 380 | |
| 381 | ALOGW("Added App 0x%" PRIx64 " on hub Handle %" PRId32 |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 382 | " as appInstance %d", entry.truncName, |
| 383 | entry.hubHandle, appInstanceHandle); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 384 | |
| 385 | return appInstanceHandle; |
| 386 | } |
| 387 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 388 | int delete_app_instance(int id, JNIEnv *env) { |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 389 | if (!db.appInstances.count(id)) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 390 | ALOGW("Cannot find App id : %d", id); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 391 | return -1; |
| 392 | } |
| 393 | |
| 394 | return_id(id); |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 395 | db.appInstances.erase(id); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 396 | if (env->CallIntMethod(db.jniInfo.jContextHubService, |
| 397 | db.jniInfo.contextHubServiceDeleteAppInstance, |
| 398 | id) != 0) { |
| 399 | ALOGW("Could not delete App id : %d", id); |
| 400 | return -1; |
| 401 | } |
| 402 | |
| 403 | ALOGI("Deleted App id : %d", id); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 404 | |
| 405 | return 0; |
| 406 | } |
| 407 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 408 | static int startLoadAppTxn(uint64_t appId, int hubHandle) { |
| 409 | app_instance_info_s *txnInfo = (app_instance_info_s *)malloc(sizeof(app_instance_info_s)); |
| 410 | int instanceId = generate_id(); |
| 411 | |
| 412 | if (!txnInfo || instanceId < 0) { |
| 413 | return_id(instanceId); |
| 414 | free(txnInfo); |
| 415 | return -1; |
| 416 | } |
| 417 | |
| 418 | txnInfo->truncName = appId; |
| 419 | txnInfo->hubHandle = hubHandle; |
| 420 | txnInfo->instanceId = instanceId; |
| 421 | |
| 422 | txnInfo->appInfo.app_name.id = appId; |
| 423 | txnInfo->appInfo.num_mem_ranges = 0; |
| 424 | txnInfo->appInfo.version = -1; // Awaited |
| 425 | |
Ashutosh Joshi | 1186440 | 2016-07-15 13:46:22 -0700 | [diff] [blame] | 426 | if (addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 427 | return_id(instanceId); |
| 428 | free(txnInfo); |
| 429 | return -1; |
| 430 | } |
| 431 | |
| 432 | return 0; |
| 433 | } |
| 434 | |
| 435 | static int startUnloadAppTxn(uint32_t appInstanceHandle) { |
| 436 | uint32_t *txnData = (uint32_t *) malloc(sizeof(uint32_t)); |
| 437 | if (!txnData) { |
| 438 | ALOGW("Cannot allocate memory to start unload transaction"); |
| 439 | return -1; |
| 440 | } |
| 441 | |
| 442 | *txnData = appInstanceHandle; |
| 443 | |
| 444 | if (addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) { |
| 445 | free(txnData); |
| 446 | ALOGW("Cannot start transaction to unload app"); |
| 447 | return -1; |
| 448 | } |
| 449 | |
| 450 | return 0; |
| 451 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 452 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 453 | static void initContextHubService() { |
| 454 | int err = 0; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 455 | db.hubInfo.hubs = nullptr; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 456 | db.hubInfo.numHubs = 0; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 457 | int i; |
| 458 | |
| 459 | err = hw_get_module(CONTEXT_HUB_MODULE_ID, |
| 460 | (hw_module_t const**)(&db.hubInfo.contextHubModule)); |
| 461 | |
| 462 | if (err) { |
| 463 | ALOGE("** Could not load %s module : err %s", CONTEXT_HUB_MODULE_ID, |
| 464 | strerror(-err)); |
| 465 | } |
| 466 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 467 | // Prep for storing app info |
| 468 | for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) { |
| 469 | db.freeIds.push(i); |
| 470 | } |
Ashutosh Joshi | adf75e3 | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 471 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 472 | initTxnManager(); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 473 | if (db.hubInfo.contextHubModule) { |
| 474 | int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule, |
| 475 | &db.hubInfo.hubs); |
| 476 | ALOGD("ContextHubModule returned %d hubs ", retNumHubs); |
| 477 | db.hubInfo.numHubs = retNumHubs; |
| 478 | |
| 479 | if (db.hubInfo.numHubs > 0) { |
| 480 | db.hubInfo.numHubs = retNumHubs; |
| 481 | db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs); |
| 482 | |
| 483 | if (!db.hubInfo.cookies) { |
| 484 | ALOGW("Ran out of memory allocating cookies, bailing"); |
| 485 | return; |
| 486 | } |
| 487 | |
| 488 | for (i = 0; i < db.hubInfo.numHubs; i++) { |
| 489 | db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 490 | ALOGI("Subscribing to hubHandle %d with OS App name %" PRIu64, i, db.hubInfo.hubs[i].os_app_name.id); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 491 | if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id, |
| 492 | context_hub_callback, |
| 493 | &db.hubInfo.cookies[i]) == 0) { |
| 494 | } |
| 495 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 496 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 497 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 498 | sendQueryForApps(ALL_APPS); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 499 | } else { |
| 500 | ALOGW("No Context Hub Module present"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 501 | } |
| 502 | } |
| 503 | |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 504 | static int onMessageReceipt(uint32_t *header, size_t headerLen, char *msg, size_t msgLen) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 505 | JNIEnv *env; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 506 | |
| 507 | if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 508 | return -1; |
| 509 | } |
| 510 | |
| 511 | jbyteArray jmsg = env->NewByteArray(msgLen); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 512 | if (jmsg == nullptr) { |
| 513 | ALOGW("Can't allocate %zu byte array", msgLen); |
| 514 | return -1; |
| 515 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 516 | jintArray jheader = env->NewIntArray(headerLen); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 517 | if (jheader == nullptr) { |
| 518 | env->DeleteLocalRef(jmsg); |
| 519 | ALOGW("Can't allocate %zu int array", headerLen); |
| 520 | return -1; |
| 521 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 522 | |
| 523 | env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg); |
| 524 | env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header); |
| 525 | |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 526 | int ret = (env->CallIntMethod(db.jniInfo.jContextHubService, |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 527 | db.jniInfo.contextHubServiceMsgReceiptCallback, |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 528 | jheader, jmsg) != 0); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 529 | env->DeleteLocalRef(jmsg); |
| 530 | env->DeleteLocalRef(jheader); |
| 531 | |
| 532 | return ret; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 533 | } |
| 534 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 535 | int handle_query_apps_response(const uint8_t *msg, int msgLen, |
| 536 | uint32_t hubHandle) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 537 | JNIEnv *env; |
| 538 | if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { |
| 539 | return -1; |
| 540 | } |
| 541 | |
| 542 | int numApps = msgLen/sizeof(hub_app_info); |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 543 | hub_app_info info; |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 544 | const hub_app_info *unalignedInfoAddr = (const hub_app_info*)msg; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 545 | |
Alexey Polyudov | ab2d445 | 2016-04-08 09:56:35 -0700 | [diff] [blame] | 546 | for (int i = 0; i < numApps; i++, unalignedInfoAddr++) { |
| 547 | memcpy(&info, unalignedInfoAddr, sizeof(info)); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 548 | // We will only have one instance of the app |
| 549 | // TODO : Change this logic once we support multiple instances of the same app |
| 550 | int appInstance = get_app_instance_for_app_id(info.app_name.id); |
| 551 | add_app_instance(&info, hubHandle, appInstance, env); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 552 | } |
| 553 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 554 | return 0; |
| 555 | } |
| 556 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 557 | static void passOnOsResponse(uint32_t hubHandle, uint32_t msgType, |
| 558 | status_response_t *rsp, int8_t *additionalData, |
| 559 | size_t additionalDataLen) { |
| 560 | JNIEnv *env; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 561 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 562 | if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { |
| 563 | ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32, msgType); |
| 564 | return; |
| 565 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 566 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 567 | uint32_t header[MSG_HEADER_SIZE]; |
| 568 | memset(header, 0, sizeof(header)); |
| 569 | |
| 570 | if (!additionalData) { |
| 571 | additionalDataLen = 0; // clamp |
| 572 | } |
| 573 | int msgLen = 1 + additionalDataLen; |
| 574 | |
| 575 | int8_t *msg = new int8_t[msgLen]; |
| 576 | |
| 577 | if (!msg) { |
| 578 | ALOGW("Unexpected : Ran out of memory, cannot send response"); |
| 579 | return; |
| 580 | } |
| 581 | |
| 582 | header[HEADER_FIELD_MSG_TYPE] = msgType; |
| 583 | header[HEADER_FIELD_MSG_VERSION] = 0; |
| 584 | header[HEADER_FIELD_HUB_HANDLE] = hubHandle; |
| 585 | header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID; |
| 586 | |
| 587 | msg[0] = rsp->result; |
| 588 | |
| 589 | if (additionalData) { |
| 590 | memcpy(&msg[1], additionalData, additionalDataLen); |
| 591 | } |
| 592 | |
| 593 | jbyteArray jmsg = env->NewByteArray(msgLen); |
| 594 | jintArray jheader = env->NewIntArray(sizeof(header)); |
| 595 | |
| 596 | env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg); |
| 597 | env->SetIntArrayRegion(jheader, 0, sizeof(header), (jint *)header); |
| 598 | |
| 599 | ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32, |
| 600 | header[HEADER_FIELD_MSG_TYPE], header[HEADER_FIELD_APP_INSTANCE], |
| 601 | header[HEADER_FIELD_HUB_HANDLE]); |
| 602 | |
| 603 | env->CallIntMethod(db.jniInfo.jContextHubService, |
| 604 | db.jniInfo.contextHubServiceMsgReceiptCallback, |
| 605 | jheader, jmsg); |
Andrew Rossignol | 52dda59 | 2016-08-09 10:54:38 -0700 | [diff] [blame] | 606 | env->DeleteLocalRef(jmsg); |
| 607 | env->DeleteLocalRef(jheader); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 608 | |
| 609 | delete[] msg; |
| 610 | } |
| 611 | |
| 612 | void closeUnloadTxn(bool success) { |
| 613 | void *txnData = nullptr; |
| 614 | hub_messages_e txnId; |
| 615 | |
| 616 | if (success && fetchTxnData(&txnId, &txnData) == 0 && |
| 617 | txnId == CONTEXT_HUB_UNLOAD_APP) { |
| 618 | db.appInstances.erase(*(uint32_t *)txnData); |
| 619 | } else { |
| 620 | ALOGW("Could not unload the app successfully ! success %d, txnData %p", success, txnData); |
| 621 | } |
| 622 | |
| 623 | closeTxn(); |
| 624 | } |
| 625 | |
| 626 | void closeLoadTxn(bool success, int *appInstanceHandle) { |
| 627 | void *txnData; |
| 628 | hub_messages_e txnId; |
| 629 | |
| 630 | if (success && fetchTxnData(&txnId, &txnData) == 0 && |
| 631 | txnId == CONTEXT_HUB_LOAD_APP) { |
| 632 | app_instance_info_s *info = (app_instance_info_s *)txnData; |
| 633 | *appInstanceHandle = info->instanceId; |
| 634 | |
| 635 | JNIEnv *env; |
| 636 | if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) { |
| 637 | add_app_instance(&info->appInfo, info->hubHandle, info->instanceId, env); |
| 638 | } else { |
| 639 | ALOGW("Could not attach to JVM !"); |
| 640 | } |
| 641 | sendQueryForApps(info->appInfo.app_name.id); |
| 642 | } else { |
| 643 | ALOGW("Could not load the app successfully ! Unexpected failure"); |
| 644 | } |
| 645 | |
| 646 | closeTxn(); |
| 647 | } |
| 648 | |
| 649 | static bool isValidOsStatus(const uint8_t *msg, size_t msgLen, |
| 650 | status_response_t *rsp) { |
| 651 | // Workaround a bug in some HALs |
| 652 | if (msgLen == 1) { |
| 653 | rsp->result = msg[0]; |
| 654 | return true; |
| 655 | } |
| 656 | |
| 657 | if (!msg || msgLen != sizeof(*rsp)) { |
| 658 | ALOGW("Received invalid response %p of size %zu", msg, msgLen); |
| 659 | return false; |
| 660 | } |
| 661 | |
| 662 | memcpy(rsp, msg, sizeof(*rsp)); |
| 663 | |
| 664 | // No sanity checks on return values |
| 665 | return true; |
| 666 | } |
| 667 | |
| 668 | static void invalidateNanoApps(uint32_t hubHandle) { |
| 669 | JNIEnv *env; |
| 670 | |
| 671 | if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) { |
| 672 | ALOGW("Could not attach to JVM !"); |
| 673 | } |
| 674 | |
| 675 | auto end = db.appInstances.end(); |
| 676 | for (auto current = db.appInstances.begin(); current != end; ) { |
| 677 | app_instance_info_s info = current->second; |
| 678 | current++; |
| 679 | if (info.hubHandle == hubHandle) { |
| 680 | delete_app_instance(info.instanceId, env); |
| 681 | } |
| 682 | } |
| 683 | } |
| 684 | |
| 685 | static int handle_os_message(uint32_t msgType, uint32_t hubHandle, |
| 686 | const uint8_t *msg, int msgLen) { |
| 687 | int retVal = -1; |
| 688 | |
| 689 | ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d", |
| 690 | hubHandle, msgType, msgLen); |
| 691 | |
| 692 | struct status_response_t rsp; |
Ashutosh Joshi | 6239cc6 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 693 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 694 | switch(msgType) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 695 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 696 | case CONTEXT_HUB_APPS_ENABLE: |
| 697 | case CONTEXT_HUB_APPS_DISABLE: |
| 698 | case CONTEXT_HUB_LOAD_APP: |
| 699 | case CONTEXT_HUB_UNLOAD_APP: |
| 700 | if (isValidOsStatus(msg, msgLen, &rsp)) { |
| 701 | if (msgType == CONTEXT_HUB_LOAD_APP) { |
| 702 | int appInstanceHandle; |
| 703 | closeLoadTxn(rsp.result == 0, &appInstanceHandle); |
| 704 | passOnOsResponse(hubHandle, msgType, &rsp, (int8_t *)(&appInstanceHandle), |
| 705 | sizeof(appInstanceHandle)); |
| 706 | } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 707 | closeUnloadTxn(rsp.result == 0); |
| 708 | passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); |
| 709 | } else { |
| 710 | passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); |
| 711 | } |
| 712 | retVal = 0; |
| 713 | } |
| 714 | break; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 715 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 716 | case CONTEXT_HUB_QUERY_APPS: |
| 717 | rsp.result = 0; |
| 718 | retVal = handle_query_apps_response(msg, msgLen, hubHandle); |
| 719 | passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); |
| 720 | break; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 721 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 722 | case CONTEXT_HUB_QUERY_MEMORY: |
| 723 | // Deferring this use |
| 724 | retVal = 0; |
| 725 | break; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 726 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 727 | case CONTEXT_HUB_OS_REBOOT: |
| 728 | if (isValidOsStatus(msg, msgLen, &rsp)) { |
| 729 | rsp.result = 0; |
| 730 | ALOGW("Context Hub handle %d restarted", hubHandle); |
Ashutosh Joshi | 1186440 | 2016-07-15 13:46:22 -0700 | [diff] [blame] | 731 | closeTxn(); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 732 | passOnOsResponse(hubHandle, msgType, &rsp, nullptr, 0); |
| 733 | invalidateNanoApps(hubHandle); |
| 734 | query_hub_for_apps(ALL_APPS, hubHandle); |
| 735 | retVal = 0; |
| 736 | } |
| 737 | break; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 738 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 739 | default: |
| 740 | retVal = -1; |
| 741 | break; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 742 | } |
| 743 | |
| 744 | return retVal; |
| 745 | } |
| 746 | |
| 747 | static bool sanity_check_cookie(void *cookie, uint32_t hub_id) { |
| 748 | int *ptr = (int *)cookie; |
| 749 | |
| 750 | if (!ptr || *ptr >= db.hubInfo.numHubs) { |
| 751 | return false; |
| 752 | } |
| 753 | |
| 754 | if (db.hubInfo.hubs[*ptr].hub_id != hub_id) { |
| 755 | return false; |
| 756 | } else { |
| 757 | return true; |
| 758 | } |
| 759 | } |
| 760 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 761 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 762 | int context_hub_callback(uint32_t hubId, |
| 763 | const struct hub_message_t *msg, |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 764 | void *cookie) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 765 | if (!msg) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 766 | ALOGW("NULL message"); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 767 | return -1; |
| 768 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 769 | if (!sanity_check_cookie(cookie, hubId)) { |
| 770 | ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing", |
| 771 | hubId, cookie); |
| 772 | |
| 773 | return -1; |
| 774 | } |
| 775 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 776 | |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 777 | uint32_t messageType = msg->message_type; |
| 778 | uint32_t hubHandle = *(uint32_t*) cookie; |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 779 | |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 780 | if (messageType < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 781 | handle_os_message(messageType, hubHandle, (uint8_t*) msg->message, msg->message_len); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 782 | } else { |
destradaa | 6469c23 | 2016-04-27 17:53:23 -0700 | [diff] [blame] | 783 | int appHandle = get_app_instance_for_app_id(msg->app_name.id); |
| 784 | if (appHandle < 0) { |
| 785 | ALOGE("Filtering out message due to invalid App Instance."); |
| 786 | } else { |
| 787 | uint32_t msgHeader[MSG_HEADER_SIZE] = {}; |
| 788 | msgHeader[HEADER_FIELD_MSG_TYPE] = messageType; |
| 789 | msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle; |
| 790 | msgHeader[HEADER_FIELD_APP_INSTANCE] = appHandle; |
| 791 | onMessageReceipt(msgHeader, MSG_HEADER_SIZE, (char*) msg->message, msg->message_len); |
| 792 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 793 | } |
| 794 | |
| 795 | return 0; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 796 | } |
| 797 | |
| 798 | static int init_jni(JNIEnv *env, jobject instance) { |
| 799 | |
| 800 | if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 801 | return -1; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 802 | } |
| 803 | |
| 804 | db.jniInfo.jContextHubService = env->NewGlobalRef(instance); |
| 805 | |
| 806 | db.jniInfo.contextHubInfoClass = |
| 807 | env->FindClass("android/hardware/location/ContextHubInfo"); |
| 808 | |
| 809 | db.jniInfo.contextHubServiceClass = |
| 810 | env->FindClass("android/hardware/location/ContextHubService"); |
| 811 | |
| 812 | db.jniInfo.memoryRegionsClass = |
| 813 | env->FindClass("android/hardware/location/MemoryRegion"); |
| 814 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 815 | db.jniInfo.contextHubInfoCtor = |
| 816 | env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V"); |
| 817 | db.jniInfo.contextHubInfoSetId = |
| 818 | env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V"); |
| 819 | db.jniInfo.contextHubInfoSetName = |
| 820 | env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", |
| 821 | "(Ljava/lang/String;)V"); |
| 822 | |
| 823 | db.jniInfo.contextHubInfoSetVendor = |
| 824 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 825 | "setVendor", "(Ljava/lang/String;)V"); |
| 826 | db.jniInfo.contextHubInfoSetToolchain = |
| 827 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 828 | "setToolchain", "(Ljava/lang/String;)V"); |
| 829 | db.jniInfo.contextHubInfoSetPlatformVersion = |
| 830 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 831 | "setPlatformVersion", "(I)V"); |
| 832 | db.jniInfo.contextHubInfoSetStaticSwVersion = |
| 833 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 834 | "setStaticSwVersion", "(I)V"); |
| 835 | db.jniInfo.contextHubInfoSetToolchainVersion = |
| 836 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 837 | "setToolchainVersion", "(I)V"); |
| 838 | db.jniInfo.contextHubInfoSetPeakMips = |
| 839 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 840 | "setPeakMips", "(F)V"); |
| 841 | db.jniInfo.contextHubInfoSetStoppedPowerDrawMw = |
| 842 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 843 | "setStoppedPowerDrawMw", "(F)V"); |
| 844 | db.jniInfo.contextHubInfoSetSleepPowerDrawMw = |
| 845 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 846 | "setSleepPowerDrawMw", "(F)V"); |
| 847 | db.jniInfo.contextHubInfoSetPeakPowerDrawMw = |
| 848 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 849 | "setPeakPowerDrawMw", "(F)V"); |
| 850 | db.jniInfo.contextHubInfoSetSupportedSensors = |
| 851 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 852 | "setSupportedSensors", "([I)V"); |
| 853 | db.jniInfo.contextHubInfoSetMemoryRegions = |
| 854 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 855 | "setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V"); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 856 | db.jniInfo.contextHubInfoSetMaxPacketLenBytes = |
| 857 | env->GetMethodID(db.jniInfo.contextHubInfoClass, |
| 858 | "setMaxPacketLenBytes", "(I)V"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 859 | |
| 860 | |
| 861 | db.jniInfo.contextHubServiceMsgReceiptCallback = |
| 862 | env->GetMethodID(db.jniInfo.contextHubServiceClass, "onMessageReceipt", |
| 863 | "([I[B)I"); |
| 864 | db.jniInfo.contextHubInfoSetName = |
| 865 | env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", |
| 866 | "(Ljava/lang/String;)V"); |
| 867 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 868 | db.jniInfo.contextHubServiceAddAppInstance = |
| 869 | env->GetMethodID(db.jniInfo.contextHubServiceClass, |
| 870 | "addAppInstance", "(IIJI)I"); |
| 871 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 872 | db.jniInfo.contextHubServiceDeleteAppInstance = |
| 873 | env->GetMethodID(db.jniInfo.contextHubServiceClass, |
| 874 | "deleteAppInstance", "(I)I"); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 875 | |
| 876 | return 0; |
| 877 | } |
| 878 | |
| 879 | static jobject constructJContextHubInfo(JNIEnv *env, const struct context_hub_t *hub) { |
| 880 | jstring jstrBuf; |
| 881 | jintArray jintBuf; |
| 882 | jobjectArray jmemBuf; |
| 883 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 884 | jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass, |
| 885 | db.jniInfo.contextHubInfoCtor); |
| 886 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub->hub_id); |
| 887 | |
| 888 | jstrBuf = env->NewStringUTF(hub->name); |
| 889 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 890 | env->DeleteLocalRef(jstrBuf); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 891 | |
| 892 | jstrBuf = env->NewStringUTF(hub->vendor); |
| 893 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 894 | env->DeleteLocalRef(jstrBuf); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 895 | |
| 896 | jstrBuf = env->NewStringUTF(hub->toolchain); |
| 897 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 898 | env->DeleteLocalRef(jstrBuf); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 899 | |
| 900 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version); |
| 901 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version); |
| 902 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 903 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, |
| 904 | hub->stopped_power_draw_mw); |
| 905 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, |
| 906 | hub->sleep_power_draw_mw); |
| 907 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, |
| 908 | hub->peak_power_draw_mw); |
| 909 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes, |
| 910 | hub->max_supported_msg_len); |
| 911 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 912 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 913 | jintBuf = env->NewIntArray(hub->num_connected_sensors); |
| 914 | int *connectedSensors = new int[hub->num_connected_sensors]; |
| 915 | |
| 916 | if (!connectedSensors) { |
| 917 | ALOGW("Cannot allocate memory! Unexpected"); |
| 918 | assert(false); |
| 919 | } else { |
| 920 | for (unsigned int i = 0; i < hub->num_connected_sensors; i++) { |
| 921 | connectedSensors[i] = hub->connected_sensors[i].sensor_id; |
| 922 | } |
| 923 | } |
| 924 | |
| 925 | env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, |
| 926 | connectedSensors); |
| 927 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 928 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 929 | env->DeleteLocalRef(jintBuf); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 930 | |
| 931 | // We are not getting the memory regions from the CH Hal - change this when it is available |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 932 | jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 933 | // Note the zero size above. We do not need to set any elements |
| 934 | env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf); |
Greg Kaiser | bece599 | 2016-05-09 10:23:56 -0700 | [diff] [blame] | 935 | env->DeleteLocalRef(jmemBuf); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 936 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 937 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 938 | delete[] connectedSensors; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 939 | return jHub; |
| 940 | } |
| 941 | |
| 942 | static jobjectArray nativeInitialize(JNIEnv *env, jobject instance) |
| 943 | { |
| 944 | jobject hub; |
| 945 | jobjectArray retArray; |
| 946 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 947 | if (init_jni(env, instance) < 0) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 948 | return nullptr; |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 949 | } |
| 950 | |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 951 | initContextHubService(); |
| 952 | |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 953 | if (db.hubInfo.numHubs > 1) { |
| 954 | ALOGW("Clamping the number of hubs to 1"); |
| 955 | db.hubInfo.numHubs = 1; |
| 956 | } |
| 957 | |
| 958 | retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 959 | |
| 960 | for(int i = 0; i < db.hubInfo.numHubs; i++) { |
| 961 | hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]); |
| 962 | env->SetObjectArrayElement(retArray, i, hub); |
| 963 | } |
| 964 | |
| 965 | return retArray; |
| 966 | } |
| 967 | |
| 968 | static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, |
| 969 | jbyteArray data_) { |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 970 | jint retVal = -1; // Default to failure |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 971 | |
| 972 | jint *header = env->GetIntArrayElements(header_, 0); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 973 | unsigned int numHeaderElements = env->GetArrayLength(header_); |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 974 | jbyte *data = env->GetByteArrayElements(data_, 0); |
| 975 | int dataBufferLength = env->GetArrayLength(data_); |
| 976 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 977 | if (numHeaderElements < MSG_HEADER_SIZE) { |
| 978 | ALOGW("Malformed header len"); |
| 979 | return -1; |
| 980 | } |
Ashutosh Joshi | cafdee9 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 981 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 982 | uint32_t appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE]; |
| 983 | uint32_t msgType = header[HEADER_FIELD_MSG_TYPE]; |
| 984 | int hubHandle = -1; |
| 985 | int hubId; |
| 986 | uint64_t appId; |
| 987 | |
| 988 | if (msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 989 | hubHandle = get_hub_handle_for_app_instance(appInstanceHandle); |
| 990 | } else if (msgType == CONTEXT_HUB_LOAD_APP) { |
| 991 | if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) { |
| 992 | return -1; |
| 993 | } |
| 994 | uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO]; |
| 995 | uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI]; |
| 996 | appId = appIdHi << 32 | appIdLo; |
| 997 | |
| 998 | hubHandle = header[HEADER_FIELD_HUB_HANDLE]; |
| 999 | } else { |
| 1000 | hubHandle = header[HEADER_FIELD_HUB_HANDLE]; |
| 1001 | } |
| 1002 | |
| 1003 | if (hubHandle < 0) { |
| 1004 | ALOGD("Invalid hub Handle %d", hubHandle); |
| 1005 | return -1; |
| 1006 | } |
| 1007 | |
| 1008 | if (msgType == CONTEXT_HUB_LOAD_APP || |
| 1009 | msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 1010 | |
| 1011 | if (isTxnPending()) { |
| 1012 | ALOGW("Cannot load or unload app while a transaction is pending !"); |
| 1013 | return -1; |
| 1014 | } |
| 1015 | |
| 1016 | if (msgType == CONTEXT_HUB_LOAD_APP) { |
| 1017 | if (startLoadAppTxn(appId, hubHandle) != 0) { |
Ashutosh Joshi | 1186440 | 2016-07-15 13:46:22 -0700 | [diff] [blame] | 1018 | ALOGW("Cannot Start Load Transaction"); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1019 | return -1; |
| 1020 | } |
| 1021 | } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 1022 | if (startUnloadAppTxn(appInstanceHandle) != 0) { |
Ashutosh Joshi | 1186440 | 2016-07-15 13:46:22 -0700 | [diff] [blame] | 1023 | ALOGW("Cannot Start UnLoad Transaction"); |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1024 | return -1; |
| 1025 | } |
| 1026 | } |
| 1027 | } |
| 1028 | |
| 1029 | bool setAddressSuccess = false; |
| 1030 | hub_message_t msg; |
| 1031 | |
| 1032 | msg.message_type = msgType; |
| 1033 | |
| 1034 | if (msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 1035 | msg.message_len = sizeof(db.appInstances[appInstanceHandle].appInfo.app_name); |
| 1036 | msg.message = &db.appInstances[appInstanceHandle].appInfo.app_name; |
| 1037 | setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0); |
| 1038 | hubId = get_hub_id_for_hub_handle(hubHandle); |
| 1039 | } else { |
| 1040 | msg.message_len = dataBufferLength; |
| 1041 | msg.message = data; |
Ashutosh Joshi | cafdee9 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 1042 | |
| 1043 | if (header[HEADER_FIELD_APP_INSTANCE] == OS_APP_ID) { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1044 | setAddressSuccess = (set_os_app_as_destination(&msg, hubHandle) == 0); |
| 1045 | hubId = get_hub_id_for_hub_handle(hubHandle); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 1046 | } else { |
Ashutosh Joshi | cafdee9 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 1047 | setAddressSuccess = (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0); |
| 1048 | hubId = get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]); |
| 1049 | } |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1050 | } |
Ashutosh Joshi | cafdee9 | 2016-04-04 16:19:29 -0700 | [diff] [blame] | 1051 | |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1052 | if (setAddressSuccess && hubId >= 0) { |
| 1053 | ALOGD("Asking HAL to remove app"); |
| 1054 | retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 1055 | } else { |
Ashutosh Joshi | 54787a5 | 2016-04-27 11:19:16 -0700 | [diff] [blame] | 1056 | ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d", |
| 1057 | header[HEADER_FIELD_APP_INSTANCE], |
| 1058 | header[HEADER_FIELD_HUB_HANDLE], |
| 1059 | (int)setAddressSuccess); |
| 1060 | } |
| 1061 | |
| 1062 | if (retVal != 0) { |
| 1063 | ALOGD("Send Message failure - %d", retVal); |
| 1064 | if (msgType == CONTEXT_HUB_LOAD_APP) { |
| 1065 | closeLoadTxn(false, nullptr); |
| 1066 | } else if (msgType == CONTEXT_HUB_UNLOAD_APP) { |
| 1067 | closeUnloadTxn(false); |
| 1068 | } |
Ashutosh Joshi | b741e3b | 2016-03-29 09:19:56 -0700 | [diff] [blame] | 1069 | } |
Peng Xu | 9ff7d22 | 2016-02-11 13:02:05 -0800 | [diff] [blame] | 1070 | |
| 1071 | env->ReleaseIntArrayElements(header_, header, 0); |
| 1072 | env->ReleaseByteArrayElements(data_, data, 0); |
| 1073 | |
| 1074 | return retVal; |
| 1075 | } |
| 1076 | |
| 1077 | //-------------------------------------------------------------------------------------------------- |
| 1078 | // |
| 1079 | static const JNINativeMethod gContextHubServiceMethods[] = { |
| 1080 | {"nativeInitialize", |
| 1081 | "()[Landroid/hardware/location/ContextHubInfo;", |
| 1082 | (void*)nativeInitialize }, |
| 1083 | {"nativeSendMessage", |
| 1084 | "([I[B)I", |
| 1085 | (void*)nativeSendMessage } |
| 1086 | }; |
| 1087 | |
| 1088 | }//namespace android |
| 1089 | |
| 1090 | using namespace android; |
| 1091 | |
| 1092 | int register_android_hardware_location_ContextHubService(JNIEnv *env) |
| 1093 | { |
| 1094 | RegisterMethodsOrDie(env, "android/hardware/location/ContextHubService", |
| 1095 | gContextHubServiceMethods, NELEM(gContextHubServiceMethods)); |
| 1096 | |
| 1097 | return 0; |
| 1098 | } |