Home | History | Annotate | Download | only in hal
      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