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 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 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 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 102 int audio_streaming_hint_start() { 103 return powerHint(PowerHint::AUDIO_STREAMING, 1); 104 } 105 106 int audio_streaming_hint_end() { 107 return powerHint(PowerHint::AUDIO_STREAMING, 0); 108 } 109 110 int audio_low_latency_hint_start() { 111 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 1); 112 } 113 114 int audio_low_latency_hint_end() { 115 return powerHint(PowerHint::AUDIO_LOW_LATENCY, 0); 116 } 117