Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 154b0883 authored by Brian Duddie's avatar Brian Duddie
Browse files

contexthub: Handle service death

Register for notification of service death for callbacks registered with
the context hub HAL. Upon this notification, unregister the callback to
avoid crashing if an event occurs prior to the service coming back up.

Bug: 36202367
Test: adb shell stop, confirm death notification received via log;
  vts-tradefed run commandAndExit vts --module VtsHalContexthubV1_0Target
Change-Id: I3c25229806cb9f2a116007939c752841edbf0985
parent 827e2910
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -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<void> 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<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
    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 @@ sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
    if (!isValidHubId(hubId)) {
        return nullptr;
    } else {
        return mCachedHubInfo[hubId].callBack;
        return mCachedHubInfo[hubId].callback;
    }
}

@@ -193,8 +204,22 @@ Return<Result> 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<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 @@ int Contexthub::handleOsMessage(sp<IContexthubCallback> 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) {
+17 −2
Original line number Diff line number Diff line
@@ -65,14 +65,26 @@ private:

    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 @@ 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);