Merge changes I0ced4012,I9b1f8ed9,Iba2a7259,I8174b895
* changes:
omx vts: update language to comply with Android's inclusive language guidance
omx: rename master to store
OMX VTS: Use GetComponentRole from OMXUtils
Convert Python OMX VTS test to Gtest
diff --git a/media/omx/1.0/vts/functional/README.md b/media/omx/1.0/vts/functional/README.md
index c5a6867..67f4aa5 100644
--- a/media/omx/1.0/vts/functional/README.md
+++ b/media/omx/1.0/vts/functional/README.md
@@ -1,12 +1,12 @@
## Omx Hal @ 1.0 tests ##
---
## Overview :
-The scope of the tests presented here is not restricted solely to testing omx hal @ 1.0 API but also test to omx core functionality and to an extent omx components as well. The current directory contains the following folders: audio, common, component, master and video. Besides common all other folders contain test fixtures for testing AV decoder, encoder components. Common constitutes files that are used across by these test applications.
+The scope of the tests presented here is not restricted solely to testing omx hal @ 1.0 API but also test to omx core functionality and to an extent omx components as well. The current directory contains the following folders: audio, common, component, store and video. Besides common all other folders contain test fixtures for testing AV decoder, encoder components. Common constitutes files that are used across by these test applications.
-#### master :
-Functionality of master is to enumerate all the omx components (and the roles it supports) available in android media framework.
+#### store :
+Functionality of store is to enumerate all the omx components (and the roles it supports) available in android media framework.
-usage: atest VtsHalMediaOmxV1\_0TargetMasterTest
+usage: atest VtsHalMediaOmxV1\_0TargetStoreTest
#### component :
This folder includes test fixtures that tests aspects common to all omx compatible components. For instance, port enabling/disabling, enumerating port formats, state transitions, flush, ..., stay common to all components irrespective of the service they offer. Test fixtures here are directed towards testing these (omx core). Every standard OMX compatible component is expected to pass these tests.
diff --git a/media/omx/1.0/vts/functional/common/Android.bp b/media/omx/1.0/vts/functional/common/Android.bp
index 7e7463a..3845b9f 100644
--- a/media/omx/1.0/vts/functional/common/Android.bp
+++ b/media/omx/1.0/vts/functional/common/Android.bp
@@ -74,5 +74,6 @@
shared_libs: [
"libnativehelper",
"libstagefright_foundation",
+ "libstagefright_omx_utils",
],
}
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
index d9d1157..a507eea 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.cpp
@@ -785,8 +785,8 @@
for (IOmx::ComponentInfo info : componentInfos) {
for (std::string role : info.mRoles) {
if (filter.empty()) {
- if (kWhiteListRoles.find(role.c_str()) == kWhiteListRoles.end()) {
- // This is for component test and the role is not in the white list.
+ if (kKnownRoles.find(role.c_str()) == kKnownRoles.end()) {
+ // This is for component test and the role is not supported.
continue;
}
} else if (role.find(filter) == std::string::npos) {
diff --git a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
index bb03dd0..02c42c1 100644
--- a/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
+++ b/media/omx/1.0/vts/functional/common/media_hidl_test_common.h
@@ -78,8 +78,8 @@
unknown,
};
-// White list audio/video roles to be tested.
-static std::set<std::string> kWhiteListRoles{
+// List known and thus tested audio/video roles.
+static std::set<std::string> kKnownRoles{
"audio_encoder.aac", "audio_encoder.amrnb", "audio_encoder.amrwb",
"audio_encoder.flac", "audio_decoder.aac", "audio_decoder.amrnb",
"audio_decoder.amrwb", "audio_decoder.flac", "audio_decoder.g711alaw",
diff --git a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp b/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
deleted file mode 100644
index c14f1da..0000000
--- a/media/omx/1.0/vts/functional/master/VtsHalMediaOmxV1_0TargetMasterTest.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "media_omx_hidl_master_test"
-#ifdef __LP64__
-#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
-#endif
-
-#include <android-base/logging.h>
-
-#include <android/hardware/media/omx/1.0/IOmx.h>
-#include <android/hardware/media/omx/1.0/IOmxNode.h>
-#include <android/hardware/media/omx/1.0/IOmxObserver.h>
-#include <android/hardware/media/omx/1.0/IOmxStore.h>
-#include <android/hardware/media/omx/1.0/types.h>
-#include <android/hidl/allocator/1.0/IAllocator.h>
-#include <android/hidl/memory/1.0/IMapper.h>
-#include <android/hidl/memory/1.0/IMemory.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-
-using ::android::hardware::media::omx::V1_0::IOmx;
-using ::android::hardware::media::omx::V1_0::IOmxObserver;
-using ::android::hardware::media::omx::V1_0::IOmxNode;
-using ::android::hardware::media::omx::V1_0::IOmxStore;
-using ::android::hardware::media::omx::V1_0::Message;
-using ::android::hardware::media::omx::V1_0::CodecBuffer;
-using ::android::hardware::media::omx::V1_0::PortMode;
-using ::android::hidl::allocator::V1_0::IAllocator;
-using ::android::hidl::memory::V1_0::IMemory;
-using ::android::hidl::memory::V1_0::IMapper;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
-#include <getopt.h>
-#include <media_hidl_test_common.h>
-
-class MasterHidlTest : public ::testing::TestWithParam<std::string> {
- public:
- virtual void SetUp() override {
- omxStore = IOmxStore::getService(GetParam());
- ASSERT_NE(omxStore, nullptr);
- omx = IOmx::getService(GetParam());
- ASSERT_NE(omx, nullptr);
- }
-
- sp<IOmxStore> omxStore;
- sp<IOmx> omx;
-
- protected:
- static void description(const std::string& description) {
- RecordProperty("description", description);
- }
-};
-
-void displayComponentInfo(hidl_vec<IOmx::ComponentInfo>& nodeList) {
- for (size_t i = 0; i < nodeList.size(); i++) {
- printf("%s | ", nodeList[i].mName.c_str());
- for (size_t j = 0; j < ((nodeList[i]).mRoles).size(); j++) {
- printf("%s ", nodeList[i].mRoles[j].c_str());
- }
- printf("\n");
- }
-}
-
-// Make sure IOmx and IOmxStore have the same set of instances.
-TEST(MasterHidlTest, instanceMatchValidation) {
- auto omxInstances = android::hardware::getAllHalInstanceNames(IOmx::descriptor);
- auto omxStoreInstances = android::hardware::getAllHalInstanceNames(IOmxStore::descriptor);
- ASSERT_EQ(omxInstances.size(), omxInstances.size());
- for (const std::string& omxInstance : omxInstances) {
- EXPECT_TRUE(std::find(omxStoreInstances.begin(), omxStoreInstances.end(), omxInstance) !=
- omxStoreInstances.end());
- }
-}
-
-// list service attributes
-TEST_P(MasterHidlTest, ListServiceAttr) {
- description("list service attributes");
- android::hardware::media::omx::V1_0::Status status;
- hidl_vec<IOmxStore::Attribute> attributes;
- EXPECT_TRUE(omxStore
- ->listServiceAttributes([&status, &attributes](
- android::hardware::media::omx::V1_0::Status _s,
- hidl_vec<IOmxStore::Attribute> const& _nl) {
- status = _s;
- attributes = _nl;
- })
- .isOk());
- ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
- if (attributes.size() == 0) ALOGV("Warning, Attribute list empty");
-}
-
-// get node prefix
-TEST_P(MasterHidlTest, getNodePrefix) {
- description("get node prefix");
- hidl_string prefix;
- omxStore->getNodePrefix(
- [&prefix](hidl_string const& _nl) { prefix = _nl; });
- if (prefix.empty()) ALOGV("Warning, Node Prefix empty");
-}
-
-// list roles
-TEST_P(MasterHidlTest, ListRoles) {
- description("list roles");
- hidl_vec<IOmxStore::RoleInfo> roleList;
- omxStore->listRoles([&roleList](hidl_vec<IOmxStore::RoleInfo> const& _nl) {
- roleList = _nl;
- });
- if (roleList.size() == 0) ALOGV("Warning, RoleInfo list empty");
-}
-
-// list components and roles.
-TEST_P(MasterHidlTest, ListNodes) {
- description("enumerate component and roles");
- android::hardware::media::omx::V1_0::Status status;
- hidl_vec<IOmx::ComponentInfo> nodeList;
- bool isPass = true;
- EXPECT_TRUE(
- omx->listNodes([&status, &nodeList](
- android::hardware::media::omx::V1_0::Status _s,
- hidl_vec<IOmx::ComponentInfo> const& _nl) {
- status = _s;
- nodeList = _nl;
- })
- .isOk());
- ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
- if (nodeList.size() == 0)
- ALOGV("Warning, ComponentInfo list empty");
- else {
- // displayComponentInfo(nodeList);
- for (size_t i = 0; i < nodeList.size(); i++) {
- sp<CodecObserver> observer = nullptr;
- sp<IOmxNode> omxNode = nullptr;
- observer = new CodecObserver(nullptr);
- ASSERT_NE(observer, nullptr);
- EXPECT_TRUE(
- omx->allocateNode(
- nodeList[i].mName, observer,
- [&](android::hardware::media::omx::V1_0::Status _s,
- sp<IOmxNode> const& _nl) {
- status = _s;
- omxNode = _nl;
- })
- .isOk());
- ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
- if (omxNode == nullptr) {
- isPass = false;
- std::cerr << "[ !OK ] " << nodeList[i].mName.c_str()
- << "\n";
- } else {
- EXPECT_TRUE((omxNode->freeNode()).isOk());
- omxNode = nullptr;
- // std::cout << "[ OK ] " << nodeList[i].mName.c_str() <<
- // "\n";
- }
- }
- }
- EXPECT_TRUE(isPass);
-}
-
-INSTANTIATE_TEST_CASE_P(
- PerInstance, MasterHidlTest,
- testing::ValuesIn(android::hardware::getAllHalInstanceNames(IOmxStore::descriptor)),
- android::hardware::PrintInstanceNameToString);
diff --git a/media/omx/1.0/vts/functional/master/Android.bp b/media/omx/1.0/vts/functional/store/Android.bp
similarity index 85%
rename from media/omx/1.0/vts/functional/master/Android.bp
rename to media/omx/1.0/vts/functional/store/Android.bp
index 8e58821..28d12ff 100644
--- a/media/omx/1.0/vts/functional/master/Android.bp
+++ b/media/omx/1.0/vts/functional/store/Android.bp
@@ -15,10 +15,11 @@
//
cc_test {
- name: "VtsHalMediaOmxV1_0TargetMasterTest",
+ name: "VtsHalMediaOmxV1_0TargetStoreTest",
defaults: ["VtsHalMediaOmxV1_0Defaults"],
- srcs: ["VtsHalMediaOmxV1_0TargetMasterTest.cpp"],
+ srcs: ["VtsHalMediaOmxV1_0TargetStoreTest.cpp"],
test_suites: [
+ "general-tests",
"vts",
],
}
diff --git a/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
new file mode 100644
index 0000000..0ad0634
--- /dev/null
+++ b/media/omx/1.0/vts/functional/store/VtsHalMediaOmxV1_0TargetStoreTest.cpp
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "media_omx_hidl_store_test"
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
+#include <android-base/logging.h>
+#include <android-base/strings.h>
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/omx/1.0/IOmxNode.h>
+#include <android/hardware/media/omx/1.0/IOmxObserver.h>
+#include <android/hardware/media/omx/1.0/IOmxStore.h>
+#include <android/hardware/media/omx/1.0/types.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMapper.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#include <media/stagefright/omx/OMXUtils.h>
+
+using ::android::sp;
+using ::android::base::Join;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::media::omx::V1_0::CodecBuffer;
+using ::android::hardware::media::omx::V1_0::IOmx;
+using ::android::hardware::media::omx::V1_0::IOmxNode;
+using ::android::hardware::media::omx::V1_0::IOmxObserver;
+using ::android::hardware::media::omx::V1_0::IOmxStore;
+using ::android::hardware::media::omx::V1_0::Message;
+using ::android::hardware::media::omx::V1_0::PortMode;
+using ::android::hidl::allocator::V1_0::IAllocator;
+using ::android::hidl::memory::V1_0::IMapper;
+using ::android::hidl::memory::V1_0::IMemory;
+
+#include <getopt.h>
+#include <media_hidl_test_common.h>
+
+class StoreHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ omxStore = IOmxStore::getService(GetParam());
+ ASSERT_NE(omxStore, nullptr);
+ omx = IOmx::getService(GetParam());
+ ASSERT_NE(omx, nullptr);
+ }
+
+ sp<IOmxStore> omxStore;
+ sp<IOmx> omx;
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+};
+
+struct AttributePattern {
+ const testing::internal::RE key;
+ const testing::internal::RE value;
+};
+
+void displayComponentInfo(hidl_vec<IOmx::ComponentInfo>& nodeList) {
+ for (size_t i = 0; i < nodeList.size(); i++) {
+ printf("%s | ", nodeList[i].mName.c_str());
+ for (size_t j = 0; j < ((nodeList[i]).mRoles).size(); j++) {
+ printf("%s ", nodeList[i].mRoles[j].c_str());
+ }
+ printf("\n");
+ }
+}
+
+void validateAttributes(
+ const std::map<const std::string, const testing::internal::RE>& knownPatterns,
+ const std::vector<const struct AttributePattern>& unknownPatterns,
+ hidl_vec<IOmxStore::Attribute> attributes) {
+ std::set<const std::string> attributeKeys;
+ for (const auto& attr : attributes) {
+ // Make sure there are no duplicates
+ const auto [nodeIter, inserted] = attributeKeys.insert(attr.key);
+ EXPECT_EQ(inserted, true) << "Attribute \"" << attr.key << "\" has duplicates.";
+
+ // Check the value against the corresponding regular
+ // expression.
+ const auto knownPattern = knownPatterns.find(attr.key);
+ if (knownPattern != knownPatterns.end()) {
+ EXPECT_EQ(testing::internal::RE::FullMatch(attr.value, knownPattern->second), true)
+ << "Attribute \"" << attr.key << "\" has invalid value \"" << attr.value << ".";
+ ;
+ } else {
+ // Failed to find exact attribute, check against
+ // possible patterns.
+ bool keyFound = false;
+ for (const auto& unknownPattern : unknownPatterns) {
+ if (testing::internal::RE::PartialMatch(attr.key, unknownPattern.key)) {
+ keyFound = true;
+ EXPECT_EQ(testing::internal::RE::FullMatch(attr.value, unknownPattern.value),
+ true)
+ << "Attribute \"" << attr.key << "\" has invalid value \"" << attr.value
+ << ".";
+ }
+ }
+ if (!keyFound) {
+ std::cout << "Warning, Unrecognized attribute \"" << attr.key << "\" with value \""
+ << attr.value << "\"." << std::endl;
+ }
+ }
+ }
+}
+
+// Make sure IOmx and IOmxStore have the same set of instances.
+TEST(StoreHidlTest, instanceMatchValidation) {
+ auto omxInstances = android::hardware::getAllHalInstanceNames(IOmx::descriptor);
+ auto omxStoreInstances = android::hardware::getAllHalInstanceNames(IOmxStore::descriptor);
+ ASSERT_EQ(omxInstances.size(), omxInstances.size());
+ for (const std::string& omxInstance : omxInstances) {
+ EXPECT_TRUE(std::find(omxStoreInstances.begin(), omxStoreInstances.end(), omxInstance) !=
+ omxStoreInstances.end());
+ }
+}
+
+// list service attributes and verify expected formats
+TEST_P(StoreHidlTest, ListServiceAttr) {
+ description("list service attributes");
+ android::hardware::media::omx::V1_0::Status status;
+ hidl_vec<IOmxStore::Attribute> attributes;
+ EXPECT_TRUE(omxStore
+ ->listServiceAttributes([&status, &attributes](
+ android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<IOmxStore::Attribute> const& _nl) {
+ status = _s;
+ attributes = _nl;
+ })
+ .isOk());
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ if (attributes.size() == 0) {
+ std::cout << "Warning, Attribute list empty" << std::endl;
+ } else {
+ /*
+ * knownPatterns is a map whose keys are the known "key" for a service
+ * attribute pair (see IOmxStore::Attribute), and whose values are the
+ * corresponding regular expressions that will have to match with the
+ * "value" of the attribute pair. If listServiceAttributes() returns an
+ * attribute that has a matching key but an unmatched value, the test
+ * will fail.
+ */
+ const std::map<const std::string, const testing::internal::RE> knownPatterns = {
+ {"max-video-encoder-input-buffers", "0|[1-9][0-9]*"},
+ {"supports-multiple-secure-codecs", "0|1"},
+ {"supports-secure-with-non-secure-codec", "0|1"},
+ };
+ /*
+ * unknownPatterns is a vector of pairs of regular expressions.
+ * For each attribute whose key is not known (i.e., does not match any
+ * of the keys in the "knownPatterns" variable defined above), that key will be
+ * tried for a match with the first element of each pair of the variable
+ * "unknownPatterns". If a match occurs, the value of that same attribute will be
+ * tried for a match with the second element of the pair. If this second
+ * match fails, the test will fail.
+ */
+ const std::vector<const struct AttributePattern> unknownPatterns = {
+ {"supports-[a-z0-9-]*", "0|1"}};
+
+ validateAttributes(knownPatterns, unknownPatterns, attributes);
+ }
+}
+
+// get node prefix
+TEST_P(StoreHidlTest, getNodePrefix) {
+ description("get node prefix");
+ hidl_string prefix;
+ omxStore->getNodePrefix(
+ [&prefix](hidl_string const& _nl) { prefix = _nl; });
+ if (prefix.empty()) std::cout << "Warning, Node Prefix empty" << std::endl;
+}
+
+// list roles and validate all RoleInfo objects
+TEST_P(StoreHidlTest, ListRoles) {
+ description("list roles");
+ hidl_vec<IOmxStore::RoleInfo> roleList;
+ omxStore->listRoles([&roleList](hidl_vec<IOmxStore::RoleInfo> const& _nl) {
+ roleList = _nl;
+ });
+ if (roleList.size() == 0) {
+ GTEST_SKIP() << "Warning, RoleInfo list empty";
+ return;
+ }
+
+ // Basic patterns for matching
+ const std::string toggle = "(0|1)";
+ const std::string string = "(.*)";
+ const std::string num = "(0|([1-9][0-9]*))";
+ const std::string size = "(" + num + "x" + num + ")";
+ const std::string ratio = "(" + num + ":" + num + ")";
+ const std::string range_num = "((" + num + "-" + num + ")|" + num + ")";
+ const std::string range_size = "((" + size + "-" + size + ")|" + size + ")";
+ const std::string range_ratio = "((" + ratio + "-" + ratio + ")|" + ratio + ")";
+ const std::string list_range_num = "(" + range_num + "(," + range_num + ")*)";
+
+ // Matching rules for node attributes with fixed keys
+ const std::map<const std::string, const testing::internal::RE> knownPatterns = {
+ {"alignment", size},
+ {"bitrate-range", range_num},
+ {"block-aspect-ratio-range", range_ratio},
+ {"block-count-range", range_num},
+ {"block-size", size},
+ {"blocks-per-second-range", range_num},
+ {"complexity-default", num},
+ {"complexity-range", range_num},
+ {"feature-adaptive-playback", toggle},
+ {"feature-bitrate-control", "(VBR|CBR|CQ)[,(VBR|CBR|CQ)]*"},
+ {"feature-can-swap-width-height", toggle},
+ {"feature-intra-refresh", toggle},
+ {"feature-partial-frame", toggle},
+ {"feature-secure-playback", toggle},
+ {"feature-tunneled-playback", toggle},
+ {"frame-rate-range", range_num},
+ {"max-channel-count", num},
+ {"max-concurrent-instances", num},
+ {"max-supported-instances", num},
+ {"pixel-aspect-ratio-range", range_ratio},
+ {"quality-default", num},
+ {"quality-range", range_num},
+ {"quality-scale", string},
+ {"sample-rate-ranges", list_range_num},
+ {"size-range", range_size},
+ };
+
+ // Strings for matching rules for node attributes with key patterns
+ const std::vector<const struct AttributePattern> unknownPatterns = {
+ {"measured-frame-rate-" + size + "-range", range_num},
+ {"feature-[a-zA-Z0-9_-]+", string},
+ };
+
+ // Matching rules for node names and owners
+ const testing::internal::RE nodeNamePattern = "[a-zA-Z0-9.-]+";
+ const testing::internal::RE nodeOwnerPattern = "[a-zA-Z0-9._-]+";
+
+ std::set<const std::string> roleKeys;
+ std::map<const std::string, std::set<const std::string>> nodeToRoles;
+ std::map<const std::string, std::set<const std::string>> ownerToNodes;
+ for (const IOmxStore::RoleInfo& role : roleList) {
+ // Make sure there are no duplicates
+ const auto [roleIter, inserted] = roleKeys.insert(role.role);
+ EXPECT_EQ(inserted, true) << "Role \"" << role.role << "\" has duplicates.";
+
+ // Make sure role name follows expected format based on type and
+ // isEncoder
+ const std::string role_name(
+ ::android::GetComponentRole(role.isEncoder, role.type.c_str()));
+ EXPECT_EQ(role_name, role.role) << "Role \"" << role.role << "\" does not match "
+ << (role.isEncoder ? "an encoder " : "a decoder ")
+ << "for mime type \"" << role.type << ".";
+
+ // Check the nodes for this role
+ std::set<const std::string> nodeKeys;
+ for (const IOmxStore::NodeInfo& node : role.nodes) {
+ // Make sure there are no duplicates
+ const auto [nodeIter, inserted] = nodeKeys.insert(node.name);
+ EXPECT_EQ(inserted, true) << "Node \"" << node.name << "\" has duplicates.";
+
+ // Check the format of node name
+ EXPECT_EQ(testing::internal::RE::FullMatch(node.name, nodeNamePattern), true)
+ << "Node name \"" << node.name << " is invalid.";
+ // Check the format of node owner
+ EXPECT_EQ(testing::internal::RE::FullMatch(node.owner, nodeOwnerPattern), true)
+ << "Node owner \"" << node.owner << " is invalid.";
+
+ validateAttributes(knownPatterns, unknownPatterns, node.attributes);
+
+ ownerToNodes[node.owner].insert(node.name);
+ nodeToRoles[node.name].insert(role.role);
+ }
+ }
+
+ // Verify the information with IOmx::listNodes().
+ // IOmxStore::listRoles() and IOmx::listNodes() should give consistent
+ // information about nodes and roles.
+ for (const auto& [owner, nodes] : ownerToNodes) {
+ // Obtain the IOmx instance for each "owner"
+ const sp<IOmx> omx = omxStore->getOmx(owner);
+ EXPECT_NE(nullptr, omx);
+
+ // Invoke IOmx::listNodes()
+ android::hardware::media::omx::V1_0::Status status;
+ hidl_vec<IOmx::ComponentInfo> nodeList;
+ EXPECT_TRUE(
+ omx->listNodes([&status, &nodeList](android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<IOmx::ComponentInfo> const& _nl) {
+ status = _s;
+ nodeList = _nl;
+ }).isOk());
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+
+ // Verify that roles for each node match with the information from
+ // IOmxStore::listRoles().
+ std::set<const std::string> nodeKeys;
+ for (IOmx::ComponentInfo node : nodeList) {
+ // Make sure there are no duplicates
+ const auto [nodeIter, inserted] = nodeKeys.insert(node.mName);
+ EXPECT_EQ(inserted, true)
+ << "IOmx::listNodes() lists duplicate nodes \"" << node.mName << "\".";
+
+ // Skip "hidden" nodes, i.e. those that are not advertised by
+ // IOmxStore::listRoles().
+ if (nodes.find(node.mName) == nodes.end()) {
+ std::cout << "Warning, IOmx::listNodes() lists unknown node \"" << node.mName
+ << "\" for IOmx instance \"" << owner << "\"." << std::endl;
+ continue;
+ }
+
+ // All the roles advertised by IOmxStore::listRoles() for this
+ // node must be included in roleKeys.
+ std::set<const std::string> difference;
+ std::set_difference(nodeToRoles[node.mName].begin(), nodeToRoles[node.mName].end(),
+ roleKeys.begin(), roleKeys.end(),
+ std::inserter(difference, difference.begin()));
+ EXPECT_EQ(difference.empty(), true) << "IOmx::listNodes() for IOmx "
+ "instance \""
+ << owner
+ << "\" does not report some "
+ "expected nodes: "
+ << android::base::Join(difference, ", ") << ".";
+ }
+ // Check that all nodes obtained from IOmxStore::listRoles() are
+ // supported by the their corresponding IOmx instances.
+ std::set<const std::string> difference;
+ std::set_difference(nodes.begin(), nodes.end(), nodeKeys.begin(), nodeKeys.end(),
+ std::inserter(difference, difference.begin()));
+ EXPECT_EQ(difference.empty(), true) << "IOmx::listNodes() for IOmx "
+ "instance \""
+ << owner
+ << "\" does not report some "
+ "expected nodes: "
+ << android::base::Join(difference, ", ") << ".";
+ }
+
+ if (!nodeToRoles.empty()) {
+ // Check that the prefix is a sensible string.
+ hidl_string prefix;
+ omxStore->getNodePrefix([&prefix](hidl_string const& _nl) { prefix = _nl; });
+ EXPECT_EQ(testing::internal::RE::PartialMatch(prefix, nodeNamePattern), true)
+ << "\"" << prefix << "\" is not a valid prefix for node names.";
+
+ // Check that all node names have the said prefix.
+ for (const auto& node : nodeToRoles) {
+ EXPECT_NE(node.first.rfind(prefix, 0), std::string::npos)
+ << "Node \"" << node.first << "\" does not start with prefix \"" << prefix
+ << "\".";
+ }
+ }
+}
+
+// list components and roles.
+TEST_P(StoreHidlTest, ListNodes) {
+ description("enumerate component and roles");
+ android::hardware::media::omx::V1_0::Status status;
+ hidl_vec<IOmx::ComponentInfo> nodeList;
+ bool isPass = true;
+ EXPECT_TRUE(
+ omx->listNodes([&status, &nodeList](
+ android::hardware::media::omx::V1_0::Status _s,
+ hidl_vec<IOmx::ComponentInfo> const& _nl) {
+ status = _s;
+ nodeList = _nl;
+ })
+ .isOk());
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ if (nodeList.size() == 0)
+ std::cout << "Warning, ComponentInfo list empty" << std::endl;
+ else {
+ // displayComponentInfo(nodeList);
+ for (size_t i = 0; i < nodeList.size(); i++) {
+ sp<CodecObserver> observer = nullptr;
+ sp<IOmxNode> omxNode = nullptr;
+ observer = new CodecObserver(nullptr);
+ ASSERT_NE(observer, nullptr);
+ EXPECT_TRUE(
+ omx->allocateNode(
+ nodeList[i].mName, observer,
+ [&](android::hardware::media::omx::V1_0::Status _s,
+ sp<IOmxNode> const& _nl) {
+ status = _s;
+ omxNode = _nl;
+ })
+ .isOk());
+ ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
+ if (omxNode == nullptr) {
+ isPass = false;
+ std::cerr << "[ !OK ] " << nodeList[i].mName.c_str()
+ << "\n";
+ } else {
+ EXPECT_TRUE((omxNode->freeNode()).isOk());
+ omxNode = nullptr;
+ // std::cout << "[ OK ] " << nodeList[i].mName.c_str() <<
+ // "\n";
+ }
+ }
+ }
+ EXPECT_TRUE(isPass);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ PerInstance, StoreHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IOmxStore::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
index 397bee6..5105d53 100644
--- a/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
+++ b/media/omx/1.0/vts/functional/video/VtsHalMediaOmxV1_0TargetVideoEncTest.cpp
@@ -289,11 +289,11 @@
};
// Mock IOmxBufferSource class. GraphicBufferSource.cpp in libstagefright/omx/
-// implements this class. Below is dummy class introduced to test if callback
+// implements this class. Below class is introduced to test if callback
// functions are actually being called or not
-struct DummyBufferSource : public IOmxBufferSource {
+struct MockBufferSource : public IOmxBufferSource {
public:
- DummyBufferSource(sp<IOmxNode> node) {
+ MockBufferSource(sp<IOmxNode> node) {
callback = 0;
executing = false;
omxNode = node;
@@ -311,7 +311,7 @@
android::Vector<BufferInfo> iBuffer, oBuffer;
};
-Return<void> DummyBufferSource::onOmxExecuting() {
+Return<void> MockBufferSource::onOmxExecuting() {
executing = true;
callback |= 0x1;
size_t index;
@@ -332,25 +332,25 @@
return Void();
};
-Return<void> DummyBufferSource::onOmxIdle() {
+Return<void> MockBufferSource::onOmxIdle() {
callback |= 0x2;
executing = false;
return Void();
};
-Return<void> DummyBufferSource::onOmxLoaded() {
+Return<void> MockBufferSource::onOmxLoaded() {
callback |= 0x4;
return Void();
};
-Return<void> DummyBufferSource::onInputBufferAdded(uint32_t buffer) {
+Return<void> MockBufferSource::onInputBufferAdded(uint32_t buffer) {
(void)buffer;
EXPECT_EQ(executing, false);
callback |= 0x8;
return Void();
};
-Return<void> DummyBufferSource::onInputBufferEmptied(
+Return<void> MockBufferSource::onInputBufferEmptied(
uint32_t buffer, const ::android::hardware::hidl_handle& fence) {
(void)fence;
callback |= 0x10;
@@ -1143,7 +1143,7 @@
setupRAWPort(omxNode, kPortIndexInput, nFrameWidth, nFrameHeight, 0,
xFramerate, eColorFormat);
- sp<DummyBufferSource> buffersource = new DummyBufferSource(omxNode);
+ sp<MockBufferSource> buffersource = new MockBufferSource(omxNode);
ASSERT_NE(buffersource, nullptr);
status = omxNode->setInputSurface(buffersource);
ASSERT_EQ(status, ::android::hardware::media::omx::V1_0::Status::OK);