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
(cherry picked from commit f4837d5bbe73df6f33aee2d0f733f72cc635de6a)
diff --git a/hal/Android.mk b/hal/Android.mk
index a6bd9bc..85a58bf 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -5,6 +5,20 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := libqcaudioperf
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+LOCAL_SHARED_LIBRARIES += libbase libhidlbase libhwbinder libutils android.hardware.power@1.2 liblog
+LOCAL_SRC_FILES := audio_perf.cpp
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_OWNER := qti
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
 LOCAL_ARM_MODE := arm
 
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
@@ -344,6 +358,7 @@
 #    LOCAL_CFLAGS += -DAUDIO_EXTN_AUTO_HAL_ENABLED
 #    LOCAL_SRC_FILES += audio_extn/auto_hal.c
 #endif
+LOCAL_SHARED_LIBRARIES += libqcaudioperf
 
 LOCAL_MODULE := audio.primary.$(TARGET_BOARD_PLATFORM)
 
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 41a3d5d..59b0072 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -69,6 +69,7 @@
 #include <audio_effects/effect_ns.h>
 #include <audio_utils/format.h>
 #include "audio_hw.h"
+#include "audio_perf.h"
 #include "platform_api.h"
 #include <platform.h>
 #include "audio_extn.h"
@@ -2706,6 +2707,7 @@
     uc_info->out_snd_device = SND_DEVICE_NONE;
 
     list_add_tail(&adev->usecase_list, &uc_info->list);
+    audio_streaming_hint_start();
     audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
                                  adev->perf_lock_opts,
                                  adev->perf_lock_opts_size);
@@ -2808,14 +2810,17 @@
     audio_extn_audiozoom_set_microphone_field_dimension(in, in->direction);
 
 done_open:
+    audio_streaming_hint_end();
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
     enable_gcov();
     return ret;
 
 error_open:
+    audio_streaming_hint_end();
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_input_stream(in);
+
 error_config:
     adev->active_input = get_next_active_input(adev);
     /*
@@ -3369,6 +3374,7 @@
 
     list_add_tail(&adev->usecase_list, &uc_info->list);
 
+    audio_streaming_hint_start();
     audio_extn_perf_lock_acquire(&adev->perf_lock_handle, 0,
                                  adev->perf_lock_opts,
                                  adev->perf_lock_opts_size);
@@ -3562,7 +3568,7 @@
                 goto error_open;
         }
     }
-
+    audio_streaming_hint_end();
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     ALOGD("%s: exit", __func__);
 
@@ -3587,6 +3593,7 @@
         pcm_close(adev->haptic_pcm);
         adev->haptic_pcm = NULL;
     }
+    audio_streaming_hint_end();
     audio_extn_perf_lock_release(&adev->perf_lock_handle);
     stop_output_stream(out);
 error_config:
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);
+}
diff --git a/hal/audio_perf.h b/hal/audio_perf.h
new file mode 100644
index 0000000..05c3036
--- /dev/null
+++ b/hal/audio_perf.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef __QAUDIOPERF_H__
+#define __QAUDIOPERF_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();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__QAUDIOPERF_H___