blob: ea4272aa382cd7fd74be4996728c3da3bc4ee340 [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.
29 */
30
31#include <ctype.h>
32#include <errno.h>
33#include <inttypes.h>
34#include <stdlib.h>
35#include <cerrno>
36#include <mutex>
37#include <string>
38
39#include <android-base/file.h>
40#include <android-base/logging.h>
41#include <hidl/HidlTransportSupport.h>
42
43#include "thermal.h"
44#include "thermalUtils.h"
45
46namespace android {
47namespace hardware {
48namespace thermal {
49namespace V2_0 {
50namespace implementation {
51
52using ::android::hardware::interfacesEqual;
53
Ram Chandrasekara56b9f52020-09-22 12:36:05 -070054static const Temperature_1_0 dummy_temp_1_0 = {
55 .type = TemperatureType_1_0::SKIN,
56 .name = "test sensor",
57 .currentValue = 30,
58 .throttlingThreshold = 40,
59 .shutdownThreshold = 60,
60 .vrThrottlingThreshold = 40,
61};
62
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070063template <typename A, typename B>
64Return<void> exit_hal(A _cb, hidl_vec<B> _data, std::string_view _msg) {
65 ThermalStatus _status;
66
67 _status.code = ThermalStatusCode::FAILURE;
68 _status.debugMessage = _msg.data();
69 LOG(ERROR) << _msg;
70 _cb(_status, _data);
71
72 return Void();
73}
74
75template <typename A>
76Return<void> exit_hal(A _cb, std::string_view _msg) {
77 ThermalStatus _status;
78
79 _status.code = ThermalStatusCode::FAILURE;
80 _status.debugMessage = _msg.data();
81 LOG(ERROR) << _msg;
82 _cb(_status);
83
84 return Void();
85}
86
87Thermal::Thermal():
88 utils(std::bind(&Thermal::sendThrottlingChangeCB, this,
89 std::placeholders::_1))
90{ }
91
92Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb)
93{
94 ThermalStatus status;
95 hidl_vec<Temperature_1_0> temperatures;
96
97 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekara56b9f52020-09-22 12:36:05 -070098 if (!utils.isSensorInitialized()) {
99 std::vector<Temperature_1_0> _temp = {dummy_temp_1_0};
100 LOG(INFO) << "Returning Dummy Value" << std::endl;
101 _hidl_cb(status, _temp);
102 return Void();
103 }
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700104
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700105 if (utils.readTemperatures(temperatures) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700106 return exit_hal(_hidl_cb, temperatures,
107 "Sensor Temperature read failure.");
108
109 _hidl_cb(status, temperatures);
110
111 return Void();
112}
113
114Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb)
115{
116
117 ThermalStatus status;
118 hidl_vec<CpuUsage> cpu_usages;
119
120 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekar72110b52020-08-06 14:39:40 -0700121 if (utils.fetchCpuUsages(cpu_usages) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700122 return exit_hal(_hidl_cb, cpu_usages,
123 "CPU usage read failure.");
124
125 _hidl_cb(status, cpu_usages);
126 return Void();
127}
128
129Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb)
130{
131 ThermalStatus status;
132 hidl_vec<CoolingDevice_1_0> cdev;
133
134 status.code = ThermalStatusCode::SUCCESS;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700135 /* V1 Cdev requires only Fan Support. */
136 _hidl_cb(status, cdev);
137 return Void();
138}
139
140Return<void> Thermal::getCurrentCoolingDevices(
141 bool filterType,
142 cdevType type,
143 getCurrentCoolingDevices_cb _hidl_cb)
144{
145 ThermalStatus status;
146 hidl_vec<CoolingDevice> cdev;
147
148 status.code = ThermalStatusCode::SUCCESS;
149 if (!utils.isCdevInitialized())
150 return exit_hal(_hidl_cb, cdev,
151 "ThermalHAL not initialized properly.");
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700152 if (utils.readCdevStates(filterType, type, cdev) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700153 return exit_hal(_hidl_cb, cdev,
154 "Failed to read thermal cooling devices.");
155
156 _hidl_cb(status, cdev);
157 return Void();
158}
159
160Return<void> Thermal::getCurrentTemperatures(
161 bool filterType,
162 TemperatureType type,
163 getCurrentTemperatures_cb _hidl_cb)
164{
165 ThermalStatus status;
166 hidl_vec<Temperature> temperatures;
167
168 status.code = ThermalStatusCode::SUCCESS;
169 if (!utils.isSensorInitialized())
170 return exit_hal(_hidl_cb, temperatures,
171 "ThermalHAL not initialized properly.");
172
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700173 if (utils.readTemperatures(filterType, type, temperatures) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700174 return exit_hal(_hidl_cb, temperatures,
175 "Sensor Temperature read failure.");
176
177 _hidl_cb(status, temperatures);
178
179 return Void();
180}
181
182Return<void> Thermal::getTemperatureThresholds(
183 bool filterType,
184 TemperatureType type,
185 getTemperatureThresholds_cb _hidl_cb)
186{
187 ThermalStatus status;
188 hidl_vec<TemperatureThreshold> thresh;
189
190 status.code = ThermalStatusCode::SUCCESS;
191 if (!utils.isSensorInitialized())
192 return exit_hal(_hidl_cb, thresh,
193 "ThermalHAL not initialized properly.");
194
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700195 if (utils.readTemperatureThreshold(filterType, type, thresh) <= 0)
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700196 return exit_hal(_hidl_cb, thresh,
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700197 "Sensor Threshold read failure or type not supported.");
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700198
199 _hidl_cb(status, thresh);
200
201 return Void();
202}
203
204Return<void> Thermal::registerThermalChangedCallback(
205 const sp<IThermalChangedCallback> &callback,
206 bool filterType,
207 TemperatureType type,
208 registerThermalChangedCallback_cb _hidl_cb)
209{
210 ThermalStatus status;
211 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700212
213 status.code = ThermalStatusCode::SUCCESS;
214 if (callback == nullptr)
215 return exit_hal(_hidl_cb, "Invalid nullptr callback");
216 if (type == TemperatureType::BCL_VOLTAGE ||
217 type == TemperatureType::BCL_CURRENT)
218 return exit_hal(_hidl_cb,
219 "BCL current and voltage notification not supported");
220
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700221 for (CallbackSetting _cb: cb) {
222 if (interfacesEqual(_cb.callback, callback))
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700223 return exit_hal(_hidl_cb,
224 "Same callback interface registered already");
225 }
226 cb.emplace_back(callback, filterType, type);
227 LOG(DEBUG) << "A callback has been registered to ThermalHAL, isFilter: " << filterType
228 << " Type: " << android::hardware::thermal::V2_0::toString(type);
229
230 _hidl_cb(status);
231 return Void();
232}
233
234Return<void> Thermal::unregisterThermalChangedCallback(
235 const sp<IThermalChangedCallback> &callback,
236 unregisterThermalChangedCallback_cb _hidl_cb)
237{
238
239 ThermalStatus status;
240 bool removed = false;
241 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
242 std::vector<CallbackSetting>::iterator it;
243
244 status.code = ThermalStatusCode::SUCCESS;
245 if (callback == nullptr)
246 return exit_hal(_hidl_cb, "Invalid nullptr callback");
247
248 for (it = cb.begin(); it != cb.end(); it++) {
249 if (interfacesEqual(it->callback, callback)) {
250 cb.erase(it);
251 LOG(DEBUG) << "callback unregistered. isFilter: "
252 << it->is_filter_type << " Type: "
253 << android::hardware::thermal::V2_0::toString(it->type);
254 removed = true;
255 break;
256 }
257 }
258 if (!removed)
259 return exit_hal(_hidl_cb, "The callback was not registered before");
260 _hidl_cb(status);
261 return Void();
262}
263
264void Thermal::sendThrottlingChangeCB(const Temperature &t)
265{
266 std::lock_guard<std::mutex> _lock(thermal_cb_mutex);
267 std::vector<CallbackSetting>::iterator it;
268
269 LOG(DEBUG) << "Throttle Severity change: " << " Type: " << (int)t.type
270 << " Name: " << t.name << " Value: " << t.value <<
271 " ThrottlingStatus: " << (int)t.throttlingStatus;
Ram Chandrasekar1003d372020-08-27 17:18:07 -0700272 it = cb.begin();
273 while (it != cb.end()) {
274 if (!it->is_filter_type || it->type == t.type) {
275 Return<void> ret = it->callback->notifyThrottling(t);
276 if (!ret.isOk()) {
277 LOG(ERROR) << "Notify callback execution error. Removing";
278 it = cb.erase(it);
279 continue;
280 }
281 }
282 it++;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700283 }
284}
285
286} // namespace implementation
287} // namespace V2_0
288} // namespace thermal
289} // namespace hardware
290} // namespace android