blob: 7134abd3f0fecae393050971ae45022582b7ce44 [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
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070031/* Changes from Qualcomm Innovation Center are provided under the following license:
32
Priyansh Jainc5ea5602024-08-12 11:18:21 +053033Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070034SPDX-License-Identifier: BSD-3-Clause-Clear */
35
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070036#include <ctype.h>
37#include <errno.h>
38#include <inttypes.h>
39#include <stdlib.h>
40#include <cerrno>
41#include <mutex>
42#include <string>
43
44#include <android-base/file.h>
45#include <android-base/logging.h>
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070046
47#include "thermal.h"
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070048
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070049namespace aidl::android::hardware::thermal{
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070050
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070051using ndk::ScopedAStatus;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070052
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070053namespace {
54
55bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
56 const std::shared_ptr<::ndk::ICInterface>& right) {
57 if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
58 return left == right;
59 }
60 return left->asBinder() == right->asBinder();
61}
62
63}// namespace
64
65static const Temperature dummy_temp_1_0 = {
66 .type = TemperatureType::SKIN,
Ram Chandrasekara56b9f52020-09-22 12:36:05 -070067 .name = "test sensor",
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070068 .value = 30,
Priyansh Jainb5864dd2024-05-20 15:45:09 +053069 .throttlingStatus = ThrottlingSeverity::NONE,
Ram Chandrasekara56b9f52020-09-22 12:36:05 -070070};
71
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070072Thermal::Thermal():
73 utils(std::bind(&Thermal::sendThrottlingChangeCB, this,
74 std::placeholders::_1))
75{ }
76
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070077ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* out_data) {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -070078
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070079 std::vector<CoolingDevice> cdev;
80
81 if (!utils.isCdevInitialized())
82 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
83 "ThermalHAL not initialized properly.");
84 else {
85 if (utils.readCdevStates(cdev) <= 0)
86 LOG(VERBOSE) << __func__ << "Failed to read thermal cooling devices.";
87 }
88
89 if (out_data != nullptr)
90 *out_data = std::move(cdev);
91
92 return ScopedAStatus::ok();
93}
94
95ScopedAStatus Thermal::getCoolingDevicesWithType(CoolingType in_type,
96 std::vector<CoolingDevice>* out_data) {
97
98 std::vector<CoolingDevice> cdev;
99
100 if (!utils.isCdevInitialized())
101 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
102 "ThermalHAL not initialized properly.");
103 else {
104 if (utils.readCdevStates(in_type, cdev) <= 0)
105 LOG(VERBOSE) << __func__ << "Failed to read thermal cooling devices.";
106 }
107
108 if (out_data != nullptr)
109 *out_data = std::move(cdev);
110
111 return ScopedAStatus::ok();
112}
113
114ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* out_temp) {
115 LOG(VERBOSE) << __func__;
116 std::vector<Temperature> temperatures;
117
Ram Chandrasekara56b9f52020-09-22 12:36:05 -0700118 if (!utils.isSensorInitialized()) {
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700119 std::vector<Temperature> _temp = {dummy_temp_1_0};
120 LOG(VERBOSE) << __func__ << " Returning Dummy Value";
121
122 if (out_temp != nullptr)
123 *out_temp = std::move(_temp);
124
125 return ScopedAStatus::ok();
Ram Chandrasekara56b9f52020-09-22 12:36:05 -0700126 }
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700127
Ram Chandrasekarf020a1d2020-08-25 14:25:14 -0700128 if (utils.readTemperatures(temperatures) <= 0)
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700129 LOG(VERBOSE) << __func__ << "Sensor Temperature read failure.";
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700130
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700131 if (out_temp != nullptr)
132 *out_temp = std::move(temperatures);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700133
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700134 return ScopedAStatus::ok();
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700135}
136
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700137ScopedAStatus Thermal::getTemperaturesWithType(TemperatureType in_type,
138 std::vector<Temperature>* out_temp) {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700139
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700140 std::vector<Temperature> temperatures;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700141
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530142 if (!utils.isSensorInitialized(in_type))
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700143 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530144 "ThermalHAL given sensor type Not initialized.");
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700145 else {
146 if (utils.readTemperatures(in_type, temperatures) <= 0)
147 LOG(VERBOSE) << __func__ << "Sensor Temperature read failure.";
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700148 }
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700149
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700150 if (out_temp != nullptr)
151 *out_temp = std::move(temperatures);
152
153 return ScopedAStatus::ok();
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700154}
155
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700156ScopedAStatus Thermal::getTemperatureThresholds(std::vector<TemperatureThreshold>* out_temp_thresh) {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700157
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700158 std::vector<TemperatureThreshold> thresh;
159
160 if (!utils.isSensorInitialized())
161 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530162 "ThermalHAL for sensor not initialized.");
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700163
164 if (utils.readTemperatureThreshold(thresh) <= 0)
165 LOG(VERBOSE) << __func__ << "Sensor Threshold read failure or type not supported.";
166
167 if (out_temp_thresh != nullptr)
168 *out_temp_thresh = std::move(thresh);
169
170 return ScopedAStatus::ok();
171}
172
173ScopedAStatus Thermal::getTemperatureThresholdsWithType(
174 TemperatureType in_type,
175 std::vector<TemperatureThreshold>* out_temp_thresh) {
176
177 std::vector<TemperatureThreshold> thresh;
178
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530179 if (!utils.isSensorInitialized(in_type))
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700180 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530181 "ThermalHAL given sensor type not initialized.");
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700182 else{
183 if (utils.readTemperatureThreshold(in_type, thresh) <= 0)
184 LOG(VERBOSE) << __func__ << "Sensor Threshold read failure or type not supported.";
185 }
186
187 if (out_temp_thresh != nullptr)
188 *out_temp_thresh = std::move(thresh);
189
190 return ScopedAStatus::ok();
191}
192
193ScopedAStatus Thermal::registerThermalChangedCallback(
194 const std::shared_ptr<IThermalChangedCallback>& in_callback) {
195
196 if (in_callback == nullptr) {
197 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
198 "Invalid nullptr callback");
199 }
200
201 {
202 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
203 TemperatureType in_type = TemperatureType::UNKNOWN;
204 for (CallbackSetting _cb: cb) {
205 if (interfacesEqual(_cb.callback, in_callback))
206 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
207 "Callback already registered");
208 }
209 cb.emplace_back(in_callback, in_type);
210 LOG(DEBUG) << "A callback has been registered to ThermalHAL ";
211 }
212 return ScopedAStatus::ok();
213}
214
215ScopedAStatus Thermal::registerThermalChangedCallbackWithType(
216 const std::shared_ptr<IThermalChangedCallback>& in_callback, TemperatureType in_type) {
217 LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
218 << ", TemperatureType: " << static_cast<int32_t>(in_type);
219 if (in_callback == nullptr) {
220 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
221 "Invalid nullptr callback");
222 }
223 if (in_type == TemperatureType::BCL_VOLTAGE ||
224 in_type == TemperatureType::BCL_CURRENT)
225 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
226 "BCL current and voltage notification not supported");
227 {
228 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
229 for (CallbackSetting _cb: cb) {
230 if (interfacesEqual(_cb.callback, in_callback))
231 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
232 "Callback already registered");
233 }
234 cb.emplace_back(in_callback, in_type);
235 LOG(DEBUG) << "A callback has been registered to ThermalHAL Type: " << android::hardware::thermal::toString(in_type);
236 }
237 return ScopedAStatus::ok();
238}
239
240ScopedAStatus Thermal::unregisterThermalChangedCallback(
241 const std::shared_ptr<IThermalChangedCallback>& in_callback) {
242
243 if (in_callback == nullptr) {
244 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
245 "Invalid nullptr callback");
246 }
247
248 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700249 std::vector<CallbackSetting>::iterator it;
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700250 bool removed = false;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700251 for (it = cb.begin(); it != cb.end(); it++) {
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700252 if (interfacesEqual(it->callback, in_callback)) {
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700253 cb.erase(it);
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700254 LOG(DEBUG) << "callback unregistered. isFilter: ";
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700255 removed = true;
256 break;
257 }
258 }
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700259 if (!removed) {
260 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
261 "Callback wasn't registered");
262 }
263 LOG(DEBUG) << "A callback has been registered to ThermalHAL" ;
264
265 return ScopedAStatus::ok();
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700266}
267
268void Thermal::sendThrottlingChangeCB(const Temperature &t)
269{
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700270 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700271 std::vector<CallbackSetting>::iterator it;
272
273 LOG(DEBUG) << "Throttle Severity change: " << " Type: " << (int)t.type
274 << " Name: " << t.name << " Value: " << t.value <<
275 " ThrottlingStatus: " << (int)t.throttlingStatus;
Ram Chandrasekar1003d372020-08-27 17:18:07 -0700276 it = cb.begin();
277 while (it != cb.end()) {
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700278 if (it->type == t.type || it->type == TemperatureType::UNKNOWN) {
279 ::ndk::ScopedAStatus ret = it->callback->notifyThrottling(t);
Ram Chandrasekar1003d372020-08-27 17:18:07 -0700280 if (!ret.isOk()) {
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700281 LOG(ERROR) << "Notify callback execution error. Removing"<<ret.getMessage();
Ram Chandrasekar1003d372020-08-27 17:18:07 -0700282 it = cb.erase(it);
283 continue;
284 }
285 }
286 it++;
Ram Chandrasekardac8f7d2020-06-10 12:23:28 -0700287 }
288}
289
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700290
291} // namespace aidl::android::hardware::thermal