1 /* 2 * Copyright (C) 2018 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) 2.0-service-mock" 18 19 #include <cmath> 20 #include <set> 21 22 #include <android-base/logging.h> 23 #include <hidl/HidlTransportSupport.h> 24 25 #include "Thermal.h" 26 27 namespace android { 28 namespace hardware { 29 namespace thermal { 30 namespace V2_0 { 31 namespace implementation { 32 33 using ::android::sp; 34 using ::android::hardware::interfacesEqual; 35 using ::android::hardware::thermal::V1_0::ThermalStatus; 36 using ::android::hardware::thermal::V1_0::ThermalStatusCode; 37 38 std::set<sp<IThermalChangedCallback>> gCallbacks; 39 40 static const Temperature_1_0 kTemp_1_0 = { 41 .type = static_cast<::android::hardware::thermal::V1_0::TemperatureType>( 42 TemperatureType::SKIN), 43 .name = "test temperature sensor", 44 .currentValue = 30.8, 45 .throttlingThreshold = 48.0, 46 .shutdownThreshold = 60.0, 47 .vrThrottlingThreshold = 49.0, 48 }; 49 50 static const Temperature_2_0 kTemp_2_0 = { 51 .type = TemperatureType::SKIN, 52 .name = "test temperature sensor", 53 .value = 30.8, 54 .throttlingStatus = ThrottlingSeverity::NONE, 55 }; 56 57 static const TemperatureThreshold kTempThreshold = { 58 .type = TemperatureType::SKIN, 59 .name = "test temperature sensor", 60 .hotThrottlingThresholds = {{NAN, NAN, NAN, 48.0, NAN, NAN, 60.0}}, 61 .coldThrottlingThresholds = {{NAN, NAN, NAN, NAN, NAN, NAN, NAN}}, 62 .vrThrottlingThreshold = 49.0, 63 }; 64 65 static const CoolingDevice_1_0 kCooling_1_0 = { 66 .type = ::android::hardware::thermal::V1_0::CoolingType::FAN_RPM, 67 .name = "test cooling device", 68 .currentValue = 100.0, 69 }; 70 71 static const CoolingDevice_2_0 kCooling_2_0 = { 72 .type = CoolingType::FAN, 73 .name = "test cooling device", 74 .value = 100, 75 }; 76 77 static const CpuUsage kCpuUsage = { 78 .name = "cpu_name", 79 .active = 0, 80 .total = 0, 81 .isOnline = true, 82 }; 83 84 // Methods from ::android::hardware::thermal::V1_0::IThermal follow. 85 Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) { 86 ThermalStatus status; 87 status.code = ThermalStatusCode::SUCCESS; 88 std::vector<Temperature_1_0> temperatures = {kTemp_1_0}; 89 _hidl_cb(status, temperatures); 90 return Void(); 91 } 92 93 Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) { 94 ThermalStatus status; 95 status.code = ThermalStatusCode::SUCCESS; 96 std::vector<CpuUsage> cpu_usages = {kCpuUsage}; 97 _hidl_cb(status, cpu_usages); 98 return Void(); 99 } 100 101 Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) { 102 ThermalStatus status; 103 status.code = ThermalStatusCode::SUCCESS; 104 std::vector<CoolingDevice_1_0> cooling_devices = {kCooling_1_0}; 105 _hidl_cb(status, cooling_devices); 106 return Void(); 107 } 108 109 // Methods from ::android::hardware::thermal::V2_0::IThermal follow. 110 Return<void> Thermal::getCurrentTemperatures(bool filterType, TemperatureType type, 111 getCurrentTemperatures_cb _hidl_cb) { 112 ThermalStatus status; 113 status.code = ThermalStatusCode::SUCCESS; 114 std::vector<Temperature_2_0> temperatures; 115 if (filterType && type != kTemp_2_0.type) { 116 status.code = ThermalStatusCode::FAILURE; 117 status.debugMessage = "Failed to read data"; 118 } else { 119 temperatures = {kTemp_2_0}; 120 } 121 _hidl_cb(status, temperatures); 122 return Void(); 123 } 124 125 Return<void> Thermal::getTemperatureThresholds(bool filterType, TemperatureType type, 126 getTemperatureThresholds_cb _hidl_cb) { 127 ThermalStatus status; 128 status.code = ThermalStatusCode::SUCCESS; 129 std::vector<TemperatureThreshold> temperature_thresholds; 130 if (filterType && type != kTempThreshold.type) { 131 status.code = ThermalStatusCode::FAILURE; 132 status.debugMessage = "Failed to read data"; 133 } else { 134 temperature_thresholds = {kTempThreshold}; 135 } 136 _hidl_cb(status, temperature_thresholds); 137 return Void(); 138 } 139 140 Return<void> Thermal::getCurrentCoolingDevices(bool filterType, CoolingType type, 141 getCurrentCoolingDevices_cb _hidl_cb) { 142 ThermalStatus status; 143 status.code = ThermalStatusCode::SUCCESS; 144 std::vector<CoolingDevice_2_0> cooling_devices; 145 if (filterType && type != kCooling_2_0.type) { 146 status.code = ThermalStatusCode::FAILURE; 147 status.debugMessage = "Failed to read data"; 148 } else { 149 cooling_devices = {kCooling_2_0}; 150 } 151 _hidl_cb(status, cooling_devices); 152 return Void(); 153 } 154 155 Return<void> Thermal::registerThermalChangedCallback(const sp<IThermalChangedCallback>& callback, 156 bool filterType, TemperatureType type, 157 registerThermalChangedCallback_cb _hidl_cb) { 158 ThermalStatus status; 159 if (callback == nullptr) { 160 status.code = ThermalStatusCode::FAILURE; 161 status.debugMessage = "Invalid nullptr callback"; 162 LOG(ERROR) << status.debugMessage; 163 _hidl_cb(status); 164 return Void(); 165 } else { 166 status.code = ThermalStatusCode::SUCCESS; 167 } 168 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_); 169 if (std::any_of(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting& c) { 170 return interfacesEqual(c.callback, callback); 171 })) { 172 status.code = ThermalStatusCode::FAILURE; 173 status.debugMessage = "Same callback interface registered already"; 174 LOG(ERROR) << status.debugMessage; 175 } else { 176 callbacks_.emplace_back(callback, filterType, type); 177 LOG(INFO) << "A callback has been registered to ThermalHAL, isFilter: " << filterType 178 << " Type: " << android::hardware::thermal::V2_0::toString(type); 179 } 180 _hidl_cb(status); 181 return Void(); 182 } 183 184 Return<void> Thermal::unregisterThermalChangedCallback( 185 const sp<IThermalChangedCallback>& callback, unregisterThermalChangedCallback_cb _hidl_cb) { 186 ThermalStatus status; 187 if (callback == nullptr) { 188 status.code = ThermalStatusCode::FAILURE; 189 status.debugMessage = "Invalid nullptr callback"; 190 LOG(ERROR) << status.debugMessage; 191 _hidl_cb(status); 192 return Void(); 193 } else { 194 status.code = ThermalStatusCode::SUCCESS; 195 } 196 bool removed = false; 197 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_); 198 callbacks_.erase( 199 std::remove_if(callbacks_.begin(), callbacks_.end(), 200 [&](const CallbackSetting& c) { 201 if (interfacesEqual(c.callback, callback)) { 202 LOG(INFO) 203 << "A callback has been unregistered from ThermalHAL, isFilter: " 204 << c.is_filter_type << " Type: " 205 << android::hardware::thermal::V2_0::toString(c.type); 206 removed = true; 207 return true; 208 } 209 return false; 210 }), 211 callbacks_.end()); 212 if (!removed) { 213 status.code = ThermalStatusCode::FAILURE; 214 status.debugMessage = "The callback was not registered before"; 215 LOG(ERROR) << status.debugMessage; 216 } 217 _hidl_cb(status); 218 return Void(); 219 } 220 221 } // namespace implementation 222 } // namespace V2_0 223 } // namespace thermal 224 } // namespace hardware 225 } // namespace android 226