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