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 (at) 1.0-impl" 18 19 #include <errno.h> 20 #include <math.h> 21 22 #include <vector> 23 24 #include <log/log.h> 25 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 37 namespace { 38 39 float finalizeTemperature(float temperature) { 40 return temperature == UNKNOWN_TEMPERATURE ? NAN : temperature; 41 } 42 43 } 44 45 Thermal::Thermal(thermal_module_t* module) : mModule(module) {} 46 47 // Methods from ::android::hardware::thermal::V1_0::IThermal follow. 48 Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) { 49 ThermalStatus status; 50 status.code = ThermalStatusCode::SUCCESS; 51 hidl_vec<Temperature> temperatures; 52 53 if (!mModule || !mModule->getTemperatures) { 54 ALOGI("getTemperatures is not implemented in Thermal HAL."); 55 _hidl_cb(status, temperatures); 56 return Void(); 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; 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); 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(); 102 } 103 104 Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) { 105 ThermalStatus status; 106 hidl_vec<CpuUsage> cpuUsages; 107 status.code = ThermalStatusCode::SUCCESS; 108 109 if (!mModule || !mModule->getCpuUsages) { 110 ALOGI("getCpuUsages is not implemented in Thermal HAL"); 111 _hidl_cb(status, cpuUsages); 112 return Void(); 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(); 140 } 141 142 Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) { 143 ThermalStatus status; 144 status.code = ThermalStatusCode::SUCCESS; 145 hidl_vec<CoolingDevice> coolingDevices; 146 147 if (!mModule || !mModule->getCoolingDevices) { 148 ALOGI("getCoolingDevices is not implemented in Thermal HAL."); 149 _hidl_cb(status, coolingDevices); 150 return Void(); 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(); 180 } 181 182 IThermal* HIDL_FETCH_IThermal(const char* /* name */) { 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 } 191 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)); 201 } 202 } 203 return new Thermal(module); 204 } 205 206 } // namespace implementation 207 } // namespace V1_0 208 } // namespace thermal 209 } // namespace hardware 210 } // namespace android 211