• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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