1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "audio_hw_primary"
18
19 #include <cinttypes>
20
21 #include <utils/Log.h>
22 #include <utils/Mutex.h>
23
24 #include <android/hardware/power/1.2/IPower.h>
25
26 #include "audio_perf.h"
27
28 using android::hardware::power::V1_2::IPower;
29 using android::hardware::power::V1_2::PowerHint;
30 using android::hardware::power::V1_2::toString;
31 using android::hardware::Return;
32 using android::hardware::Void;
33 using android::hardware::hidl_death_recipient;
34 using android::hidl::base::V1_0::IBase;
35
36 // Do not use gPowerHAL, use getPowerHal to retrieve a copy instead
37 static android::sp<IPower> gPowerHal_ = nullptr;
38 // Protect gPowerHal_
39 static std::mutex gPowerHalMutex;
40
41 // PowerHalDeathRecipient to invalid the client when service dies
42 struct PowerHalDeathRecipient : virtual public hidl_death_recipient {
43 // hidl_death_recipient interface
serviceDiedPowerHalDeathRecipient44 virtual void serviceDied(uint64_t, const android::wp<IBase>&) override {
45 std::lock_guard<std::mutex> lock(gPowerHalMutex);
46 ALOGE("PowerHAL just died");
47 gPowerHal_ = nullptr;
48 }
49 };
50
51 // Retrieve a copy of client
getPowerHal()52 static android::sp<IPower> getPowerHal() {
53 std::lock_guard<std::mutex> lock(gPowerHalMutex);
54 static android::sp<PowerHalDeathRecipient> gPowerHalDeathRecipient = nullptr;
55 static bool gPowerHalExists = true;
56
57 if (gPowerHalExists && gPowerHal_ == nullptr) {
58 gPowerHal_ = IPower::getService();
59
60 if (gPowerHal_ == nullptr) {
61 ALOGE("Unable to get Power service");
62 gPowerHalExists = false;
63 } else {
64 if (gPowerHalDeathRecipient == nullptr) {
65 gPowerHalDeathRecipient = new PowerHalDeathRecipient();
66 }
67 Return<bool> linked = gPowerHal_->linkToDeath(
68 gPowerHalDeathRecipient, 0 /* cookie */);
69 if (!linked.isOk()) {
70 ALOGE("Transaction error in linking to PowerHAL death: %s",
71 linked.description().c_str());
72 gPowerHal_ = nullptr;
73 } else if (!linked) {
74 ALOGW("Unable to link to PowerHal death notifications");
75 gPowerHal_ = nullptr;
76 } else {
77 ALOGD("Connect to PowerHAL and link to death "
78 "notification successfully");
79 }
80 }
81 }
82 return gPowerHal_;
83 }
84
powerHint(PowerHint hint,int32_t data)85 static bool powerHint(PowerHint hint, int32_t data) {
86 android::sp<IPower> powerHal = getPowerHal();
87 if (powerHal == nullptr) {
88 return false;
89 }
90
91 auto ret = powerHal->powerHintAsync_1_2(hint, data);
92
93 if (!ret.isOk()) {
94 ALOGE("powerHint failed, hint: %s, data: %" PRId32 ", error: %s",
95 toString(hint).c_str(),
96 data,
97 ret.description().c_str());
98 }
99 return ret.isOk();
100 }
101
audio_streaming_hint_start()102 int audio_streaming_hint_start() {
103 return powerHint(PowerHint::AUDIO_STREAMING, 1);
104 }
105
audio_streaming_hint_end()106 int audio_streaming_hint_end() {
107 return powerHint(PowerHint::AUDIO_STREAMING, 0);
108 }
109
audio_low_latency_hint_start()110 int audio_low_latency_hint_start() {
111 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 1);
112 }
113
audio_low_latency_hint_end()114 int audio_low_latency_hint_end() {
115 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 0);
116 }
117