Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2016 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 "android.hardware.thermal@1.0-impl" |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 18 | |
| 19 | #include <errno.h> |
Polina Bondarenko | 93a2d68 | 2017-01-19 15:55:19 +0100 | [diff] [blame^] | 20 | #include <math.h> |
Mark Salyzyn | 3ff5260 | 2017-01-10 10:16:48 -0800 | [diff] [blame] | 21 | |
| 22 | #include <vector> |
| 23 | |
| 24 | #include <log/log.h> |
| 25 | |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 26 | #include <hardware/hardware.h> |
| 27 | #include <hardware/thermal.h> |
| 28 | |
| 29 | #include "Thermal.h" |
| 30 | |
| 31 | namespace android { |
| 32 | namespace hardware { |
| 33 | namespace thermal { |
| 34 | namespace V1_0 { |
| 35 | namespace implementation { |
| 36 | |
Polina Bondarenko | 93a2d68 | 2017-01-19 15:55:19 +0100 | [diff] [blame^] | 37 | namespace { |
| 38 | |
| 39 | float finalizeTemperature(float temperature) { |
| 40 | return temperature == UNKNOWN_TEMPERATURE ? NAN : temperature; |
| 41 | } |
| 42 | |
| 43 | } |
| 44 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 45 | Thermal::Thermal(thermal_module_t* module) : mModule(module) {} |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 46 | |
| 47 | // Methods from ::android::hardware::thermal::V1_0::IThermal follow. |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 48 | Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) { |
| 49 | ThermalStatus status; |
| 50 | status.code = ThermalStatusCode::SUCCESS; |
| 51 | hidl_vec<Temperature> temperatures; |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 52 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 53 | if (!mModule || !mModule->getTemperatures) { |
| 54 | ALOGI("getTemperatures is not implemented in Thermal HAL."); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 55 | _hidl_cb(status, temperatures); |
| 56 | return Void(); |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | ssize_t size = mModule->getTemperatures(mModule, nullptr, 0); |
| 60 | if (size >= 0) { |
| 61 | std::vector<temperature_t> list; |
| 62 | list.resize(size); |
| 63 | size = mModule->getTemperatures(mModule, list.data(), list.size()); |
| 64 | if (size >= 0) { |
| 65 | temperatures.resize(list.size()); |
| 66 | for (size_t i = 0; i < list.size(); ++i) { |
| 67 | switch (list[i].type) { |
| 68 | case DEVICE_TEMPERATURE_UNKNOWN: |
| 69 | temperatures[i].type = TemperatureType::UNKNOWN; |
| 70 | break; |
| 71 | case DEVICE_TEMPERATURE_CPU: |
| 72 | temperatures[i].type = TemperatureType::CPU; |
| 73 | break; |
| 74 | case DEVICE_TEMPERATURE_GPU: |
| 75 | temperatures[i].type = TemperatureType::GPU; |
| 76 | break; |
| 77 | case DEVICE_TEMPERATURE_BATTERY: |
| 78 | temperatures[i].type = TemperatureType::BATTERY; |
| 79 | break; |
| 80 | case DEVICE_TEMPERATURE_SKIN: |
| 81 | temperatures[i].type = TemperatureType::SKIN; |
| 82 | break; |
| 83 | default: |
| 84 | ALOGE("Unknown temperature %s type", list[i].name); |
| 85 | ; |
| 86 | } |
| 87 | temperatures[i].name = list[i].name; |
Polina Bondarenko | 93a2d68 | 2017-01-19 15:55:19 +0100 | [diff] [blame^] | 88 | temperatures[i].currentValue = finalizeTemperature(list[i].current_value); |
| 89 | temperatures[i].throttlingThreshold = finalizeTemperature(list[i].throttling_threshold); |
| 90 | temperatures[i].shutdownThreshold = finalizeTemperature(list[i].shutdown_threshold); |
| 91 | temperatures[i].vrThrottlingThreshold = |
| 92 | finalizeTemperature(list[i].vr_throttling_threshold); |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 93 | } |
| 94 | } |
| 95 | } |
| 96 | if (size < 0) { |
| 97 | status.code = ThermalStatusCode::FAILURE; |
| 98 | status.debugMessage = strerror(-size); |
| 99 | } |
| 100 | _hidl_cb(status, temperatures); |
| 101 | return Void(); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 102 | } |
| 103 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 104 | Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) { |
| 105 | ThermalStatus status; |
| 106 | hidl_vec<CpuUsage> cpuUsages; |
| 107 | status.code = ThermalStatusCode::SUCCESS; |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 108 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 109 | if (!mModule || !mModule->getCpuUsages) { |
| 110 | ALOGI("getCpuUsages is not implemented in Thermal HAL"); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 111 | _hidl_cb(status, cpuUsages); |
| 112 | return Void(); |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | ssize_t size = mModule->getCpuUsages(mModule, nullptr); |
| 116 | if (size >= 0) { |
| 117 | std::vector<cpu_usage_t> list; |
| 118 | list.resize(size); |
| 119 | size = mModule->getCpuUsages(mModule, list.data()); |
| 120 | if (size >= 0) { |
| 121 | list.resize(size); |
| 122 | cpuUsages.resize(size); |
| 123 | for (size_t i = 0; i < list.size(); ++i) { |
| 124 | cpuUsages[i].name = list[i].name; |
| 125 | cpuUsages[i].active = list[i].active; |
| 126 | cpuUsages[i].total = list[i].total; |
| 127 | cpuUsages[i].isOnline = list[i].is_online; |
| 128 | } |
| 129 | } else { |
| 130 | status.code = ThermalStatusCode::FAILURE; |
| 131 | status.debugMessage = strerror(-size); |
| 132 | } |
| 133 | } |
| 134 | if (size < 0) { |
| 135 | status.code = ThermalStatusCode::FAILURE; |
| 136 | status.debugMessage = strerror(-size); |
| 137 | } |
| 138 | _hidl_cb(status, cpuUsages); |
| 139 | return Void(); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 140 | } |
| 141 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 142 | Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) { |
| 143 | ThermalStatus status; |
| 144 | status.code = ThermalStatusCode::SUCCESS; |
| 145 | hidl_vec<CoolingDevice> coolingDevices; |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 146 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 147 | if (!mModule || !mModule->getCoolingDevices) { |
| 148 | ALOGI("getCoolingDevices is not implemented in Thermal HAL."); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 149 | _hidl_cb(status, coolingDevices); |
| 150 | return Void(); |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | ssize_t size = mModule->getCoolingDevices(mModule, nullptr, 0); |
| 154 | if (size >= 0) { |
| 155 | std::vector<cooling_device_t> list; |
| 156 | list.resize(size); |
| 157 | size = mModule->getCoolingDevices(mModule, list.data(), list.size()); |
| 158 | if (size >= 0) { |
| 159 | list.resize(size); |
| 160 | coolingDevices.resize(list.size()); |
| 161 | for (size_t i = 0; i < list.size(); ++i) { |
| 162 | switch (list[i].type) { |
| 163 | case FAN_RPM: |
| 164 | coolingDevices[i].type = CoolingType::FAN_RPM; |
| 165 | break; |
| 166 | default: |
| 167 | ALOGE("Unknown cooling device %s type", list[i].name); |
| 168 | } |
| 169 | coolingDevices[i].name = list[i].name; |
| 170 | coolingDevices[i].currentValue = list[i].current_value; |
| 171 | } |
| 172 | } |
| 173 | } |
| 174 | if (size < 0) { |
| 175 | status.code = ThermalStatusCode::FAILURE; |
| 176 | status.debugMessage = strerror(-size); |
| 177 | } |
| 178 | _hidl_cb(status, coolingDevices); |
| 179 | return Void(); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 180 | } |
| 181 | |
| 182 | IThermal* HIDL_FETCH_IThermal(const char* /* name */) { |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 183 | thermal_module_t* module; |
| 184 | status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID, |
| 185 | const_cast<hw_module_t const**>( |
| 186 | reinterpret_cast<hw_module_t**>(&module))); |
| 187 | if (err || !module) { |
| 188 | ALOGE("Couldn't load %s module (%s)", THERMAL_HARDWARE_MODULE_ID, |
| 189 | strerror(-err)); |
| 190 | } |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 191 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 192 | if (err == 0 && module->common.methods->open) { |
| 193 | struct hw_device_t* device; |
| 194 | err = module->common.methods->open(&module->common, |
| 195 | THERMAL_HARDWARE_MODULE_ID, &device); |
| 196 | if (err) { |
| 197 | ALOGE("Couldn't open %s module (%s)", THERMAL_HARDWARE_MODULE_ID, |
| 198 | strerror(-err)); |
| 199 | } else { |
| 200 | return new Thermal(reinterpret_cast<thermal_module_t*>(device)); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 201 | } |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 202 | } |
| 203 | return new Thermal(module); |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 204 | } |
| 205 | |
Polina Bondarenko | 59d05eb | 2016-11-03 16:41:18 +0100 | [diff] [blame] | 206 | } // namespace implementation |
Polina Bondarenko | 254e2fe | 2016-10-11 16:39:23 +0200 | [diff] [blame] | 207 | } // namespace V1_0 |
| 208 | } // namespace thermal |
| 209 | } // namespace hardware |
| 210 | } // namespace android |