0b7c652553
Bug: b/269370789 Test: m Change-Id: I67d035271c177dfee88ac7272baa7cc9cdef3e00
305 lines
11 KiB
C++
305 lines
11 KiB
C++
/*
|
|
* Copyright (C) 2023 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.
|
|
*/
|
|
|
|
#include "include/thermalutils/ThermalHidlWrapper.h"
|
|
|
|
#include <hidl/HidlTransportSupport.h>
|
|
|
|
#include <cmath>
|
|
|
|
namespace aidl {
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace thermal {
|
|
|
|
using ::android::hardware::Void;
|
|
|
|
namespace {
|
|
|
|
template <typename T, typename U>
|
|
Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
|
|
ThermalStatus status;
|
|
status.code = ThermalStatusCode::FAILURE;
|
|
status.debugMessage = debug_msg.data();
|
|
_hidl_cb(status, data);
|
|
return Void();
|
|
}
|
|
|
|
template <typename T>
|
|
Return<void> setFailureAndCallback(T _hidl_cb, std::string_view debug_msg) {
|
|
ThermalStatus status;
|
|
status.code = ThermalStatusCode::FAILURE;
|
|
status.debugMessage = debug_msg.data();
|
|
_hidl_cb(status);
|
|
return Void();
|
|
}
|
|
|
|
template <typename T, typename U>
|
|
Return<void> setInitFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
|
|
return setFailureAndCallback(
|
|
_hidl_cb, data, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
|
|
}
|
|
|
|
template <typename T>
|
|
Return<void> setInitFailureAndCallback(T _hidl_cb) {
|
|
return setFailureAndCallback(
|
|
_hidl_cb, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
|
|
}
|
|
|
|
template <typename T, typename U>
|
|
Return<void> setUnsupportedFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
|
|
return setFailureAndCallback(_hidl_cb, data, "Operation unsupported by Thermal HIDL wrapper");
|
|
}
|
|
|
|
TemperatureType_2_0 convertAidlTemperatureType(const TemperatureType& type) {
|
|
if (type < TemperatureType::CPU || type > TemperatureType::NPU) {
|
|
return TemperatureType_2_0::UNKNOWN;
|
|
}
|
|
return static_cast<TemperatureType_2_0>(type);
|
|
}
|
|
|
|
CoolingType_2_0 convertAidlCoolingType(const CoolingType& type) {
|
|
if (type < CoolingType::FAN || type > CoolingType::COMPONENT) {
|
|
return CoolingType_2_0::COMPONENT;
|
|
}
|
|
return static_cast<CoolingType_2_0>(type);
|
|
}
|
|
|
|
Temperature_2_0 convertAidlTemperature(const Temperature& temperature) {
|
|
Temperature_2_0 t = Temperature_2_0{
|
|
convertAidlTemperatureType(temperature.type), temperature.name, temperature.value,
|
|
static_cast<ThrottlingSeverity_2_0>(temperature.throttlingStatus)};
|
|
return t;
|
|
}
|
|
|
|
CoolingDevice_2_0 convertAidlCoolingDevice(const CoolingDevice& cooling_device) {
|
|
CoolingDevice_2_0 t =
|
|
CoolingDevice_2_0{convertAidlCoolingType(cooling_device.type), cooling_device.name,
|
|
static_cast<uint64_t>(cooling_device.value)};
|
|
return t;
|
|
}
|
|
TemperatureThreshold_2_0 convertAidlTemperatureThreshold(const TemperatureThreshold& threshold) {
|
|
TemperatureThreshold_2_0 t =
|
|
TemperatureThreshold_2_0{convertAidlTemperatureType(threshold.type), threshold.name,
|
|
threshold.hotThrottlingThresholds.data(),
|
|
threshold.coldThrottlingThresholds.data(), NAN};
|
|
return t;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Methods from ::android::hardware::thermal::V1_0::IThermal follow.
|
|
Return<void> ThermalHidlWrapper::getTemperatures(getTemperatures_cb _hidl_cb) {
|
|
hidl_vec<Temperature_1_0> ret_1_0;
|
|
setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::getCpuUsages(
|
|
std::function<void(const ThermalStatus&, const hidl_vec<CpuUsage>&)> _hidl_cb) {
|
|
hidl_vec<CpuUsage> ret_1_0;
|
|
setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::getCoolingDevices(
|
|
std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_1_0>&)> _hidl_cb) {
|
|
hidl_vec<CoolingDevice_1_0> ret_1_0;
|
|
setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
|
|
return Void();
|
|
}
|
|
|
|
// Methods from ::android::hardware::thermal::V2_0::IThermal follow.
|
|
Return<void> ThermalHidlWrapper::getCurrentTemperatures(
|
|
bool filterType, TemperatureType_2_0 type,
|
|
std::function<void(const ThermalStatus&, const hidl_vec<Temperature_2_0>&)> _hidl_cb) {
|
|
hidl_vec<Temperature_2_0> ret_2_0;
|
|
if (!thermal_service_) {
|
|
setInitFailureAndCallback(_hidl_cb, ret_2_0);
|
|
}
|
|
|
|
std::vector<Temperature> ret_aidl;
|
|
ThermalStatus status;
|
|
::ndk::ScopedAStatus a_status;
|
|
if (filterType) {
|
|
a_status = thermal_service_->getTemperaturesWithType(static_cast<TemperatureType>(type),
|
|
&ret_aidl);
|
|
} else {
|
|
a_status = thermal_service_->getTemperatures(&ret_aidl);
|
|
}
|
|
if (a_status.isOk()) {
|
|
std::vector<Temperature_2_0> ret;
|
|
for (const auto& temperature : ret_aidl) {
|
|
ret.push_back(convertAidlTemperature(temperature));
|
|
}
|
|
_hidl_cb(status, hidl_vec<Temperature_2_0>(ret));
|
|
} else {
|
|
setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::getTemperatureThresholds(
|
|
bool filterType, TemperatureType_2_0 type,
|
|
std::function<void(const ThermalStatus&, const hidl_vec<TemperatureThreshold_2_0>&)>
|
|
_hidl_cb) {
|
|
hidl_vec<TemperatureThreshold_2_0> ret_2_0;
|
|
if (!thermal_service_) {
|
|
setInitFailureAndCallback(_hidl_cb, ret_2_0);
|
|
}
|
|
|
|
std::vector<TemperatureThreshold> ret_aidl;
|
|
ThermalStatus status;
|
|
::ndk::ScopedAStatus a_status;
|
|
if (filterType) {
|
|
a_status = thermal_service_->getTemperatureThresholdsWithType(
|
|
static_cast<TemperatureType>(type), &ret_aidl);
|
|
} else {
|
|
a_status = thermal_service_->getTemperatureThresholds(&ret_aidl);
|
|
}
|
|
if (a_status.isOk()) {
|
|
std::vector<TemperatureThreshold_2_0> ret;
|
|
for (const auto& threshold : ret_aidl) {
|
|
ret.push_back(convertAidlTemperatureThreshold(threshold));
|
|
}
|
|
_hidl_cb(status, hidl_vec<TemperatureThreshold_2_0>(ret));
|
|
} else {
|
|
setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::registerThermalChangedCallback(
|
|
const sp<IThermalChangedCallback_2_0>& callback, bool filterType, TemperatureType_2_0 type,
|
|
std::function<void(const ThermalStatus&)> _hidl_cb) {
|
|
if (!thermal_service_) {
|
|
setInitFailureAndCallback(_hidl_cb);
|
|
}
|
|
if (callback == nullptr) {
|
|
setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
|
|
return Void();
|
|
}
|
|
std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
|
|
for (const auto& callback_wrapper : callback_wrappers_) {
|
|
if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
|
|
callback.get())) {
|
|
setFailureAndCallback(_hidl_cb, "The callback was already registered through wrapper");
|
|
return Void();
|
|
}
|
|
}
|
|
std::shared_ptr<IThermalChangedCallbackWrapper> callback_wrapper =
|
|
ndk::SharedRefBase::make<IThermalChangedCallbackWrapper>(callback);
|
|
::ndk::ScopedAStatus a_status;
|
|
ThermalStatus status;
|
|
if (filterType) {
|
|
a_status = thermal_service_->registerThermalChangedCallbackWithType(
|
|
callback_wrapper, static_cast<TemperatureType>(type));
|
|
} else {
|
|
a_status = thermal_service_->registerThermalChangedCallback(callback_wrapper);
|
|
}
|
|
if (a_status.isOk()) {
|
|
callback_wrappers_.push_back(callback_wrapper);
|
|
_hidl_cb(status);
|
|
} else {
|
|
setFailureAndCallback(_hidl_cb, a_status.getMessage());
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::unregisterThermalChangedCallback(
|
|
const sp<IThermalChangedCallback_2_0>& callback,
|
|
std::function<void(const ThermalStatus&)> _hidl_cb) {
|
|
if (!thermal_service_) {
|
|
setInitFailureAndCallback(_hidl_cb);
|
|
}
|
|
if (callback == nullptr) {
|
|
setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
|
|
return Void();
|
|
}
|
|
std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
|
|
for (auto it = callback_wrappers_.begin(); it != callback_wrappers_.end(); it++) {
|
|
auto callback_wrapper = *it;
|
|
if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
|
|
callback.get())) {
|
|
::ndk::ScopedAStatus a_status;
|
|
ThermalStatus status;
|
|
a_status = thermal_service_->unregisterThermalChangedCallback(callback_wrapper);
|
|
if (a_status.isOk()) {
|
|
callback_wrappers_.erase(it);
|
|
_hidl_cb(status);
|
|
} else {
|
|
setFailureAndCallback(_hidl_cb, a_status.getMessage());
|
|
}
|
|
return Void();
|
|
}
|
|
}
|
|
setFailureAndCallback(_hidl_cb, "The callback was not registered through wrapper before");
|
|
return Void();
|
|
}
|
|
|
|
Return<void> ThermalHidlWrapper::getCurrentCoolingDevices(
|
|
bool filterType, CoolingType_2_0 type,
|
|
std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_2_0>&)> _hidl_cb) {
|
|
hidl_vec<CoolingDevice_2_0> ret_2_0;
|
|
if (!thermal_service_) {
|
|
setInitFailureAndCallback(_hidl_cb, ret_2_0);
|
|
}
|
|
|
|
std::vector<CoolingDevice> ret_aidl;
|
|
ThermalStatus status;
|
|
::ndk::ScopedAStatus a_status;
|
|
if (filterType) {
|
|
a_status = thermal_service_->getCoolingDevicesWithType(static_cast<CoolingType>(type),
|
|
&ret_aidl);
|
|
} else {
|
|
a_status = thermal_service_->getCoolingDevices(&ret_aidl);
|
|
}
|
|
if (a_status.isOk()) {
|
|
std::vector<CoolingDevice_2_0> ret;
|
|
for (const auto& cooling_device : ret_aidl) {
|
|
ret.push_back(convertAidlCoolingDevice(cooling_device));
|
|
}
|
|
_hidl_cb(status, hidl_vec<CoolingDevice_2_0>(ret));
|
|
} else {
|
|
setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
|
Return<void> ThermalHidlWrapper::debug(const hidl_handle& handle,
|
|
const hidl_vec<hidl_string>& args) {
|
|
if (handle != nullptr && handle->numFds >= 1) {
|
|
int fd = handle->data[0];
|
|
char** arr = new char*[args.size()];
|
|
for (size_t i = 0; i < args.size(); i++) {
|
|
arr[i] = strdup(args[i].c_str());
|
|
}
|
|
thermal_service_->dump(fd, (const char**)arr, args.size());
|
|
}
|
|
return Void();
|
|
}
|
|
|
|
::ndk::ScopedAStatus ThermalHidlWrapper::IThermalChangedCallbackWrapper::notifyThrottling(
|
|
const Temperature& temperature) {
|
|
callback_2_0_->notifyThrottling(convertAidlTemperature(temperature));
|
|
return ::ndk::ScopedAStatus::ok();
|
|
}
|
|
|
|
} // namespace thermal
|
|
} // namespace hardware
|
|
} // namespace android
|
|
} // namespace aidl
|