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

Commit 2e5a23c8 authored by Tomasz Wasilczyk's avatar Tomasz Wasilczyk
Browse files

Implement HAL death monitoring.

Bug: b/36863239
Test: one-off integration test (not committed)
Change-Id: I4f6d5b559d14c7f7eb4756cce00908722b0169ec
parent e8f4b34b
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -107,10 +107,15 @@ void NativeCallbackThread::stop() {
        mQueueCond.signal();
    }

    if (pthread_self() == mThread) {
        // you can't self-join a thread, but it's ok when calling from our sub-task
        ALOGD("About to stop native callback thread %p", this);
    } else {
        auto ret = pthread_join(mThread, nullptr);
        ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);

        ALOGD("Stopped native callback thread %p", this);
    }
}

} // namespace android
+33 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ namespace radio {
namespace Tuner {

using hardware::Return;
using hardware::hidl_death_recipient;
using hardware::hidl_vec;

namespace V1_0 = hardware::broadcastradio::V1_0;
@@ -63,6 +64,15 @@ static struct {

static const char* const kAudioDeviceName = "Radio tuner source";

class HalDeathRecipient : public hidl_death_recipient {
    wp<V1_1::ITunerCallback> mTunerCallback;

public:
    HalDeathRecipient(wp<V1_1::ITunerCallback> tunerCallback):mTunerCallback(tunerCallback) {}

    virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who);
};

struct TunerContext {
    TunerContext() {}

@@ -71,6 +81,7 @@ struct TunerContext {
    bool mWithAudio;
    sp<V1_0::ITuner> mHalTuner;
    sp<V1_1::ITuner> mHalTuner11;
    sp<HalDeathRecipient> mHalDeathRecipient;

private:
    DISALLOW_COPY_AND_ASSIGN(TunerContext);
@@ -109,6 +120,16 @@ static void nativeFinalize(JNIEnv *env, jobject obj, jlong nativeContext) {
    delete ctx;
}

void HalDeathRecipient::serviceDied(uint64_t cookie __unused,
        const wp<hidl::base::V1_0::IBase>& who __unused) {
    ALOGW("HAL Tuner died unexpectedly");

    auto tunerCallback = mTunerCallback.promote();
    if (tunerCallback == nullptr) return;

    tunerCallback->hardwareFailure();
}

// TODO(b/62713378): implement support for multiple tuners open at the same time
static void notifyAudioService(TunerContext& ctx, bool connected) {
    if (!ctx.mWithAudio) return;
@@ -133,12 +154,19 @@ void setHalTuner(JNIEnv *env, JavaRef<jobject> const &jTuner, sp<V1_0::ITuner> h
        // dropping the last reference will close HAL tuner
        return;
    }
    if (ctx.mHalTuner != nullptr) {
        ALOGE("HAL tuner is already set.");
        return;
    }

    ctx.mHalTuner = halTuner;
    ctx.mHalTuner11 = V1_1::ITuner::castFrom(halTuner).withDefault(nullptr);
    ALOGW_IF(ctx.mHalRev >= HalRevision::V1_1 && ctx.mHalTuner11 == nullptr,
            "Provided tuner does not implement 1.1 HAL");

    ctx.mHalDeathRecipient = new HalDeathRecipient(getNativeCallback(env, jTuner));
    halTuner->linkToDeath(ctx.mHalDeathRecipient, 0);

    notifyAudioService(ctx, true);
}

@@ -175,7 +203,12 @@ static void nativeClose(JNIEnv *env, jobject obj, jlong nativeContext) {
    }

    ALOGI("Closing tuner %p", ctx.mHalTuner.get());

    notifyAudioService(ctx, false);

    ctx.mHalTuner->unlinkToDeath(ctx.mHalDeathRecipient);
    ctx.mHalDeathRecipient = nullptr;

    ctx.mHalTuner11 = nullptr;
    ctx.mHalTuner = nullptr;
}