blob: 835fbfa85aa09f1ff938b6d6bb7eb4aa41b9cd4d [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();
Xiang Wange7b177e2022-12-21 17:55:11 -0800137 // Remove the local callback
138 status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
139 ASSERT_TRUE(status.isOk()) << status.getMessage();
140 // Expect to fail with null callback
141 status = mThermal->unregisterThermalChangedCallback(nullptr);
142 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
143}
144
145// Test Thermal->registerThermalChangedCallbackWithType.
146TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackWithTypeTest) {
147 // Expect to fail with same callback
148 ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallbackWithType(
149 mThermalCallback, TemperatureType::SKIN);
150 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
151 // Expect to fail with null callback
152 status = mThermal->registerThermalChangedCallbackWithType(nullptr, TemperatureType::SKIN);
153 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
154 std::shared_ptr<ThermalCallback> localThermalCallback =
155 ndk::SharedRefBase::make<ThermalCallback>();
156 // Expect to succeed with different callback
157 status = mThermal->registerThermalChangedCallbackWithType(localThermalCallback,
158 TemperatureType::SKIN);
159 ASSERT_TRUE(status.isOk()) << status.getMessage();
Xiang Wange7b177e2022-12-21 17:55:11 -0800160 // Remove the local callback
161 status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
162 ASSERT_TRUE(status.isOk()) << status.getMessage();
163 // Expect to fail with null callback
164 status = mThermal->unregisterThermalChangedCallback(nullptr);
165 ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
166}
167
168// Test Thermal->getCurrentTemperatures().
169TEST_P(ThermalAidlTest, TemperatureTest) {
170 std::vector<Temperature> ret;
171 ::ndk::ScopedAStatus status = mThermal->getTemperatures(&ret);
172 if (status.isOk()) {
173 for (auto& i : ret) {
174 EXPECT_LT(0u, i.name.size());
175 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
176 }
177 } else {
178 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
179 }
180
181 auto types = ::ndk::enum_range<TemperatureType>();
182 for (const auto& type : types) {
183 status = mThermal->getTemperaturesWithType(type, &ret);
184
185 if (status.isOk()) {
186 for (auto& i : ret) {
187 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
188 toString(i.type) + " for " + i.name;
189 EXPECT_LT(0u, i.name.size());
190 }
191 } else {
192 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
193 }
194 }
195}
196
197// Test Thermal->getTemperatureThresholds().
198TEST_P(ThermalAidlTest, TemperatureThresholdTest) {
199 std::vector<TemperatureThreshold> ret;
200 ::ndk::ScopedAStatus status = mThermal->getTemperatureThresholds(&ret);
201 if (status.isOk()) {
202 for (auto& i : ret) {
203 EXPECT_LT(0u, i.name.size());
204 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
205 }
206 } else {
207 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
208 }
209
210 auto types = ::ndk::enum_range<TemperatureType>();
211 for (const auto& type : types) {
212 status = mThermal->getTemperatureThresholdsWithType(type, &ret);
213
214 if (status.isOk()) {
215 for (auto& i : ret) {
216 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
217 toString(i.type) + " for " + i.name;
218 EXPECT_LT(0u, i.name.size());
219 }
220 } else {
221 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
222 }
223 }
224}
225
226// Test Thermal->getCoolingDevices().
227TEST_P(ThermalAidlTest, CoolingDeviceTest) {
228 std::vector<CoolingDevice> ret;
229 ::ndk::ScopedAStatus status = mThermal->getCoolingDevices(&ret);
230 if (status.isOk()) {
231 for (auto& i : ret) {
232 EXPECT_LT(0u, i.name.size());
233 LOG(INFO) << i.name + " " + toString(i.type) << "\n";
234 }
235 } else {
236 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
237 }
238
239 auto types = ::ndk::enum_range<CoolingType>();
240 for (const auto& type : types) {
241 status = mThermal->getCoolingDevicesWithType(type, &ret);
242 if (status.isOk()) {
243 ASSERT_TRUE(status.isOk());
244 for (auto& i : ret) {
245 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
246 toString(i.type) + " for " + i.name;
247 EXPECT_LT(0u, i.name.size());
248 }
249 } else {
250 ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
251 }
252 }
253}
254
Peiyong Lin56960752022-09-30 21:52:52 +0000255GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
256INSTANTIATE_TEST_SUITE_P(
257 Thermal, ThermalAidlTest,
258 testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
259 ::android::PrintInstanceNameToString);
260
261} // namespace
Xiang Wangdd0edc62023-02-08 16:47:06 -0800262} // namespace aidl::android::hardware::thermal
Peiyong Lin56960752022-09-30 21:52:52 +0000263
264int main(int argc, char** argv) {
265 ::testing::InitGoogleTest(&argc, argv);
266 ABinderProcess_setThreadPoolMaxThreadCount(1);
267 ABinderProcess_startThreadPool();
268 return RUN_ALL_TESTS();
269}