diff options
author | Yifan Hong <elsk@google.com> | 2023-03-10 23:42:22 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-03-10 23:42:22 +0000 |
commit | 28ae003b87e958e4b81d03008c7e8bcda85f1de4 (patch) | |
tree | 8d33b6d32779fed89210c6f14f08fb163e716820 | |
parent | 62a0b9d929d924bc7975d1bc08d56aade0a1a645 (diff) | |
parent | 8c032d0a05df58196eb82fb438924a79b597651c (diff) | |
download | hal-28ae003b87e958e4b81d03008c7e8bcda85f1de4.tar.gz |
Treble VINTF test: Allow vendor extensions for passthrough HALs. am: 2bec0220cf am: 8c032d0a05
Original change: https://android-review.googlesource.com/c/platform/test/vts-testcase/hal/+/2481498
Change-Id: I1991f356d00ae5eb4481bebe3bcd8991b4f0f0be
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | treble/vintf/SingleManifestTest.cpp | 81 | ||||
-rw-r--r-- | treble/vintf/SingleManifestTest.h | 4 |
2 files changed, 83 insertions, 2 deletions
diff --git a/treble/vintf/SingleManifestTest.cpp b/treble/vintf/SingleManifestTest.cpp index 14778912..0cfedfee 100644 --- a/treble/vintf/SingleManifestTest.cpp +++ b/treble/vintf/SingleManifestTest.cpp @@ -106,7 +106,8 @@ static FqInstance ToFqInstance(const string &interface, // Given android.foo.bar@x.y::IFoo/default, attempt to get // android.foo.bar@x.y::IFoo/default, android.foo.bar@x.(y-1)::IFoo/default, // ... android.foo.bar@x.0::IFoo/default until the passthrough HAL is retrieved. -static sp<IBase> GetPassthroughService(const FqInstance &fq_instance) { +static sp<IBase> GetPassthroughServiceExact(const FqInstance &fq_instance, + bool expect_interface_chain_valid) { for (size_t minor_version = fq_instance.getMinorVersion();; --minor_version) { // String out instance name from fq_instance. FqInstance interface; @@ -131,7 +132,7 @@ static sp<IBase> GetPassthroughService(const FqInstance &fq_instance) { } } }); - if (!interface_chain_valid) { + if (!interface_chain_valid && expect_interface_chain_valid) { ADD_FAILURE() << "Retrieved " << interface.string() << "/" << fq_instance.getInstance() << " as " << fq_instance.string() @@ -153,6 +154,82 @@ static sp<IBase> GetPassthroughService(const FqInstance &fq_instance) { return nullptr; } +// Given vendor.foo.bar@x.y::IFoo/default, also look up all declared passthrough +// HAL implementations on the device that implements this interface. +sp<IBase> SingleHidlTest::GetPassthroughService(const FqInstance &fq_instance) { + sp<IBase> hal_service = GetPassthroughServiceExact( + fq_instance, true /* expect_interface_chain_valid */); + if (hal_service != nullptr) { + return hal_service; + } + + // For vendor extensions, hal_service may be null because we don't know + // its interfaceChain()[1] to call getService(). However, the base interface + // should be declared in the manifest. Attempt to find it. + cout + << "Can't find passthrough service " << fq_instance.string() + << ". It might be a vendor extension. Searching all passthrough services " + "on the device for a match." + << endl; + + const auto &[_, manifest] = GetParam(); + auto all_declared_passthrough_instances = GetHidlInstances(manifest); + for (const HidlInstance &other_hidl_instance : + all_declared_passthrough_instances) { + if (other_hidl_instance.transport() != Transport::PASSTHROUGH) { + continue; + } + if (other_hidl_instance.instance_name() != fq_instance.getInstance()) { + cout << "Skipping " << other_hidl_instance.fq_name().string() << "/" + << other_hidl_instance.instance_name() + << " because instance name is not " << fq_instance.getInstance(); + continue; + } + auto other_fq_instance = FqInstance::from( + other_hidl_instance.fq_name(), other_hidl_instance.instance_name()); + if (!other_fq_instance) { + cout << other_hidl_instance.fq_name().string() << "/" + << other_hidl_instance.instance_name() + << " is not a valid FqInstance, skipping." << endl; + continue; + } + auto other_service = GetPassthroughServiceExact( + *other_fq_instance, false /* expect_interface_chain_valid */); + if (other_service == nullptr) { + cout << "Cannot retrieve " << other_fq_instance->string() << ", skipping." + << endl; + continue; + } + bool match = false; + auto other_interface_chain_ret = + other_service->interfaceChain([&](const auto &chain) { + for (const auto &intf : chain) { + auto other_fq_instance_in_chain = FqInstance::from( + std::string(intf) + "/" + other_fq_instance->getInstance()); + if (other_fq_instance_in_chain == fq_instance) { + match = true; + break; + } + } + }); + if (!other_interface_chain_ret.isOk()) { + cout << "Cannot call interfaceChain on " << other_fq_instance->string() + << ", skipping." << endl; + continue; + } + if (match) { + cout << "The implementation of " << other_fq_instance->string() + << " also implements " << fq_instance.string() + << ", using it to check if passthrough is allowed for " + << fq_instance.string() << endl; + return other_service; + } + } + cout << "Can't find any other passthrough service implementing " + << fq_instance.string() << endl; + return nullptr; +} + // returns true only if the specified apex is updated static bool IsApexUpdated(const std::string &apex_name) { using namespace ::android::apex; diff --git a/treble/vintf/SingleManifestTest.h b/treble/vintf/SingleManifestTest.h index 22003073..09967f3b 100644 --- a/treble/vintf/SingleManifestTest.h +++ b/treble/vintf/SingleManifestTest.h @@ -17,6 +17,8 @@ #ifndef VTS_TREBLE_VINTF_TEST_SINGLE_MANIFEST_TEST_H_ #define VTS_TREBLE_VINTF_TEST_SINGLE_MANIFEST_TEST_H_ #include <gtest/gtest.h> +#include <hidl-util/FqInstance.h> + #include "VtsTrebleVintfTestBase.h" namespace android { @@ -30,6 +32,8 @@ class SingleHidlTest : public VtsTrebleVintfTestBase, std::tuple<HidlInstance, HalManifestPtr>> { public: virtual ~SingleHidlTest() {} + + sp<IBase> GetPassthroughService(const android::FqInstance& fq_instance); }; // A parameterized test for an HIDL HAL registered through hwservicemanager |