diff options
| author | Ashutosh Joshi <ashutoshj@google.com> | 2016-11-15 13:48:58 -0800 |
|---|---|---|
| committer | Ashutosh Joshi <ashutoshj@google.com> | 2016-12-19 21:22:27 -0800 |
| commit | 1bec86a18590a420f60148b90e2f266098b29bfe (patch) | |
| tree | e19de55e695b7dffb43a95b9fa6d2e5e03d36bce /contexthub/1.0/default | |
| parent | d5c2cef024c406607aeafe4e7cad4caffaf6eaab (diff) | |
| download | android_hardware_interfaces-1bec86a18590a420f60148b90e2f266098b29bfe.tar.gz android_hardware_interfaces-1bec86a18590a420f60148b90e2f266098b29bfe.tar.bz2 android_hardware_interfaces-1bec86a18590a420f60148b90e2f266098b29bfe.zip | |
Contexthub HAL default implementation and service.
Adds the default context hub hal implementation and service.
Test: Context Hub GTS tests still pass.
Change-Id: I7416ce9ec8efca7f98d2bb63606f030f4e8c8ead
Diffstat (limited to 'contexthub/1.0/default')
| -rw-r--r-- | contexthub/1.0/default/Android.bp | 33 | ||||
| -rw-r--r-- | contexthub/1.0/default/Android.mk | 23 | ||||
| -rw-r--r-- | contexthub/1.0/default/Contexthub.cpp | 528 | ||||
| -rw-r--r-- | contexthub/1.0/default/Contexthub.h | 105 | ||||
| -rw-r--r-- | contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc | 4 | ||||
| -rw-r--r-- | contexthub/1.0/default/service.cpp | 27 |
6 files changed, 720 insertions, 0 deletions
diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp new file mode 100644 index 000000000..7c5f79d70 --- /dev/null +++ b/contexthub/1.0/default/Android.bp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +cc_library_shared { + name: "android.hardware.contexthub@1.0-impl", + relative_install_path: "hw", + srcs: ["Contexthub.cpp"], + shared_libs: [ + "liblog", + "libcutils", + "libhardware", + "libhwbinder", + "libbase", + "libcutils", + "libutils", + "libhidlbase", + "libhidltransport", + "android.hardware.contexthub@1.0", + ], +} diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk new file mode 100644 index 000000000..ad40878ce --- /dev/null +++ b/contexthub/1.0/default/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_MODULE := android.hardware.contexthub@1.0-service +LOCAL_INIT_RC := android.hardware.contexthub@1.0-service.rc +LOCAL_SRC_FILES := \ + service.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + libbase \ + libcutils \ + libdl \ + libhardware \ + libhardware_legacy \ + libhidlbase \ + libhidltransport \ + libhwbinder \ + liblog \ + libutils \ + android.hardware.contexthub@1.0 \ + +include $(BUILD_EXECUTABLE) diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp new file mode 100644 index 000000000..d530a8720 --- /dev/null +++ b/contexthub/1.0/default/Contexthub.cpp @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Contexthub.h" + +#include <inttypes.h> + +#include <android/log.h> +#include <android/hardware/contexthub/1.0/IContexthub.h> +#include <hardware/context_hub.h> + +#undef LOG_TAG +#define LOG_TAG "ContextHubHalAdapter" + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_0 { +namespace implementation { + +static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF); + +Contexthub::Contexthub() + : mInitCheck(NO_INIT), + mContextHubModule(nullptr), + mIsTransactionPending(false) { + const hw_module_t *module; + + mInitCheck = hw_get_module(CONTEXT_HUB_MODULE_ID, &module); + + if (mInitCheck != OK) { + ALOGE("Could not load %s module: %s", CONTEXT_HUB_MODULE_ID, strerror(-mInitCheck)); + } else if (module == nullptr) { + ALOGE("hal returned succes but a null module!"); + // Assign an error, this should not really happen... + mInitCheck = UNKNOWN_ERROR; + } else { + ALOGI("Loaded Context Hub module"); + mContextHubModule = reinterpret_cast<const context_hub_module_t *>(module); + } +} + +bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) { + if (!isValidHubId(hubId)) { + ALOGW("%s: Hub information is null for hubHandle %d", + __FUNCTION__, + hubId); + return false; + } else { + msg->app_name = mCachedHubInfo[hubId].osAppName; + return true; + } +} + +Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) { + std::vector<ContextHub> hubs; + if (isInitialized()) { + const context_hub_t *hubArray = nullptr; + size_t numHubs; + + // Explicitly discarding const. HAL method discards it. + numHubs = mContextHubModule->get_hubs(const_cast<context_hub_module_t *>(mContextHubModule), + &hubArray); + ALOGI("Context Hub Hal Adapter reports %zu hubs", numHubs); + + mCachedHubInfo.clear(); + + for (size_t i = 0; i < numHubs; i++) { + CachedHubInformation info; + ContextHub c; + + c.hubId = hubArray[i].hub_id; + c.name = hubArray[i].name; + c.vendor = hubArray[i].vendor; + c.toolchain = hubArray[i].toolchain; + c.toolchainVersion = hubArray[i].toolchain_version; + c.platformVersion = hubArray[i].platform_version; + c.maxSupportedMsgLen = hubArray[i].max_supported_msg_len; + c.peakMips = hubArray[i].peak_mips; + c.peakPowerDrawMw = hubArray[i].peak_power_draw_mw; + c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw; + c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw; + + info.callBack = nullptr; + info.osAppName = hubArray[i].os_app_name; + mCachedHubInfo[hubArray[i].hub_id] = info; + + hubs.push_back(c); + } + } else { + ALOGW("Context Hub Hal Adapter not initialized"); + } + + _hidl_cb(hubs); + return Void(); +} + +bool Contexthub::isValidHubId(uint32_t hubId) { + if (!mCachedHubInfo.count(hubId)) { + ALOGW("Hub information not found for hubId %" PRIu32, hubId); + return false; + } else { + return true; + } +} + +sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) { + if (!isValidHubId(hubId)) { + return nullptr; + } else { + return mCachedHubInfo[hubId].callBack; + } +} + +Return<Result> Contexthub::sendMessageToHub(uint32_t hubId, + const ContextHubMsg &msg) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) { + return Result::BAD_PARAMS; + } + + hub_message_t txMsg = { + .app_name.id = msg.appName, + .message_type = msg.msgType, + .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above + .message = static_cast<const uint8_t *>(msg.msg.data()), + }; + + ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64, + txMsg.message_type, + txMsg.message_len, + txMsg.app_name.id); + + if(mContextHubModule->send_message(hubId, &txMsg) != 0) { + return Result::TRANSACTION_FAILED; + } + + return Result::OK; +} + +Return<Result> Contexthub::reboot(uint32_t hubId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + hub_message_t msg; + + if (setOsAppAsDestination(&msg, hubId) == false) { + return Result::BAD_PARAMS; + } + + msg.message_type = CONTEXT_HUB_OS_REBOOT; + msg.message_len = 0; + msg.message = nullptr; + + if(mContextHubModule->send_message(hubId, &msg) != 0) { + return Result::TRANSACTION_FAILED; + } else { + return Result::OK; + } +} + +Return<Result> Contexthub::registerCallback(uint32_t hubId, + const sp<IContexthubCallback> &cb) { + Return<Result> retVal = Result::BAD_PARAMS; + + if (!isInitialized()) { + // Not initilalized + ALOGW("Context hub not initialized successfully"); + retVal = Result::NOT_INIT; + } else if (!isValidHubId(hubId)) { + // Initialized, but hubId is not valid + retVal = Result::BAD_PARAMS; + } else if (mContextHubModule->subscribe_messages(hubId, + contextHubCb, + this) == 0) { + // Initialized && valid hub && subscription successful + retVal = Result::OK; + mCachedHubInfo[hubId].callBack = cb; + } else { + // Initalized && valid hubId - but subscription unsuccessful + // This is likely an internal error in the HAL implementation, but we + // cannot add more information. + ALOGW("Could not subscribe to the hub for callback"); + retVal = Result::UNKNOWN_FAILURE; + } + + return retVal; +} + +static bool isValidOsStatus(const uint8_t *msg, + size_t msgLen, + status_response_t *rsp) { + // Workaround a bug in some HALs + if (msgLen == 1) { + rsp->result = msg[0]; + return true; + } + + if (msg == nullptr || msgLen != sizeof(*rsp)) { + ALOGI("Received invalid response (is null : %d, size %zu)", + msg == nullptr ? 1 : 0, + msgLen); + return false; + } + + memcpy(rsp, msg, sizeof(*rsp)); + + // No sanity checks on return values + return true; +} + +int Contexthub::handleOsMessage(sp<IContexthubCallback> cb, + uint32_t msgType, + const uint8_t *msg, + int msgLen) { + int retVal = -1; + + + switch(msgType) { + case CONTEXT_HUB_APPS_ENABLE: + case CONTEXT_HUB_APPS_DISABLE: + case CONTEXT_HUB_LOAD_APP: + case CONTEXT_HUB_UNLOAD_APP: + { + struct status_response_t rsp; + TransactionResult result; + if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) { + retVal = 0; + result = TransactionResult::SUCCESS; + } else { + result = TransactionResult::FAILURE; + } + + if (cb != nullptr) { + cb->handleTxnResult(mTransactionId, result); + } + retVal = 0; + mIsTransactionPending = false; + break; + } + + case CONTEXT_HUB_QUERY_APPS: + { + std::vector<HubAppInfo> apps; + int numApps = msgLen / sizeof(hub_app_info); + const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg); + + for (int i = 0; i < numApps; i++) { + hub_app_info query_info; + memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info)); + HubAppInfo app; + app.appId = query_info.app_name.id; + app.version = query_info.version; + // TODO :: Add memory ranges + + apps.push_back(app); + } + + if (cb != nullptr) { + cb->handleAppsInfo(apps); + } + retVal = 0; + break; + } + + case CONTEXT_HUB_QUERY_MEMORY: + { + // Deferring this use + retVal = 0; + break; + } + + case CONTEXT_HUB_OS_REBOOT: + { + mIsTransactionPending = false; + if (cb != nullptr) { + cb->handleHubEvent(AsyncEventType::RESTARTED); + } + retVal = 0; + break; + } + + default: + { + retVal = -1; + break; + } + } + + return retVal; +} + +int Contexthub::contextHubCb(uint32_t hubId, + const struct hub_message_t *rxMsg, + void *cookie) { + Contexthub *obj = static_cast<Contexthub *>(cookie); + + if (rxMsg == nullptr) { + ALOGW("Ignoring NULL message"); + return -1; + } + + if (!obj->isValidHubId(hubId)) { + ALOGW("Invalid hub Id %" PRIu32, hubId); + return -1; + } + + sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId); + + if (cb == nullptr) { + // This should not ever happen + ALOGW("No callback registered, returning"); + return -1; + } + + if (rxMsg->message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) { + obj->handleOsMessage(cb, + rxMsg->message_type, + static_cast<const uint8_t *>(rxMsg->message), + rxMsg->message_len); + } else { + ContextHubMsg msg; + + msg.appName = rxMsg->app_name.id; + msg.msgType = rxMsg->message_type; + msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg->message), + static_cast<const uint8_t *>(rxMsg->message) + + rxMsg->message_len); + + cb->handleClientMsg(msg); + } + + return 0; +} + +Return<Result> Contexthub::unloadNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + if (mIsTransactionPending) { + return Result::TRANSACTION_PENDING; + } + + hub_message_t msg; + + if (setOsAppAsDestination(&msg, hubId) == false) { + return Result::BAD_PARAMS; + } + + struct apps_disable_request_t req; + + msg.message_type = CONTEXT_HUB_UNLOAD_APP; + msg.message_len = sizeof(req); + msg.message = &req; + req.app_name.id = appId; + + if(mContextHubModule->send_message(hubId, &msg) != 0) { + return Result::TRANSACTION_FAILED; + } else { + mTransactionId = transactionId; + mIsTransactionPending = true; + return Result::OK; + } +} + +Return<Result> Contexthub::loadNanoApp(uint32_t hubId, + const ::android::hardware::hidl_vec<uint8_t>& appBinary, + uint32_t transactionId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + if (mIsTransactionPending) { + return Result::TRANSACTION_PENDING; + } + + hub_message_t hubMsg; + + if (setOsAppAsDestination(&hubMsg, hubId) == false) { + return Result::BAD_PARAMS; + } + + hubMsg.message_type = CONTEXT_HUB_LOAD_APP; + hubMsg.message_len = appBinary.size(); + hubMsg.message = appBinary.data(); + + if(mContextHubModule->send_message(hubId, &hubMsg) != 0) { + return Result::TRANSACTION_FAILED; + } else { + mTransactionId = transactionId; + mIsTransactionPending = true; + return Result::OK; + } +} + +Return<Result> Contexthub::enableNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + if (mIsTransactionPending) { + return Result::TRANSACTION_PENDING; + } + + hub_message_t msg; + + if (setOsAppAsDestination(&msg, hubId) == false) { + return Result::BAD_PARAMS; + } + + struct apps_enable_request_t req; + + msg.message_type = CONTEXT_HUB_APPS_ENABLE; + msg.message_len = sizeof(req); + req.app_name.id = appId; + msg.message = &req; + + if(mContextHubModule->send_message(hubId, &msg) != 0) { + return Result::TRANSACTION_FAILED; + } else { + mTransactionId = transactionId; + mIsTransactionPending = true; + return Result::OK; + } +} + +Return<Result> Contexthub::disableNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + if (mIsTransactionPending) { + return Result::TRANSACTION_PENDING; + } + + hub_message_t msg; + + if (setOsAppAsDestination(&msg, hubId) == false) { + return Result::BAD_PARAMS; + } + + struct apps_disable_request_t req; + + msg.message_type = CONTEXT_HUB_APPS_DISABLE; + msg.message_len = sizeof(req); + req.app_name.id = appId; + msg.message = &req; + + if(mContextHubModule->send_message(hubId, &msg) != 0) { + return Result::TRANSACTION_FAILED; + } else { + mTransactionId = transactionId; + mIsTransactionPending = true; + return Result::OK; + } +} + +Return<Result> Contexthub::queryApps(uint32_t hubId) { + if (!isInitialized()) { + return Result::NOT_INIT; + } + + hub_message_t msg; + + if (setOsAppAsDestination(&msg, hubId) == false) { + ALOGW("Could not find hubId %" PRIu32, hubId); + return Result::BAD_PARAMS; + } + + query_apps_request_t payload; + payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter + msg.message = &payload; + msg.message_len = sizeof(payload); + msg.message_type = CONTEXT_HUB_QUERY_APPS; + + if(mContextHubModule->send_message(hubId, &msg) != 0) { + ALOGW("Query Apps sendMessage failed"); + return Result::TRANSACTION_FAILED; + } + + return Result::OK; +} + +bool Contexthub::isInitialized() { + return (mInitCheck == OK && mContextHubModule != nullptr); +} + +IContexthub *HIDL_FETCH_IContexthub(const char * halName) { + ALOGI("%s Called for %s", __FUNCTION__, halName); + Contexthub *contexthub = new Contexthub; + + if (!contexthub->isInitialized()) { + delete contexthub; + contexthub = nullptr; + } + + return contexthub; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace contexthub +} // namespace hardware +} // namespace android diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h new file mode 100644 index 000000000..0883ce821 --- /dev/null +++ b/contexthub/1.0/default/Contexthub.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_ +#define ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_ + +#include <unordered_map> + +#include <android/hardware/contexthub/1.0/IContexthub.h> +#include <hardware/context_hub.h> + +namespace android { +namespace hardware { +namespace contexthub { +namespace V1_0 { +namespace implementation { + +struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub { + Contexthub(); + + Return<void> getHubs(getHubs_cb _hidl_cb) override; + + Return<Result> registerCallback(uint32_t hubId, + const sp<IContexthubCallback> &cb) override; + + Return<Result> sendMessageToHub(uint32_t hubId, + const ContextHubMsg &msg) override; + + Return<Result> loadNanoApp(uint32_t hubId, + const ::android::hardware::hidl_vec<uint8_t>& appBinary, + uint32_t transactionId) override; + + Return<Result> unloadNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) override; + + Return<Result> enableNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) override; + + Return<Result> disableNanoApp(uint32_t hubId, + uint64_t appId, + uint32_t transactionId) override; + + Return<Result> queryApps(uint32_t hubId) override; + + Return<Result> reboot(uint32_t hubId); + + bool isInitialized(); + +private: + + struct CachedHubInformation{ + struct hub_app_name_t osAppName; + sp<IContexthubCallback> callBack; + }; + + status_t mInitCheck; + const struct context_hub_module_t *mContextHubModule; + std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo; + + sp<IContexthubCallback> mCb; + bool mIsTransactionPending; + uint32_t mTransactionId; + + bool isValidHubId(uint32_t hubId); + + sp<IContexthubCallback> getCallBackForHubId(uint32_t hubId); + + int handleOsMessage(sp<IContexthubCallback> cb, + uint32_t msgType, + const uint8_t *msg, + int msgLen); + + static int contextHubCb(uint32_t hubId, + const struct hub_message_t *rxMsg, + void *cookie); + + bool setOsAppAsDestination(hub_message_t *msg, int hubId); + + DISALLOW_COPY_AND_ASSIGN(Contexthub); +}; + +extern "C" IContexthub *HIDL_FETCH_IContexthub(const char *name); + +} // namespace implementation +} // namespace V1_0 +} // namespace contexthub +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_ diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc new file mode 100644 index 000000000..8dba85f5c --- /dev/null +++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc @@ -0,0 +1,4 @@ +service contexthub-hal-1-0 /system/bin/hw/android.hardware.contexthub@1.0-service + class hal + user system + group system diff --git a/contexthub/1.0/default/service.cpp b/contexthub/1.0/default/service.cpp new file mode 100644 index 000000000..db9a4e710 --- /dev/null +++ b/contexthub/1.0/default/service.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "android.hardware.contexthub@1.0-service" + +#include <android/hardware/contexthub/1.0/IContexthub.h> +#include <hidl/LegacySupport.h> + +using android::hardware::contexthub::V1_0::IContexthub; +using android::hardware::defaultPassthroughServiceImplementation; + +int main() { + return defaultPassthroughServiceImplementation<IContexthub>("context_hub"); +} |
