diff options
author | Wei Wang <wvw@google.com> | 2020-02-03 12:09:08 -0800 |
---|---|---|
committer | Wei Wang <wvw@google.com> | 2020-02-11 10:53:34 -0800 |
commit | e18c26251b791295ef0f0655a846f707898ec4c5 (patch) | |
tree | 589ec5f122c9831f3781acb31cd0f6e46219ac07 | |
parent | d5e027d22718d89f32a201c3eb545ba004682859 (diff) | |
download | audio-e18c26251b791295ef0f0655a846f707898ec4c5.tar.gz |
Support Power HAL AIDL service
Bug: 148798433
Test: Build
Change-Id: Ie14d90bf17faad68beb16a9916e2fab9627b1eb4
-rw-r--r-- | hal/Android.mk | 3 | ||||
-rw-r--r-- | hal/audio_perf.cpp | 257 | ||||
-rw-r--r-- | hal/audio_perf.h | 12 |
3 files changed, 199 insertions, 73 deletions
diff --git a/hal/Android.mk b/hal/Android.mk index afb0128..eb806be 100644 --- a/hal/Android.mk +++ b/hal/Android.mk @@ -226,6 +226,9 @@ endif LOCAL_SHARED_LIBRARIES += libbase libhidlbase libutils android.hardware.power@1.2 liblog +LOCAL_SHARED_LIBRARIES += android.hardware.power-ndk_platform +LOCAL_SHARED_LIBRARIES += libbinder_ndk + LOCAL_SRC_FILES += audio_perf.cpp LOCAL_HEADER_LIBRARIES += libhardware_headers diff --git a/hal/audio_perf.cpp b/hal/audio_perf.cpp index 671a324..4623f19 100644 --- a/hal/audio_perf.cpp +++ b/hal/audio_perf.cpp @@ -22,95 +22,216 @@ #include <utils/Mutex.h> #include <android/hardware/power/1.2/IPower.h> +#include <aidl/android/hardware/power/Boost.h> +#include <aidl/android/hardware/power/IPower.h> +#include <aidl/android/hardware/power/Mode.h> +#include <android/binder_manager.h> #include "audio_perf.h" -using android::hardware::power::V1_2::IPower; -using android::hardware::power::V1_2::PowerHint; -using android::hardware::power::V1_2::toString; -using android::hardware::Return; -using android::hardware::Void; -using android::hardware::hidl_death_recipient; -using android::hidl::base::V1_0::IBase; - -// Do not use gPowerHAL, use getPowerHal to retrieve a copy instead -static android::sp<IPower> gPowerHal_ = nullptr; -// Protect gPowerHal_ +// Protect gPowerHal_1_2_ and gPowerHal_Aidl_ +static android::sp<android::hardware::power::V1_2::IPower> gPowerHal_1_2_; +static std::shared_ptr<aidl::android::hardware::power::IPower> gPowerHal_Aidl_; static std::mutex gPowerHalMutex; +static constexpr int kDefaultBoostDurationMs = 2000; +static constexpr int kBoostOff = -1; -// PowerHalDeathRecipient to invalid the client when service dies -struct PowerHalDeathRecipient : virtual public hidl_death_recipient { - // hidl_death_recipient interface - virtual void serviceDied(uint64_t, const android::wp<IBase>&) override { - std::lock_guard<std::mutex> lock(gPowerHalMutex); - ALOGE("PowerHAL just died"); - gPowerHal_ = nullptr; - } +static const std::string kInstance = + std::string(aidl::android::hardware::power::IPower::descriptor) + "/default"; + +enum hal_version { + NONE, + HIDL_1_2, + AIDL, }; -// Retrieve a copy of client -static android::sp<IPower> getPowerHal() { - std::lock_guard<std::mutex> lock(gPowerHalMutex); - static android::sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr; - static bool gPowerHalExists = true; +// Connnect PowerHAL +static hal_version connectPowerHalLocked() { + static bool gPowerHalHidlExists = true; + static bool gPowerHalAidlExists = true; - if (gPowerHalExists && gPowerHal_ == nullptr) { - gPowerHal_ = IPower::getService(); + if (!gPowerHalHidlExists && !gPowerHalAidlExists) { + return NONE; + } - if (gPowerHal_ == nullptr) { - ALOGE("Unable to get Power service"); - gPowerHalExists = false; + if (gPowerHalAidlExists) { + // (re)connect if handle is null + if (!gPowerHal_Aidl_) { + ndk::SpAIBinder pwBinder = ndk::SpAIBinder( + AServiceManager_getService(kInstance.c_str())); + gPowerHal_Aidl_ = aidl::android::hardware::power::IPower::fromBinder(pwBinder); + } + if (gPowerHal_Aidl_) { + ALOGI("Successfully connected to Power Hal Aidl service."); + return AIDL; } else { - if (gPowerHalDeathRecipient == nullptr) { - gPowerHalDeathRecipient = new PowerHalDeathRecipient(); - } - Return<bool> linked = gPowerHal_->linkToDeath( - gPowerHalDeathRecipient, 0 /* cookie */); - if (!linked.isOk()) { - ALOGE("Transaction error in linking to PowerHAL death: %s", - linked.description().c_str()); - gPowerHal_ = nullptr; - } else if (!linked) { - ALOGW("Unable to link to PowerHal death notifications"); - gPowerHal_ = nullptr; - } else { - ALOGD("Connect to PowerHAL and link to death " - "notification successfully"); - } + // no more try on this handle + gPowerHalAidlExists = false; } } - return gPowerHal_; -} -static bool powerHint(PowerHint hint, int32_t data) { - android::sp<IPower> powerHal = getPowerHal(); - if (powerHal == nullptr) { - return false; + if (gPowerHalHidlExists) { + // (re)connect if handle is null + if (!gPowerHal_1_2_) { + gPowerHal_1_2_ = + android::hardware::power::V1_2::IPower::getService(); + } + if (gPowerHal_1_2_) { + ALOGI("Successfully connected to Power Hal Hidl service."); + return HIDL_1_2; + } else { + // no more try on this handle + gPowerHalHidlExists = false; + } } - auto ret = powerHal->powerHintAsync_1_2(hint, data); - - if (!ret.isOk()) { - ALOGE("powerHint failed, hint: %s, data: %" PRId32 ", error: %s", - toString(hint).c_str(), - data, - ret.description().c_str()); - } - return ret.isOk(); + return NONE; } -int audio_streaming_hint_start() { - return powerHint(PowerHint::AUDIO_STREAMING, 1); +bool audio_streaming_hint_start() { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + switch(connectPowerHalLocked()) { + case NONE: + return false; + case HIDL_1_2: + { + auto ret = gPowerHal_1_2_->powerHintAsync_1_2( + android::hardware::power::V1_2::PowerHint::AUDIO_STREAMING, + 1); + if (!ret.isOk()) { + ALOGE("powerHint failed, error: %s", + ret.description().c_str()); + gPowerHal_1_2_ = nullptr; + return false; + } + return true; + } + case AIDL: + { + auto ret = gPowerHal_Aidl_->setBoost( + aidl::android::hardware::power::Boost::AUDIO_LAUNCH, + kDefaultBoostDurationMs); + if (!ret.isOk()) { + std::string err = ret.getDescription(); + ALOGE("Failed to set power hint. Error: %s", err.c_str()); + gPowerHal_Aidl_ = nullptr; + return false; + } + return true; + } + default: + ALOGE("Unknown HAL state"); + return false; + } } -int audio_streaming_hint_end() { - return powerHint(PowerHint::AUDIO_STREAMING, 0); +bool audio_streaming_hint_end() { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + switch(connectPowerHalLocked()) { + case NONE: + return false; + case HIDL_1_2: + { + auto ret = gPowerHal_1_2_->powerHintAsync_1_2( + android::hardware::power::V1_2::PowerHint::AUDIO_STREAMING, + 0); + if (!ret.isOk()) { + ALOGE("powerHint failed, error: %s", + ret.description().c_str()); + gPowerHal_1_2_ = nullptr; + return false; + } + return true; + } + case AIDL: + { + auto ret = gPowerHal_Aidl_->setBoost( + aidl::android::hardware::power::Boost::AUDIO_LAUNCH, + kBoostOff); + if (!ret.isOk()) { + std::string err = ret.getDescription(); + ALOGE("Failed to set power hint. Error: %s", err.c_str()); + gPowerHal_Aidl_ = nullptr; + return false; + } + return true; + } + default: + ALOGE("Unknown HAL state"); + return false; + } } -int audio_low_latency_hint_start() { - return powerHint(PowerHint::AUDIO_LOW_LATENCY, 1); +bool audio_low_latency_hint_start() { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + switch(connectPowerHalLocked()) { + case NONE: + return false; + case HIDL_1_2: + { + auto ret = gPowerHal_1_2_->powerHintAsync_1_2( + android::hardware::power::V1_2::PowerHint::AUDIO_LOW_LATENCY, + 1); + if (!ret.isOk()) { + ALOGE("powerHint failed, error: %s", + ret.description().c_str()); + gPowerHal_1_2_ = nullptr; + return false; + } + return true; + } + case AIDL: + { + auto ret = gPowerHal_Aidl_->setMode( + aidl::android::hardware::power::Mode::AUDIO_STREAMING_LOW_LATENCY, + true); + if (!ret.isOk()) { + std::string err = ret.getDescription(); + ALOGE("Failed to set power hint. Error: %s", err.c_str()); + gPowerHal_Aidl_ = nullptr; + return false; + } + return true; + } + default: + ALOGE("Unknown HAL state"); + return false; + } } -int audio_low_latency_hint_end() { - return powerHint(PowerHint::AUDIO_LOW_LATENCY, 0); +bool audio_low_latency_hint_end() { + std::lock_guard<std::mutex> lock(gPowerHalMutex); + switch(connectPowerHalLocked()) { + case NONE: + return false; + case HIDL_1_2: + { + auto ret = gPowerHal_1_2_->powerHintAsync_1_2( + android::hardware::power::V1_2::PowerHint::AUDIO_LOW_LATENCY, + 0); + if (!ret.isOk()) { + ALOGE("powerHint failed, error: %s", + ret.description().c_str()); + gPowerHal_1_2_ = nullptr; + return false; + } + return true; + } + case AIDL: + { + auto ret = gPowerHal_Aidl_->setMode( + aidl::android::hardware::power::Mode::AUDIO_STREAMING_LOW_LATENCY, + false); + if (!ret.isOk()) { + std::string err = ret.getDescription(); + ALOGE("Failed to set power hint. Error: %s", err.c_str()); + gPowerHal_Aidl_ = nullptr; + return false; + } + return true; + } + default: + ALOGE("Unknown HAL state"); + return false; + } } diff --git a/hal/audio_perf.h b/hal/audio_perf.h index b564938..2fa1160 100644 --- a/hal/audio_perf.h +++ b/hal/audio_perf.h @@ -17,15 +17,17 @@ #ifndef __QAUDIOPERF_H__ #define __QAUDIOPERF_H__ +#include <stdbool.h> + #ifdef __cplusplus extern "C" { #endif -int audio_streaming_hint_start(); -int audio_streaming_hint_end(); - -int audio_low_latency_hint_start(); -int audio_low_latency_hint_end(); +// return true on success, false on failure +bool audio_streaming_hint_start(); +bool audio_streaming_hint_end(); +bool audio_low_latency_hint_start(); +bool audio_low_latency_hint_end(); #ifdef __cplusplus } |