blob: 05cc8e0acf166b26ac54cc6ae2a84681865c76c5 [file] [log] [blame]
Peiyong Lin56960752022-09-30 21:52:52 +00001/*
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#include <algorithm>
18#include <chrono>
19#include <cmath>
20#include <memory>
21#include <string>
22#include <thread>
23#include <vector>
24
25#define LOG_TAG "thermal_aidl_hal_test"
26
27#include <aidl/Gtest.h>
28#include <aidl/Vintf.h>
29#include <aidl/android/hardware/thermal/BnThermal.h>
30#include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
31#include <android-base/logging.h>
32#include <android-base/properties.h>
33#include <android/binder_ibinder.h>
34#include <android/binder_interface_utils.h>
35#include <android/binder_manager.h>
36#include <android/binder_process.h>
37#include <android/binder_status.h>
38#include <gtest/gtest.h>
39
40#include <unistd.h>
41
42namespace aidl::android::hardware::thermal {
43
44namespace {
45
46using ::android::sp;
47using android::hardware::thermal::CoolingDevice;
48using android::hardware::thermal::IThermal;
49using android::hardware::thermal::Temperature;
50using android::hardware::thermal::TemperatureType;
51
52using namespace std::string_literals;
53using namespace std::chrono_literals;
54
55static const Temperature kThrottleTemp = {
56 .type = TemperatureType::SKIN,
57 .name = "test temperature sensor",
58 .value = 98.6,
59 .throttlingStatus = ThrottlingSeverity::CRITICAL,
60};
61
62// Callback class for receiving thermal event notifications from main class
63class ThermalCallback : public BnThermalChangedCallback {
64 public:
65 ndk::ScopedAStatus notifyThrottling(const Temperature&) override {
66 {
67 std::lock_guard<std::mutex> lock(mMutex);
68 mInvoke = true;
69 }
70 mNotifyThrottling.notify_all();
71 return ndk::ScopedAStatus::ok();
72 }
73
74 template <typename R, typename P>
75 [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
76 std::unique_lock<std::mutex> lock(mMutex);
77 bool r = mNotifyThrottling.wait_for(lock, duration, [this] { return this->mInvoke; });
78 mInvoke = false;
79 return r;
80 }
81
82 private:
83 std::mutex mMutex;
84 std::condition_variable mNotifyThrottling;
85 bool mInvoke = false;
86};
87
88// The main test class for THERMAL HIDL HAL.
89class ThermalAidlTest : public testing::TestWithParam<std::string> {
90 public:
91 void SetUp() override {
92 AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
93 ASSERT_NE(binder, nullptr);
94 mThermal = IThermal::fromBinder(ndk::SpAIBinder(binder));
95
96 mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
97 ASSERT_NE(mThermalCallback, nullptr);
Xiang Wange7b177e2022-12-21 17:55:11 -080098 ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
99 ASSERT_TRUE(status.isOk()) << status.getMessage();
Peiyong Lin56960752022-09-30 21:52:52 +0000100 }
101
102 void TearDown() override {
Xiang Wange7b177e2022-12-21 17:55:11 -0800103 ::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
104 ASSERT_TRUE(status.isOk()) << status.getMessage();
Peiyong Lin56960752022-09-30 21:52:52 +0000105 // Expect to fail if unregister again
Xiang Wangd43e8732023-02-07 12:10:33 -0800106 status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
Xiang Wangd43e8732023-02-07 12:10:33 -0800107 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
Peiyong Lin56960752022-09-30 21:52:52 +0000108 }
109
110 protected:
111 std::shared_ptr<IThermal> mThermal;
112 std::shared_ptr<ThermalCallback> mThermalCallback;
113};
114
115// Test ThermalChangedCallback::notifyThrottling().
116// This just calls into and back from our local ThermalChangedCallback impl.
117TEST_P(ThermalAidlTest, NotifyThrottlingTest) {
118 std::shared_ptr<ThermalCallback> thermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
Xiang Wange7b177e2022-12-21 17:55:11 -0800119 ::ndk::ScopedAStatus status = thermalCallback->notifyThrottling(kThrottleTemp);
120 ASSERT_TRUE(status.isOk()) << status.getMessage();
Peiyong Lin56960752022-09-30 21:52:52 +0000121 ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
122}
123
Xiang Wange7b177e2022-12-21 17:55:11 -0800124// Test Thermal->registerThermalChangedCallback.
125TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
126 // Expect to fail with same callback
127 ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
128 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
129 // Expect to fail with null callback
130 status = mThermal->registerThermalChangedCallback(nullptr);
131 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
132 std::shared_ptr<ThermalCallback> localThermalCallback =
133 ndk::SharedRefBase::make<ThermalCallback>();
134 // Expect to succeed with different callback
135 status = mThermal->registerThermalChangedCallback(localThermalCallback);
136 ASSERT_TRUE(status.isOk()) << status.getMessage();
137 ASSERT_TRUE(localThermalCallback->waitForCallback(200ms));
138 // Remove the local callback
139 status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
140 ASSERT_TRUE(status.isOk()) << status.getMessage();
141 // Expect to fail with null callback
142 status = mThermal->unregisterThermalChangedCallback(nullptr);
143 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
144}
145
146// Test Thermal->registerThermalChangedCallbackWithType.
147TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackWithTypeTest) {
148 // Expect to fail with same callback
149 ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallbackWithType(
150 mThermalCallback, TemperatureType::SKIN);
151 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
152 // Expect to fail with null callback
153 status = mThermal->registerThermalChangedCallbackWithType(nullptr, TemperatureType::SKIN);
154 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
155 std::shared_ptr<ThermalCallback> localThermalCallback =
156 ndk::SharedRefBase::make<ThermalCallback>();
157 // Expect to succeed with different callback
158 status = mThermal->registerThermalChangedCallbackWithType(localThermalCallback,
159 TemperatureType::SKIN);
160 ASSERT_TRUE(status.isOk()) << status.getMessage();
161 ASSERT_TRUE(localThermalCallback->waitForCallback(200ms));
162 // Remove the local callback
163 status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
164 ASSERT_TRUE(status.isOk()) << status.getMessage();
165 // Expect to fail with null callback
166 status = mThermal->unregisterThermalChangedCallback(nullptr);
167 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
168}
169
170// Test Thermal->getCurrentTemperatures().
171TEST_P(ThermalAidlTest, TemperatureTest) {
172 std::vector<Temperature> ret;
173 ::ndk::ScopedAStatus status = mThermal->getTemperatures(&ret);
174 if (status.isOk()) {
175 for (auto& i : ret) {
176 EXPECT_LT(0u, i.name.size());
177 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
178 }
179 } else {
180 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
181 }
182
183 auto types = ::ndk::enum_range<TemperatureType>();
184 for (const auto& type : types) {
185 status = mThermal->getTemperaturesWithType(type, &ret);
186
187 if (status.isOk()) {
188 for (auto& i : ret) {
189 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
190 toString(i.type) + " for " + i.name;
191 EXPECT_LT(0u, i.name.size());
192 }
193 } else {
194 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
195 }
196 }
197}
198
199// Test Thermal->getTemperatureThresholds().
200TEST_P(ThermalAidlTest, TemperatureThresholdTest) {
201 std::vector<TemperatureThreshold> ret;
202 ::ndk::ScopedAStatus status = mThermal->getTemperatureThresholds(&ret);
203 if (status.isOk()) {
204 for (auto& i : ret) {
205 EXPECT_LT(0u, i.name.size());
206 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
207 }
208 } else {
209 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
210 }
211
212 auto types = ::ndk::enum_range<TemperatureType>();
213 for (const auto& type : types) {
214 status = mThermal->getTemperatureThresholdsWithType(type, &ret);
215
216 if (status.isOk()) {
217 for (auto& i : ret) {
218 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
219 toString(i.type) + " for " + i.name;
220 EXPECT_LT(0u, i.name.size());
221 }
222 } else {
223 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
224 }
225 }
226}
227
228// Test Thermal->getCoolingDevices().
229TEST_P(ThermalAidlTest, CoolingDeviceTest) {
230 std::vector<CoolingDevice> ret;
231 ::ndk::ScopedAStatus status = mThermal->getCoolingDevices(&ret);
232 if (status.isOk()) {
233 for (auto& i : ret) {
234 EXPECT_LT(0u, i.name.size());
235 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
236 }
237 } else {
238 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
239 }
240
241 auto types = ::ndk::enum_range<CoolingType>();
242 for (const auto& type : types) {
243 status = mThermal->getCoolingDevicesWithType(type, &ret);
244 if (status.isOk()) {
245 ASSERT_TRUE(status.isOk());
246 for (auto& i : ret) {
247 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
248 toString(i.type) + " for " + i.name;
249 EXPECT_LT(0u, i.name.size());
250 }
251 } else {
252 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
253 }
254 }
255}
256
Peiyong Lin56960752022-09-30 21:52:52 +0000257GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
258INSTANTIATE_TEST_SUITE_P(
259 Thermal, ThermalAidlTest,
260 testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
261 ::android::PrintInstanceNameToString);
262
263} // namespace
Xiang Wangdd0edc62023-02-08 16:47:06 -0800264} // namespace aidl::android::hardware::thermal
Peiyong Lin56960752022-09-30 21:52:52 +0000265
266int main(int argc, char** argv) {
267 ::testing::InitGoogleTest(&argc, argv);
268 ABinderProcess_setThreadPoolMaxThreadCount(1);
269 ABinderProcess_startThreadPool();
270 return RUN_ALL_TESTS();
271}