Merge "contexthub: Handle service death" into oc-dev
diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp
index 4a6b3f2..bf45900 100644
--- a/contexthub/1.0/default/Contexthub.cpp
+++ b/contexthub/1.0/default/Contexthub.cpp
@@ -38,6 +38,7 @@
Contexthub::Contexthub()
: mInitCheck(NO_INIT),
mContextHubModule(nullptr),
+ mDeathRecipient(new DeathRecipient(this)),
mIsTransactionPending(false) {
const hw_module_t *module;
@@ -96,7 +97,7 @@
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 Void();
}
+Contexthub::DeathRecipient::DeathRecipient(sp<Contexthub> contexthub)
+ : mContexthub(contexthub) {}
+
+void Contexthub::DeathRecipient::serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ uint32_t hubId = static_cast<uint32_t>(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 @@
if (!isValidHubId(hubId)) {
return nullptr;
} else {
- return mCachedHubInfo[hubId].callBack;
+ return mCachedHubInfo[hubId].callback;
}
}
@@ -193,8 +204,22 @@
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<bool> linkResult = cb->linkToDeath(mDeathRecipient, hubId);
+ bool linkSuccess = linkResult.isOk() ?
+ static_cast<bool>(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 @@
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 236e079..db23ec2 100644
--- a/contexthub/1.0/default/Contexthub.h
+++ b/contexthub/1.0/default/Contexthub.h
@@ -65,14 +65,26 @@
struct CachedHubInformation{
struct hub_app_name_t osAppName;
- sp<IContexthubCallback> callBack;
+ sp<IContexthubCallback> callback;
+ };
+
+ class DeathRecipient : public hidl_death_recipient {
+ public:
+ DeathRecipient(const sp<Contexthub> contexthub);
+
+ void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who) override;
+
+ private:
+ sp<Contexthub> mContexthub;
};
status_t mInitCheck;
const struct context_hub_module_t *mContextHubModule;
std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo;
- sp<IContexthubCallback> mCb;
+ sp<DeathRecipient> mDeathRecipient;
bool mIsTransactionPending;
uint32_t mTransactionId;
@@ -85,6 +97,9 @@
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);