1 /*
2 * Copyright (C) 2018 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 <cerrno>
18 #include <mutex>
19 #include <string>
20
21 #include <android-base/file.h>
22 #include <android-base/logging.h>
23 #include <hidl/HidlTransportSupport.h>
24
25 #include "Thermal.h"
26 #include "thermal-helper.h"
27
28 namespace android {
29 namespace hardware {
30 namespace thermal {
31 namespace V2_0 {
32 namespace implementation {
33
34 namespace {
35
36 using ::android::hardware::interfacesEqual;
37 using ::android::hardware::thermal::V1_0::ThermalStatus;
38 using ::android::hardware::thermal::V1_0::ThermalStatusCode;
39
40 template <typename T, typename U>
setFailureAndCallback(T _hidl_cb,hidl_vec<U> data,std::string_view debug_msg)41 Return<void> setFailureAndCallback(T _hidl_cb, hidl_vec<U> data, std::string_view debug_msg) {
42 ThermalStatus status;
43 status.code = ThermalStatusCode::FAILURE;
44 status.debugMessage = debug_msg.data();
45 _hidl_cb(status, data);
46 return Void();
47 }
48
49 template <typename T, typename U>
setInitFailureAndCallback(T _hidl_cb,hidl_vec<U> data)50 Return<void> setInitFailureAndCallback(T _hidl_cb, hidl_vec<U> data) {
51 return setFailureAndCallback(_hidl_cb, data, "Failure initializing thermal HAL");
52 }
53
54 } // namespace
55
56 // On init we will spawn a thread which will continually watch for
57 // throttling. When throttling is seen, if we have a callback registered
58 // the thread will call notifyThrottling() else it will log the dropped
59 // throttling event and do nothing. The thread is only killed when
60 // Thermal() is killed.
Thermal()61 Thermal::Thermal()
62 : thermal_helper_(
63 std::bind(&Thermal::sendThermalChangedCallback, this, std::placeholders::_1)) {}
64
65 // Methods from ::android::hardware::thermal::V1_0::IThermal.
getTemperatures(getTemperatures_cb _hidl_cb)66 Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) {
67 ThermalStatus status;
68 status.code = ThermalStatusCode::SUCCESS;
69 hidl_vec<Temperature_1_0> temperatures;
70
71 if (!thermal_helper_.isInitializedOk()) {
72 LOG(ERROR) << "ThermalHAL not initialized properly.";
73 return setInitFailureAndCallback(_hidl_cb, temperatures);
74 }
75
76 if (!thermal_helper_.fillTemperatures(&temperatures)) {
77 return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors.");
78 }
79
80 _hidl_cb(status, temperatures);
81 return Void();
82 }
83
getCpuUsages(getCpuUsages_cb _hidl_cb)84 Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) {
85 ThermalStatus status;
86 status.code = ThermalStatusCode::SUCCESS;
87 hidl_vec<CpuUsage> cpu_usages;
88
89 if (!thermal_helper_.isInitializedOk()) {
90 return setInitFailureAndCallback(_hidl_cb, cpu_usages);
91 }
92
93 if (!thermal_helper_.fillCpuUsages(&cpu_usages)) {
94 return setFailureAndCallback(_hidl_cb, cpu_usages, "Failed to get CPU usages.");
95 }
96
97 _hidl_cb(status, cpu_usages);
98 return Void();
99 }
100
getCoolingDevices(getCoolingDevices_cb _hidl_cb)101 Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) {
102 ThermalStatus status;
103 status.code = ThermalStatusCode::SUCCESS;
104 hidl_vec<CoolingDevice_1_0> cooling_devices;
105
106 if (!thermal_helper_.isInitializedOk()) {
107 return setInitFailureAndCallback(_hidl_cb, cooling_devices);
108 }
109 _hidl_cb(status, cooling_devices);
110 return Void();
111 }
112
getCurrentTemperatures(bool filterType,TemperatureType_2_0 type,getCurrentTemperatures_cb _hidl_cb)113 Return<void> Thermal::getCurrentTemperatures(bool filterType, TemperatureType_2_0 type,
114 getCurrentTemperatures_cb _hidl_cb) {
115 ThermalStatus status;
116 status.code = ThermalStatusCode::SUCCESS;
117 hidl_vec<Temperature_2_0> temperatures;
118
119 if (!thermal_helper_.isInitializedOk()) {
120 LOG(ERROR) << "ThermalHAL not initialized properly.";
121 return setInitFailureAndCallback(_hidl_cb, temperatures);
122 }
123
124 if (!thermal_helper_.fillCurrentTemperatures(filterType, type, &temperatures)) {
125 return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors.");
126 }
127
128 _hidl_cb(status, temperatures);
129 return Void();
130 }
131
getTemperatureThresholds(bool filterType,TemperatureType_2_0 type,getTemperatureThresholds_cb _hidl_cb)132 Return<void> Thermal::getTemperatureThresholds(bool filterType, TemperatureType_2_0 type,
133 getTemperatureThresholds_cb _hidl_cb) {
134 ThermalStatus status;
135 status.code = ThermalStatusCode::SUCCESS;
136 hidl_vec<TemperatureThreshold> temperatures;
137
138 if (!thermal_helper_.isInitializedOk()) {
139 LOG(ERROR) << "ThermalHAL not initialized properly.";
140 return setInitFailureAndCallback(_hidl_cb, temperatures);
141 }
142
143 if (!thermal_helper_.fillTemperatureThresholds(filterType, type, &temperatures)) {
144 return setFailureAndCallback(_hidl_cb, temperatures, "Failed to read thermal sensors.");
145 }
146
147 _hidl_cb(status, temperatures);
148 return Void();
149 }
150
getCurrentCoolingDevices(bool filterType,CoolingType type,getCurrentCoolingDevices_cb _hidl_cb)151 Return<void> Thermal::getCurrentCoolingDevices(bool filterType, CoolingType type,
152 getCurrentCoolingDevices_cb _hidl_cb) {
153 ThermalStatus status;
154 status.code = ThermalStatusCode::SUCCESS;
155 hidl_vec<CoolingDevice_2_0> cooling_devices;
156
157 if (!thermal_helper_.isInitializedOk()) {
158 LOG(ERROR) << "ThermalHAL not initialized properly.";
159 return setInitFailureAndCallback(_hidl_cb, cooling_devices);
160 }
161
162 if (!thermal_helper_.fillCurrentCoolingDevices(filterType, type, &cooling_devices)) {
163 return setFailureAndCallback(_hidl_cb, cooling_devices, "Failed to read thermal sensors.");
164 }
165
166 _hidl_cb(status, cooling_devices);
167 return Void();
168 }
169
registerThermalChangedCallback(const sp<IThermalChangedCallback> & callback,bool filterType,TemperatureType_2_0 type,registerThermalChangedCallback_cb _hidl_cb)170 Return<void> Thermal::registerThermalChangedCallback(const sp<IThermalChangedCallback> &callback,
171 bool filterType, TemperatureType_2_0 type,
172 registerThermalChangedCallback_cb _hidl_cb) {
173 ThermalStatus status;
174 if (callback == nullptr) {
175 status.code = ThermalStatusCode::FAILURE;
176 status.debugMessage = "Invalid nullptr callback";
177 LOG(ERROR) << status.debugMessage;
178 _hidl_cb(status);
179 return Void();
180 } else {
181 status.code = ThermalStatusCode::SUCCESS;
182 }
183 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
184 if (std::any_of(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting &c) {
185 return interfacesEqual(c.callback, callback);
186 })) {
187 status.code = ThermalStatusCode::FAILURE;
188 status.debugMessage = "Same callback registered already";
189 LOG(ERROR) << status.debugMessage;
190 } else {
191 callbacks_.emplace_back(callback, filterType, type);
192 LOG(INFO) << "a callback has been registered to ThermalHAL, isFilter: " << filterType
193 << " Type: " << android::hardware::thermal::V2_0::toString(type);
194 }
195 _hidl_cb(status);
196 return Void();
197 }
198
unregisterThermalChangedCallback(const sp<IThermalChangedCallback> & callback,unregisterThermalChangedCallback_cb _hidl_cb)199 Return<void> Thermal::unregisterThermalChangedCallback(
200 const sp<IThermalChangedCallback> &callback, unregisterThermalChangedCallback_cb _hidl_cb) {
201 ThermalStatus status;
202 if (callback == nullptr) {
203 status.code = ThermalStatusCode::FAILURE;
204 status.debugMessage = "Invalid nullptr callback";
205 LOG(ERROR) << status.debugMessage;
206 _hidl_cb(status);
207 return Void();
208 } else {
209 status.code = ThermalStatusCode::SUCCESS;
210 }
211 bool removed = false;
212 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
213 callbacks_.erase(
214 std::remove_if(callbacks_.begin(), callbacks_.end(),
215 [&](const CallbackSetting &c) {
216 if (interfacesEqual(c.callback, callback)) {
217 LOG(INFO)
218 << "a callback has been unregistered to ThermalHAL, isFilter: "
219 << c.is_filter_type << " Type: "
220 << android::hardware::thermal::V2_0::toString(c.type);
221 removed = true;
222 return true;
223 }
224 return false;
225 }),
226 callbacks_.end());
227 if (!removed) {
228 status.code = ThermalStatusCode::FAILURE;
229 status.debugMessage = "The callback was not registered before";
230 LOG(ERROR) << status.debugMessage;
231 }
232 _hidl_cb(status);
233 return Void();
234 }
235
sendThermalChangedCallback(const Temperature_2_0 & t)236 void Thermal::sendThermalChangedCallback(const Temperature_2_0 &t) {
237 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
238
239 LOG(VERBOSE) << "Sending notification: "
240 << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
241 << " Name: " << t.name << " CurrentValue: " << t.value << " ThrottlingStatus: "
242 << android::hardware::thermal::V2_0::toString(t.throttlingStatus);
243
244 callbacks_.erase(
245 std::remove_if(callbacks_.begin(), callbacks_.end(),
246 [&](const CallbackSetting &c) {
247 if (!c.is_filter_type || t.type == c.type) {
248 Return<void> ret = c.callback->notifyThrottling(t);
249 return !ret.isOk();
250 }
251 LOG(ERROR)
252 << "a Thermal callback is dead, removed from callback list.";
253 return false;
254 }),
255 callbacks_.end());
256 }
257
dumpVirtualSensorInfo(std::ostringstream * dump_buf)258 void Thermal::dumpVirtualSensorInfo(std::ostringstream *dump_buf) {
259 *dump_buf << "VirtualSensorInfo:" << std::endl;
260 const auto &map = thermal_helper_.GetSensorInfoMap();
261 for (const auto &sensor_info_pair : map) {
262 if (sensor_info_pair.second.virtual_sensor_info != nullptr) {
263 *dump_buf << " Name: " << sensor_info_pair.first << std::endl;
264 *dump_buf << " LinkedSensorName: [";
265 for (size_t i = 0;
266 i < sensor_info_pair.second.virtual_sensor_info->linked_sensors.size(); i++) {
267 *dump_buf << sensor_info_pair.second.virtual_sensor_info->linked_sensors[i] << " ";
268 }
269 *dump_buf << "]" << std::endl;
270 *dump_buf << " LinkedSensorCoefficient: [";
271 for (size_t i = 0; i < sensor_info_pair.second.virtual_sensor_info->coefficients.size();
272 i++) {
273 *dump_buf << sensor_info_pair.second.virtual_sensor_info->coefficients[i] << " ";
274 }
275 *dump_buf << "]" << std::endl;
276 *dump_buf << " Offset: " << sensor_info_pair.second.virtual_sensor_info->offset
277 << std::endl;
278 *dump_buf << " Trigger Sensor: "
279 << (sensor_info_pair.second.virtual_sensor_info->trigger_sensor.empty()
280 ? "N/A"
281 : sensor_info_pair.second.virtual_sensor_info->trigger_sensor)
282 << std::endl;
283 *dump_buf << " Formula: ";
284 switch (sensor_info_pair.second.virtual_sensor_info->formula) {
285 case FormulaOption::COUNT_THRESHOLD:
286 *dump_buf << "COUNT_THRESHOLD";
287 break;
288 case FormulaOption::WEIGHTED_AVG:
289 *dump_buf << "WEIGHTED_AVG";
290 break;
291 case FormulaOption::MAXIMUM:
292 *dump_buf << "MAXIMUM";
293 break;
294 case FormulaOption::MINIMUM:
295 *dump_buf << "MINIMUM";
296 break;
297 default:
298 *dump_buf << "NONE";
299 break;
300 }
301
302 *dump_buf << std::endl;
303 }
304 }
305 }
306
dumpThrottlingInfo(std::ostringstream * dump_buf)307 void Thermal::dumpThrottlingInfo(std::ostringstream *dump_buf) {
308 *dump_buf << "Throttling Info:" << std::endl;
309 const auto &map = thermal_helper_.GetSensorInfoMap();
310 for (const auto &name_info_pair : map) {
311 if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
312 *dump_buf << " Name: " << name_info_pair.first << std::endl;
313 *dump_buf << " PID Info:" << std::endl;
314 *dump_buf << " K_po: [";
315 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
316 *dump_buf << name_info_pair.second.throttling_info->k_po[i] << " ";
317 }
318 *dump_buf << "]" << std::endl;
319 *dump_buf << " K_pu: [";
320 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
321 *dump_buf << name_info_pair.second.throttling_info->k_pu[i] << " ";
322 }
323 *dump_buf << "]" << std::endl;
324 *dump_buf << " K_i: [";
325 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
326 *dump_buf << name_info_pair.second.throttling_info->k_i[i] << " ";
327 }
328 *dump_buf << "]" << std::endl;
329 *dump_buf << " K_d: [";
330 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
331 *dump_buf << name_info_pair.second.throttling_info->k_d[i] << " ";
332 }
333 *dump_buf << "]" << std::endl;
334 *dump_buf << " i_max: [";
335 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
336 *dump_buf << name_info_pair.second.throttling_info->i_max[i] << " ";
337 }
338 *dump_buf << "]" << std::endl;
339 *dump_buf << " max_alloc_power: [";
340 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
341 *dump_buf << name_info_pair.second.throttling_info->max_alloc_power[i] << " ";
342 }
343 *dump_buf << "]" << std::endl;
344 *dump_buf << " min_alloc_power: [";
345 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
346 *dump_buf << name_info_pair.second.throttling_info->min_alloc_power[i] << " ";
347 }
348 *dump_buf << "]" << std::endl;
349 *dump_buf << " s_power: [";
350 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
351 *dump_buf << name_info_pair.second.throttling_info->s_power[i] << " ";
352 }
353 *dump_buf << "]" << std::endl;
354 *dump_buf << " i_cutoff: [";
355 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
356 *dump_buf << name_info_pair.second.throttling_info->i_cutoff[i] << " ";
357 }
358 *dump_buf << "]" << std::endl;
359 *dump_buf << " Binded CDEV Info:" << std::endl;
360 if (name_info_pair.second.throttling_info->binded_cdev_info_map.size()) {
361 for (const auto &binded_cdev_info_pair :
362 name_info_pair.second.throttling_info->binded_cdev_info_map) {
363 *dump_buf << " Cooling device name: " << binded_cdev_info_pair.first
364 << std::endl;
365 *dump_buf << " WeightForPID: [";
366 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
367 *dump_buf << binded_cdev_info_pair.second.cdev_weight_for_pid[i] << " ";
368 }
369 *dump_buf << "]" << std::endl;
370 *dump_buf << " Ceiling: [";
371 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
372 *dump_buf << binded_cdev_info_pair.second.cdev_ceiling[i] << " ";
373 }
374 *dump_buf << "]" << std::endl;
375 *dump_buf << " Floor with PowerLink: [";
376 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
377 *dump_buf << binded_cdev_info_pair.second.cdev_floor_with_power_link[i]
378 << " ";
379 }
380 *dump_buf << "]" << std::endl;
381 *dump_buf << " Hard limit: [";
382 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
383 *dump_buf << binded_cdev_info_pair.second.limit_info[i] << " ";
384 }
385 *dump_buf << "]" << std::endl;
386
387 if (!binded_cdev_info_pair.second.power_rail.empty()) {
388 *dump_buf << " Binded power rail: "
389 << binded_cdev_info_pair.second.power_rail << std::endl;
390 *dump_buf << " Power threshold: [";
391 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
392 *dump_buf << binded_cdev_info_pair.second.power_thresholds[i] << " ";
393 }
394 *dump_buf << "]" << std::endl;
395 *dump_buf << " Release logic: ";
396 switch (binded_cdev_info_pair.second.release_logic) {
397 case ReleaseLogic::INCREASE:
398 *dump_buf << "INCREASE";
399 break;
400 case ReleaseLogic::DECREASE:
401 *dump_buf << "DECREASE";
402 break;
403 case ReleaseLogic::STEPWISE:
404 *dump_buf << "STEPWISE";
405 break;
406 case ReleaseLogic::RELEASE_TO_FLOOR:
407 *dump_buf << "RELEASE_TO_FLOOR";
408 break;
409 default:
410 *dump_buf << "NONE";
411 break;
412 }
413 *dump_buf << std::endl;
414 *dump_buf << " high_power_check: " << std::boolalpha
415 << binded_cdev_info_pair.second.high_power_check << std::endl;
416 *dump_buf << " throttling_with_power_link: " << std::boolalpha
417 << binded_cdev_info_pair.second.throttling_with_power_link
418 << std::endl;
419 }
420 }
421 }
422 }
423 }
424 }
425
dumpThrottlingRequestStatus(std::ostringstream * dump_buf)426 void Thermal::dumpThrottlingRequestStatus(std::ostringstream *dump_buf) {
427 const auto &sensor_status_map = thermal_helper_.GetSensorStatusMap();
428 const auto &cdev_status_map = thermal_helper_.GetCdevStatusMap();
429 const auto &release_map = thermal_helper_.GetThrottlingReleaseMap();
430 *dump_buf << "Throttling Request Status " << std::endl;
431 for (const auto &cdev_status_pair : cdev_status_map) {
432 *dump_buf << " Name: " << cdev_status_pair.first << std::endl;
433 for (const auto &request_pair : cdev_status_pair.second) {
434 *dump_buf << " Request Sensor: " << request_pair.first << std::endl;
435 *dump_buf << " Request Throttling State: " << request_pair.second << std::endl;
436 if (sensor_status_map.at(request_pair.first).pid_request_map.size() &&
437 sensor_status_map.at(request_pair.first)
438 .pid_request_map.count(cdev_status_pair.first)) {
439 *dump_buf << " PID Request State: "
440 << sensor_status_map.at(request_pair.first)
441 .pid_request_map.at(cdev_status_pair.first)
442 << std::endl;
443 }
444 if (sensor_status_map.at(request_pair.first).hard_limit_request_map.size() &&
445 sensor_status_map.at(request_pair.first)
446 .hard_limit_request_map.count(cdev_status_pair.first)) {
447 *dump_buf << " Hard Limit Request State: "
448 << sensor_status_map.at(request_pair.first)
449 .hard_limit_request_map.at(cdev_status_pair.first)
450 << std::endl;
451 }
452 if (release_map.count(request_pair.first) &&
453 release_map.at(request_pair.first).count(cdev_status_pair.first)) {
454 const auto &cdev_release_info =
455 release_map.at(request_pair.first).at(cdev_status_pair.first);
456 *dump_buf << " Release Step: " << cdev_release_info.release_step << std::endl;
457 }
458 }
459 }
460 }
461
dumpPowerRailInfo(std::ostringstream * dump_buf)462 void Thermal::dumpPowerRailInfo(std::ostringstream *dump_buf) {
463 const auto &power_rail_info_map = thermal_helper_.GetPowerRailInfoMap();
464 const auto &power_status_map = thermal_helper_.GetPowerStatusMap();
465
466 *dump_buf << "Power Rail Info " << std::endl;
467 for (const auto &power_rail_pair : power_rail_info_map) {
468 *dump_buf << " Power Rail: " << power_rail_pair.first << std::endl;
469 *dump_buf << " Power Sample Count: " << power_rail_pair.second.power_sample_count
470 << std::endl;
471 *dump_buf << " Power Sample Delay: " << power_rail_pair.second.power_sample_delay.count()
472 << std::endl;
473 for (const auto &power_status_pair : power_status_map) {
474 if (power_status_pair.second.count(power_rail_pair.first)) {
475 auto power_history =
476 power_status_pair.second.at(power_rail_pair.first).power_history;
477 *dump_buf << " Request Sensor: " << power_status_pair.first << std::endl;
478 *dump_buf
479 << " Last Updated AVG Power: "
480 << power_status_pair.second.at(power_rail_pair.first).last_updated_avg_power
481 << " mW" << std::endl;
482 if (power_rail_pair.second.virtual_power_rail_info != nullptr) {
483 *dump_buf << " Formula=";
484 switch (power_rail_pair.second.virtual_power_rail_info->formula) {
485 case FormulaOption::COUNT_THRESHOLD:
486 *dump_buf << "COUNT_THRESHOLD";
487 break;
488 case FormulaOption::WEIGHTED_AVG:
489 *dump_buf << "WEIGHTED_AVG";
490 break;
491 case FormulaOption::MAXIMUM:
492 *dump_buf << "MAXIMUM";
493 break;
494 case FormulaOption::MINIMUM:
495 *dump_buf << "MINIMUM";
496 break;
497 default:
498 *dump_buf << "NONE";
499 break;
500 }
501 *dump_buf << std::endl;
502 }
503 for (size_t i = 0; i < power_history.size(); ++i) {
504 if (power_rail_pair.second.virtual_power_rail_info != nullptr) {
505 *dump_buf << " Linked power rail "
506 << power_rail_pair.second.virtual_power_rail_info
507 ->linked_power_rails[i]
508 << std::endl;
509 *dump_buf << " Coefficient="
510 << power_rail_pair.second.virtual_power_rail_info->coefficients[i]
511 << std::endl;
512 *dump_buf << " Power Samples: ";
513 } else {
514 *dump_buf << " Power Samples: ";
515 }
516 while (power_history[i].size() > 0) {
517 const auto power_sample = power_history[i].front();
518 power_history[i].pop();
519 *dump_buf << "(T=" << power_sample.duration
520 << ", uWs=" << power_sample.energy_counter << ") ";
521 }
522 *dump_buf << std::endl;
523 }
524 }
525 }
526 }
527 }
528
debug(const hidl_handle & handle,const hidl_vec<hidl_string> &)529 Return<void> Thermal::debug(const hidl_handle &handle, const hidl_vec<hidl_string> &) {
530 if (handle != nullptr && handle->numFds >= 1) {
531 int fd = handle->data[0];
532 std::ostringstream dump_buf;
533
534 if (!thermal_helper_.isInitializedOk()) {
535 dump_buf << "ThermalHAL not initialized properly." << std::endl;
536 } else {
537 {
538 hidl_vec<Temperature_1_0> temperatures;
539 dump_buf << "getTemperatures:" << std::endl;
540 if (!thermal_helper_.fillTemperatures(&temperatures)) {
541 dump_buf << "Failed to read thermal sensors." << std::endl;
542 }
543
544 for (const auto &t : temperatures) {
545 dump_buf << " Type: " << android::hardware::thermal::V1_0::toString(t.type)
546 << " Name: " << t.name << " CurrentValue: " << t.currentValue
547 << " ThrottlingThreshold: " << t.throttlingThreshold
548 << " ShutdownThreshold: " << t.shutdownThreshold
549 << " VrThrottlingThreshold: " << t.vrThrottlingThreshold << std::endl;
550 }
551 }
552 {
553 hidl_vec<CpuUsage> cpu_usages;
554 dump_buf << "getCpuUsages:" << std::endl;
555 if (!thermal_helper_.fillCpuUsages(&cpu_usages)) {
556 dump_buf << "Failed to get CPU usages." << std::endl;
557 }
558
559 for (const auto &usage : cpu_usages) {
560 dump_buf << " Name: " << usage.name << " Active: " << usage.active
561 << " Total: " << usage.total << " IsOnline: " << usage.isOnline
562 << std::endl;
563 }
564 }
565 {
566 dump_buf << "getCurrentTemperatures:" << std::endl;
567 hidl_vec<Temperature_2_0> temperatures;
568 if (!thermal_helper_.fillCurrentTemperatures(false, TemperatureType_2_0::SKIN,
569 &temperatures)) {
570 dump_buf << "Failed to getCurrentTemperatures." << std::endl;
571 }
572
573 for (const auto &t : temperatures) {
574 dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
575 << " Name: " << t.name << " CurrentValue: " << t.value
576 << " ThrottlingStatus: "
577 << android::hardware::thermal::V2_0::toString(t.throttlingStatus)
578 << std::endl;
579 }
580 }
581 {
582 dump_buf << "getTemperatureThresholds:" << std::endl;
583 hidl_vec<TemperatureThreshold> temperatures;
584 if (!thermal_helper_.fillTemperatureThresholds(false, TemperatureType_2_0::SKIN,
585 &temperatures)) {
586 dump_buf << "Failed to getTemperatureThresholds." << std::endl;
587 }
588
589 for (const auto &t : temperatures) {
590 dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(t.type)
591 << " Name: " << t.name;
592 dump_buf << " hotThrottlingThreshold: [";
593 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
594 dump_buf << t.hotThrottlingThresholds[i] << " ";
595 }
596 dump_buf << "] coldThrottlingThreshold: [";
597 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
598 dump_buf << t.coldThrottlingThresholds[i] << " ";
599 }
600 dump_buf << "] vrThrottlingThreshold: " << t.vrThrottlingThreshold;
601 dump_buf << std::endl;
602 }
603 }
604 {
605 dump_buf << "getCurrentCoolingDevices:" << std::endl;
606 hidl_vec<CoolingDevice_2_0> cooling_devices;
607 if (!thermal_helper_.fillCurrentCoolingDevices(false, CoolingType::CPU,
608 &cooling_devices)) {
609 dump_buf << "Failed to getCurrentCoolingDevices." << std::endl;
610 }
611
612 for (const auto &c : cooling_devices) {
613 dump_buf << " Type: " << android::hardware::thermal::V2_0::toString(c.type)
614 << " Name: " << c.name << " CurrentValue: " << c.value << std::endl;
615 }
616 }
617 {
618 dump_buf << "Callbacks: Total " << callbacks_.size() << std::endl;
619 for (const auto &c : callbacks_) {
620 dump_buf << " IsFilter: " << c.is_filter_type
621 << " Type: " << android::hardware::thermal::V2_0::toString(c.type)
622 << std::endl;
623 }
624 }
625 {
626 dump_buf << "getHysteresis:" << std::endl;
627 const auto &map = thermal_helper_.GetSensorInfoMap();
628 for (const auto &name_info_pair : map) {
629 dump_buf << " Name: " << name_info_pair.first;
630 dump_buf << " hotHysteresis: [";
631 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
632 dump_buf << name_info_pair.second.hot_hysteresis[i] << " ";
633 }
634 dump_buf << "] coldHysteresis: [";
635 for (size_t i = 0; i < kThrottlingSeverityCount; ++i) {
636 dump_buf << name_info_pair.second.cold_hysteresis[i] << " ";
637 }
638 dump_buf << "]" << std::endl;
639 }
640 }
641 {
642 dump_buf << "SendCallback" << std::endl;
643 dump_buf << " Enabled List: ";
644 const auto &map = thermal_helper_.GetSensorInfoMap();
645 for (const auto &name_info_pair : map) {
646 if (name_info_pair.second.send_cb) {
647 dump_buf << name_info_pair.first << " ";
648 }
649 }
650 dump_buf << std::endl;
651 }
652 {
653 dump_buf << "SendPowerHint" << std::endl;
654 dump_buf << " Enabled List: ";
655 const auto &map = thermal_helper_.GetSensorInfoMap();
656 for (const auto &name_info_pair : map) {
657 if (name_info_pair.second.send_powerhint) {
658 dump_buf << name_info_pair.first << " ";
659 }
660 }
661 dump_buf << std::endl;
662 }
663 dumpVirtualSensorInfo(&dump_buf);
664 dumpThrottlingInfo(&dump_buf);
665 dumpThrottlingRequestStatus(&dump_buf);
666 dumpPowerRailInfo(&dump_buf);
667 {
668 dump_buf << "AIDL Power Hal exist: " << std::boolalpha
669 << thermal_helper_.isAidlPowerHalExist() << std::endl;
670 dump_buf << "AIDL Power Hal connected: " << std::boolalpha
671 << thermal_helper_.isPowerHalConnected() << std::endl;
672 dump_buf << "AIDL Power Hal Ext connected: " << std::boolalpha
673 << thermal_helper_.isPowerHalExtConnected() << std::endl;
674 }
675 }
676 std::string buf = dump_buf.str();
677 if (!android::base::WriteStringToFd(buf, fd)) {
678 PLOG(ERROR) << "Failed to dump state to fd";
679 }
680 fsync(fd);
681 }
682 return Void();
683 }
684
685 } // namespace implementation
686 } // namespace V2_0
687 } // namespace thermal
688 } // namespace hardware
689 } // namespace android
690