summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYifan Hong <elsk@google.com>2023-03-10 23:42:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-03-10 23:42:22 +0000
commit28ae003b87e958e4b81d03008c7e8bcda85f1de4 (patch)
tree8d33b6d32779fed89210c6f14f08fb163e716820
parent62a0b9d929d924bc7975d1bc08d56aade0a1a645 (diff)
parent8c032d0a05df58196eb82fb438924a79b597651c (diff)
downloadhal-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.cpp81
-rw-r--r--treble/vintf/SingleManifestTest.h4
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