• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <algorithm>
18 #include <chrono>
19 #include <cmath>
20 #include <memory>
21 #include <string>
22 #include <thread>
23 #include <unordered_map>
24 #include <vector>
25 
26 #define LOG_TAG "thermal_aidl_hal_test"
27 
28 #include <VtsCoreUtil.h>
29 #include <aidl/Gtest.h>
30 #include <aidl/Vintf.h>
31 #include <aidl/android/hardware/thermal/BnCoolingDeviceChangedCallback.h>
32 #include <aidl/android/hardware/thermal/BnThermal.h>
33 #include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
34 #include <android-base/logging.h>
35 #include <android-base/properties.h>
36 #include <android/binder_ibinder.h>
37 #include <android/binder_interface_utils.h>
38 #include <android/binder_manager.h>
39 #include <android/binder_process.h>
40 #include <android/binder_status.h>
41 #include <cutils/properties.h>
42 #include <gtest/gtest.h>
43 
44 #include <unistd.h>
45 
46 namespace aidl::android::hardware::thermal {
47 
48 namespace {
49 
50 using ::android::sp;
51 using android::hardware::thermal::CoolingDevice;
52 using android::hardware::thermal::IThermal;
53 using android::hardware::thermal::Temperature;
54 using android::hardware::thermal::TemperatureType;
55 
56 using namespace std::string_literals;
57 using namespace std::chrono_literals;
58 
59 static const Temperature kThrottleTemp = {
60         .type = TemperatureType::SKIN,
61         .name = "test temperature sensor",
62         .value = 98.6,
63         .throttlingStatus = ThrottlingSeverity::CRITICAL,
64 };
65 
66 static const CoolingDevice kCoolingDevice = {
67         .type = CoolingType::CPU,
68         .name = "test cooling device",
69         .value = 1,
70         .powerLimitMw = 300,
71         .powerMw = 500,
72         .timeWindowMs = 7000,
73 };
74 
75 static const std::string FEATURE_WATCH = "android.hardware.type.watch";
76 static const std::string FEATURE_TELEVISION = "android.hardware.type.television";
77 static const std::string FEATURE_LEANBACK = "android.software.leanback";
78 static const std::string FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
79 static const std::string FEATURE_PC = "android.hardware.type.pc";
80 static const std::string FEATURE_EMBEDDED = "android.hardware.type.embedded";
81 static const std::string kNonHandheldFeatures[] = {FEATURE_AUTOMOTIVE, FEATURE_LEANBACK,
82                                                    FEATURE_PC,         FEATURE_TELEVISION,
83                                                    FEATURE_WATCH,      FEATURE_EMBEDDED};
84 
85 // Callback class for receiving thermal event notifications from main class
86 class ThermalCallback : public BnThermalChangedCallback {
87   public:
notifyThrottling(const Temperature &)88     ndk::ScopedAStatus notifyThrottling(const Temperature&) override {
89         {
90             std::lock_guard<std::mutex> lock(mMutex);
91             mInvoke = true;
92         }
93         mNotifyThrottling.notify_all();
94         return ndk::ScopedAStatus::ok();
95     }
96 
notifyThresholdChanged(const TemperatureThreshold &)97     ndk::ScopedAStatus notifyThresholdChanged(const TemperatureThreshold&) {
98         return ndk::ScopedAStatus::ok();
99     }
100 
101     template <typename R, typename P>
waitForCallback(std::chrono::duration<R,P> duration)102     [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
103         std::unique_lock<std::mutex> lock(mMutex);
104         bool r = mNotifyThrottling.wait_for(lock, duration, [this] { return this->mInvoke; });
105         mInvoke = false;
106         return r;
107     }
108 
109   private:
110     std::mutex mMutex;
111     std::condition_variable mNotifyThrottling;
112     bool mInvoke = false;
113 };
114 
115 // Callback class for receiving cooling device event notifications from main class
116 class CoolingDeviceCallback : public BnCoolingDeviceChangedCallback {
117   public:
notifyCoolingDeviceChanged(const CoolingDevice &)118     ndk::ScopedAStatus notifyCoolingDeviceChanged(const CoolingDevice&) override {
119         {
120             std::lock_guard<std::mutex> lock(mMutex);
121             mInvoke = true;
122         }
123         mNotifyCoolingDeviceChanged.notify_all();
124         return ndk::ScopedAStatus::ok();
125     }
126 
127     template <typename R, typename P>
waitForCallback(std::chrono::duration<R,P> duration)128     [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
129         std::unique_lock<std::mutex> lock(mMutex);
130         bool r = mNotifyCoolingDeviceChanged.wait_for(lock, duration,
131                                                       [this] { return this->mInvoke; });
132         mInvoke = false;
133         return r;
134     }
135 
136   private:
137     std::mutex mMutex;
138     std::condition_variable mNotifyCoolingDeviceChanged;
139     bool mInvoke = false;
140 };
141 
142 // The main test class for THERMAL HIDL HAL.
143 class ThermalAidlTest : public testing::TestWithParam<std::string> {
144   public:
SetUp()145     void SetUp() override {
146         AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
147         ASSERT_NE(binder, nullptr);
148         mThermal = IThermal::fromBinder(ndk::SpAIBinder(binder));
149 
150         mThermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
151         ASSERT_NE(mThermalCallback, nullptr);
152         ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
153         ASSERT_TRUE(status.isOk()) << status.getMessage();
154 
155         auto ret = mThermal->getInterfaceVersion(&thermal_version);
156         ASSERT_TRUE(ret.isOk()) << ret;
157         if (thermal_version > 1) {
158             mCoolingDeviceCallback = ndk::SharedRefBase::make<CoolingDeviceCallback>();
159             ASSERT_NE(mCoolingDeviceCallback, nullptr);
160             status = mThermal->registerCoolingDeviceChangedCallbackWithType(mCoolingDeviceCallback,
161                                                                             kCoolingDevice.type);
162             ASSERT_TRUE(status.isOk()) << status.getMessage();
163         }
164     }
165 
TearDown()166     void TearDown() override {
167         ::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
168         ASSERT_TRUE(status.isOk()) << status.getMessage();
169 
170         // Expect to fail if unregister again
171         status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
172         ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
173 
174         auto ret = mThermal->getInterfaceVersion(&thermal_version);
175         ASSERT_TRUE(ret.isOk()) << ret;
176         if (thermal_version > 1) {
177             status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
178             ASSERT_TRUE(status.isOk()) << status.getMessage();
179             status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
180             ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
181         }
182     }
183 
isEmulator()184     bool isEmulator() {
185         if (property_get_bool("ro.boot.qemu", false)) {
186             return true;
187         }
188         char device[PROP_VALUE_MAX];
189         char model[PROP_VALUE_MAX];
190         char name[PROP_VALUE_MAX];
191         char hardware[PROP_VALUE_MAX];
192 
193         property_get("ro.product.device", device, "");
194         property_get("ro.product.model", model, "");
195         property_get("ro.product.name", name, "");
196         property_get("ro.hardware", hardware, "");
197 
198         std::string deviceStr(device);
199         std::string modelStr(model);
200         std::string nameStr(name);
201         std::string hardwareStr(hardware);
202 
203         return deviceStr.rfind("vsoc_", 0) == 0 || modelStr.rfind("Cuttlefish ", 0) == 0 ||
204                nameStr.rfind("cf_", 0) == 0 || nameStr.rfind("aosp_cf_", 0) == 0 ||
205                hardwareStr.find("goldfish") != std::string::npos ||
206                hardwareStr.find("ranchu") != std::string::npos ||
207                hardwareStr.find("cutf_cvm") != std::string::npos ||
208                hardwareStr.find("starfish") != std::string::npos;
209     }
210 
211     // Stores thermal version
212     int32_t thermal_version;
213 
214   protected:
215     std::shared_ptr<IThermal> mThermal;
216     std::shared_ptr<ThermalCallback> mThermalCallback;
217     std::shared_ptr<CoolingDeviceCallback> mCoolingDeviceCallback;
218 };
219 
220 // Test ThermalChangedCallback::notifyThrottling().
221 // This just calls into and back from our local ThermalChangedCallback impl.
TEST_P(ThermalAidlTest,NotifyThrottlingTest)222 TEST_P(ThermalAidlTest, NotifyThrottlingTest) {
223     std::shared_ptr<ThermalCallback> thermalCallback = ndk::SharedRefBase::make<ThermalCallback>();
224     ::ndk::ScopedAStatus status = thermalCallback->notifyThrottling(kThrottleTemp);
225     ASSERT_TRUE(status.isOk()) << status.getMessage();
226     ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
227 }
228 
229 // Test CoolingDeviceChangedCallback::notifyCoolingDeviceChanged().
230 // This just calls into and back from our local CoolingDeviceChangedCallback impl.
TEST_P(ThermalAidlTest,NotifyCoolingDeviceChangedTest)231 TEST_P(ThermalAidlTest, NotifyCoolingDeviceChangedTest) {
232     auto ret = mThermal->getInterfaceVersion(&thermal_version);
233     ASSERT_TRUE(ret.isOk()) << ret;
234     if (thermal_version < 2) {
235         return;
236     }
237     std::shared_ptr<CoolingDeviceCallback> cdevCallback =
238             ndk::SharedRefBase::make<CoolingDeviceCallback>();
239     ::ndk::ScopedAStatus status = cdevCallback->notifyCoolingDeviceChanged(kCoolingDevice);
240     ASSERT_TRUE(status.isOk()) << status.getMessage();
241     ASSERT_TRUE(cdevCallback->waitForCallback(200ms));
242 }
243 
244 // Test Thermal->registerThermalChangedCallback.
TEST_P(ThermalAidlTest,RegisterThermalChangedCallbackTest)245 TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
246     // Expect to fail with same callback
247     ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
248     ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
249     // Expect to fail with null callback
250     status = mThermal->registerThermalChangedCallback(nullptr);
251     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT
252         || status.getExceptionCode() == EX_NULL_POINTER);
253     std::shared_ptr<ThermalCallback> localThermalCallback =
254             ndk::SharedRefBase::make<ThermalCallback>();
255     // Expect to succeed with different callback
256     status = mThermal->registerThermalChangedCallback(localThermalCallback);
257     ASSERT_TRUE(status.isOk()) << status.getMessage();
258     // Remove the local callback
259     status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
260     ASSERT_TRUE(status.isOk()) << status.getMessage();
261     // Expect to fail with null callback
262     status = mThermal->unregisterThermalChangedCallback(nullptr);
263     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT
264         || status.getExceptionCode() == EX_NULL_POINTER);
265 }
266 
267 // Test Thermal->registerThermalChangedCallbackWithType.
TEST_P(ThermalAidlTest,RegisterThermalChangedCallbackWithTypeTest)268 TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackWithTypeTest) {
269     // Expect to fail with same callback
270     ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallbackWithType(
271             mThermalCallback, TemperatureType::SKIN);
272     ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
273     // Expect to fail with null callback
274     status = mThermal->registerThermalChangedCallbackWithType(nullptr, TemperatureType::SKIN);
275     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT
276         || status.getExceptionCode() == EX_NULL_POINTER);
277     std::shared_ptr<ThermalCallback> localThermalCallback =
278             ndk::SharedRefBase::make<ThermalCallback>();
279     // Expect to succeed with different callback
280     status = mThermal->registerThermalChangedCallbackWithType(localThermalCallback,
281                                                               TemperatureType::SKIN);
282     ASSERT_TRUE(status.isOk()) << status.getMessage();
283     // Remove the local callback
284     status = mThermal->unregisterThermalChangedCallback(localThermalCallback);
285     ASSERT_TRUE(status.isOk()) << status.getMessage();
286     // Expect to fail with null callback
287     status = mThermal->unregisterThermalChangedCallback(nullptr);
288     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT
289         || status.getExceptionCode() == EX_NULL_POINTER);
290 }
291 
292 // Test Thermal->registerCoolingDeviceChangedCallbackWithType.
TEST_P(ThermalAidlTest,RegisterCoolingDeviceChangedCallbackWithTypeTest)293 TEST_P(ThermalAidlTest, RegisterCoolingDeviceChangedCallbackWithTypeTest) {
294     auto ret = mThermal->getInterfaceVersion(&thermal_version);
295     ASSERT_TRUE(ret.isOk()) << ret;
296     if (thermal_version < 2) {
297         return;
298     }
299 
300     // Expect to fail with same callback
301     ::ndk::ScopedAStatus status = mThermal->registerCoolingDeviceChangedCallbackWithType(
302             mCoolingDeviceCallback, CoolingType::CPU);
303     ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
304     // Expect to fail with null callback
305     status = mThermal->registerCoolingDeviceChangedCallbackWithType(nullptr, CoolingType::CPU);
306     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
307                 status.getExceptionCode() == EX_NULL_POINTER);
308     std::shared_ptr<CoolingDeviceCallback> localCoolingDeviceCallback =
309             ndk::SharedRefBase::make<CoolingDeviceCallback>();
310     // Expect to succeed with different callback
311     status = mThermal->registerCoolingDeviceChangedCallbackWithType(localCoolingDeviceCallback,
312                                                                     CoolingType::CPU);
313     ASSERT_TRUE(status.isOk()) << status.getMessage();
314     // Remove the local callback
315     status = mThermal->unregisterCoolingDeviceChangedCallback(localCoolingDeviceCallback);
316     ASSERT_TRUE(status.isOk()) << status.getMessage();
317     // Expect to fail with null callback
318     status = mThermal->unregisterCoolingDeviceChangedCallback(nullptr);
319     ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
320                 status.getExceptionCode() == EX_NULL_POINTER);
321 }
322 
323 // Test Thermal->getCurrentTemperatures().
TEST_P(ThermalAidlTest,TemperatureTest)324 TEST_P(ThermalAidlTest, TemperatureTest) {
325     std::vector<Temperature> ret;
326     ::ndk::ScopedAStatus status = mThermal->getTemperatures(&ret);
327     if (status.isOk()) {
328         for (auto& i : ret) {
329             EXPECT_LT(0u, i.name.size());
330             LOG(INFO) << i.name + " " + toString(i.type) << "\n";
331         }
332     } else {
333         ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
334     }
335 
336     auto types = ::ndk::enum_range<TemperatureType>();
337     for (const auto& type : types) {
338         status = mThermal->getTemperaturesWithType(type, &ret);
339 
340         if (status.isOk()) {
341             for (auto& i : ret) {
342                 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
343                                                    toString(i.type) + " for " + i.name;
344                 EXPECT_LT(0u, i.name.size());
345             }
346         } else {
347             ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
348         }
349     }
350 }
351 
352 // Test Thermal->getTemperatureThresholds().
TEST_P(ThermalAidlTest,TemperatureThresholdTest)353 TEST_P(ThermalAidlTest, TemperatureThresholdTest) {
354     std::vector<TemperatureThreshold> ret;
355     ::ndk::ScopedAStatus status = mThermal->getTemperatureThresholds(&ret);
356     if (status.isOk()) {
357         for (auto& i : ret) {
358             EXPECT_LT(0u, i.name.size());
359             LOG(INFO) << i.name + " " + toString(i.type) << "\n";
360         }
361     } else {
362         ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
363     }
364 
365     auto types = ::ndk::enum_range<TemperatureType>();
366     for (const auto& type : types) {
367         status = mThermal->getTemperatureThresholdsWithType(type, &ret);
368 
369         if (status.isOk()) {
370             for (auto& i : ret) {
371                 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
372                                                    toString(i.type) + " for " + i.name;
373                 EXPECT_LT(0u, i.name.size());
374             }
375         } else {
376             ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
377         }
378     }
379 }
380 
381 // Test Thermal->getTemperatureThresholdsWithType(SKIN).
382 // @VsrTest = GMS-VSR-3.2.5-001
383 // @VsrTest = VSR-3.2.5-001
384 // @VsrTest = GMS-VSR-3.2.5-002
385 // @VsrTest = VSR-3.2.5-002
TEST_P(ThermalAidlTest,SkinTemperatureThresholdsTest)386 TEST_P(ThermalAidlTest, SkinTemperatureThresholdsTest) {
387     auto apiLevel = ::android::base::GetIntProperty<int32_t>("ro.vendor.api_level", 0);
388     if (apiLevel < 202404) {
389         GTEST_SKIP() << "Skipping test as the vendor level is below 202404: " << apiLevel;
390     }
391     if (isEmulator()) {
392         GTEST_SKIP() << "Skipping test on emulator";
393     }
394     for (const auto& feature : kNonHandheldFeatures) {
395         if (::testing::deviceSupportsFeature(feature.c_str())) {
396             GTEST_SKIP() << "Skipping test as the device has feature: " << feature;
397         }
398     }
399     std::vector<Temperature> temperatures;
400     ::ndk::ScopedAStatus status =
401             mThermal->getTemperaturesWithType(TemperatureType::SKIN, &temperatures);
402     ASSERT_TRUE(status.isOk()) << "getTemperaturesWithType(SKIN) failed";
403     ASSERT_FALSE(temperatures.empty()) << "getTemperaturesWithType(SKIN) returns empty";
404     ASSERT_EQ(1, temperatures.size())
405             << "getTemperaturesWithType(SKIN) returns multiple temperatures";
406 
407     std::vector<TemperatureThreshold> thresholds;
408     status = mThermal->getTemperatureThresholdsWithType(TemperatureType::SKIN, &thresholds);
409     ASSERT_TRUE(status.isOk()) << "getTemperatureThresholdsWithType(SKIN) failed";
410     ASSERT_FALSE(thresholds.empty()) << "getTemperatureThresholdsWithType(SKIN) returns empty";
411     ASSERT_EQ(1, thresholds.size())
412             << "getTemperatureThresholdsWithType(SKIN) returns multiple thresholds";
413     auto temperature = temperatures[0];
414     auto threshold = thresholds[0];
415     ASSERT_EQ(temperature.name, threshold.name);
416     auto severities = ::ndk::enum_range<ThrottlingSeverity>();
417     auto cardinality = std::distance(severities.begin(), severities.end());
418     ASSERT_NE(NAN, temperature.value);
419     ASSERT_EQ(cardinality, threshold.hotThrottlingThresholds.size());
420     float lastThreshold = threshold.hotThrottlingThresholds[1];
421     // skip NONE, and check that the rest should be set and non-decreasing
422     for (auto i = 2; i < cardinality; i++) {
423         float t = threshold.hotThrottlingThresholds[i];
424         ASSERT_NE(NAN, t);
425         ASSERT_TRUE(t >= lastThreshold) << "Temperature thresholds should be non-decreasing "
426                                         << "but got " << t << " for status " << i << " and "
427                                         << lastThreshold << " for status " << i - 1;
428         lastThreshold = t;
429     }
430 }
431 
432 // Test Thermal->getCoolingDevices().
TEST_P(ThermalAidlTest,CoolingDeviceTest)433 TEST_P(ThermalAidlTest, CoolingDeviceTest) {
434     std::vector<CoolingDevice> ret;
435     ::ndk::ScopedAStatus status = mThermal->getCoolingDevices(&ret);
436     if (status.isOk()) {
437         for (auto& i : ret) {
438             EXPECT_LT(0u, i.name.size());
439             LOG(INFO) << i.name + " " + toString(i.type) << "\n";
440         }
441     } else {
442         ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
443     }
444 
445     auto types = ::ndk::enum_range<CoolingType>();
446     for (const auto& type : types) {
447         status = mThermal->getCoolingDevicesWithType(type, &ret);
448         if (status.isOk()) {
449             ASSERT_TRUE(status.isOk());
450             for (auto& i : ret) {
451                 EXPECT_EQ(type, i.type) << "Expect type " + toString(type) + " but got " +
452                                                    toString(i.type) + " for " + i.name;
453                 EXPECT_LT(0u, i.name.size());
454             }
455         } else {
456             ASSERT_EQ(EX_ILLEGAL_STATE, status.getExceptionCode());
457         }
458     }
459 }
460 
461 // Test Thermal->forecastSkinTemperature.
TEST_P(ThermalAidlTest,ForecastSkinTemperatureTest)462 TEST_P(ThermalAidlTest, ForecastSkinTemperatureTest) {
463     auto apiLevel = ::android::base::GetIntProperty<int32_t>("ro.vendor.api_level", 0);
464     if (apiLevel < 202504) {
465         GTEST_SKIP() << "Skipping test as the vendor level is below 202504: " << apiLevel;
466     }
467     float temperature = 0.0f;
468     ::ndk::ScopedAStatus status = mThermal->forecastSkinTemperature(1, &temperature);
469     if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
470         GTEST_SKIP() << "Skipping test as temperature forecast is not supported";
471     }
472     for (int i = 0; i <= 60; i++) {
473         status = mThermal->forecastSkinTemperature(i, &temperature);
474         ASSERT_NE(NAN, temperature);
475     }
476 }
477 
478 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
479 INSTANTIATE_TEST_SUITE_P(
480         Thermal, ThermalAidlTest,
481         testing::ValuesIn(::android::getAidlHalInstanceNames(IThermal::descriptor)),
482         ::android::PrintInstanceNameToString);
483 
484 }  // namespace
485 }  // namespace aidl::android::hardware::thermal
486 
main(int argc,char ** argv)487 int main(int argc, char** argv) {
488     ::testing::InitGoogleTest(&argc, argv);
489     ABinderProcess_setThreadPoolMaxThreadCount(1);
490     ABinderProcess_startThreadPool();
491     return RUN_ALL_TESTS();
492 }
493