diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp index 4a6b3f278b..bf459005b4 100644 --- a/contexthub/1.0/default/Contexthub.cpp +++ b/contexthub/1.0/default/Contexthub.cpp @@ -38,6 +38,7 @@ static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF); Contexthub::Contexthub() : mInitCheck(NO_INIT), mContextHubModule(nullptr), + mDeathRecipient(new DeathRecipient(this)), mIsTransactionPending(false) { const hw_module_t *module; @@ -96,7 +97,7 @@ Return Contexthub::getHubs(getHubs_cb _hidl_cb) { c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw; c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw; - info.callBack = nullptr; + info.callback = nullptr; info.osAppName = hubArray[i].os_app_name; mCachedHubInfo[hubArray[i].hub_id] = info; @@ -110,6 +111,16 @@ Return Contexthub::getHubs(getHubs_cb _hidl_cb) { return Void(); } +Contexthub::DeathRecipient::DeathRecipient(sp contexthub) + : mContexthub(contexthub) {} + +void Contexthub::DeathRecipient::serviceDied( + uint64_t cookie, + const wp<::android::hidl::base::V1_0::IBase>& /*who*/) { + uint32_t hubId = static_cast(cookie); + mContexthub->handleServiceDeath(hubId); +} + bool Contexthub::isValidHubId(uint32_t hubId) { if (!mCachedHubInfo.count(hubId)) { ALOGW("Hub information not found for hubId %" PRIu32, hubId); @@ -123,7 +134,7 @@ sp Contexthub::getCallBackForHubId(uint32_t hubId) { if (!isValidHubId(hubId)) { return nullptr; } else { - return mCachedHubInfo[hubId].callBack; + return mCachedHubInfo[hubId].callback; } } @@ -193,8 +204,22 @@ Return Contexthub::registerCallback(uint32_t hubId, contextHubCb, this) == 0) { // Initialized && valid hub && subscription successful + if (mCachedHubInfo[hubId].callback != nullptr) { + ALOGD("Modifying callback for hubId %" PRIu32, hubId); + mCachedHubInfo[hubId].callback->unlinkToDeath(mDeathRecipient); + } + + mCachedHubInfo[hubId].callback = cb; + if (cb != nullptr) { + Return linkResult = cb->linkToDeath(mDeathRecipient, hubId); + bool linkSuccess = linkResult.isOk() ? + static_cast(linkResult) : false; + if (!linkSuccess) { + ALOGW("Couldn't link death recipient for hubId %" PRIu32, + hubId); + } + } 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 @@ -309,6 +334,16 @@ int Contexthub::handleOsMessage(sp cb, return retVal; } +void Contexthub::handleServiceDeath(uint32_t hubId) { + ALOGI("Callback/service died for hubId %" PRIu32, hubId); + int ret = mContextHubModule->subscribe_messages(hubId, nullptr, nullptr); + if (ret != 0) { + ALOGW("Failed to unregister callback from hubId %" PRIu32 ": %d", + hubId, ret); + } + mCachedHubInfo[hubId].callback.clear(); +} + int Contexthub::contextHubCb(uint32_t hubId, const struct hub_message_t *rxMsg, void *cookie) { diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h index 236e0798f2..db23ec2e63 100644 --- a/contexthub/1.0/default/Contexthub.h +++ b/contexthub/1.0/default/Contexthub.h @@ -65,14 +65,26 @@ private: struct CachedHubInformation{ struct hub_app_name_t osAppName; - sp callBack; + sp callback; + }; + + class DeathRecipient : public hidl_death_recipient { + public: + DeathRecipient(const sp contexthub); + + void serviceDied( + uint64_t cookie, + const wp<::android::hidl::base::V1_0::IBase>& who) override; + + private: + sp mContexthub; }; status_t mInitCheck; const struct context_hub_module_t *mContextHubModule; std::unordered_map mCachedHubInfo; - sp mCb; + sp mDeathRecipient; bool mIsTransactionPending; uint32_t mTransactionId; @@ -85,6 +97,9 @@ private: const uint8_t *msg, int msgLen); + // Handle the case where the callback registered for the given hub ID dies + void handleServiceDeath(uint32_t hubId); + static int contextHubCb(uint32_t hubId, const struct hub_message_t *rxMsg, void *cookie);