/*
* Copyright 2018 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.
*/
#undef LOG_TAG
#define LOG_TAG "PowerAdvisor"
#include <cinttypes>
#include <utils/Log.h>
#include <utils/Mutex.h>
#include "PowerAdvisor.h"
namespace android {
namespace Hwc2 {
PowerAdvisor::~PowerAdvisor() = default;
namespace impl {
namespace V1_0 = android::hardware::power::V1_0;
using V1_3::PowerHint;
PowerAdvisor::~PowerAdvisor() = default;
PowerAdvisor::PowerAdvisor() = default;
void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expected) {
if (expected) {
mExpensiveDisplays.insert(displayId);
} else {
mExpensiveDisplays.erase(displayId);
}
const bool expectsExpensiveRendering = !mExpensiveDisplays.empty();
if (mNotifiedExpensiveRendering != expectsExpensiveRendering) {
const sp<V1_3::IPower> powerHal = getPowerHal();
if (powerHal == nullptr) {
return;
}
auto ret = powerHal->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING,
expectsExpensiveRendering);
// If Power HAL 1.3 was available previously but now fails,
// it may restart, so attempt to reconnect next time
if (!ret.isOk()) {
mReconnectPowerHal = true;
return;
}
mNotifiedExpensiveRendering = expectsExpensiveRendering;
}
}
sp<V1_3::IPower> PowerAdvisor::getPowerHal() {
static sp<V1_3::IPower> sPowerHal_1_3 = nullptr;
static bool sHasPowerHal_1_3 = true;
if (mReconnectPowerHal) {
sPowerHal_1_3 = nullptr;
mReconnectPowerHal = false;
}
// Power HAL 1.3 is not guaranteed to be available, thus we need to query
// Power HAL 1.0 first and try to cast it to Power HAL 1.3.
// Power HAL 1.0 is always available, thus if we fail to query it, it means
// Power HAL is not available temporarily and we should retry later. However,
// if Power HAL 1.0 is available and we can't cast it to Power HAL 1.3,
// it means Power HAL 1.3 is not available at all, so we should stop trying.
if (sHasPowerHal_1_3 && sPowerHal_1_3 == nullptr) {
sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService();
if (powerHal_1_0 != nullptr) {
// Try to cast to Power HAL 1.3
sPowerHal_1_3 = V1_3::IPower::castFrom(powerHal_1_0);
if (sPowerHal_1_3 == nullptr) {
ALOGW("No Power HAL 1.3 service in system");
sHasPowerHal_1_3 = false;
} else {
ALOGI("Loaded Power HAL 1.3 service");
}
}
}
return sPowerHal_1_3;
}
} // namespace impl
} // namespace Hwc2
} // namespace android