1 /*
2 * Copyright (C) 2018 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 "SingleManifestTest.h"
18
19 #include <aidl/metadata.h>
20 #include <android-base/file.h>
21 #include <android-base/hex.h>
22 #include <android-base/properties.h>
23 #include <android-base/strings.h>
24 #include <android/apex/ApexInfo.h>
25 #include <android/apex/IApexService.h>
26 #include <android/vintf/IServiceInfoFetcher.h>
27 #include <android/vintf/ServiceInfo.h>
28 #include <binder/IServiceManager.h>
29 #include <binder/Parcel.h>
30 #include <binder/RpcSession.h>
31 #include <binder/Stability.h>
32 #include <binder/Status.h>
33 #include <dirent.h>
34 #include <dlfcn.h>
35 #include <gmock/gmock.h>
36 #include <hidl-util/FqInstance.h>
37 #include <hidl/HidlTransportUtils.h>
38 #include <stdio.h>
39 #include <vintf/constants.h>
40 #include <vintf/parse_string.h>
41
42 #include <algorithm>
43
44 #include "utils.h"
45
46 using ::testing::AnyOf;
47 using ::testing::Contains;
48 using ::testing::StartsWith;
49
50 namespace android {
51 namespace vintf {
52 namespace testing {
53
54 namespace {
55
56 constexpr int kAndroidApi202404 = 202404;
57 constexpr int kAndroidApi202504 = 202504;
58 constexpr int kTrustyTestVmVintfTaPort = 1000;
59
60 } // namespace
61 using android::FqInstance;
62 using android::vintf::IServiceInfoFetcher;
63 using android::vintf::ServiceInfo;
64 using android::vintf::toFQNameString;
65
66 // For devices that launched <= Android O-MR1, systems/hals/implementations
67 // were delivered to companies which either don't start up on device boot.
LegacyAndExempt(const FQName & fq_name)68 bool LegacyAndExempt(const FQName &fq_name) {
69 return GetVendorApiLevel() <= 27 && !IsAndroidPlatformInterface(fq_name);
70 }
71
FailureHalMissing(const FQName & fq_name,const std::string & instance)72 void FailureHalMissing(const FQName &fq_name, const std::string &instance) {
73 if (LegacyAndExempt(fq_name)) {
74 cout << "[ WARNING ] " << fq_name.string() << "/" << instance
75 << " not available but is exempted because it is legacy. It is still "
76 "recommended to fix this."
77 << endl;
78 } else {
79 ADD_FAILURE() << fq_name.string() << "/" << instance << " not available.";
80 }
81 }
82
FailureHashMissing(const FQName & fq_name)83 void FailureHashMissing(const FQName &fq_name) {
84 if (LegacyAndExempt(fq_name)) {
85 cout << "[ WARNING ] " << fq_name.string()
86 << " has an empty hash but is exempted because it is legacy. It is "
87 "still recommended to fix this. This is because it was compiled "
88 "without being frozen in a corresponding current.txt file."
89 << endl;
90 } else if (base::GetProperty("ro.build.version.codename", "") != "REL") {
91 cout << "[ WARNING ] " << fq_name.string()
92 << " has an empty hash but is exempted because it is not a release "
93 "build"
94 << endl;
95 } else {
96 ADD_FAILURE()
97 << fq_name.string()
98 << " has an empty hash. This is because it was compiled "
99 "without being frozen in a corresponding current.txt file.";
100 }
101 }
102
ServiceName(const AidlInstance & aidl_instance)103 static inline std::string ServiceName(const AidlInstance &aidl_instance) {
104 return aidl_instance.package() + "." + aidl_instance.interface() + "/" +
105 aidl_instance.instance();
106 }
107
ServiceName(const ServiceInfo & hal_info)108 static inline std::string ServiceName(const ServiceInfo &hal_info) {
109 return hal_info.type + "/" + hal_info.instance;
110 }
111
ToFqInstance(const string & interface,const string & instance)112 static FqInstance ToFqInstance(const string &interface,
113 const string &instance) {
114 FqInstance fq_interface;
115 FqInstance ret;
116
117 if (!fq_interface.setTo(interface)) {
118 ADD_FAILURE() << interface << " is not a valid FQName";
119 return ret;
120 }
121 if (!ret.setTo(fq_interface.getPackage(), fq_interface.getMajorVersion(),
122 fq_interface.getMinorVersion(), fq_interface.getInterface(),
123 instance)) {
124 ADD_FAILURE() << "Cannot convert to FqInstance: " << interface << "/"
125 << instance;
126 }
127 return ret;
128 }
129
130 // Given android.foo.bar@x.y::IFoo/default, attempt to get
131 // android.foo.bar@x.y::IFoo/default, android.foo.bar@x.(y-1)::IFoo/default,
132 // ... android.foo.bar@x.0::IFoo/default until the passthrough HAL is retrieved.
GetPassthroughServiceExact(const FqInstance & fq_instance,bool expect_interface_chain_valid)133 static sp<IBase> GetPassthroughServiceExact(const FqInstance &fq_instance,
134 bool expect_interface_chain_valid) {
135 for (size_t minor_version = fq_instance.getMinorVersion();; --minor_version) {
136 // String out instance name from fq_instance.
137 FqInstance interface;
138 if (!interface.setTo(fq_instance.getPackage(),
139 fq_instance.getMajorVersion(), minor_version,
140 fq_instance.getInterface())) {
141 ADD_FAILURE() << fq_instance.string()
142 << " doesn't contain a valid FQName";
143 return nullptr;
144 }
145
146 auto hal_service = VtsTrebleVintfTestBase::GetHidlService(
147 interface.string(), fq_instance.getInstance(), Transport::PASSTHROUGH);
148
149 if (hal_service != nullptr) {
150 bool interface_chain_valid = false;
151 hal_service->interfaceChain([&](const auto &chain) {
152 for (const auto &intf : chain) {
153 if (intf == interface.string()) {
154 interface_chain_valid = true;
155 return;
156 }
157 }
158 });
159 if (!interface_chain_valid && expect_interface_chain_valid) {
160 ADD_FAILURE() << "Retrieved " << interface.string() << "/"
161 << fq_instance.getInstance() << " as "
162 << fq_instance.string()
163 << " but interfaceChain() doesn't contain "
164 << fq_instance.string();
165 return nullptr;
166 }
167 cout << "Retrieved " << interface.string() << "/"
168 << fq_instance.getInstance() << " as " << fq_instance.string()
169 << endl;
170 return hal_service;
171 }
172
173 if (minor_version == 0) {
174 return nullptr;
175 }
176 }
177 ADD_FAILURE() << "Should not reach here";
178 return nullptr;
179 }
180
181 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleHwbinderHalTest);
182 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleHidlTest);
183
184 // Given vendor.foo.bar@x.y::IFoo/default, also look up all declared passthrough
185 // HAL implementations on the device that implements this interface.
GetPassthroughService(const FqInstance & fq_instance)186 sp<IBase> SingleHidlTest::GetPassthroughService(const FqInstance &fq_instance) {
187 sp<IBase> hal_service = GetPassthroughServiceExact(
188 fq_instance, true /* expect_interface_chain_valid */);
189 if (hal_service != nullptr) {
190 return hal_service;
191 }
192
193 // For vendor extensions, hal_service may be null because we don't know
194 // its interfaceChain()[1] to call getService(). However, the base interface
195 // should be declared in the manifest. Attempt to find it.
196 cout
197 << "Can't find passthrough service " << fq_instance.string()
198 << ". It might be a vendor extension. Searching all passthrough services "
199 "on the device for a match."
200 << endl;
201
202 const auto &[_, manifest] = GetParam();
203 auto all_declared_passthrough_instances = GetHidlInstances(manifest);
204 for (const HidlInstance &other_hidl_instance :
205 all_declared_passthrough_instances) {
206 if (other_hidl_instance.transport() != Transport::PASSTHROUGH) {
207 continue;
208 }
209 if (other_hidl_instance.instance_name() != fq_instance.getInstance()) {
210 cout << "Skipping " << other_hidl_instance.fq_name().string() << "/"
211 << other_hidl_instance.instance_name()
212 << " because instance name is not " << fq_instance.getInstance();
213 continue;
214 }
215 auto other_fq_instance = FqInstance::from(
216 other_hidl_instance.fq_name(), other_hidl_instance.instance_name());
217 if (!other_fq_instance) {
218 cout << other_hidl_instance.fq_name().string() << "/"
219 << other_hidl_instance.instance_name()
220 << " is not a valid FqInstance, skipping." << endl;
221 continue;
222 }
223 auto other_service = GetPassthroughServiceExact(
224 *other_fq_instance, false /* expect_interface_chain_valid */);
225 if (other_service == nullptr) {
226 cout << "Cannot retrieve " << other_fq_instance->string() << ", skipping."
227 << endl;
228 continue;
229 }
230 bool match = false;
231 auto other_interface_chain_ret =
232 other_service->interfaceChain([&](const auto &chain) {
233 for (const auto &intf : chain) {
234 auto other_fq_instance_in_chain = FqInstance::from(
235 std::string(intf) + "/" + other_fq_instance->getInstance());
236 if (other_fq_instance_in_chain == fq_instance) {
237 match = true;
238 break;
239 }
240 }
241 });
242 if (!other_interface_chain_ret.isOk()) {
243 cout << "Cannot call interfaceChain on " << other_fq_instance->string()
244 << ", skipping." << endl;
245 continue;
246 }
247 if (match) {
248 cout << "The implementation of " << other_fq_instance->string()
249 << " also implements " << fq_instance.string()
250 << ", using it to check if passthrough is allowed for "
251 << fq_instance.string() << endl;
252 return other_service;
253 }
254 }
255 cout << "Can't find any other passthrough service implementing "
256 << fq_instance.string() << endl;
257 return nullptr;
258 }
259
260 // returns true only if the specified apex is updated
IsApexUpdated(const std::string & apex_name)261 static bool IsApexUpdated(const std::string &apex_name) {
262 using namespace ::android::apex;
263 auto binder =
264 defaultServiceManager()->waitForService(String16("apexservice"));
265 if (binder != nullptr) {
266 auto apex_service = interface_cast<IApexService>(binder);
267 std::vector<ApexInfo> list;
268 auto status = apex_service->getActivePackages(&list);
269 EXPECT_TRUE(status.isOk())
270 << "Failed to getActivePackages():" << status.exceptionMessage();
271 for (const ApexInfo &apex_info : list) {
272 if (apex_info.moduleName == apex_name) {
273 return !apex_info.isFactory;
274 }
275 }
276 }
277 return false;
278 }
279
280 // Tests that no HAL outside of the allowed set is specified as passthrough in
281 // VINTF.
282 // @VsrTest = VSR-3.2-014
TEST_P(SingleHidlTest,HalIsBinderized)283 TEST_P(SingleHidlTest, HalIsBinderized) {
284 const auto &[hidl_instance, manifest] = GetParam();
285 const FQName &fq_name = hidl_instance.fq_name();
286 auto opt_fq_instance =
287 FqInstance::from(fq_name, hidl_instance.instance_name());
288 ASSERT_TRUE(opt_fq_instance);
289 const FqInstance &fq_instance = *opt_fq_instance;
290
291 EXPECT_THAT(hidl_instance.transport(),
292 AnyOf(Transport::HWBINDER, Transport::PASSTHROUGH))
293 << "HIDL HAL has unknown transport specified in VINTF ("
294 << hidl_instance.transport() << ": " << fq_instance.string();
295
296 if (hidl_instance.transport() == Transport::HWBINDER) {
297 return;
298 }
299
300 set<FqInstance> passthrough_allowed;
301 auto hal_service = GetPassthroughService(fq_instance);
302 if (hal_service == nullptr) {
303 cout << "Skip calling interfaceChain on " << fq_instance.string()
304 << " because it can't be retrieved directly." << endl;
305 } else {
306 // For example, given the following interfaceChain when
307 // hal_service is "android.hardware.mapper@2.0::IMapper/default":
308 // ["vendor.foo.mapper@1.0::IMapper",
309 // "android.hardware.mapper@2.1::IMapper",
310 // "android.hardware.mapper@2.0::IMapper",
311 // "android.hidl.base@1.0::IBase"],
312 // Allow the following:
313 // ["vendor.foo.mapper@1.0::IMapper/default",
314 // "android.hardware.mapper@2.1::IMapper/default",
315 // "android.hardware.mapper@2.0::IMapper/default"]
316 hal_service->interfaceChain([&](const auto &chain) {
317 vector<FqInstance> fq_instances;
318 std::transform(
319 chain.begin(), chain.end(), std::back_inserter(fq_instances),
320 [&](const auto &interface) {
321 return ToFqInstance(interface, fq_instance.getInstance());
322 });
323
324 bool allowing = false;
325 for (auto it = fq_instances.rbegin(); it != fq_instances.rend(); ++it) {
326 if (kPassthroughHals.find(it->getPackage()) != kPassthroughHals.end()) {
327 allowing = true;
328 }
329 if (allowing) {
330 cout << it->string() << " is allowed to be passthrough" << endl;
331 passthrough_allowed.insert(*it);
332 }
333 }
334 });
335 }
336
337 EXPECT_THAT(passthrough_allowed, Contains(fq_instance))
338 << "HIDL HAL can't be passthrough under Treble rules (or they "
339 "can't be retrieved): "
340 << fq_instance.string();
341 }
342
343 // Tests that all HALs specified in the VINTF are available through service
344 // manager.
345 // This tests (HAL in manifest) => (HAL is served)
346 // @VsrTest = VSR-3.2-014
TEST_P(SingleHidlTest,HalIsServed)347 TEST_P(SingleHidlTest, HalIsServed) {
348 // Verifies that HAL is available through service manager and is served from a
349 // specific set of partitions.
350
351 const auto &[hidl_instance, manifest] = GetParam();
352
353 Partition expected_partition = PartitionOfType(manifest->type());
354 const FQName &fq_name = hidl_instance.fq_name();
355 const string &instance_name = hidl_instance.instance_name();
356 Transport transport = hidl_instance.transport();
357
358 sp<IBase> hal_service;
359
360 if (transport == Transport::PASSTHROUGH) {
361 using android::hardware::details::canCastInterface;
362
363 // Passthrough services all start with minor version 0.
364 // there are only three of them listed above. They are looked
365 // up based on their binary location. For instance,
366 // V1_0::IFoo::getService() might correspond to looking up
367 // android.hardware.foo@1.0-impl for the symbol
368 // HIDL_FETCH_IFoo. For @1.1::IFoo to continue to work with
369 // 1.0 clients, it must also be present in a library that is
370 // called the 1.0 name. Clients can say:
371 // mFoo1_0 = V1_0::IFoo::getService();
372 // mFoo1_1 = V1_1::IFoo::castFrom(mFoo1_0);
373 // This is the standard pattern for making a service work
374 // for both versions (mFoo1_1 != nullptr => you have 1.1)
375 // and a 1.0 client still works with the 1.1 interface.
376
377 if (!IsAndroidPlatformInterface(fq_name)) {
378 // This isn't the case for extensions of core Google interfaces.
379 return;
380 }
381
382 const FQName lowest_name =
383 fq_name.withVersion(fq_name.getPackageMajorVersion(), 0);
384 hal_service = GetHidlService(lowest_name, instance_name, transport);
385 EXPECT_TRUE(canCastInterface(hal_service.get(), fq_name.string().c_str()))
386 << fq_name.string() << " is not on the device.";
387 } else {
388 hal_service = GetHidlService(fq_name, instance_name, transport);
389 }
390
391 if (hal_service == nullptr) {
392 FailureHalMissing(fq_name, instance_name);
393 return;
394 }
395
396 EXPECT_EQ(transport == Transport::HWBINDER, hal_service->isRemote())
397 << "transport is " << transport << "but HAL service is "
398 << (hal_service->isRemote() ? "" : "not") << " remote.";
399 EXPECT_EQ(transport == Transport::PASSTHROUGH, !hal_service->isRemote())
400 << "transport is " << transport << "but HAL service is "
401 << (hal_service->isRemote() ? "" : "not") << " remote.";
402
403 if (!hal_service->isRemote()) return;
404
405 Partition partition = GetPartition(hal_service);
406 if (partition == Partition::UNKNOWN) return;
407 EXPECT_EQ(expected_partition, partition)
408 << fq_name.string() << "/" << instance_name << " is in partition "
409 << partition << " but is expected to be in " << expected_partition;
410 }
411
412 // Tests that all HALs which are served are specified in the VINTF
413 // This tests (HAL is served) => (HAL in manifest)
414 // @VsrTest = VSR-3.2-014
TEST_P(SingleHwbinderHalTest,ServedHwbinderHalIsInManifest)415 TEST_P(SingleHwbinderHalTest, ServedHwbinderHalIsInManifest) {
416 const auto &[fq_instance_name, manifest] = GetParam();
417
418 if (fq_instance_name.find(IBase::descriptor) == 0) {
419 GTEST_SKIP() << "Ignore IBase: " << fq_instance_name;
420 }
421
422 auto expected_partition = PartitionOfType(manifest->type());
423 std::set<std::string> manifest_hwbinder_hals =
424 GetDeclaredHidlHalsOfTransport(manifest, Transport::HWBINDER);
425
426 auto opt_fq_instance = FqInstance::from(fq_instance_name);
427 ASSERT_TRUE(opt_fq_instance);
428 const FqInstance &fq_instance = *opt_fq_instance;
429
430 auto service = GetHidlService(
431 toFQNameString(fq_instance.getPackage(), fq_instance.getVersion(),
432 fq_instance.getInterface()),
433 fq_instance.getInstance(), Transport::HWBINDER);
434 ASSERT_NE(service, nullptr);
435
436 Partition partition = GetPartition(service);
437 if (partition == Partition::UNKNOWN) {
438 // Caught by SystemVendorTest.ServedHwbinderHalIsInManifest
439 // if that test is run.
440 GTEST_SKIP() << "Unable to determine partition. "
441 "Refer to SystemVendorTest.ServedHwbinderHalIsInManifest "
442 "or SingleHwbinderHalTest.ServedHwbinderHalIsInManifest "
443 "for the other manifest for correct result: "
444 << fq_instance_name;
445 }
446 if (partition != expected_partition) {
447 GTEST_SKIP() << "Skipping because this test only test "
448 << expected_partition << " partition on the "
449 << manifest->type()
450 << " side of Treble boundary. "
451 "Refer to SystemVendorTest.ServedHwbinderHalIsInManifest "
452 "or SingleHwbinderHalTest.ServedHwbinderHalIsInManifest "
453 "for the other manifest for correct result: "
454 << fq_instance_name;
455 }
456 EXPECT_NE(manifest_hwbinder_hals.find(fq_instance_name),
457 manifest_hwbinder_hals.end())
458 << fq_instance_name << " is being served, but it is not in a manifest.";
459 }
460
GetTestCaseSuffix(const::testing::TestParamInfo<ParamType> & info)461 std::string SingleHwbinderHalTest::GetTestCaseSuffix(
462 const ::testing::TestParamInfo<ParamType> &info) {
463 const auto &[fq_instance_name, manifest] = info.param;
464 return SanitizeTestCaseName(fq_instance_name) + "_" +
465 std::to_string(info.index);
466 }
467
468 // Tests that all HALs which are served are specified in the VINTF
469 // This tests (HAL is served) => (HAL in manifest) for passthrough HALs
470 // @VsrTest = VSR-3.2-014
TEST_P(SingleHidlTest,ServedPassthroughHalIsInManifest)471 TEST_P(SingleHidlTest, ServedPassthroughHalIsInManifest) {
472 const auto &[hidl_instance, manifest] = GetParam();
473 const FQName &fq_name = hidl_instance.fq_name();
474 const string &instance_name = hidl_instance.instance_name();
475 Transport transport = hidl_instance.transport();
476 std::set<std::string> manifest_passthrough_hals =
477 GetDeclaredHidlHalsOfTransport(manifest, Transport::PASSTHROUGH);
478
479 if (transport != Transport::PASSTHROUGH) {
480 GTEST_SKIP() << "Not passthrough: " << fq_name.string() << "/"
481 << instance_name;
482 }
483
484 // See HalIsServed. These are always retrieved through the base interface
485 // and if it is not a google defined interface, it must be an extension of
486 // one.
487 if (!IsAndroidPlatformInterface(fq_name)) {
488 GTEST_SKIP() << "Not Android Platform Interface: " << fq_name.string()
489 << "/" << instance_name;
490 }
491
492 const FQName lowest_name =
493 fq_name.withVersion(fq_name.getPackageMajorVersion(), 0);
494 sp<IBase> hal_service = GetHidlService(lowest_name, instance_name, transport);
495 ASSERT_NE(nullptr, hal_service)
496 << "Could not get service " << fq_name.string() << "/" << instance_name;
497
498 Return<void> ret = hal_service->interfaceChain(
499 [&manifest_passthrough_hals, &instance_name](const auto &interfaces) {
500 for (const auto &interface : interfaces) {
501 if (std::string(interface) == IBase::descriptor) continue;
502
503 const std::string instance =
504 std::string(interface) + "/" + instance_name;
505 EXPECT_NE(manifest_passthrough_hals.find(instance),
506 manifest_passthrough_hals.end())
507 << "Instance missing from manifest: " << instance;
508 }
509 });
510 EXPECT_TRUE(ret.isOk());
511 }
512
513 // Tests that HAL interfaces are officially released.
514 // @VsrTest = VSR-3.2-014
TEST_P(SingleHidlTest,InterfaceIsReleased)515 TEST_P(SingleHidlTest, InterfaceIsReleased) {
516 const auto &[hidl_instance, manifest] = GetParam();
517
518 const FQName &fq_name = hidl_instance.fq_name();
519 const string &instance_name = hidl_instance.instance_name();
520 Transport transport = hidl_instance.transport();
521
522 // See HalIsServed. These are always retrieved through the base interface
523 // and if it is not a google defined interface, it must be an extension of
524 // one.
525 if (transport == Transport::PASSTHROUGH &&
526 (!IsAndroidPlatformInterface(fq_name) ||
527 fq_name.getPackageMinorVersion() != 0)) {
528 return;
529 }
530
531 sp<IBase> hal_service = GetHidlService(fq_name, instance_name, transport);
532
533 if (hal_service == nullptr) {
534 FailureHalMissing(fq_name, instance_name);
535 return;
536 }
537
538 vector<string> iface_chain = GetInterfaceChain(hal_service);
539
540 vector<string> hash_chain{};
541 hal_service->getHashChain([&hash_chain](
542 const hidl_vec<HashCharArray> &chain) {
543 for (const HashCharArray &hash : chain) {
544 hash_chain.push_back(android::base::HexString(hash.data(), hash.size()));
545 }
546 });
547
548 ASSERT_EQ(iface_chain.size(), hash_chain.size());
549 for (size_t i = 0; i < iface_chain.size(); ++i) {
550 FQName fq_iface_name;
551 if (!FQName::parse(iface_chain[i], &fq_iface_name)) {
552 ADD_FAILURE() << "Could not parse iface name " << iface_chain[i]
553 << " from interface chain of " << fq_name.string();
554 return;
555 }
556 string hash = hash_chain[i];
557 if (hash == android::base::HexString(Hash::kEmptyHash.data(),
558 Hash::kEmptyHash.size())) {
559 FailureHashMissing(fq_iface_name);
560 } else if (IsAndroidPlatformInterface(fq_iface_name)) {
561 set<string> released_hashes = ReleasedHashes(fq_iface_name);
562 EXPECT_NE(released_hashes.find(hash), released_hashes.end())
563 << "Hash not found. This interface was not released." << endl
564 << "Interface name: " << fq_iface_name.string() << endl
565 << "Hash: " << hash << endl;
566 }
567 }
568 }
569
metadataForInterface(const std::string & name)570 static std::optional<AidlInterfaceMetadata> metadataForInterface(
571 const std::string &name) {
572 for (const auto &module : AidlInterfaceMetadata::all()) {
573 if (std::find(module.types.begin(), module.types.end(), name) !=
574 module.types.end()) {
575 return module;
576 }
577 }
578 return std::nullopt;
579 }
580
581 #ifdef TRUSTED_HAL_TEST
GetTrustedHalInfoFetcher()582 sp<IServiceInfoFetcher> GetTrustedHalInfoFetcher() {
583 int test_vm_cid = base::GetIntProperty("trusty.test_vm.vm_cid", -1);
584 if (test_vm_cid == -1) {
585 cout << "no test VM is running";
586 return nullptr;
587 }
588
589 auto session = RpcSession::make();
590 status_t status =
591 session->setupVsockClient(test_vm_cid, kTrustyTestVmVintfTaPort);
592 if (status != android::OK) {
593 cout << "unable to set up vsock client";
594 return nullptr;
595 }
596 sp<IBinder> root = session->getRootObject();
597 if (root == nullptr) {
598 cout << "failed to get root object for IServiceInfoFetcher";
599 return nullptr;
600 }
601 return IServiceInfoFetcher::asInterface(root);
602 }
603
TEST(TrustedHalDeclaredTest,TrustedHalDeclaredMatchesInstalled)604 TEST(TrustedHalDeclaredTest, TrustedHalDeclaredMatchesInstalled) {
605 auto trusted_hal_info_fetcher = GetTrustedHalInfoFetcher();
606 ASSERT_NE(trusted_hal_info_fetcher, nullptr)
607 << "failed to get IServiceInfoFetcher";
608
609 // Retrieve the list of actually installed Trusted HALs.
610 std::vector<std::string> actual_trusted_hal_list;
611 ASSERT_TRUE(
612 trusted_hal_info_fetcher->listAllServices(&actual_trusted_hal_list)
613 .isOk())
614 << "failed to list all services";
615 std::set<std::string> actual_instances(actual_trusted_hal_list.begin(),
616 actual_trusted_hal_list.end());
617
618 // Retrieve the list of declared Trusted HALs from the vintf manifest.
619 std::set<std::string> declared_instances = {};
620 for (const auto &aidl_instance : VtsTrebleVintfTestBase::GetAidlInstances(
621 VintfObject::GetDeviceHalManifest())) {
622 if (aidl_instance.exclusiveTo() == ExclusiveTo::VM) {
623 declared_instances.insert(ServiceName(aidl_instance));
624 }
625 }
626
627 // Compare the declared and actual sets.
628 ASSERT_EQ(declared_instances, actual_instances)
629 << "Declared Trusted HAL instances (exclusive to VM) do not match the "
630 << "actually installed instances.";
631 }
632
633 #else // TRUSTED_HAL_TEST
634 // TODO(b/150155678): using standard code to do this
getInterfaceVersion(const sp<IBinder> & binder)635 static int32_t getInterfaceVersion(const sp<IBinder> &binder) {
636 Parcel data;
637 Parcel reply;
638 const auto &descriptor = binder->getInterfaceDescriptor();
639 data.writeInterfaceToken(descriptor);
640 status_t err = binder->transact(IBinder::LAST_CALL_TRANSACTION, data, &reply);
641 // On upgrading devices, the HAL may not implement this transaction. libvintf
642 // treats missing <version> as version 1, so we do the same here.
643 if (err == UNKNOWN_TRANSACTION) {
644 std::cout << "INFO: " << descriptor
645 << " does not have an interface version, using default value "
646 << android::vintf::kDefaultAidlMinorVersion << std::endl;
647 return android::vintf::kDefaultAidlMinorVersion;
648 }
649 EXPECT_EQ(OK, err);
650 binder::Status status;
651 EXPECT_EQ(OK, status.readFromParcel(reply));
652 EXPECT_TRUE(status.isOk()) << status.toString8().c_str();
653 auto version = reply.readInt32();
654 return version;
655 }
656
657 // TODO(b/150155678): using standard code to do this
getInterfaceHash(const sp<IBinder> & binder)658 static std::string getInterfaceHash(const sp<IBinder> &binder) {
659 Parcel data;
660 Parcel reply;
661 data.writeInterfaceToken(binder->getInterfaceDescriptor());
662 status_t err =
663 binder->transact(IBinder::LAST_CALL_TRANSACTION - 1, data, &reply, 0);
664 if (err == UNKNOWN_TRANSACTION) {
665 return "";
666 }
667 EXPECT_EQ(OK, err);
668 binder::Status status;
669 EXPECT_EQ(OK, status.readFromParcel(reply));
670 EXPECT_TRUE(status.isOk()) << status.toString8().c_str();
671 std::string str;
672 EXPECT_EQ(OK, reply.readUtf8FromUtf16(&str));
673 return str;
674 }
675
getExtensionInfos(const sp<IBinder> & binder)676 std::vector<ServiceInfo> getExtensionInfos(const sp<IBinder> &binder) {
677 // if you end up here because of a stack overflow when running this
678 // test... you have a cycle in your interface extensions. Break that
679 // cycle to continue.
680 std::vector<ServiceInfo> extensions = {};
681 sp<IBinder> parent = binder;
682 sp<IBinder> extension;
683 while (parent) {
684 status_t status = parent->getExtension(&extension);
685 if (status != OK || !extension) {
686 break;
687 }
688 ServiceInfo info;
689 info.type =
690 std::string(String8(extension->getInterfaceDescriptor()).c_str());
691 info.requireVintfDeclaration =
692 android::internal::Stability::requiresVintfDeclaration(extension);
693 info.hash = getInterfaceHash(parent);
694 extensions.push_back(info);
695 parent = extension;
696 }
697 return extensions;
698 }
699 #endif // TRUSTED_HAL_TEST
700
CheckAidlVersionMatchesDeclared(const AidlInstance & declared_instance,const ServiceInfo & actual_hal_info)701 static bool CheckAidlVersionMatchesDeclared(
702 const AidlInstance &declared_instance, const ServiceInfo &actual_hal_info) {
703 const auto name = ServiceName(actual_hal_info);
704 const auto actual_version = actual_hal_info.version;
705 if (actual_version < 1) {
706 ADD_FAILURE() << "For " << name << ", version should be >= 1 but it is "
707 << actual_version << ".";
708 return false;
709 }
710
711 uint64_t declared_version = declared_instance.version();
712 if (declared_version == actual_version) {
713 std::cout << "For " << name << ", version " << actual_version
714 << " matches declared value." << std::endl;
715 return true;
716 }
717
718 const optional<string> &updatable_via_apex =
719 declared_instance.updatable_via_apex();
720 // allow upgrade if updatable HAL's declared APEX is actually updated.
721 // or if the HAL is updatable via system.
722 const bool allow_upgrade = (updatable_via_apex.has_value() &&
723 IsApexUpdated(updatable_via_apex.value())) ||
724 declared_instance.updatable_via_system();
725 if (allow_upgrade && actual_version > declared_version) {
726 std::cout << "For " << name << ", upgraded version " << actual_version
727 << " is okay. (declared value = " << declared_version << ".)"
728 << std::endl;
729 return true;
730 }
731
732 // Android R VINTF did not support AIDL version in the manifest.
733 Level shipping_fcm_version = VintfObject::GetDeviceHalManifest()->level();
734 if (shipping_fcm_version != Level::UNSPECIFIED &&
735 shipping_fcm_version <= Level::R) {
736 std::cout << "For " << name << ", manifest declares version "
737 << declared_version << ", but the actual version is "
738 << actual_version << ". Exempted for shipping FCM version "
739 << shipping_fcm_version << ". (b/178458001, b/199190514)"
740 << std::endl;
741 return true;
742 }
743
744 ADD_FAILURE()
745 << "For " << name << ", manifest (targeting FCM:" << shipping_fcm_version
746 << ") declares version " << declared_version
747 << ", but the actual version is " << actual_version << std::endl
748 << "Either the VINTF manifest <hal> entry needs to be updated with a "
749 "version tag for the actual version, or the implementation should be "
750 "changed to use the declared version";
751 return false;
752 }
753
halsUpdatableViaSystem()754 static std::vector<std::string> halsUpdatableViaSystem() {
755 std::vector<std::string> hals = {};
756 // The KeyMint HALs connecting to the Trusty VM in the system image are
757 // supposed to be enabled in vendor init when the system property
758 // |trusty.security_vm.keymint.enabled| is set to true in W.
759 if (base::GetBoolProperty("trusty.security_vm.keymint.enabled", false)) {
760 hals.push_back("android.hardware.security.keymint.IKeyMintDevice/default");
761 hals.push_back(
762 "android.hardware.security.keymint.IRemotelyProvisionedComponent/"
763 "default");
764 hals.push_back(
765 "android.hardware.security.sharedsecret.ISharedSecret/default");
766 hals.push_back(
767 "android.hardware.security.secureclock.ISecureClock/default");
768 }
769 return hals;
770 }
771
checkHash(const ServiceInfo & hal_info,bool ignore_rel,const std::optional<const std::string> & parent_interface)772 static inline void checkHash(
773 const ServiceInfo &hal_info, bool ignore_rel,
774 const std::optional<const std::string> &parent_interface) {
775 const std::string &interface = hal_info.type;
776 const std::string &hash = hal_info.hash;
777 const std::optional<AidlInterfaceMetadata> metadata =
778 metadataForInterface(interface);
779 const std::string parent_log =
780 parent_interface
781 ? "\nThis interface is set as an extension via setExtension on " +
782 *parent_interface
783 : "";
784
785 const bool is_aosp = base::StartsWith(interface, "android.");
786 ASSERT_TRUE(!is_aosp || metadata)
787 << "AOSP interface must have metadata: "
788 << interface << ". Do not use the "
789 << "'android.' prefix for non-AOSP HALs" << parent_log;
790 const bool is_release =
791 base::GetProperty("ro.build.version.codename", "") == "REL";
792
793 const std::vector<std::string> hashes =
794 metadata ? metadata->hashes : std::vector<std::string>();
795 const bool found_hash =
796 std::find(hashes.begin(), hashes.end(), hash) != hashes.end();
797
798 if (is_aosp) {
799 if (!found_hash) {
800 if (is_release || ignore_rel) {
801 ADD_FAILURE() << "Interface "
802 << interface << " has an unrecognized hash: '" << hash
803 << "'. The following hashes are known:\n"
804 << base::Join(hashes, '\n')
805 << "\nHAL interfaces must be released and unchanged."
806 << parent_log;
807 } else {
808 std::cout << "INFO: using unfrozen hash '" << hash << "' for "
809 << interface << ". This will become an error upon release."
810 << parent_log << std::endl;
811 }
812 }
813 } else {
814 // is partner-owned
815 //
816 // we only require that these are frozen, but we cannot check them for
817 // accuracy
818 if (hash.empty() || hash == "notfrozen") {
819 if (is_release) {
820 ADD_FAILURE()
821 << "Interface "
822 << interface << " is used but not frozen (cannot find hash for it)."
823 << parent_log;
824 } else {
825 std::cout << "INFO: missing hash for "
826 << interface << ". This will become an error upon release."
827 << parent_log << std::endl;
828 }
829 }
830 }
831 }
832
833 // This checks to make sure all vintf extensions are frozen.
834 // We do not check for known hashes because the Android framework does not
835 // support these extensions without out-of-tree changes from partners.
836 // @param binder - the parent binder to check all of its extensions
checkVintfExtensionInterfaces(const ServiceInfo & info)837 void checkVintfExtensionInterfaces(const ServiceInfo &info) {
838 // if you end up here because of a stack overflow when running this
839 // test... you have a cycle in your interface extensions. Break that
840 // cycle to continue.
841 for (const auto &extension : info.extensions) {
842 if (extension.requireVintfDeclaration) {
843 checkHash(extension, false, info.type);
844 }
845 checkVintfExtensionInterfaces(extension);
846 }
847 }
848
849 // This checks if @updatable-via-apex in VINTF is correct.
checkVintfUpdatableViaApex(const std::string & exe,const std::string & apex_name)850 void checkVintfUpdatableViaApex(const std::string &exe,
851 const std::string &apex_name) {
852 // HAL service should start from the apex
853 ASSERT_THAT(exe, StartsWith("/apex/" + apex_name + "/"));
854 }
855
TEST_P(SingleAidlTest,ExpectedUpdatableViaSystemHals)856 TEST_P(SingleAidlTest, ExpectedUpdatableViaSystemHals) {
857 const auto &[aidl_instance, _] = GetParam();
858 const std::string name = ServiceName(aidl_instance);
859
860 const auto hals = halsUpdatableViaSystem();
861 if (std::find(hals.begin(), hals.end(), name) != hals.end()) {
862 ASSERT_TRUE(aidl_instance.updatable_via_system())
863 << "HAL " << name << " has system dependency but not declared with "
864 << "updatable-via-system in the VINTF manifest.";
865 } else {
866 ASSERT_FALSE(aidl_instance.updatable_via_system())
867 << "HAL " << name << " is declared with updatable-via-system in the "
868 << "VINTF manifest but it does not have system dependency.";
869 }
870 }
871
872 // An AIDL HAL with VINTF stability can only be registered if it is in the
873 // manifest. However, we still must manually check that every declared HAL is
874 // actually present on the device.
875 // @VsrTest = VSR-3.2-014
TEST_P(SingleAidlTest,HalIsServed)876 TEST_P(SingleAidlTest, HalIsServed) {
877 const auto &[aidl_instance, manifest] = GetParam();
878 const string &package = aidl_instance.package();
879 uint64_t version = aidl_instance.version();
880 const string &interface = aidl_instance.interface();
881 const string &instance = aidl_instance.instance();
882 const optional<string> &updatable_via_apex =
883 aidl_instance.updatable_via_apex();
884
885 const std::string type = package + "." + interface;
886 const std::string name = type + "/" + instance;
887
888 ServiceInfo actual_hal_info;
889 Partition actual_partition;
890
891 #ifdef TRUSTED_HAL_TEST
892 if (aidl_instance.exclusiveTo() != ExclusiveTo::VM) {
893 GTEST_SKIP() << name
894 << " is not check in this test as it is not exclusive to VM";
895 }
896 auto trusted_hal_info_fetcher = GetTrustedHalInfoFetcher();
897 ASSERT_NE(trusted_hal_info_fetcher, nullptr)
898 << "failed to get IServiceInfoFetcher";
899
900 ASSERT_TRUE(
901 trusted_hal_info_fetcher->getServiceInfo(name, &actual_hal_info).isOk())
902 << "failed to get service info for HAL exclusive to VM: " << name;
903
904 actual_partition = Partition::VENDOR;
905 #else // TRUSTED_HAL_TEST
906 if (aidl_instance.exclusiveTo() == ExclusiveTo::VM) {
907 GTEST_SKIP() << name
908 << " is not check in this test as it is exclusive to VM";
909 }
910 sp<IBinder> binder = GetAidlService(name);
911 ASSERT_NE(binder, nullptr) << "Failed to get " << name;
912
913 actual_hal_info.type = type;
914 actual_hal_info.instance = instance;
915 actual_hal_info.requireVintfDeclaration =
916 android::internal::Stability::requiresVintfDeclaration(binder);
917 actual_hal_info.version = getInterfaceVersion(binder);
918 actual_hal_info.hash = getInterfaceHash(binder);
919
920 pid_t pid;
921 ASSERT_EQ(OK, binder->getDebugPid(&pid));
922 actual_partition = PartitionOfProcess(pid);
923
924 ASSERT_TRUE(base::Readlink("/proc/" + std::to_string(pid) + "/exe",
925 &actual_hal_info.exe));
926
927 actual_hal_info.extensions = getExtensionInfos(binder);
928 #endif // TRUSTED_HAL_TEST
929
930 ASSERT_EQ(name, ServiceName(actual_hal_info));
931 if (GetVendorApiLevel() >= kAndroidApi202404 &&
932 !actual_hal_info.requireVintfDeclaration) {
933 ADD_FAILURE() << "Interface " << name
934 << " is declared in the VINTF manifest "
935 << "but it does not have \"vintf\" stability. "
936 << "Add 'stability: \"vintf\" to the aidl_interface module, "
937 << "or remove it from the VINTF manifest.";
938 }
939 // If we know this version is frozen, even on non-REL builds we should throw
940 // an error if this is an AOSP interfaces with a hash that we don't know
941 // about.
942 const bool reliable_version =
943 CheckAidlVersionMatchesDeclared(aidl_instance, actual_hal_info);
944 const std::optional<AidlInterfaceMetadata> metadata =
945 metadataForInterface(type);
946 const bool is_existing =
947 metadata ? std::find(metadata->versions.begin(), metadata->versions.end(),
948 version) != metadata->versions.end()
949 : false;
950 const bool ignore_rel_for_aosp = reliable_version && is_existing;
951
952 checkHash(actual_hal_info, ignore_rel_for_aosp, std::nullopt);
953
954 if (GetVendorApiLevel() >= kAndroidApi202504) {
955 checkVintfExtensionInterfaces(actual_hal_info);
956 }
957
958 // TODO(b/388106311): always be able to determine where this code comes from
959 const bool ableToDeterminePartition = actual_partition != Partition::UNKNOWN;
960 if (GetVendorApiLevel() >= kAndroidApi202504 && ableToDeterminePartition) {
961 Partition expected_partition = PartitionOfType(manifest->type());
962 EXPECT_EQ(expected_partition, actual_partition);
963 }
964
965 if (updatable_via_apex.has_value()) {
966 checkVintfUpdatableViaApex(actual_hal_info.exe, updatable_via_apex.value());
967 }
968 }
969
970 // We don't want to add more same process HALs in Android. We have some 3rd
971 // party ones such as openGL and Vulkan. In the future, we should verify those
972 // here as well. However we want to strictly limit other HALs because a
973 // same-process HAL confuses the client and server SELinux permissions. In
974 // Android, we prefer upstream Linux support, then secondary to that, we prefer
975 // having hardware use in a process isolated from the Android framework.
976 struct NativePackage {
977 std::string name;
978 int32_t majorVersion;
979 };
980
operator <<(ostream & os,const NativePackage & pkg)981 ostream &operator<<(ostream &os, const NativePackage &pkg) {
982 os << pkg.name << "-v" << pkg.majorVersion;
983 return os;
984 }
985
986 static const std::array<NativePackage, 1> kKnownNativePackages = {
987 NativePackage{"mapper", 5},
988 };
989 static const std::vector<std::string> kNativeHalPaths = {
990 "/vendor/lib/hw/",
991 "/vendor/lib64/hw/",
992 };
993
findKnownNativePackage(std::string_view package)994 static std::optional<NativePackage> findKnownNativePackage(
995 std::string_view package) {
996 for (const auto &it : kKnownNativePackages) {
997 if (it.name == package) {
998 return it;
999 }
1000 }
1001 return std::nullopt;
1002 }
1003
1004 // using device manifest test for access to GetNativeInstances
TEST(NativeDeclaredTest,NativeDeclaredIfExists)1005 TEST(NativeDeclaredTest, NativeDeclaredIfExists) {
1006 std::set<std::string> names; // e.g. 'mapper.instance_name'
1007
1008 // read all the native HALs installed on disk
1009 bool found_a_dir = false;
1010 for (const std::string &dir : kNativeHalPaths) {
1011 DIR *dp = opendir(dir.c_str());
1012 if (dp == nullptr) continue;
1013 found_a_dir = true;
1014
1015 dirent *entry;
1016 while ((entry = readdir(dp))) {
1017 std::string name = entry->d_name;
1018 size_t dot_one = name.find('.');
1019 if (dot_one == std::string::npos) continue;
1020 size_t dot_end = name.rfind('.');
1021 if (dot_end == std::string::npos || dot_one == dot_end) continue;
1022 ASSERT_LT(dot_one, dot_end);
1023 if (name.substr(dot_end) != ".so") continue;
1024
1025 std::string package = name.substr(0, dot_one);
1026 if (!findKnownNativePackage(package).has_value()) continue;
1027
1028 names.insert(name.substr(0, dot_end));
1029 }
1030 closedir(dp);
1031 }
1032 ASSERT_TRUE(found_a_dir);
1033
1034 // ignore HALs which are declared, because they'll be checked in
1035 // SingleNativeTest ExistsIfDeclared
1036 for (const auto &hal : VtsTrebleVintfTestBase::GetNativeInstances(
1037 VintfObject::GetDeviceHalManifest())) {
1038 std::string this_name = hal.package() + "." + hal.instance();
1039 names.erase(this_name);
1040 }
1041
1042 for (const std::string &name : names) {
1043 ADD_FAILURE() << name
1044 << " is installed on the device, but it's not declared in "
1045 "the VINTF manifest";
1046 }
1047 }
1048
1049 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SingleNativeTest);
TEST_P(SingleNativeTest,ExistsIfDeclared)1050 TEST_P(SingleNativeTest, ExistsIfDeclared) {
1051 const auto &[native_instance, manifest] = GetParam();
1052
1053 // Currently only support rev'ing the major version
1054 EXPECT_EQ(native_instance.minor_version(), 0);
1055
1056 auto knownPackageInfo = findKnownNativePackage(native_instance.package());
1057 ASSERT_TRUE(knownPackageInfo.has_value())
1058 << "Unsupported package: " << native_instance.package()
1059 << " must be one of: " << base::Join(kKnownNativePackages, ", ");
1060 EXPECT_EQ(native_instance.major_version(), knownPackageInfo->majorVersion);
1061 EXPECT_TRUE(native_instance.interface() == "I" ||
1062 native_instance.interface() == "")
1063 << "Interface must be 'I' or '' for native HAL: "
1064 << native_instance.interface();
1065
1066 void *so = openDeclaredPassthroughHal(
1067 String16(native_instance.package().c_str()),
1068 String16(native_instance.instance().c_str()), RTLD_LAZY | RTLD_LOCAL);
1069 ASSERT_NE(so, nullptr) << "Failed to load " << native_instance << dlerror();
1070
1071 std::string upperPackage = native_instance.package();
1072 std::transform(upperPackage.begin(), upperPackage.end(), upperPackage.begin(),
1073 ::toupper);
1074 std::string versionSymbol = "ANDROID_HAL_" + upperPackage + "_VERSION";
1075 int32_t *halVersion = (int32_t *)dlsym(so, versionSymbol.c_str());
1076 ASSERT_NE(halVersion, nullptr) << "Failed to find symbol " << versionSymbol;
1077 EXPECT_EQ(native_instance.major_version(), *halVersion);
1078
1079 dlclose(so);
1080 }
1081
1082 } // namespace testing
1083 } // namespace vintf
1084 } // namespace android
1085