Implement HAL death monitoring.

Bug: b/36863239
Test: one-off integration test (not committed)
Change-Id: I4f6d5b559d14c7f7eb4756cce00908722b0169ec
This commit is contained in:
Tomasz Wasilczyk
2017-06-19 14:47:03 -07:00
parent e8f4b34bee
commit 2e5a23c86e
2 changed files with 41 additions and 3 deletions

View File

@@ -107,10 +107,15 @@ void NativeCallbackThread::stop() {
mQueueCond.signal();
}
auto ret = pthread_join(mThread, nullptr);
ALOGE_IF(ret != 0, "Couldn't join thread: %d", ret);
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);
ALOGD("Stopped native callback thread %p", this);
}
}
} // namespace android

View File

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