blob: 04a96d42fe82e2a987f2a46026b23b6c5ab7fc66 [file] [log] [blame]
Yu Shan726d51a2022-02-22 17:37:21 -08001/*
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 "VtsHalAutomotiveVehicle"
18
19#include <IVhalClient.h>
20#include <VehicleHalTypes.h>
21#include <VehicleUtils.h>
22#include <aidl/Gtest.h>
23#include <aidl/Vintf.h>
24#include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
25#include <android-base/stringprintf.h>
26#include <android-base/thread_annotations.h>
27#include <android/binder_process.h>
28#include <gtest/gtest.h>
29#include <hidl/GtestPrinter.h>
30#include <hidl/ServiceManagement.h>
31#include <inttypes.h>
32#include <utils/Log.h>
Yu Shan4569ef52022-03-18 14:34:25 -070033#include <utils/SystemClock.h>
Yu Shan726d51a2022-02-22 17:37:21 -080034
35#include <chrono>
36#include <mutex>
37#include <unordered_map>
38#include <unordered_set>
39#include <vector>
40
41using ::aidl::android::hardware::automotive::vehicle::IVehicle;
42using ::aidl::android::hardware::automotive::vehicle::StatusCode;
43using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
44using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
45using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
46using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
47using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
48using ::android::getAidlHalInstanceNames;
49using ::android::base::ScopedLockAssertion;
50using ::android::base::StringPrintf;
51using ::android::frameworks::automotive::vhal::HalPropError;
52using ::android::frameworks::automotive::vhal::IHalPropConfig;
53using ::android::frameworks::automotive::vhal::IHalPropValue;
54using ::android::frameworks::automotive::vhal::ISubscriptionCallback;
55using ::android::frameworks::automotive::vhal::IVhalClient;
56using ::android::hardware::getAllHalInstanceNames;
57using ::android::hardware::Sanitize;
58using ::android::hardware::automotive::vehicle::toInt;
59
60constexpr int32_t kInvalidProp = 0x31600207;
61
62struct ServiceDescriptor {
63 std::string name;
64 bool isAidlService;
65};
66
67class VtsVehicleCallback final : public ISubscriptionCallback {
68 private:
69 std::mutex mLock;
70 std::unordered_map<int32_t, size_t> mEventsCount GUARDED_BY(mLock);
Yu Shan4569ef52022-03-18 14:34:25 -070071 std::unordered_map<int32_t, std::vector<int64_t>> mEventTimestamps GUARDED_BY(mLock);
Yu Shan726d51a2022-02-22 17:37:21 -080072 std::condition_variable mEventCond;
73
74 public:
75 void onPropertyEvent(const std::vector<std::unique_ptr<IHalPropValue>>& values) override {
76 {
77 std::lock_guard<std::mutex> lockGuard(mLock);
78 for (auto& value : values) {
Yu Shan4569ef52022-03-18 14:34:25 -070079 int32_t propId = value->getPropId();
80 mEventsCount[propId] += 1;
81 mEventTimestamps[propId].push_back(value->getTimestamp());
Yu Shan726d51a2022-02-22 17:37:21 -080082 }
83 }
84 mEventCond.notify_one();
85 }
86
87 void onPropertySetError([[maybe_unused]] const std::vector<HalPropError>& errors) override {
88 // Do nothing.
89 }
90
91 template <class Rep, class Period>
92 bool waitForExpectedEvents(int32_t propId, size_t expectedEvents,
93 const std::chrono::duration<Rep, Period>& timeout) {
94 std::unique_lock<std::mutex> uniqueLock(mLock);
95 return mEventCond.wait_for(uniqueLock, timeout, [this, propId, expectedEvents] {
96 ScopedLockAssertion lockAssertion(mLock);
97 return mEventsCount[propId] >= expectedEvents;
98 });
99 }
100
Yu Shan4569ef52022-03-18 14:34:25 -0700101 std::vector<int64_t> getEventTimestamps(int32_t propId) {
102 {
103 std::lock_guard<std::mutex> lockGuard(mLock);
104 return mEventTimestamps[propId];
105 }
106 }
107
Yu Shan726d51a2022-02-22 17:37:21 -0800108 void reset() {
109 std::lock_guard<std::mutex> lockGuard(mLock);
110 mEventsCount.clear();
111 }
112};
113
114class VtsHalAutomotiveVehicleTargetTest : public testing::TestWithParam<ServiceDescriptor> {
Yu Shanda7a4dd2023-10-09 14:43:36 -0700115protected:
116 bool checkIsSupported(int32_t propertyId);
Yu Shan726d51a2022-02-22 17:37:21 -0800117
Yu Shanda7a4dd2023-10-09 14:43:36 -0700118public:
119 virtual void SetUp() override {
120 auto descriptor = GetParam();
121 if (descriptor.isAidlService) {
122 mVhalClient = IVhalClient::tryCreateAidlClient(descriptor.name.c_str());
123 } else {
124 mVhalClient = IVhalClient::tryCreateHidlClient(descriptor.name.c_str());
125 }
Yu Shan726d51a2022-02-22 17:37:21 -0800126
Yu Shanda7a4dd2023-10-09 14:43:36 -0700127 ASSERT_NE(mVhalClient, nullptr) << "Failed to connect to VHAL";
128
129 mCallback = std::make_shared<VtsVehicleCallback>();
130 }
Yu Shan726d51a2022-02-22 17:37:21 -0800131
132 static bool isBooleanGlobalProp(int32_t property) {
133 return (property & toInt(VehiclePropertyType::MASK)) ==
134 toInt(VehiclePropertyType::BOOLEAN) &&
135 (property & toInt(VehicleArea::MASK)) == toInt(VehicleArea::GLOBAL);
136 }
137
138 protected:
139 std::shared_ptr<IVhalClient> mVhalClient;
140 std::shared_ptr<VtsVehicleCallback> mCallback;
141};
142
143TEST_P(VtsHalAutomotiveVehicleTargetTest, useAidlBackend) {
144 if (!mVhalClient->isAidlVhal()) {
145 GTEST_SKIP() << "AIDL backend is not available, HIDL backend is used instead";
146 }
147}
148
149TEST_P(VtsHalAutomotiveVehicleTargetTest, useHidlBackend) {
150 if (mVhalClient->isAidlVhal()) {
151 GTEST_SKIP() << "AIDL backend is available, HIDL backend is not used";
152 }
153}
154
Yu Shanda7a4dd2023-10-09 14:43:36 -0700155// Test getAllPropConfigs() returns at least 1 property configs.
Yu Shan726d51a2022-02-22 17:37:21 -0800156TEST_P(VtsHalAutomotiveVehicleTargetTest, getAllPropConfigs) {
157 ALOGD("VtsHalAutomotiveVehicleTargetTest::getAllPropConfigs");
158
159 auto result = mVhalClient->getAllPropConfigs();
160
161 ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
162 << result.error().message();
Yu Shanda7a4dd2023-10-09 14:43:36 -0700163 ASSERT_GE(result.value().size(), 1u)
164 << StringPrintf("Expect to get at least 1 property config, got %zu",
165 result.value().size());
Yu Shan726d51a2022-02-22 17:37:21 -0800166}
167
Yu Shanda7a4dd2023-10-09 14:43:36 -0700168// Test getPropConfigs() can query properties returned by getAllPropConfigs.
169TEST_P(VtsHalAutomotiveVehicleTargetTest, getPropConfigsWithValidProps) {
Yu Shan726d51a2022-02-22 17:37:21 -0800170 ALOGD("VtsHalAutomotiveVehicleTargetTest::getRequiredPropConfigs");
171
Yu Shanda7a4dd2023-10-09 14:43:36 -0700172 std::vector<int32_t> properties;
173 auto result = mVhalClient->getAllPropConfigs();
Yu Shan726d51a2022-02-22 17:37:21 -0800174
Yu Shanda7a4dd2023-10-09 14:43:36 -0700175 ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
176 << result.error().message();
177 for (const auto& cfgPtr : result.value()) {
178 properties.push_back(cfgPtr->getPropId());
179 }
180
181 result = mVhalClient->getPropConfigs(properties);
Yu Shan726d51a2022-02-22 17:37:21 -0800182
183 ASSERT_TRUE(result.ok()) << "Failed to get required property config, error: "
184 << result.error().message();
Yu Shanda7a4dd2023-10-09 14:43:36 -0700185 ASSERT_EQ(result.value().size(), properties.size())
186 << StringPrintf("Expect to get exactly %zu configs, got %zu",
187 properties.size(), result.value().size());
Yu Shan726d51a2022-02-22 17:37:21 -0800188}
189
190// Test getPropConfig() with an invalid propertyId returns an error code.
191TEST_P(VtsHalAutomotiveVehicleTargetTest, getPropConfigsWithInvalidProp) {
192 ALOGD("VtsHalAutomotiveVehicleTargetTest::getPropConfigsWithInvalidProp");
193
194 auto result = mVhalClient->getPropConfigs({kInvalidProp});
195
196 ASSERT_FALSE(result.ok()) << StringPrintf(
197 "Expect failure to get prop configs for invalid prop: %" PRId32, kInvalidProp);
198 ASSERT_NE(result.error().message(), "") << "Expect error message not to be empty";
199}
200
201// Test get() return current value for properties.
202TEST_P(VtsHalAutomotiveVehicleTargetTest, get) {
203 ALOGD("VtsHalAutomotiveVehicleTargetTest::get");
204
205 int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
Yu Shanda7a4dd2023-10-09 14:43:36 -0700206 if (!checkIsSupported(propId)) {
207 GTEST_SKIP() << "Property: " << propId << " is not supported, skip the test";
208 }
Yu Shan726d51a2022-02-22 17:37:21 -0800209 auto result = mVhalClient->getValueSync(*mVhalClient->createHalPropValue(propId));
210
211 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32
212 ", error: %s",
213 propId, result.error().message().c_str());
214 ASSERT_NE(result.value(), nullptr) << "Result value must not be null";
215}
216
217// Test get() with an invalid propertyId return an error codes.
218TEST_P(VtsHalAutomotiveVehicleTargetTest, getInvalidProp) {
219 ALOGD("VtsHalAutomotiveVehicleTargetTest::getInvalidProp");
220
221 auto result = mVhalClient->getValueSync(*mVhalClient->createHalPropValue(kInvalidProp));
222
223 ASSERT_FALSE(result.ok()) << StringPrintf(
224 "Expect failure to get property for invalid prop: %" PRId32, kInvalidProp);
225}
226
227// Test set() on read_write properties.
228TEST_P(VtsHalAutomotiveVehicleTargetTest, setProp) {
229 ALOGD("VtsHalAutomotiveVehicleTargetTest::setProp");
230
231 // skip hvac related properties
232 std::unordered_set<int32_t> hvacProps = {toInt(VehicleProperty::HVAC_DEFROSTER),
233 toInt(VehicleProperty::HVAC_AC_ON),
234 toInt(VehicleProperty::HVAC_MAX_AC_ON),
235 toInt(VehicleProperty::HVAC_MAX_DEFROST_ON),
236 toInt(VehicleProperty::HVAC_RECIRC_ON),
237 toInt(VehicleProperty::HVAC_DUAL_ON),
238 toInt(VehicleProperty::HVAC_AUTO_ON),
239 toInt(VehicleProperty::HVAC_POWER_ON),
240 toInt(VehicleProperty::HVAC_AUTO_RECIRC_ON),
241 toInt(VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON)};
242 auto result = mVhalClient->getAllPropConfigs();
243 ASSERT_TRUE(result.ok());
244
245 for (const auto& cfgPtr : result.value()) {
246 const IHalPropConfig& cfg = *cfgPtr;
247 int32_t propId = cfg.getPropId();
248 // test on boolean and writable property
249 if (cfg.getAccess() == toInt(VehiclePropertyAccess::READ_WRITE) &&
250 isBooleanGlobalProp(propId) && !hvacProps.count(propId)) {
251 auto propToGet = mVhalClient->createHalPropValue(propId);
252 auto getValueResult = mVhalClient->getValueSync(*propToGet);
253
254 ASSERT_TRUE(getValueResult.ok())
255 << StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
256 propId, getValueResult.error().message().c_str());
257 ASSERT_NE(getValueResult.value(), nullptr)
258 << StringPrintf("Result value must not be null for property: %" PRId32, propId);
259
260 const IHalPropValue& value = *getValueResult.value();
261 size_t intValueSize = value.getInt32Values().size();
262 ASSERT_EQ(intValueSize, 1u) << StringPrintf(
263 "Expect exactly 1 int value for boolean property: %" PRId32 ", got %zu", propId,
264 intValueSize);
265
266 int setValue = value.getInt32Values()[0] == 1 ? 0 : 1;
267 auto propToSet = mVhalClient->createHalPropValue(propId);
268 propToSet->setInt32Values({setValue});
269 auto setValueResult = mVhalClient->setValueSync(*propToSet);
270
271 ASSERT_TRUE(setValueResult.ok())
272 << StringPrintf("Failed to set value for property: %" PRId32 ", error: %s",
273 propId, setValueResult.error().message().c_str());
274
275 // check set success
276 getValueResult = mVhalClient->getValueSync(*propToGet);
277 ASSERT_TRUE(getValueResult.ok())
278 << StringPrintf("Failed to get value for property: %" PRId32 ", error: %s",
279 propId, getValueResult.error().message().c_str());
280 ASSERT_NE(getValueResult.value(), nullptr)
281 << StringPrintf("Result value must not be null for property: %" PRId32, propId);
282 ASSERT_EQ(getValueResult.value()->getInt32Values(), std::vector<int32_t>({setValue}))
283 << StringPrintf("Boolean value not updated after set for property: %" PRId32,
284 propId);
285 }
286 }
287}
288
289// Test set() on an read_only property.
290TEST_P(VtsHalAutomotiveVehicleTargetTest, setNotWritableProp) {
291 ALOGD("VtsHalAutomotiveVehicleTargetTest::setNotWritableProp");
292
293 int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
Yu Shanda7a4dd2023-10-09 14:43:36 -0700294 if (!checkIsSupported(propId)) {
295 GTEST_SKIP() << "Property: " << propId << " is not supported, skip the test";
296 }
297
Yu Shan726d51a2022-02-22 17:37:21 -0800298 auto getValueResult = mVhalClient->getValueSync(*mVhalClient->createHalPropValue(propId));
299 ASSERT_TRUE(getValueResult.ok())
300 << StringPrintf("Failed to get value for property: %" PRId32 ", error: %s", propId,
301 getValueResult.error().message().c_str());
302
303 auto setValueResult = mVhalClient->setValueSync(*getValueResult.value());
304
305 ASSERT_FALSE(setValueResult.ok()) << "Expect set a read-only value to fail";
Yu Shan24fee7b2022-03-03 15:10:51 -0800306 ASSERT_EQ(setValueResult.error().code(), StatusCode::ACCESS_DENIED);
Yu Shan726d51a2022-02-22 17:37:21 -0800307}
308
309// Test subscribe() and unsubscribe().
310TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeAndUnsubscribe) {
311 ALOGD("VtsHalAutomotiveVehicleTargetTest::subscribeAndUnsubscribe");
312
313 int32_t propId = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
Yu Shanda7a4dd2023-10-09 14:43:36 -0700314 if (!checkIsSupported(propId)) {
315 GTEST_SKIP() << "Property: " << propId << " is not supported, skip the test";
316 }
Yu Shan726d51a2022-02-22 17:37:21 -0800317
Yu Shan4569ef52022-03-18 14:34:25 -0700318 auto propConfigsResult = mVhalClient->getPropConfigs({propId});
319
320 ASSERT_TRUE(propConfigsResult.ok()) << "Failed to get property config for PERF_VEHICLE_SPEED: "
321 << "error: " << propConfigsResult.error().message();
322 ASSERT_EQ(propConfigsResult.value().size(), 1u)
323 << "Expect to return 1 config for PERF_VEHICLE_SPEED";
324 auto& propConfig = propConfigsResult.value()[0];
325 float minSampleRate = propConfig->getMinSampleRate();
326 float maxSampleRate = propConfig->getMaxSampleRate();
327
328 if (minSampleRate < 1) {
329 GTEST_SKIP() << "Sample rate for vehicle speed < 1 times/sec, skip test since it would "
330 "take too long";
331 }
Yu Shan726d51a2022-02-22 17:37:21 -0800332
333 auto client = mVhalClient->getSubscriptionClient(mCallback);
334 ASSERT_NE(client, nullptr) << "Failed to get subscription client";
335
Yu Shan4569ef52022-03-18 14:34:25 -0700336 auto result = client->subscribe({{.propId = propId, .sampleRate = minSampleRate}});
Yu Shan726d51a2022-02-22 17:37:21 -0800337
338 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32
339 ", error: %s",
340 propId, result.error().message().c_str());
Yu Shan4569ef52022-03-18 14:34:25 -0700341
342 if (mVhalClient->isAidlVhal()) {
343 // Skip checking timestamp for HIDL because the behavior for sample rate and timestamp is
344 // only specified clearly for AIDL.
345
346 // Timeout is 2 seconds, which gives a 1 second buffer.
347 ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(minSampleRate),
348 std::chrono::seconds(2)))
349 << "Didn't get enough events for subscribing to minSampleRate";
350 }
351
352 result = client->subscribe({{.propId = propId, .sampleRate = maxSampleRate}});
353
354 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to subscribe to property: %" PRId32
355 ", error: %s",
356 propId, result.error().message().c_str());
357
358 if (mVhalClient->isAidlVhal()) {
359 ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, std::floor(maxSampleRate),
360 std::chrono::seconds(2)))
361 << "Didn't get enough events for subscribing to maxSampleRate";
362
363 std::unordered_set<int64_t> timestamps;
364 // Event event should have a different timestamp.
365 for (const int64_t& eventTimestamp : mCallback->getEventTimestamps(propId)) {
366 ASSERT_TRUE(timestamps.find(eventTimestamp) == timestamps.end())
367 << "two events for the same property must not have the same timestamp";
368 timestamps.insert(eventTimestamp);
369 }
370 }
Yu Shan726d51a2022-02-22 17:37:21 -0800371
372 result = client->unsubscribe({propId});
373 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to unsubscribe to property: %" PRId32
374 ", error: %s",
375 propId, result.error().message().c_str());
376
377 mCallback->reset();
378 ASSERT_FALSE(mCallback->waitForExpectedEvents(propId, 10, std::chrono::seconds(1)))
379 << "Expect not to get events after unsubscription";
380}
381
382// Test subscribe() with an invalid property.
383TEST_P(VtsHalAutomotiveVehicleTargetTest, subscribeInvalidProp) {
384 ALOGD("VtsHalAutomotiveVehicleTargetTest::subscribeInvalidProp");
385
386 std::vector<SubscribeOptions> options = {
387 SubscribeOptions{.propId = kInvalidProp, .sampleRate = 10.0}};
388
389 auto client = mVhalClient->getSubscriptionClient(mCallback);
390 ASSERT_NE(client, nullptr) << "Failed to get subscription client";
391
392 auto result = client->subscribe(options);
393
394 ASSERT_FALSE(result.ok()) << StringPrintf("Expect subscribing to property: %" PRId32 " to fail",
395 kInvalidProp);
396}
397
Yu Shan4569ef52022-03-18 14:34:25 -0700398// Test the timestamp returned in GetValues results is the timestamp when the value is retrieved.
399TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetValuesTimestampAIDL) {
400 if (!mVhalClient->isAidlVhal()) {
401 GTEST_SKIP() << "Skip checking timestamp for HIDL because the behavior is only specified "
402 "for AIDL";
403 }
404
405 int32_t propId = toInt(VehicleProperty::PARKING_BRAKE_ON);
Yu Shanda7a4dd2023-10-09 14:43:36 -0700406 if (!checkIsSupported(propId)) {
407 GTEST_SKIP() << "Property: " << propId << " is not supported, skip the test";
408 }
Yu Shan4569ef52022-03-18 14:34:25 -0700409 auto prop = mVhalClient->createHalPropValue(propId);
410
411 auto result = mVhalClient->getValueSync(*prop);
412
413 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32
414 ", error: %s",
415 propId, result.error().message().c_str());
416 ASSERT_NE(result.value(), nullptr) << "Result value must not be null";
417 ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value";
418
419 bool parkBrakeOnValue1 = (result.value()->getInt32Values()[0] == 1);
420 int64_t timestampValue1 = result.value()->getTimestamp();
421
422 result = mVhalClient->getValueSync(*prop);
423
424 ASSERT_TRUE(result.ok()) << StringPrintf("Failed to get value for property: %" PRId32
425 ", error: %s",
426 propId, result.error().message().c_str());
427 ASSERT_NE(result.value(), nullptr) << "Result value must not be null";
428 ASSERT_EQ(result.value()->getInt32Values().size(), 1u) << "Result must contain 1 int value";
429
430 bool parkBarkeOnValue2 = (result.value()->getInt32Values()[0] == 1);
431 int64_t timestampValue2 = result.value()->getTimestamp();
432
433 if (parkBarkeOnValue2 == parkBrakeOnValue1) {
434 ASSERT_EQ(timestampValue2, timestampValue1)
435 << "getValue result must contain a timestamp updated when the value was updated, if"
436 "the value does not change, expect the same timestamp";
437 } else {
438 ASSERT_GT(timestampValue2, timestampValue1)
439 << "getValue result must contain a timestamp updated when the value was updated, if"
440 "the value changes, expect the newer value has a larger timestamp";
441 }
442}
443
Yu Shanda7a4dd2023-10-09 14:43:36 -0700444bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
445 auto result = mVhalClient->getPropConfigs({propertyId});
446 return result.ok();
447}
448
Yu Shan726d51a2022-02-22 17:37:21 -0800449std::vector<ServiceDescriptor> getDescriptors() {
450 std::vector<ServiceDescriptor> descriptors;
451 for (std::string name : getAidlHalInstanceNames(IVehicle::descriptor)) {
452 descriptors.push_back({
453 .name = name,
454 .isAidlService = true,
455 });
456 }
457 for (std::string name : getAllHalInstanceNames(IVehicle::descriptor)) {
458 descriptors.push_back({
459 .name = name,
460 .isAidlService = false,
461 });
462 }
463 return descriptors;
464}
465
466GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveVehicleTargetTest);
467
468INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveVehicleTargetTest,
469 testing::ValuesIn(getDescriptors()),
470 [](const testing::TestParamInfo<ServiceDescriptor>& info) {
471 std::string name = "";
472 if (info.param.isAidlService) {
473 name += "aidl_";
474 } else {
475 name += "hidl_";
476 }
477 name += info.param.name;
478 return Sanitize(name);
479 });
480
481int main(int argc, char** argv) {
482 ::testing::InitGoogleTest(&argc, argv);
483 ABinderProcess_setThreadPoolMaxThreadCount(1);
484 return RUN_ALL_TESTS();
485}