Home | History | Annotate | Download | only in default
      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