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