blob: 05a992a792fb0b7714038d94ede1594278960293 [file] [log] [blame]
Xiang Wang0b7c6522023-02-15 15:42:22 -08001/*
2 * Copyright (C) 2023 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#include "include/thermalutils/ThermalHidlWrapper.h"
18
19#include <hidl/HidlTransportSupport.h>
20
21#include <cmath>
22
23namespace aidl {
24namespace android {
25namespace hardware {
26namespace thermal {
27
28using ::android::hardware::Void;
29
30namespace {
31
32template <typename T, typename U>
33Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
34 ThermalStatus status;
35 status.code = ThermalStatusCode::FAILURE;
36 status.debugMessage = debug_msg.data();
37 _hidl_cb(status, data);
38 return Void();
39}
40
41template <typename T>
42Return<void> setFailureAndCallback(T _hidl_cb, std::string_view debug_msg) {
43 ThermalStatus status;
44 status.code = ThermalStatusCode::FAILURE;
45 status.debugMessage = debug_msg.data();
46 _hidl_cb(status);
47 return Void();
48}
49
50template <typename T, typename U>
51Return<void> setInitFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
52 return setFailureAndCallback(
53 _hidl_cb, data, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
54}
55
56template <typename T>
57Return<void> setInitFailureAndCallback(T _hidl_cb) {
58 return setFailureAndCallback(
59 _hidl_cb, "Thermal AIDL HAL client used by HIDL wrapper was not initialized");
60}
61
62template <typename T, typename U>
63Return<void> setUnsupportedFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
64 return setFailureAndCallback(_hidl_cb, data, "Operation unsupported by Thermal HIDL wrapper");
65}
66
67TemperatureType_2_0 convertAidlTemperatureType(const TemperatureType& type) {
68 if (type < TemperatureType::CPU || type > TemperatureType::NPU) {
69 return TemperatureType_2_0::UNKNOWN;
70 }
71 return static_cast<TemperatureType_2_0>(type);
72}
73
74CoolingType_2_0 convertAidlCoolingType(const CoolingType& type) {
75 if (type < CoolingType::FAN || type > CoolingType::COMPONENT) {
76 return CoolingType_2_0::COMPONENT;
77 }
78 return static_cast<CoolingType_2_0>(type);
79}
80
81Temperature_2_0 convertAidlTemperature(const Temperature& temperature) {
82 Temperature_2_0 t = Temperature_2_0{
83 convertAidlTemperatureType(temperature.type), temperature.name, temperature.value,
84 static_cast<ThrottlingSeverity_2_0>(temperature.throttlingStatus)};
85 return t;
86}
87
88CoolingDevice_2_0 convertAidlCoolingDevice(const CoolingDevice& cooling_device) {
89 CoolingDevice_2_0 t =
90 CoolingDevice_2_0{convertAidlCoolingType(cooling_device.type), cooling_device.name,
91 static_cast<uint64_t>(cooling_device.value)};
92 return t;
93}
94TemperatureThreshold_2_0 convertAidlTemperatureThreshold(const TemperatureThreshold& threshold) {
95 TemperatureThreshold_2_0 t =
96 TemperatureThreshold_2_0{convertAidlTemperatureType(threshold.type), threshold.name,
97 threshold.hotThrottlingThresholds.data(),
98 threshold.coldThrottlingThresholds.data(), NAN};
99 return t;
100}
101
102} // namespace
103
104// Methods from ::android::hardware::thermal::V1_0::IThermal follow.
105Return<void> ThermalHidlWrapper::getTemperatures(getTemperatures_cb _hidl_cb) {
106 hidl_vec<Temperature_1_0> ret_1_0;
107 setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
108 return Void();
109}
110
111Return<void> ThermalHidlWrapper::getCpuUsages(
112 std::function<void(const ThermalStatus&, const hidl_vec<CpuUsage>&)> _hidl_cb) {
113 hidl_vec<CpuUsage> ret_1_0;
114 setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
115 return Void();
116}
117
118Return<void> ThermalHidlWrapper::getCoolingDevices(
119 std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_1_0>&)> _hidl_cb) {
120 hidl_vec<CoolingDevice_1_0> ret_1_0;
121 setUnsupportedFailureAndCallback(_hidl_cb, ret_1_0);
122 return Void();
123}
124
125// Methods from ::android::hardware::thermal::V2_0::IThermal follow.
126Return<void> ThermalHidlWrapper::getCurrentTemperatures(
127 bool filterType, TemperatureType_2_0 type,
128 std::function<void(const ThermalStatus&, const hidl_vec<Temperature_2_0>&)> _hidl_cb) {
129 hidl_vec<Temperature_2_0> ret_2_0;
130 if (!thermal_service_) {
131 setInitFailureAndCallback(_hidl_cb, ret_2_0);
132 }
133
134 std::vector<Temperature> ret_aidl;
135 ThermalStatus status;
136 ::ndk::ScopedAStatus a_status;
137 if (filterType) {
138 a_status = thermal_service_->getTemperaturesWithType(static_cast<TemperatureType>(type),
139 &ret_aidl);
140 } else {
141 a_status = thermal_service_->getTemperatures(&ret_aidl);
142 }
143 if (a_status.isOk()) {
144 std::vector<Temperature_2_0> ret;
145 for (const auto& temperature : ret_aidl) {
146 ret.push_back(convertAidlTemperature(temperature));
147 }
148 _hidl_cb(status, hidl_vec<Temperature_2_0>(ret));
149 } else {
150 setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
151 }
152 return Void();
153}
154
155Return<void> ThermalHidlWrapper::getTemperatureThresholds(
156 bool filterType, TemperatureType_2_0 type,
157 std::function<void(const ThermalStatus&, const hidl_vec<TemperatureThreshold_2_0>&)>
158 _hidl_cb) {
159 hidl_vec<TemperatureThreshold_2_0> ret_2_0;
160 if (!thermal_service_) {
161 setInitFailureAndCallback(_hidl_cb, ret_2_0);
162 }
163
164 std::vector<TemperatureThreshold> ret_aidl;
165 ThermalStatus status;
166 ::ndk::ScopedAStatus a_status;
167 if (filterType) {
168 a_status = thermal_service_->getTemperatureThresholdsWithType(
169 static_cast<TemperatureType>(type), &ret_aidl);
170 } else {
171 a_status = thermal_service_->getTemperatureThresholds(&ret_aidl);
172 }
173 if (a_status.isOk()) {
174 std::vector<TemperatureThreshold_2_0> ret;
175 for (const auto& threshold : ret_aidl) {
176 ret.push_back(convertAidlTemperatureThreshold(threshold));
177 }
178 _hidl_cb(status, hidl_vec<TemperatureThreshold_2_0>(ret));
179 } else {
180 setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
181 }
182 return Void();
183}
184
185Return<void> ThermalHidlWrapper::registerThermalChangedCallback(
186 const sp<IThermalChangedCallback_2_0>& callback, bool filterType, TemperatureType_2_0 type,
187 std::function<void(const ThermalStatus&)> _hidl_cb) {
188 if (!thermal_service_) {
189 setInitFailureAndCallback(_hidl_cb);
190 }
191 if (callback == nullptr) {
192 setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
193 return Void();
194 }
195 std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
196 for (const auto& callback_wrapper : callback_wrappers_) {
197 if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
198 callback.get())) {
199 setFailureAndCallback(_hidl_cb, "The callback was already registered through wrapper");
200 return Void();
201 }
202 }
203 std::shared_ptr<IThermalChangedCallbackWrapper> callback_wrapper =
204 ndk::SharedRefBase::make<IThermalChangedCallbackWrapper>(callback);
205 ::ndk::ScopedAStatus a_status;
206 ThermalStatus status;
207 if (filterType) {
208 a_status = thermal_service_->registerThermalChangedCallbackWithType(
209 callback_wrapper, static_cast<TemperatureType>(type));
210 } else {
211 a_status = thermal_service_->registerThermalChangedCallback(callback_wrapper);
212 }
213 if (a_status.isOk()) {
214 callback_wrappers_.push_back(callback_wrapper);
215 _hidl_cb(status);
216 } else {
217 setFailureAndCallback(_hidl_cb, a_status.getMessage());
218 }
219 return Void();
220}
221
222Return<void> ThermalHidlWrapper::unregisterThermalChangedCallback(
223 const sp<IThermalChangedCallback_2_0>& callback,
224 std::function<void(const ThermalStatus&)> _hidl_cb) {
225 if (!thermal_service_) {
226 setInitFailureAndCallback(_hidl_cb);
227 }
228 if (callback == nullptr) {
229 setFailureAndCallback(_hidl_cb, "Invalid nullptr callback");
230 return Void();
231 }
232 std::lock_guard<std::mutex> _lock(callback_wrappers_mutex_);
233 for (auto it = callback_wrappers_.begin(); it != callback_wrappers_.end(); it++) {
234 auto callback_wrapper = *it;
235 if (::android::hardware::interfacesEqual(callback_wrapper->callback_2_0_.get(),
236 callback.get())) {
237 ::ndk::ScopedAStatus a_status;
238 ThermalStatus status;
239 a_status = thermal_service_->unregisterThermalChangedCallback(callback_wrapper);
240 if (a_status.isOk()) {
241 callback_wrappers_.erase(it);
242 _hidl_cb(status);
243 } else {
244 setFailureAndCallback(_hidl_cb, a_status.getMessage());
245 }
246 return Void();
247 }
248 }
249 setFailureAndCallback(_hidl_cb, "The callback was not registered through wrapper before");
250 return Void();
251}
252
253Return<void> ThermalHidlWrapper::getCurrentCoolingDevices(
254 bool filterType, CoolingType_2_0 type,
255 std::function<void(const ThermalStatus&, const hidl_vec<CoolingDevice_2_0>&)> _hidl_cb) {
256 hidl_vec<CoolingDevice_2_0> ret_2_0;
257 if (!thermal_service_) {
258 setInitFailureAndCallback(_hidl_cb, ret_2_0);
259 }
260
261 std::vector<CoolingDevice> ret_aidl;
262 ThermalStatus status;
263 ::ndk::ScopedAStatus a_status;
264 if (filterType) {
265 a_status = thermal_service_->getCoolingDevicesWithType(static_cast<CoolingType>(type),
266 &ret_aidl);
267 } else {
268 a_status = thermal_service_->getCoolingDevices(&ret_aidl);
269 }
270 if (a_status.isOk()) {
271 std::vector<CoolingDevice_2_0> ret;
272 for (const auto& cooling_device : ret_aidl) {
273 ret.push_back(convertAidlCoolingDevice(cooling_device));
274 }
275 _hidl_cb(status, hidl_vec<CoolingDevice_2_0>(ret));
276 } else {
277 setFailureAndCallback(_hidl_cb, ret_2_0, a_status.getMessage());
278 }
279 return Void();
280}
281
282// Methods from ::android::hidl::base::V1_0::IBase follow.
283Return<void> ThermalHidlWrapper::debug(const hidl_handle& handle,
284 const hidl_vec<hidl_string>& args) {
285 if (handle != nullptr && handle->numFds >= 1) {
286 int fd = handle->data[0];
287 char** arr = new char*[args.size()];
288 for (size_t i = 0; i < args.size(); i++) {
289 arr[i] = strdup(args[i].c_str());
290 }
291 thermal_service_->dump(fd, (const char**)arr, args.size());
292 }
293 return Void();
294}
295
296::ndk::ScopedAStatus ThermalHidlWrapper::IThermalChangedCallbackWrapper::notifyThrottling(
297 const Temperature& temperature) {
298 callback_2_0_->notifyThrottling(convertAidlTemperature(temperature));
299 return ::ndk::ScopedAStatus::ok();
300}
301
302} // namespace thermal
303} // namespace hardware
304} // namespace android
305} // namespace aidl