audio-hal: use powerHAL 1.2 to do performance hint
1) Add PowerHAL 1.2 client
2) call PowerHAL powerhint on msm8998 instead of perfd
Test: Play audio and see powerhint handled
Bug: 62041945
Change-Id: I33ab8eaa7a3a3a953fb6531e0864b4ed62387ba2
diff --git a/hal/audio_perf.cpp b/hal/audio_perf.cpp
new file mode 100644
index 0000000..671a324
--- /dev/null
+++ b/hal/audio_perf.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "audio_hw_primary"
+
+#include <cinttypes>
+
+#include <utils/Log.h>
+#include <utils/Mutex.h>
+
+#include <android/hardware/power/1.2/IPower.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_
+static std::mutex gPowerHalMutex;
+
+// 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;
+ }
+};
+
+// 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;
+
+ if (gPowerHalExists && gPowerHal_ == nullptr) {
+ gPowerHal_ = IPower::getService();
+
+ if (gPowerHal_ == nullptr) {
+ ALOGE("Unable to get Power service");
+ gPowerHalExists = false;
+ } 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");
+ }
+ }
+ }
+ return gPowerHal_;
+}
+
+static bool powerHint(PowerHint hint, int32_t data) {
+ android::sp<IPower> powerHal = getPowerHal();
+ if (powerHal == nullptr) {
+ return 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();
+}
+
+int audio_streaming_hint_start() {
+ return powerHint(PowerHint::AUDIO_STREAMING, 1);
+}
+
+int audio_streaming_hint_end() {
+ return powerHint(PowerHint::AUDIO_STREAMING, 0);
+}
+
+int audio_low_latency_hint_start() {
+ return powerHint(PowerHint::AUDIO_LOW_LATENCY, 1);
+}
+
+int audio_low_latency_hint_end() {
+ return powerHint(PowerHint::AUDIO_LOW_LATENCY, 0);
+}