blob: c00320e5ec7119498b079fb58afd0362c8507c8c [file] [log] [blame]
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -07001/*
2 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Minghao Zhang0bed6312022-04-08 15:16:39 +080029 *
30 * Changes from Qualcomm Innovation Center are provided under the following license:
31 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted (subject to the limitations in the
35 * disclaimer below) provided that the following conditions are met:
36 *
37 * * Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 *
40 * * Redistributions in binary form must reproduce the above
41 * copyright notice, this list of conditions and the following
42 * disclaimer in the documentation and/or other materials provided
43 * with the distribution.
44 *
45 * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
46 * contributors may be used to endorse or promote products derived
47 * from this software without specific prior written permission.
48 *
49 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
50 * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
51 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
52 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
53 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
55 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
57 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
59 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
61 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070062 */
63
64#include <ctype.h>
65#include <errno.h>
66#include <inttypes.h>
67#include <stdlib.h>
68#include <cerrno>
69#include <mutex>
70#include <string>
71
72#include <android-base/file.h>
73#include <android-base/logging.h>
74#include <hidl/HidlTransportSupport.h>
75
76#include "thermal.h"
77#include "thermalUtils.h"
78
79namespace android {
80namespace hardware {
81namespace thermal {
82namespace V2_0 {
83namespace implementation {
84
85using ::android::hardware::interfacesEqual;
86
Ram Chandrasekara56b9f52020-09-22 12:36:05 -070087static const Temperature_1_0 dummy_temp_1_0 = {
88 .type = TemperatureType_1_0::SKIN,
89 .name = "test sensor",
90 .currentValue = 30,
91 .throttlingThreshold = 40,
92 .shutdownThreshold = 60,
93 .vrThrottlingThreshold = 40,
94};
95
Minghao Zhangd6fbfa12022-03-29 22:00:09 +080096static const Temperature dummy_temp_2_0 = {
97 .type = TemperatureType::SKIN,
98 .name = "test sensor",
99 .value = 25.0,
100 .throttlingStatus = ThrottlingSeverity::NONE,
101};
102
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700103template <typename A, typename B>
104Return<void> exit_hal(A _cb, hidl_vec<B> _data, std::string_view _msg) {
105 ThermalStatus _status;
106
107 _status.code = ThermalStatusCode::FAILURE;
108 _status.debugMessage = _msg.data();
109 LOG(ERROR) << _msg;
110 _cb(_status, _data);
111
112 return Void();
113}
114
115template <typename A>
116Return<void> exit_hal(A _cb, std::string_view _msg) {
117 ThermalStatus _status;
118
119 _status.code = ThermalStatusCode::FAILURE;
120 _status.debugMessage = _msg.data();
121 LOG(ERROR) << _msg;
122 _cb(_status);
123
124 return Void();
125}
126
127Thermal::Thermal():
128 utils(std::bind(&Thermal::sendThrottlingChangeCB, this,
129 std::placeholders::_1))
130{ }
131
132Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb)
133{
134 ThermalStatus status;
135 hidl_vec<Temperature_1_0> temperatures;
136
137 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekara56b9f52020-09-22 12:36:05 -0700138 if (!utils.isSensorInitialized()) {
139 std::vector<Temperature_1_0> _temp = {dummy_temp_1_0};
140 LOG(INFO) << "Returning Dummy Value" << std::endl;
141 _hidl_cb(status, _temp);
142 return Void();
143 }
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700144
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700145 if (utils.readTemperatures(temperatures) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700146 return exit_hal(_hidl_cb, temperatures,
147 "Sensor Temperature read failure.");
148
149 _hidl_cb(status, temperatures);
150
151 return Void();
152}
153
154Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb)
155{
156
157 ThermalStatus status;
158 hidl_vec<CpuUsage> cpu_usages;
159
160 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekar72110b52020-08-06 14:39:40 -0700161 if (utils.fetchCpuUsages(cpu_usages) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700162 return exit_hal(_hidl_cb, cpu_usages,
163 "CPU usage read failure.");
164
165 _hidl_cb(status, cpu_usages);
166 return Void();
167}
168
169Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb)
170{
171 ThermalStatus status;
172 hidl_vec<CoolingDevice_1_0> cdev;
173
174 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700175 /* V1 Cdev requires only Fan Support. */
176 _hidl_cb(status, cdev);
177 return Void();
178}
179
180Return<void> Thermal::getCurrentCoolingDevices(
181 bool filterType,
182 cdevType type,
183 getCurrentCoolingDevices_cb _hidl_cb)
184{
185 ThermalStatus status;
186 hidl_vec<CoolingDevice> cdev;
187
188 status.code = ThermalStatusCode::SUCCESS;
189 if (!utils.isCdevInitialized())
190 return exit_hal(_hidl_cb, cdev,
191 "ThermalHAL not initialized properly.");
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700192 if (utils.readCdevStates(filterType, type, cdev) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700193 return exit_hal(_hidl_cb, cdev,
194 "Failed to read thermal cooling devices.");
195
196 _hidl_cb(status, cdev);
197 return Void();
198}
199
200Return<void> Thermal::getCurrentTemperatures(
201 bool filterType,
202 TemperatureType type,
203 getCurrentTemperatures_cb _hidl_cb)
204{
205 ThermalStatus status;
206 hidl_vec<Temperature> temperatures;
207
208 status.code = ThermalStatusCode::SUCCESS;
209 if (!utils.isSensorInitialized())
210 return exit_hal(_hidl_cb, temperatures,
211 "ThermalHAL not initialized properly.");
212
Minghao Zhangd6fbfa12022-03-29 22:00:09 +0800213 if (utils.readTemperatures(filterType, type, temperatures) <= 0) {
214 if (filterType && type != dummy_temp_2_0.type) {
215 status.code = ThermalStatusCode::FAILURE;
216 status.debugMessage = "Failed to read dummy temperature value";
217 } else {
218 temperatures = {dummy_temp_2_0};
219 LOG(INFO) << "Returning Dummy Temperature Value" << std::endl;
220 }
221 }
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700222
223 _hidl_cb(status, temperatures);
224
225 return Void();
226}
227
228Return<void> Thermal::getTemperatureThresholds(
229 bool filterType,
230 TemperatureType type,
231 getTemperatureThresholds_cb _hidl_cb)
232{
233 ThermalStatus status;
234 hidl_vec<TemperatureThreshold> thresh;
235
236 status.code = ThermalStatusCode::SUCCESS;
237 if (!utils.isSensorInitialized())
238 return exit_hal(_hidl_cb, thresh,
239 "ThermalHAL not initialized properly.");
240
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700241 if (utils.readTemperatureThreshold(filterType, type, thresh) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700242 return exit_hal(_hidl_cb, thresh,
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700243 "Sensor Threshold read failure or type not supported.");
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700244
245 _hidl_cb(status, thresh);
246
247 return Void();
248}
249
250Return<void> Thermal::registerThermalChangedCallback(
251 const sp<IThermalChangedCallback> &callback,
252 bool filterType,
253 TemperatureType type,
254 registerThermalChangedCallback_cb _hidl_cb)
255{
256 ThermalStatus status;
257 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700258
259 status.code = ThermalStatusCode::SUCCESS;
260 if (callback == nullptr)
261 return exit_hal(_hidl_cb, "Invalid nullptr callback");
262 if (type == TemperatureType::BCL_VOLTAGE ||
263 type == TemperatureType::BCL_CURRENT)
264 return exit_hal(_hidl_cb,
265 "BCL current and voltage notification not supported");
266
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700267 for (CallbackSetting _cb: cb) {
268 if (interfacesEqual(_cb.callback, callback))
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700269 return exit_hal(_hidl_cb,
270 "Same callback interface registered already");
271 }
272 cb.emplace_back(callback, filterType, type);
273 LOG(DEBUG) << "A callback has been registered to ThermalHAL, isFilter: " << filterType
274 << " Type: " << android::hardware::thermal::V2_0::toString(type);
275
276 _hidl_cb(status);
277 return Void();
278}
279
280Return<void> Thermal::unregisterThermalChangedCallback(
281 const sp<IThermalChangedCallback> &callback,
282 unregisterThermalChangedCallback_cb _hidl_cb)
283{
284
285 ThermalStatus status;
286 bool removed = false;
287 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
288 std::vector<CallbackSetting>::iterator it;
289
290 status.code = ThermalStatusCode::SUCCESS;
291 if (callback == nullptr)
292 return exit_hal(_hidl_cb, "Invalid nullptr callback");
293
294 for (it = cb.begin(); it != cb.end(); it++) {
295 if (interfacesEqual(it->callback, callback)) {
296 cb.erase(it);
297 LOG(DEBUG) << "callback unregistered. isFilter: "
298 << it->is_filter_type << " Type: "
299 << android::hardware::thermal::V2_0::toString(it->type);
300 removed = true;
301 break;
302 }
303 }
304 if (!removed)
305 return exit_hal(_hidl_cb, "The callback was not registered before");
306 _hidl_cb(status);
307 return Void();
308}
309
310void Thermal::sendThrottlingChangeCB(const Temperature &t)
311{
312 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
313 std::vector<CallbackSetting>::iterator it;
314
315 LOG(DEBUG) << "Throttle Severity change: " << " Type: " << (int)t.type
316 << " Name: " << t.name << " Value: " << t.value <<
317 " ThrottlingStatus: " << (int)t.throttlingStatus;
Ram Chandrasekar1003d372020-08-27 17:18:07 -0700318 it = cb.begin();
319 while (it != cb.end()) {
320 if (!it->is_filter_type || it->type == t.type) {
321 Return<void> ret = it->callback->notifyThrottling(t);
322 if (!ret.isOk()) {
323 LOG(ERROR) << "Notify callback execution error. Removing";
324 it = cb.erase(it);
325 continue;
326 }
327 }
328 it++;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700329 }
330}
331
332} // namespace implementation
333} // namespace V2_0
334} // namespace thermal
335} // namespace hardware
336} // namespace android