Loading graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +327 −5 Original line number Diff line number Diff line Loading @@ -8,15 +8,18 @@ #include <binder/ProcessState.h> #include <composer-vts/include/GraphicsComposerCallback.h> #include <gtest/gtest.h> #include <algorithm> #include <regex> #include <string> #include <thread> #include <unordered_map> #include <unordered_set> #include <utility> #pragma push_macro("LOG_TAG") #undef LOG_TAG #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest" typedef int32_t Config; namespace aidl::android::hardware::graphics::composer3::vts { namespace { Loading Loading @@ -61,8 +64,8 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { // returns an invalid display id (one that has not been registered to a // display. Currently assuming that a device will never have close to // std::numeric_limit<uint64_t>::max() displays registered while running tests uint64_t GetInvalidDisplayId() { uint64_t id = std::numeric_limits<uint64_t>::max(); int64_t GetInvalidDisplayId() { int64_t id = std::numeric_limits<int64_t>::max(); while (id > 0) { if (std::none_of(mDisplays.begin(), mDisplays.end(), [&](const VtsDisplay& display) { return id == display.get(); })) { Loading @@ -87,7 +90,7 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { std::vector<VtsDisplay> vtsDisplays; vtsDisplays.reserve(displays.size()); for (int64_t display : displays) { Config activeConfig; int32_t activeConfig; EXPECT_TRUE(mComposerClient->getActiveConfig(display, &activeConfig).isOk()); int32_t displayWidth; EXPECT_TRUE(mComposerClient Loading @@ -106,6 +109,61 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { } } // returns an invalid config id which is std::numeric_limit<int32_t>::max() int32_t GetInvalidConfigId() { return IComposerClient::INVALID_CONFIGURATION; } ndk::ScopedAStatus setActiveConfigWithConstraints( VtsDisplay& display, int32_t config, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* timeline) { auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config, constraints, timeline); if (error.isOk()) { int32_t displayWidth; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH, &displayWidth) .isOk()); int32_t displayHeight; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT, &displayHeight) .isOk()); display.setDimensions(displayWidth, displayHeight); } return error; } void Test_setContentTypeForDisplay(const int64_t& display, const std::vector<ContentType>& capabilities, const ContentType& contentType, const char* contentTypeStr) { const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(), contentType) != capabilities.end(); if (!contentTypeSupport) { EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, mComposerClient->setContentType(display, contentType) .getServiceSpecificError()); GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display " << std::to_string(display) << ", skipping test"; return; } EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk()); EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk()); } void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) { for (const auto& display : mDisplays) { std::vector<ContentType> supportedContentTypes; const auto error = mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); EXPECT_TRUE(error.isOk()); Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType, contentTypeStr); } } std::shared_ptr<IComposer> mComposer; std::shared_ptr<IComposerClient> mComposerClient; int64_t mInvalidDisplayId; Loading @@ -129,6 +187,270 @@ TEST_P(GraphicsComposerAidlTest, getDisplayCapabilities) { } } TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) { DisplayConnectionType type; EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk()); for (const auto& display : mDisplays) { EXPECT_TRUE(mComposerClient->getDisplayConnectionType(display.get(), &type).isOk()); } } TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) { for (const auto& display : mDisplays) { std::vector<int32_t> configs; mComposerClient->getDisplayConfigs(display.get(), &configs); for (const auto& config : configs) { const std::array<DisplayAttribute, 4> requiredAttributes = {{ DisplayAttribute::WIDTH, DisplayAttribute::HEIGHT, DisplayAttribute::VSYNC_PERIOD, DisplayAttribute::CONFIG_GROUP, }}; int32_t value; for (const auto& attribute : requiredAttributes) { EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, attribute, &value) .isOk()); EXPECT_NE(-1, value); } const std::array<DisplayAttribute, 2> optionalAttributes = {{ DisplayAttribute::DPI_X, DisplayAttribute::DPI_Y, }}; for (const auto& attribute : optionalAttributes) { const auto error = mComposerClient->getDisplayAttribute(display.get(), config, attribute, &value); if (error.isOk()) { EXPECT_EQ(EX_NONE, error.getServiceSpecificError()); } else { EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError()); } } } } } TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) { for (const auto& display : mDisplays) { std::vector<int32_t> configs; mComposerClient->getDisplayConfigs(display.get(), &configs); EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) { return config == IComposerClient::INVALID_CONFIGURATION; })); } } TEST_P(GraphicsComposerAidlTest, getDisplayAttributeConfigsInAGroupDifferOnlyByVsyncPeriod) { struct Resolution { int32_t width; int32_t height; }; struct Dpi { int32_t x; int32_t y; }; for (const auto& display : mDisplays) { std::vector<int32_t> configs; EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk()); std::unordered_map<int32_t, Resolution> configGroupToResolutionMap; std::unordered_map<int32_t, Dpi> configGroupToDpiMap; for (const auto& config : configs) { int32_t configGroup = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::CONFIG_GROUP, &configGroup) .isOk()); int32_t width = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH, &width) .isOk()); int32_t height = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT, &height) .isOk()); if (configGroupToResolutionMap.find(configGroup) == configGroupToResolutionMap.end()) { configGroupToResolutionMap[configGroup] = {width, height}; } EXPECT_EQ(configGroupToResolutionMap[configGroup].width, width); EXPECT_EQ(configGroupToResolutionMap[configGroup].height, height); int32_t dpiX = -1; mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_X, &dpiX); int32_t dpiY = -1; mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_Y, &dpiY); if (dpiX == -1 && dpiY == -1) { continue; } if (configGroupToDpiMap.find(configGroup) == configGroupToDpiMap.end()) { configGroupToDpiMap[configGroup] = {dpiX, dpiY}; } EXPECT_EQ(configGroupToDpiMap[configGroup].x, dpiX); EXPECT_EQ(configGroupToDpiMap[configGroup].y, dpiY); } } } TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod_BadDisplay) { int32_t vsyncPeriodNanos; const auto error = mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadDisplay) { VsyncPeriodChangeTimeline timeline; VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); int32_t config = 0; auto const error = mComposerClient->setActiveConfigWithConstraints(mInvalidDisplayId, config, constraints, &timeline); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) { VsyncPeriodChangeTimeline timeline; VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); for (VtsDisplay& display : mDisplays) { int32_t invalidConfigId = GetInvalidConfigId(); const auto error = setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError()); } } TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) { EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true) .getServiceSpecificError()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false) .getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyMode) { for (const auto& display : mDisplays) { std::vector<DisplayCapability> capabilities; const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities); EXPECT_TRUE(error.isOk()); const bool allmSupport = std::find(capabilities.begin(), capabilities.end(), DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end(); if (!allmSupport) { const auto errorIsOn = mComposerClient->setAutoLowLatencyMode(display.get(), true); EXPECT_FALSE(errorIsOn.isOk()); EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOn.getServiceSpecificError()); const auto errorIsOff = mComposerClient->setAutoLowLatencyMode(display.get(), false); EXPECT_FALSE(errorIsOff.isOk()); EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOff.getServiceSpecificError()); GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display " << std::to_string(display.get()) << ", skipping test"; return; } EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), true).isOk()); EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), false).isOk()); } } TEST_P(GraphicsComposerAidlTest, getSupportedContentTypesBadDisplay) { std::vector<ContentType> supportedContentTypes; const auto error = mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, getSupportedContentTypes) { std::vector<ContentType> supportedContentTypes; for (const auto& display : mDisplays) { supportedContentTypes.clear(); const auto error = mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); ASSERT_TRUE(error.isOk()); const bool noneSupported = std::find(supportedContentTypes.begin(), supportedContentTypes.end(), ContentType::NONE) != supportedContentTypes.end(); EXPECT_FALSE(noneSupported); } } TEST_P(GraphicsComposerAidlTest, setContentTypeNoneAlwaysAccepted) { for (const auto& display : mDisplays) { const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE); EXPECT_TRUE(error.isOk()); } } TEST_P(GraphicsComposerAidlTest, setContentTypeBadDisplay) { constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO, ContentType::CINEMA, ContentType::GAME}; for (const auto& type : types) { auto const error = mComposerClient->setContentType(mInvalidDisplayId, type); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } } TEST_P(GraphicsComposerAidlTest, setGraphicsContentType) { Test_setContentType(ContentType::GRAPHICS, "GRAPHICS"); } TEST_P(GraphicsComposerAidlTest, setPhotoContentType) { Test_setContentType(ContentType::PHOTO, "PHOTO"); } TEST_P(GraphicsComposerAidlTest, setCinemaContentType) { Test_setContentType(ContentType::CINEMA, "CINEMA"); } TEST_P(GraphicsComposerAidlTest, setGameContentType) { Test_setContentType(ContentType::GAME, "GAME"); } TEST_P(GraphicsComposerAidlTest, getLayerGenericMetadataKeys) { std::vector<LayerGenericMetadataKey> keys; EXPECT_TRUE(mComposerClient->getLayerGenericMetadataKeys(&keys).isOk()); std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$"); std::unordered_set<std::string> uniqueNames; for (const auto& key : keys) { std::string name(key.name.c_str()); // Keys must not start with 'android' or 'com.android' EXPECT_FALSE(name.find("android") == 0); EXPECT_FALSE(name.find("com.android") == 0); // Keys must be in reverse domain name format EXPECT_TRUE(std::regex_match(name, reverseDomainName)); // Keys must be unique within this list const auto& [iter, inserted] = uniqueNames.insert(name); EXPECT_TRUE(inserted); } } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerAidlTest, Loading Loading
graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +327 −5 Original line number Diff line number Diff line Loading @@ -8,15 +8,18 @@ #include <binder/ProcessState.h> #include <composer-vts/include/GraphicsComposerCallback.h> #include <gtest/gtest.h> #include <algorithm> #include <regex> #include <string> #include <thread> #include <unordered_map> #include <unordered_set> #include <utility> #pragma push_macro("LOG_TAG") #undef LOG_TAG #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest" typedef int32_t Config; namespace aidl::android::hardware::graphics::composer3::vts { namespace { Loading Loading @@ -61,8 +64,8 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { // returns an invalid display id (one that has not been registered to a // display. Currently assuming that a device will never have close to // std::numeric_limit<uint64_t>::max() displays registered while running tests uint64_t GetInvalidDisplayId() { uint64_t id = std::numeric_limits<uint64_t>::max(); int64_t GetInvalidDisplayId() { int64_t id = std::numeric_limits<int64_t>::max(); while (id > 0) { if (std::none_of(mDisplays.begin(), mDisplays.end(), [&](const VtsDisplay& display) { return id == display.get(); })) { Loading @@ -87,7 +90,7 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { std::vector<VtsDisplay> vtsDisplays; vtsDisplays.reserve(displays.size()); for (int64_t display : displays) { Config activeConfig; int32_t activeConfig; EXPECT_TRUE(mComposerClient->getActiveConfig(display, &activeConfig).isOk()); int32_t displayWidth; EXPECT_TRUE(mComposerClient Loading @@ -106,6 +109,61 @@ class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> { } } // returns an invalid config id which is std::numeric_limit<int32_t>::max() int32_t GetInvalidConfigId() { return IComposerClient::INVALID_CONFIGURATION; } ndk::ScopedAStatus setActiveConfigWithConstraints( VtsDisplay& display, int32_t config, const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* timeline) { auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config, constraints, timeline); if (error.isOk()) { int32_t displayWidth; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH, &displayWidth) .isOk()); int32_t displayHeight; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT, &displayHeight) .isOk()); display.setDimensions(displayWidth, displayHeight); } return error; } void Test_setContentTypeForDisplay(const int64_t& display, const std::vector<ContentType>& capabilities, const ContentType& contentType, const char* contentTypeStr) { const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(), contentType) != capabilities.end(); if (!contentTypeSupport) { EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, mComposerClient->setContentType(display, contentType) .getServiceSpecificError()); GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display " << std::to_string(display) << ", skipping test"; return; } EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk()); EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk()); } void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) { for (const auto& display : mDisplays) { std::vector<ContentType> supportedContentTypes; const auto error = mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); EXPECT_TRUE(error.isOk()); Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType, contentTypeStr); } } std::shared_ptr<IComposer> mComposer; std::shared_ptr<IComposerClient> mComposerClient; int64_t mInvalidDisplayId; Loading @@ -129,6 +187,270 @@ TEST_P(GraphicsComposerAidlTest, getDisplayCapabilities) { } } TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) { DisplayConnectionType type; EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk()); for (const auto& display : mDisplays) { EXPECT_TRUE(mComposerClient->getDisplayConnectionType(display.get(), &type).isOk()); } } TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) { for (const auto& display : mDisplays) { std::vector<int32_t> configs; mComposerClient->getDisplayConfigs(display.get(), &configs); for (const auto& config : configs) { const std::array<DisplayAttribute, 4> requiredAttributes = {{ DisplayAttribute::WIDTH, DisplayAttribute::HEIGHT, DisplayAttribute::VSYNC_PERIOD, DisplayAttribute::CONFIG_GROUP, }}; int32_t value; for (const auto& attribute : requiredAttributes) { EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, attribute, &value) .isOk()); EXPECT_NE(-1, value); } const std::array<DisplayAttribute, 2> optionalAttributes = {{ DisplayAttribute::DPI_X, DisplayAttribute::DPI_Y, }}; for (const auto& attribute : optionalAttributes) { const auto error = mComposerClient->getDisplayAttribute(display.get(), config, attribute, &value); if (error.isOk()) { EXPECT_EQ(EX_NONE, error.getServiceSpecificError()); } else { EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError()); } } } } } TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) { for (const auto& display : mDisplays) { std::vector<int32_t> configs; mComposerClient->getDisplayConfigs(display.get(), &configs); EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) { return config == IComposerClient::INVALID_CONFIGURATION; })); } } TEST_P(GraphicsComposerAidlTest, getDisplayAttributeConfigsInAGroupDifferOnlyByVsyncPeriod) { struct Resolution { int32_t width; int32_t height; }; struct Dpi { int32_t x; int32_t y; }; for (const auto& display : mDisplays) { std::vector<int32_t> configs; EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk()); std::unordered_map<int32_t, Resolution> configGroupToResolutionMap; std::unordered_map<int32_t, Dpi> configGroupToDpiMap; for (const auto& config : configs) { int32_t configGroup = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::CONFIG_GROUP, &configGroup) .isOk()); int32_t width = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::WIDTH, &width) .isOk()); int32_t height = -1; EXPECT_TRUE(mComposerClient ->getDisplayAttribute(display.get(), config, DisplayAttribute::HEIGHT, &height) .isOk()); if (configGroupToResolutionMap.find(configGroup) == configGroupToResolutionMap.end()) { configGroupToResolutionMap[configGroup] = {width, height}; } EXPECT_EQ(configGroupToResolutionMap[configGroup].width, width); EXPECT_EQ(configGroupToResolutionMap[configGroup].height, height); int32_t dpiX = -1; mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_X, &dpiX); int32_t dpiY = -1; mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_Y, &dpiY); if (dpiX == -1 && dpiY == -1) { continue; } if (configGroupToDpiMap.find(configGroup) == configGroupToDpiMap.end()) { configGroupToDpiMap[configGroup] = {dpiX, dpiY}; } EXPECT_EQ(configGroupToDpiMap[configGroup].x, dpiX); EXPECT_EQ(configGroupToDpiMap[configGroup].y, dpiY); } } } TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod_BadDisplay) { int32_t vsyncPeriodNanos; const auto error = mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadDisplay) { VsyncPeriodChangeTimeline timeline; VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); int32_t config = 0; auto const error = mComposerClient->setActiveConfigWithConstraints(mInvalidDisplayId, config, constraints, &timeline); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) { VsyncPeriodChangeTimeline timeline; VsyncPeriodChangeConstraints constraints; constraints.seamlessRequired = false; constraints.desiredTimeNanos = systemTime(); for (VtsDisplay& display : mDisplays) { int32_t invalidConfigId = GetInvalidConfigId(); const auto error = setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError()); } } TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) { EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true) .getServiceSpecificError()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false) .getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyMode) { for (const auto& display : mDisplays) { std::vector<DisplayCapability> capabilities; const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities); EXPECT_TRUE(error.isOk()); const bool allmSupport = std::find(capabilities.begin(), capabilities.end(), DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end(); if (!allmSupport) { const auto errorIsOn = mComposerClient->setAutoLowLatencyMode(display.get(), true); EXPECT_FALSE(errorIsOn.isOk()); EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOn.getServiceSpecificError()); const auto errorIsOff = mComposerClient->setAutoLowLatencyMode(display.get(), false); EXPECT_FALSE(errorIsOff.isOk()); EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOff.getServiceSpecificError()); GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display " << std::to_string(display.get()) << ", skipping test"; return; } EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), true).isOk()); EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), false).isOk()); } } TEST_P(GraphicsComposerAidlTest, getSupportedContentTypesBadDisplay) { std::vector<ContentType> supportedContentTypes; const auto error = mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } TEST_P(GraphicsComposerAidlTest, getSupportedContentTypes) { std::vector<ContentType> supportedContentTypes; for (const auto& display : mDisplays) { supportedContentTypes.clear(); const auto error = mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes); ASSERT_TRUE(error.isOk()); const bool noneSupported = std::find(supportedContentTypes.begin(), supportedContentTypes.end(), ContentType::NONE) != supportedContentTypes.end(); EXPECT_FALSE(noneSupported); } } TEST_P(GraphicsComposerAidlTest, setContentTypeNoneAlwaysAccepted) { for (const auto& display : mDisplays) { const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE); EXPECT_TRUE(error.isOk()); } } TEST_P(GraphicsComposerAidlTest, setContentTypeBadDisplay) { constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO, ContentType::CINEMA, ContentType::GAME}; for (const auto& type : types) { auto const error = mComposerClient->setContentType(mInvalidDisplayId, type); EXPECT_FALSE(error.isOk()); EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError()); } } TEST_P(GraphicsComposerAidlTest, setGraphicsContentType) { Test_setContentType(ContentType::GRAPHICS, "GRAPHICS"); } TEST_P(GraphicsComposerAidlTest, setPhotoContentType) { Test_setContentType(ContentType::PHOTO, "PHOTO"); } TEST_P(GraphicsComposerAidlTest, setCinemaContentType) { Test_setContentType(ContentType::CINEMA, "CINEMA"); } TEST_P(GraphicsComposerAidlTest, setGameContentType) { Test_setContentType(ContentType::GAME, "GAME"); } TEST_P(GraphicsComposerAidlTest, getLayerGenericMetadataKeys) { std::vector<LayerGenericMetadataKey> keys; EXPECT_TRUE(mComposerClient->getLayerGenericMetadataKeys(&keys).isOk()); std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$"); std::unordered_set<std::string> uniqueNames; for (const auto& key : keys) { std::string name(key.name.c_str()); // Keys must not start with 'android' or 'com.android' EXPECT_FALSE(name.find("android") == 0); EXPECT_FALSE(name.find("com.android") == 0); // Keys must be in reverse domain name format EXPECT_TRUE(std::regex_match(name, reverseDomainName)); // Keys must be unique within this list const auto& [iter, inserted] = uniqueNames.insert(name); EXPECT_TRUE(inserted); } } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, GraphicsComposerAidlTest, Loading