blob: 671a324eb0a3e3308e0ed0514940d38f37e36ccf [file] [log] [blame]
Wei Wangf7ca6c92017-11-21 14:51:20 -08001/*
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
28using android::hardware::power::V1_2::IPower;
29using android::hardware::power::V1_2::PowerHint;
30using android::hardware::power::V1_2::toString;
31using android::hardware::Return;
32using android::hardware::Void;
33using android::hardware::hidl_death_recipient;
34using android::hidl::base::V1_0::IBase;
35
36// Do not use gPowerHAL, use getPowerHal to retrieve a copy instead
37static android::sp<IPower> gPowerHal_ = nullptr;
38// Protect gPowerHal_
39static std::mutex gPowerHalMutex;
40
41// PowerHalDeathRecipient to invalid the client when service dies
42struct PowerHalDeathRecipient : virtual public hidl_death_recipient {
43 // hidl_death_recipient interface
44 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
52static 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
85static 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
102int audio_streaming_hint_start() {
103 return powerHint(PowerHint::AUDIO_STREAMING, 1);
104}
105
106int audio_streaming_hint_end() {
107 return powerHint(PowerHint::AUDIO_STREAMING, 0);
108}
109
110int audio_low_latency_hint_start() {
111 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 1);
112}
113
114int audio_low_latency_hint_end() {
115 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 0);
116}