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