Home | History | Annotate | Download | only in thermal
      1 /*
      2  * Copyright (C) 2017 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 #include <cerrno>
     18 #include <vector>
     19 
     20 #include <android-base/file.h>
     21 #include <android-base/logging.h>
     22 
     23 #include "Thermal.h"
     24 #include "thermal-helper.h"
     25 
     26 namespace android {
     27 namespace hardware {
     28 namespace thermal {
     29 namespace V1_1 {
     30 namespace implementation {
     31 
     32 Thermal::Thermal() : enabled(initThermal()) {}
     33 
     34 namespace {
     35 
     36 // Saves the IThermalCallback client object registered from the
     37 // framework for sending thermal events to the framework thermal event bus.
     38 sp<IThermalCallback> gThermalCallback;
     39 
     40 struct ThermalDeathRecipient : hidl_death_recipient {
     41     virtual void serviceDied(
     42         uint64_t cookie __unused, const wp<IBase>& who __unused) {
     43         gThermalCallback = nullptr;
     44         LOG(ERROR) << "IThermalCallback HIDL service died";
     45     }
     46 };
     47 
     48 sp<ThermalDeathRecipient> gThermalCallbackDied = nullptr;
     49 
     50 } // anonymous namespace
     51 
     52 // Methods from ::android::hardware::thermal::V1_0::IThermal follow.
     53 Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) {
     54     ThermalStatus status;
     55     status.code = ThermalStatusCode::SUCCESS;
     56     hidl_vec<Temperature> temperatures;
     57     temperatures.resize(kTemperatureNum);
     58 
     59     if (!enabled) {
     60         status.code = ThermalStatusCode::FAILURE;
     61         status.debugMessage = "Unsupported hardware";
     62         _hidl_cb(status, temperatures);
     63         LOG(ERROR) << "ThermalHAL not initialized properly.";
     64         return Void();
     65     }
     66 
     67     if (fillTemperatures(&temperatures) != kTemperatureNum) {
     68         status.code = ThermalStatusCode::FAILURE;
     69         status.debugMessage = "Error reading thermal sensors.";
     70     }
     71     _hidl_cb(status, temperatures);
     72 
     73     for (auto& t : temperatures) {
     74         LOG(DEBUG) << "getTemperatures "
     75                    << " Type: " << static_cast<int>(t.type)
     76                    << " Name: " << t.name
     77                    << " CurrentValue: " << t.currentValue
     78                    << " ThrottlingThreshold: " << t.throttlingThreshold
     79                    << " ShutdownThreshold: " << t.shutdownThreshold
     80                    << " VrThrottlingThreshold: " << t.vrThrottlingThreshold;
     81     }
     82 
     83     return Void();
     84 }
     85 
     86 Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) {
     87     ThermalStatus status;
     88     status.code = ThermalStatusCode::SUCCESS;
     89     hidl_vec<CpuUsage> cpuUsages;
     90     cpuUsages.resize(kCpuNum);
     91 
     92     if (!enabled) {
     93         status.code = ThermalStatusCode::FAILURE;
     94         status.debugMessage = "Unsupported hardware";
     95         _hidl_cb(status, cpuUsages);
     96         LOG(ERROR) << "ThermalHAL not initialized properly.";
     97         return Void();
     98     }
     99 
    100     ssize_t ret = fillCpuUsages(&cpuUsages);
    101     if (ret < 0) {
    102         status.code = ThermalStatusCode::FAILURE;
    103         status.debugMessage = strerror(-ret);
    104     }
    105 
    106     for (auto& u : cpuUsages) {
    107         LOG(DEBUG) << "getCpuUsages "
    108                    << " Name: " << u.name
    109                    << " Active: " << u.active
    110                    << " Total: " << u.total
    111                    << " IsOnline: " << u.isOnline;
    112     }
    113 
    114     _hidl_cb(status, cpuUsages);
    115     return Void();
    116 }
    117 
    118 Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) {
    119     ThermalStatus status;
    120     status.code = ThermalStatusCode::SUCCESS;
    121     hidl_vec<CoolingDevice> coolingDevices;
    122 
    123     if (!enabled) {
    124         status.code = ThermalStatusCode::FAILURE;
    125         status.debugMessage = "Unsupported hardware";
    126         _hidl_cb(status, coolingDevices);
    127         LOG(ERROR) << "ThermalHAL not initialized properly.";
    128         return Void();
    129     }
    130 
    131     LOG(DEBUG) << "No Cooling Device";
    132     _hidl_cb(status, coolingDevices);
    133     return Void();
    134 }
    135 
    136 // Methods from ::android::hardware::thermal::V1_1::IThermal follow.
    137 
    138 Return<void> Thermal::registerThermalCallback(
    139     const sp<IThermalCallback>& callback) {
    140     gThermalCallback = callback;
    141 
    142     if (gThermalCallback != nullptr) {
    143         if (gThermalCallbackDied == nullptr)
    144             gThermalCallbackDied = new ThermalDeathRecipient();
    145 
    146         if (gThermalCallbackDied != nullptr)
    147             gThermalCallback->linkToDeath(
    148                 gThermalCallbackDied, 0x451F /* cookie, unused */);
    149         LOG(INFO) << "ThermalCallback registered";
    150     } else {
    151         LOG(INFO) << "ThermalCallback unregistered";
    152     }
    153     return Void();
    154 }
    155 
    156 // Local functions used internally by thermal-engine follow.
    157 
    158 std::string Thermal::getSkinSensorType() {
    159     return getTargetSkinSensorType();
    160 }
    161 
    162 void Thermal::notifyThrottling(
    163     bool isThrottling, const Temperature& temperature) {
    164     if (gThermalCallback != nullptr) {
    165         Return<void> ret =
    166             gThermalCallback->notifyThrottling(isThrottling, temperature);
    167         if (!ret.isOk()) {
    168           if (ret.isDeadObject()) {
    169               gThermalCallback = nullptr;
    170               LOG(WARNING) << "Dropped throttling event, ThermalCallback died";
    171           } else {
    172               LOG(WARNING) <<
    173                   "Failed to send throttling event to ThermalCallback";
    174           }
    175         }
    176     } else {
    177         LOG(WARNING) <<
    178             "Dropped throttling event, no ThermalCallback registered";
    179     }
    180 }
    181 
    182 Return<void> Thermal::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
    183     if (handle != nullptr && handle->numFds >= 1) {
    184         int fd = handle->data[0];
    185         std::ostringstream dump_buf;
    186 
    187         if (!enabled) {
    188             dump_buf << "ThermalHAL not initialized properly." << std::endl;
    189         } else {
    190             hidl_vec<Temperature> temperatures;
    191             hidl_vec<CpuUsage> cpu_usages;
    192             cpu_usages.resize(kCpuNum);
    193             temperatures.resize(kTemperatureNum);
    194 
    195             dump_buf << "getTemperatures:" << std::endl;
    196             if (fillTemperatures(&temperatures) != kTemperatureNum) {
    197                 dump_buf << "Failed to read thermal sensors." << std::endl;
    198             } else {
    199                 for (const auto& t : temperatures) {
    200                     dump_buf << "Name: " << t.name
    201                              << " Type: " << android::hardware::thermal::V1_0::toString(t.type)
    202                              << " CurrentValue: " << t.currentValue
    203                              << " ThrottlingThreshold: " << t.throttlingThreshold
    204                              << " ShutdownThreshold: " << t.shutdownThreshold
    205                              << " VrThrottlingThreshold: " << t.vrThrottlingThreshold
    206                              << std::endl;
    207                 }
    208             }
    209 
    210             dump_buf << "getCpuUsages:" << std::endl;
    211             ssize_t ret = fillCpuUsages(&cpu_usages);
    212             if (ret < 0) {
    213                 dump_buf << "Failed to get CPU usages." << std::endl;
    214             } else {
    215                 for (const auto& usage : cpu_usages) {
    216                     dump_buf << "Name: " << usage.name
    217                              << " Active: " << usage.active
    218                              << " Total: " << usage.total
    219                              << " IsOnline: " << usage.isOnline
    220                              << std::endl;
    221                 }
    222             }
    223 
    224         }
    225         std::string buf = dump_buf.str();
    226         if (!android::base::WriteStringToFd(buf, fd)) {
    227             PLOG(ERROR) << "Failed to dump state to fd";
    228         }
    229         fsync(fd);
    230     }
    231     return Void();
    232 }
    233 
    234 }  // namespace implementation
    235 }  // namespace V1_1
    236 }  // namespace thermal
    237 }  // namespace hardware
    238 }  // namespace android
    239