1 /*
2 * Copyright (C) 2022 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 "thermal_service_example"
18
19 #include "Thermal.h"
20
21 #include <android-base/logging.h>
22
23 namespace aidl::android::hardware::thermal::impl::example {
24
25 using ndk::ScopedAStatus;
26
27 namespace {
28
interfacesEqual(const std::shared_ptr<::ndk::ICInterface> & left,const std::shared_ptr<::ndk::ICInterface> & right)29 bool interfacesEqual(const std::shared_ptr<::ndk::ICInterface>& left,
30 const std::shared_ptr<::ndk::ICInterface>& right) {
31 if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
32 return left == right;
33 }
34 return left->asBinder() == right->asBinder();
35 }
36
37 } // namespace
38
getCoolingDevices(std::vector<CoolingDevice> *)39 ScopedAStatus Thermal::getCoolingDevices(std::vector<CoolingDevice>* /* out_devices */) {
40 LOG(VERBOSE) << __func__;
41 return ScopedAStatus::ok();
42 }
43
getCoolingDevicesWithType(CoolingType in_type,std::vector<CoolingDevice> *)44 ScopedAStatus Thermal::getCoolingDevicesWithType(CoolingType in_type,
45 std::vector<CoolingDevice>* /* out_devices */) {
46 LOG(VERBOSE) << __func__ << " CoolingType: " << static_cast<int32_t>(in_type);
47 return ScopedAStatus::ok();
48 }
49
getTemperatures(std::vector<Temperature> * out_temperatures)50 ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* out_temperatures) {
51 LOG(VERBOSE) << __func__;
52 std::vector<Temperature> temperatures;
53 temperatures.push_back(Temperature{
54 .name = "skin",
55 .type = TemperatureType::SKIN,
56 .value = 30.1f,
57 });
58 temperatures.push_back(Temperature{
59 .name = "battery",
60 .type = TemperatureType::BATTERY,
61 .value = 30.2f,
62 });
63 *out_temperatures = temperatures;
64 return ScopedAStatus::ok();
65 }
66
getTemperaturesWithType(TemperatureType in_type,std::vector<Temperature> * out_temperatures)67 ScopedAStatus Thermal::getTemperaturesWithType(TemperatureType in_type,
68 std::vector<Temperature>* out_temperatures) {
69 LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
70 if (in_type == TemperatureType::SKIN) {
71 std::vector<Temperature> temperatures;
72 temperatures.push_back(Temperature{
73 .name = "skin",
74 .type = TemperatureType::SKIN,
75 .value = 30.1f,
76 });
77 *out_temperatures = temperatures;
78 } else if (in_type == TemperatureType::BATTERY) {
79 std::vector<Temperature> temperatures;
80 temperatures.push_back(Temperature{
81 .name = "battery",
82 .type = TemperatureType::BATTERY,
83 .value = 30.2f,
84 });
85 *out_temperatures = temperatures;
86 }
87 return ScopedAStatus::ok();
88 }
89
getTemperatureThresholds(std::vector<TemperatureThreshold> * out_temperatureThresholds)90 ScopedAStatus Thermal::getTemperatureThresholds(
91 std::vector<TemperatureThreshold>* out_temperatureThresholds) {
92 LOG(VERBOSE) << __func__;
93 std::vector<TemperatureThreshold> temperatureThresholds;
94 temperatureThresholds.push_back(TemperatureThreshold{
95 .name = "skin",
96 .type = TemperatureType::SKIN,
97 .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
98 });
99 temperatureThresholds.push_back(TemperatureThreshold{
100 .name = "battery",
101 .type = TemperatureType::BATTERY,
102 .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
103 });
104 *out_temperatureThresholds = temperatureThresholds;
105 return ScopedAStatus::ok();
106 }
107
getTemperatureThresholdsWithType(TemperatureType in_type,std::vector<TemperatureThreshold> * out_temperatureThresholds)108 ScopedAStatus Thermal::getTemperatureThresholdsWithType(
109 TemperatureType in_type,
110 std::vector<TemperatureThreshold>* out_temperatureThresholds) {
111 LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
112 if (in_type == TemperatureType::SKIN) {
113 std::vector<TemperatureThreshold> temperatureThresholds;
114 temperatureThresholds.push_back(TemperatureThreshold{
115 .name = "skin",
116 .type = TemperatureType::SKIN,
117 .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
118 });
119 *out_temperatureThresholds = temperatureThresholds;
120 } else if (in_type == TemperatureType::BATTERY) {
121 std::vector<TemperatureThreshold> temperatureThresholds;
122 temperatureThresholds.push_back(TemperatureThreshold{
123 .name = "battery",
124 .type = TemperatureType::BATTERY,
125 .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
126 });
127 *out_temperatureThresholds = temperatureThresholds;
128 }
129 return ScopedAStatus::ok();
130 }
131
registerThermalChangedCallback(const std::shared_ptr<IThermalChangedCallback> & in_callback)132 ScopedAStatus Thermal::registerThermalChangedCallback(
133 const std::shared_ptr<IThermalChangedCallback>& in_callback) {
134 LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
135 if (in_callback == nullptr) {
136 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
137 "Invalid nullptr callback");
138 }
139 {
140 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
141 if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
142 [&](const std::shared_ptr<IThermalChangedCallback>& c) {
143 return interfacesEqual(c, in_callback);
144 })) {
145 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
146 "Callback already registered");
147 }
148 thermal_callbacks_.push_back(in_callback);
149 }
150 return ScopedAStatus::ok();
151 }
152
registerThermalChangedCallbackWithType(const std::shared_ptr<IThermalChangedCallback> & in_callback,TemperatureType in_type)153 ScopedAStatus Thermal::registerThermalChangedCallbackWithType(
154 const std::shared_ptr<IThermalChangedCallback>& in_callback, TemperatureType in_type) {
155 LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback
156 << ", TemperatureType: " << static_cast<int32_t>(in_type);
157 if (in_callback == nullptr) {
158 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
159 "Invalid nullptr callback");
160 }
161 {
162 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
163 if (std::any_of(thermal_callbacks_.begin(), thermal_callbacks_.end(),
164 [&](const std::shared_ptr<IThermalChangedCallback>& c) {
165 return interfacesEqual(c, in_callback);
166 })) {
167 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
168 "Callback already registered");
169 }
170 thermal_callbacks_.push_back(in_callback);
171 }
172 return ScopedAStatus::ok();
173 }
174
unregisterThermalChangedCallback(const std::shared_ptr<IThermalChangedCallback> & in_callback)175 ScopedAStatus Thermal::unregisterThermalChangedCallback(
176 const std::shared_ptr<IThermalChangedCallback>& in_callback) {
177 LOG(VERBOSE) << __func__ << " IThermalChangedCallback: " << in_callback;
178 if (in_callback == nullptr) {
179 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
180 "Invalid nullptr callback");
181 }
182 {
183 std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
184 bool removed = false;
185 thermal_callbacks_.erase(
186 std::remove_if(thermal_callbacks_.begin(), thermal_callbacks_.end(),
187 [&](const std::shared_ptr<IThermalChangedCallback>& c) {
188 if (interfacesEqual(c, in_callback)) {
189 removed = true;
190 return true;
191 }
192 return false;
193 }),
194 thermal_callbacks_.end());
195 if (!removed) {
196 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
197 "Callback wasn't registered");
198 }
199 }
200 return ScopedAStatus::ok();
201 }
202
registerCoolingDeviceChangedCallbackWithType(const std::shared_ptr<ICoolingDeviceChangedCallback> & in_callback,CoolingType in_type)203 ScopedAStatus Thermal::registerCoolingDeviceChangedCallbackWithType(
204 const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback, CoolingType in_type) {
205 LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback
206 << ", CoolingType: " << static_cast<int32_t>(in_type);
207 if (in_callback == nullptr) {
208 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
209 "Invalid nullptr callback");
210 }
211 {
212 std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
213 if (std::any_of(cdev_callbacks_.begin(), cdev_callbacks_.end(),
214 [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
215 return interfacesEqual(c, in_callback);
216 })) {
217 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
218 "Callback already registered");
219 }
220 cdev_callbacks_.push_back(in_callback);
221 }
222 return ScopedAStatus::ok();
223 }
224
unregisterCoolingDeviceChangedCallback(const std::shared_ptr<ICoolingDeviceChangedCallback> & in_callback)225 ScopedAStatus Thermal::unregisterCoolingDeviceChangedCallback(
226 const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) {
227 LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback;
228 if (in_callback == nullptr) {
229 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
230 "Invalid nullptr callback");
231 }
232 {
233 std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
234 bool removed = false;
235 cdev_callbacks_.erase(
236 std::remove_if(cdev_callbacks_.begin(), cdev_callbacks_.end(),
237 [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
238 if (interfacesEqual(c, in_callback)) {
239 removed = true;
240 return true;
241 }
242 return false;
243 }),
244 cdev_callbacks_.end());
245 if (!removed) {
246 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
247 "Callback wasn't registered");
248 }
249 }
250 return ScopedAStatus::ok();
251 }
252
forecastSkinTemperature(int32_t,float *)253 ndk::ScopedAStatus Thermal::forecastSkinTemperature(int32_t, float*) {
254 return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
255 }
256
257 } // namespace aidl::android::hardware::thermal::impl::example
258