| /* |
| * Copyright (C) 2016 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 "graphics_composer_hidl_hal_test" |
| |
| #include <android-base/logging.h> |
| #include <android-base/properties.h> |
| #include <composer-vts/2.1/ComposerVts.h> |
| #include <composer-vts/2.1/GraphicsComposerCallback.h> |
| #include <composer-vts/2.1/TestCommandReader.h> |
| #include <gtest/gtest.h> |
| #include <hardware/hwcomposer2.h> |
| #include <hidl/GtestPrinter.h> |
| #include <hidl/ServiceManagement.h> |
| #include <ui/GraphicBuffer.h> |
| |
| #include <unistd.h> |
| |
| #include <algorithm> |
| #include <array> |
| #include <memory> |
| #include <mutex> |
| #include <unordered_set> |
| #include <vector> |
| |
| namespace android { |
| namespace hardware { |
| namespace graphics { |
| namespace composer { |
| namespace V2_1 { |
| namespace vts { |
| namespace { |
| |
| using android::hardware::graphics::common::V1_0::BufferUsage; |
| using android::hardware::graphics::common::V1_0::ColorMode; |
| using android::hardware::graphics::common::V1_0::ColorTransform; |
| using android::hardware::graphics::common::V1_0::Dataspace; |
| using android::hardware::graphics::common::V1_0::PixelFormat; |
| using android::hardware::graphics::common::V1_0::Transform; |
| |
| class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> { |
| protected: |
| void SetUp() override { |
| ASSERT_NO_FATAL_FAILURE( |
| mComposer = std::make_unique<Composer>(IComposer::getService(GetParam()))); |
| ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient()); |
| |
| mComposerCallback = new GraphicsComposerCallback; |
| mComposerClient->registerCallback(mComposerCallback); |
| |
| // assume the first display is primary and is never removed |
| mPrimaryDisplay = waitForFirstDisplay(); |
| |
| // explicitly disable vsync |
| mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); |
| mComposerCallback->setVsyncAllowed(false); |
| |
| mInvalidDisplayId = GetInvalidDisplayId(); |
| |
| // Although 0 could be an invalid display, a return value of 0 |
| // from GetInvalidDisplayId means all other ids are in use, a condition which |
| // we are assuming a device will never have |
| ASSERT_NE(0, mInvalidDisplayId); |
| } |
| |
| void TearDown() override { |
| if (mComposerCallback != nullptr) { |
| EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount()); |
| EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount()); |
| EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount()); |
| } |
| } |
| |
| // 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 |
| Display GetInvalidDisplayId() { |
| std::vector<Display> validDisplays = mComposerCallback->getDisplays(); |
| |
| uint64_t id = std::numeric_limits<uint64_t>::max(); |
| while (id > 0) { |
| if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) { |
| return id; |
| } |
| id--; |
| } |
| |
| return 0; |
| } |
| |
| // use the slot count usually set by SF |
| static constexpr uint32_t kBufferSlotCount = 64; |
| |
| std::unique_ptr<Composer> mComposer; |
| std::unique_ptr<ComposerClient> mComposerClient; |
| sp<GraphicsComposerCallback> mComposerCallback; |
| // the first display and is assumed never to be removed |
| Display mPrimaryDisplay; |
| Display mInvalidDisplayId; |
| |
| private: |
| Display waitForFirstDisplay() { |
| while (true) { |
| std::vector<Display> displays = mComposerCallback->getDisplays(); |
| if (displays.empty()) { |
| usleep(5 * 1000); |
| continue; |
| } |
| |
| return displays[0]; |
| } |
| } |
| }; |
| |
| /** |
| * Test IComposer::getCapabilities. |
| * |
| * Test that IComposer::getCapabilities returns no invalid capabilities. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetCapabilities) { |
| auto capabilities = mComposer->getCapabilities(); |
| ASSERT_EQ(capabilities.end(), |
| std::find(capabilities.begin(), capabilities.end(), IComposer::Capability::INVALID)); |
| } |
| |
| /** |
| * Test IComposer::dumpDebugInfo. |
| */ |
| TEST_P(GraphicsComposerHidlTest, DumpDebugInfo) { |
| mComposer->dumpDebugInfo(); |
| } |
| |
| /** |
| * Test IComposer::createClient. |
| * |
| * Test that IComposerClient is a singleton. |
| */ |
| TEST_P(GraphicsComposerHidlTest, CreateClientSingleton) { |
| mComposer->getRaw()->createClient( |
| [&](const auto& tmpError, const auto&) { EXPECT_EQ(Error::NO_RESOURCES, tmpError); }); |
| } |
| |
| /** |
| * Test IComposerClient::createVirtualDisplay and |
| * IComposerClient::destroyVirtualDisplay. |
| * |
| * Test that virtual displays can be created and has the correct display type. |
| */ |
| TEST_P(GraphicsComposerHidlTest, CreateVirtualDisplay) { |
| if (mComposerClient->getMaxVirtualDisplayCount() == 0) { |
| GTEST_SUCCEED() << "no virtual display support"; |
| return; |
| } |
| |
| Display display; |
| PixelFormat format; |
| ASSERT_NO_FATAL_FAILURE( |
| display = mComposerClient->createVirtualDisplay(64, 64, PixelFormat::IMPLEMENTATION_DEFINED, |
| kBufferSlotCount, &format)); |
| |
| // test display type |
| IComposerClient::DisplayType type = mComposerClient->getDisplayType(display); |
| EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type); |
| |
| mComposerClient->destroyVirtualDisplay(display); |
| } |
| |
| /** |
| * Test IComposerClient::destroyVirtualDisplay |
| * |
| * Test that passing a bad display handle to destroyVirtualDisplay |
| * returns a BAD_DISPLAY error |
| */ |
| TEST_P(GraphicsComposerHidlTest, DestroyVirtualDisplayBadDisplay) { |
| if (mComposerClient->getMaxVirtualDisplayCount() == 0) { |
| GTEST_SUCCEED() << "no virtual display support"; |
| return; |
| } |
| |
| Error error = mComposerClient->getRaw()->destroyVirtualDisplay(mInvalidDisplayId); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::createLayer and IComposerClient::destroyLayer. |
| * |
| * Test that layers can be created and destroyed. |
| */ |
| TEST_P(GraphicsComposerHidlTest, CreateLayer) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mComposerClient->destroyLayer(mPrimaryDisplay, layer); |
| } |
| |
| /** |
| * Test IComposerClient::createLayer |
| * |
| * Test that passing in an invalid display handle to createLayer returns |
| * BAD_DISPLAY. |
| */ |
| TEST_P(GraphicsComposerHidlTest, CreateLayerBadDisplay) { |
| Error error; |
| mComposerClient->getRaw()->createLayer( |
| mInvalidDisplayId, kBufferSlotCount, |
| [&](const auto& tmpOutError, const auto&) { error = tmpOutError; }); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::destroyLayer |
| * |
| * Test that passing in an invalid display handle to destroyLayer returns |
| * BAD_DISPLAY |
| */ |
| TEST_P(GraphicsComposerHidlTest, DestroyLayerBadDisplay) { |
| Error error; |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| error = mComposerClient->getRaw()->destroyLayer(mInvalidDisplayId, layer); |
| |
| EXPECT_EQ(Error::BAD_DISPLAY, error); |
| |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(mPrimaryDisplay, layer)); |
| } |
| |
| /** |
| * Test IComposerClient::destroyLayer |
| * |
| * Test that passing in an invalid layer handle to destroyLayer returns |
| * BAD_LAYER |
| */ |
| TEST_P(GraphicsComposerHidlTest, DestroyLayerBadLayerError) { |
| // We haven't created any layers yet, so any id should be invalid |
| Error error = mComposerClient->getRaw()->destroyLayer(mPrimaryDisplay, 1); |
| |
| EXPECT_EQ(Error::BAD_LAYER, error); |
| } |
| |
| /** |
| * Test IComposerClient::getActiveConfig |
| * |
| * Test that passing in a bad display handle to getActiveConfig generates a |
| * BAD_DISPLAY error |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetActiveConfigBadDisplay) { |
| Error error; |
| mComposerClient->getRaw()->getActiveConfig( |
| mInvalidDisplayId, [&](const auto& tmpOutError, const auto&) { error = tmpOutError; }); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::getDisplayConfigs |
| * |
| * Test IComposerClient::getDisplayConfigs returns no error |
| * when passed in a valid display |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDisplayConfig) { |
| std::vector<Config> configs; |
| ASSERT_NO_FATAL_FAILURE(configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay)); |
| } |
| |
| /** |
| * Test IComposerClient::getDisplayConfigs |
| * |
| * Test IComposerClient::getDisplayConfigs returns BAD_DISPLAY |
| * when passed in an invalid display handle |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDisplayConfigBadDisplay) { |
| Error error; |
| mComposerClient->getRaw()->getDisplayConfigs( |
| mInvalidDisplayId, [&](const auto& tmpOutError, const auto&) { error = tmpOutError; }); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::getDisplayName. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDisplayName) { |
| mComposerClient->getDisplayName(mPrimaryDisplay); |
| } |
| |
| /** |
| * Test IComposerClient::getDisplayType. |
| * |
| * Test that IComposerClient::getDisplayType returns the correct display type |
| * for the primary display. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDisplayType) { |
| ASSERT_EQ(IComposerClient::DisplayType::PHYSICAL, |
| mComposerClient->getDisplayType(mPrimaryDisplay)); |
| } |
| |
| /** |
| * Test IComposerClient::getClientTargetSupport. |
| * |
| * Test that IComposerClient::getClientTargetSupport returns true for the |
| * required client targets. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport) { |
| std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); |
| for (auto config : configs) { |
| int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, |
| IComposerClient::Attribute::WIDTH); |
| int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, |
| IComposerClient::Attribute::HEIGHT); |
| ASSERT_LT(0, width); |
| ASSERT_LT(0, height); |
| |
| mComposerClient->setActiveConfig(mPrimaryDisplay, config); |
| |
| ASSERT_TRUE(mComposerClient->getClientTargetSupport( |
| mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN)); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::getClientTargetSupport |
| * |
| * Test that IComposerClient::getClientTargetSupport returns BAD_DISPLAY when |
| * passed an invalid display handle |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetClientTargetSupportBadDisplay) { |
| std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); |
| for (auto config : configs) { |
| int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, |
| IComposerClient::Attribute::WIDTH); |
| int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, |
| IComposerClient::Attribute::HEIGHT); |
| ASSERT_LT(0, width); |
| ASSERT_LT(0, height); |
| |
| mComposerClient->setActiveConfig(mPrimaryDisplay, config); |
| |
| Error error = mComposerClient->getRaw()->getClientTargetSupport( |
| mInvalidDisplayId, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN); |
| EXPECT_EQ(Error::BAD_DISPLAY, error); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::getDisplayAttribute. |
| * |
| * Test that IComposerClient::getDisplayAttribute succeeds for the required |
| * formats, and succeeds or fails correctly for optional attributes. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute) { |
| std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); |
| for (auto config : configs) { |
| const std::array<IComposerClient::Attribute, 3> requiredAttributes = {{ |
| IComposerClient::Attribute::WIDTH, IComposerClient::Attribute::HEIGHT, |
| IComposerClient::Attribute::VSYNC_PERIOD, |
| }}; |
| for (auto attribute : requiredAttributes) { |
| mComposerClient->getDisplayAttribute(mPrimaryDisplay, config, attribute); |
| } |
| |
| const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{ |
| IComposerClient::Attribute::DPI_X, IComposerClient::Attribute::DPI_Y, |
| }}; |
| for (auto attribute : optionalAttributes) { |
| mComposerClient->getRaw()->getDisplayAttribute( |
| mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) { |
| EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED); |
| }); |
| } |
| } |
| } |
| |
| /** |
| * Test IComposerClient::getHdrCapabilities. |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetHdrCapabilities) { |
| float maxLuminance; |
| float maxAverageLuminance; |
| float minLuminance; |
| mComposerClient->getHdrCapabilities(mPrimaryDisplay, &maxLuminance, &maxAverageLuminance, |
| &minLuminance); |
| } |
| |
| /** |
| * Test IComposerClient::setClientTargetSlotCount. |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetClientTargetSlotCount) { |
| mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount); |
| } |
| |
| /** |
| * Test IComposerClient::setActiveConfig. |
| * |
| * Test that IComposerClient::setActiveConfig succeeds for all display |
| * configs. |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetActiveConfig) { |
| std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); |
| for (auto config : configs) { |
| mComposerClient->setActiveConfig(mPrimaryDisplay, config); |
| ASSERT_EQ(config, mComposerClient->getActiveConfig(mPrimaryDisplay)); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setActiveConfig |
| * |
| * Test that config set during IComposerClient::setActiveConfig is maintained |
| * during a display on/off power cycle |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetActiveConfigPowerCycle) { |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::OFF)); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON)); |
| |
| std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay); |
| for (auto config : configs) { |
| mComposerClient->setActiveConfig(mPrimaryDisplay, config); |
| ASSERT_EQ(config, mComposerClient->getActiveConfig(mPrimaryDisplay)); |
| |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::OFF)); |
| ASSERT_NO_FATAL_FAILURE( |
| mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON)); |
| ASSERT_EQ(config, mComposerClient->getActiveConfig(mPrimaryDisplay)); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::getColorMode |
| * |
| * Test that IComposerClient::getColorMode always returns ColorMode::NATIVE |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetColorModes) { |
| std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay); |
| auto nativeModeLocation = std::find(modes.begin(), modes.end(), ColorMode::NATIVE); |
| |
| ASSERT_NE(modes.end(), nativeModeLocation); |
| } |
| |
| /** |
| * Test IComposerClient::setColorMode. |
| * |
| * Test that IComposerClient::setColorMode succeeds for all color modes. |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetColorMode) { |
| std::unordered_set<ColorMode> validModes; |
| for (auto mode : hidl_enum_range<ColorMode>()) { |
| validModes.insert(mode); |
| } |
| |
| std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay); |
| for (auto mode : modes) { |
| if (validModes.count(mode)) { |
| mComposerClient->setColorMode(mPrimaryDisplay, mode); |
| } |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setColorMode |
| * |
| * Test that IComposerClient::setColorMode returns BAD_DISPLAY for |
| * an invalid display handle |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetColorModeBadDisplay) { |
| std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay); |
| for (auto mode : modes) { |
| Error error = mComposerClient->getRaw()->setColorMode(mInvalidDisplayId, mode); |
| EXPECT_EQ(Error::BAD_DISPLAY, error); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setColorMode |
| * |
| * Test that IComposerClient::setColorMode returns BAD_PARAMETER when passed in |
| * an invalid color mode |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetColorModeBadParameter) { |
| Error error = |
| mComposerClient->getRaw()->setColorMode(mPrimaryDisplay, static_cast<ColorMode>(-1)); |
| ASSERT_EQ(Error::BAD_PARAMETER, error); |
| } |
| |
| /** |
| * Test IComposerClient::getDozeSupport |
| * |
| * Test that IComposerClient::getDozeSupport returns |
| * BAD_DISPLAY when passed an invalid display handle |
| */ |
| TEST_P(GraphicsComposerHidlTest, GetDozeSupportBadDisplay) { |
| Error error; |
| mComposerClient->getRaw()->getDozeSupport( |
| mInvalidDisplayId, [&](const auto& tmpOutError, const auto&) { error = tmpOutError; }); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::setPowerMode. |
| * |
| * Test that IComposerClient::setPowerMode succeeds for all power modes. |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetPowerMode) { |
| std::vector<IComposerClient::PowerMode> modes; |
| modes.push_back(IComposerClient::PowerMode::OFF); |
| |
| if (mComposerClient->getDozeSupport(mPrimaryDisplay)) { |
| modes.push_back(IComposerClient::PowerMode::DOZE); |
| modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND); |
| } |
| |
| // push ON last |
| modes.push_back(IComposerClient::PowerMode::ON); |
| |
| for (auto mode : modes) { |
| mComposerClient->setPowerMode(mPrimaryDisplay, mode); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setPowerMode |
| * |
| * Test IComposerClient::setPowerMode succeeds with different |
| * orderings of power modes |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetPowerModeVariations) { |
| std::vector<IComposerClient::PowerMode> modes; |
| modes.push_back(IComposerClient::PowerMode::OFF); |
| modes.push_back(IComposerClient::PowerMode::ON); |
| modes.push_back(IComposerClient::PowerMode::OFF); |
| for (auto mode : modes) { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, mode)); |
| } |
| |
| modes.clear(); |
| |
| modes.push_back(IComposerClient::PowerMode::OFF); |
| modes.push_back(IComposerClient::PowerMode::OFF); |
| for (auto mode : modes) { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, mode)); |
| } |
| |
| modes.clear(); |
| if (mComposerClient->getDozeSupport(mPrimaryDisplay)) { |
| modes.push_back(IComposerClient::PowerMode::DOZE); |
| modes.push_back(IComposerClient::PowerMode::DOZE); |
| |
| for (auto mode : modes) { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, mode)); |
| } |
| |
| modes.clear(); |
| |
| modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND); |
| modes.push_back(IComposerClient::PowerMode::DOZE_SUSPEND); |
| |
| for (auto mode : modes) { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, mode)); |
| } |
| } |
| |
| modes.clear(); |
| |
| modes.push_back(IComposerClient::PowerMode::ON); |
| modes.push_back(IComposerClient::PowerMode::ON); |
| for (auto mode : modes) { |
| ASSERT_NO_FATAL_FAILURE(mComposerClient->setPowerMode(mPrimaryDisplay, mode)); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setPowerMode |
| * |
| * Test IComposerClient::setPowerMode returns BAD_DISPLAY when passed an invalid |
| * display handle |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetPowerModeBadDisplay) { |
| Error error = |
| mComposerClient->getRaw()->setPowerMode(mInvalidDisplayId, IComposerClient::PowerMode::ON); |
| ASSERT_EQ(Error::BAD_DISPLAY, error); |
| } |
| |
| /** |
| * Test IComposerClient::setPowerMode |
| * |
| * Test that IComposerClient::setPowerMode returns UNSUPPORTED when passed DOZE |
| * or DOZE_SUSPEND on devices that do not support DOZE/DOZE_SUSPEND |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetPowerModeUnsupported) { |
| if (!mComposerClient->getDozeSupport(mPrimaryDisplay)) { |
| Error error = mComposerClient->getRaw()->setPowerMode(mPrimaryDisplay, |
| IComposerClient::PowerMode::DOZE); |
| EXPECT_EQ(Error::UNSUPPORTED, error); |
| |
| error = mComposerClient->getRaw()->setPowerMode(mPrimaryDisplay, |
| IComposerClient::PowerMode::DOZE_SUSPEND); |
| EXPECT_EQ(Error::UNSUPPORTED, error); |
| } |
| } |
| |
| /** |
| * Test IComposerClient::setPowerMode |
| * |
| * Tests that IComposerClient::setPowerMode returns BAD_PARAMETER when passed an invalid |
| * PowerMode |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetPowerModeBadParameter) { |
| Error error = mComposerClient->getRaw()->setPowerMode( |
| mPrimaryDisplay, static_cast<IComposerClient::PowerMode>(-1)); |
| ASSERT_EQ(Error::BAD_PARAMETER, error); |
| } |
| |
| /** |
| * Test IComposerClient::setVsyncEnabled. |
| * |
| * Test that IComposerClient::setVsyncEnabled succeeds and there is no |
| * spurious vsync events. |
| */ |
| TEST_P(GraphicsComposerHidlTest, SetVsyncEnabled) { |
| mComposerCallback->setVsyncAllowed(true); |
| |
| mComposerClient->setVsyncEnabled(mPrimaryDisplay, true); |
| usleep(60 * 1000); |
| mComposerClient->setVsyncEnabled(mPrimaryDisplay, false); |
| |
| mComposerCallback->setVsyncAllowed(false); |
| } |
| |
| // Tests for IComposerClient::Command. |
| class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest { |
| protected: |
| void SetUp() override { |
| ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp()); |
| |
| Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay); |
| mDisplayWidth = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig, |
| IComposerClient::Attribute::WIDTH); |
| mDisplayHeight = mComposerClient->getDisplayAttribute(mPrimaryDisplay, activeConfig, |
| IComposerClient::Attribute::HEIGHT); |
| mWriter = std::make_unique<CommandWriterBase>(1024); |
| mReader = std::make_unique<TestCommandReader>(); |
| } |
| |
| void TearDown() override { |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); |
| } |
| |
| sp<GraphicBuffer> allocate() { return allocate(mDisplayWidth, mDisplayHeight); } |
| |
| sp<GraphicBuffer> allocate(int32_t width, int32_t height) { |
| auto result = sp<GraphicBuffer>::make( |
| width, height, static_cast<int32_t>(PixelFormat::RGBA_8888), /*layerCount*/ 1, |
| static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN | |
| BufferUsage::COMPOSER_OVERLAY)); |
| if (result->initCheck() != STATUS_OK) { |
| return nullptr; |
| } |
| return result; |
| } |
| |
| void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); } |
| |
| std::unique_ptr<CommandWriterBase> mWriter; |
| std::unique_ptr<TestCommandReader> mReader; |
| int32_t mDisplayWidth; |
| int32_t mDisplayHeight; |
| }; |
| |
| /** |
| * Test IComposerClient::Command::SET_COLOR_TRANSFORM. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_COLOR_TRANSFORM) { |
| const std::array<float, 16> identity = {{ |
| 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, |
| 1.0f, |
| }}; |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->setColorTransform(identity.data(), ColorTransform::IDENTITY); |
| |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_CLIENT_TARGET. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_CLIENT_TARGET) { |
| mComposerClient->setClientTargetSlotCount(mPrimaryDisplay, kBufferSlotCount); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->setClientTarget(0, nullptr, -1, Dataspace::UNKNOWN, |
| std::vector<IComposerClient::Rect>()); |
| |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_OUTPUT_BUFFER. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_OUTPUT_BUFFER) { |
| if (mComposerClient->getMaxVirtualDisplayCount() == 0) { |
| GTEST_SUCCEED() << "no virtual display support"; |
| return; |
| } |
| |
| Display display; |
| PixelFormat format; |
| ASSERT_NO_FATAL_FAILURE( |
| display = mComposerClient->createVirtualDisplay(64, 64, PixelFormat::IMPLEMENTATION_DEFINED, |
| kBufferSlotCount, &format)); |
| |
| auto handle = allocate(); |
| ASSERT_TRUE(handle); |
| |
| mWriter->selectDisplay(display); |
| mWriter->setOutputBuffer(0, handle->handle, -1); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::VALIDATE_DISPLAY. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, VALIDATE_DISPLAY) { |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->validateDisplay(); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::ACCEPT_DISPLAY_CHANGES. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, ACCEPT_DISPLAY_CHANGES) { |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->validateDisplay(); |
| mWriter->acceptDisplayChanges(); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::PRESENT_DISPLAY. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY) { |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->validateDisplay(); |
| mWriter->presentDisplay(); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::PRESENT_DISPLAY |
| * |
| * Test that IComposerClient::Command::PRESENT_DISPLAY works without |
| * additional call to validateDisplay when only the layer buffer handle and |
| * surface damage have been set |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, PRESENT_DISPLAY_NO_LAYER_STATE_CHANGES) { |
| if (!mComposer->hasCapability( |
| static_cast<IComposer::Capability>(HWC2_CAPABILITY_SKIP_VALIDATE))) { |
| std::cout << "Device does not have skip validate capability, skipping" << std::endl; |
| GTEST_SUCCEED(); |
| return; |
| } |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON); |
| mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE); |
| |
| auto handle = allocate(); |
| ASSERT_NE(nullptr, handle.get()); |
| |
| IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; |
| |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); |
| mWriter->setLayerDisplayFrame(displayFrame); |
| mWriter->setLayerPlaneAlpha(1); |
| mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight}); |
| mWriter->setLayerTransform(static_cast<Transform>(0)); |
| mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame)); |
| mWriter->setLayerZOrder(10); |
| mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame)); |
| mWriter->setLayerBuffer(0, handle->handle, -1); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| GTEST_SUCCEED() << "Composition change requested, skipping test"; |
| return; |
| } |
| |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->selectLayer(layer); |
| auto handle2 = allocate(); |
| ASSERT_NE(nullptr, handle2.get()); |
| mWriter->setLayerBuffer(0, handle2->handle, -1); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, {0, 0, 10, 10})); |
| mWriter->presentDisplay(); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_CURSOR_POSITION. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_CURSOR_POSITION) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| auto handle = allocate(); |
| ASSERT_NE(nullptr, handle.get()); |
| IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBuffer(0, handle->handle, -1); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR); |
| mWriter->setLayerDisplayFrame(displayFrame); |
| mWriter->setLayerPlaneAlpha(1); |
| mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight}); |
| mWriter->setLayerTransform(static_cast<Transform>(0)); |
| mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame)); |
| mWriter->setLayerZOrder(10); |
| mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame)); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| mWriter->validateDisplay(); |
| |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| GTEST_SUCCEED() << "Composition change requested, skipping test"; |
| return; |
| } |
| mWriter->presentDisplay(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->setLayerCursorPosition(1, 1); |
| mWriter->setLayerCursorPosition(0, 0); |
| mWriter->validateDisplay(); |
| mWriter->presentDisplay(); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_BUFFER. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER) { |
| auto handle = allocate(); |
| ASSERT_NE(nullptr, handle.get()); |
| |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBuffer(0, handle->handle, -1); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_BUFFER with the behavior used for clearing buffer slots. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BUFFER_multipleTimes) { |
| // A placeholder buffer used to clear buffer slots |
| auto clearSlotBuffer = allocate(1u, 1u); |
| |
| // |
| // Set the layer buffer to the first buffer |
| // |
| auto handle1 = allocate(); |
| ASSERT_NE(nullptr, handle1.get()); |
| IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight}; |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE( |
| layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); |
| mWriter->setLayerDisplayFrame(displayFrame); |
| mWriter->setLayerBuffer(0, handle1->handle, -1); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| GTEST_SUCCEED() << "Composition change requested, skipping test"; |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| // |
| // Set the layer buffer to the second buffer |
| // |
| auto handle2 = allocate(); |
| ASSERT_NE(nullptr, handle2.get()); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); |
| mWriter->setLayerDisplayFrame(displayFrame); |
| mWriter->setLayerBuffer(1, handle2->handle, -1); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| GTEST_SUCCEED() << "Composition change requested, skipping test"; |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| // |
| // Set the layer buffer to the third buffer |
| // |
| auto handle3 = allocate(); |
| ASSERT_NE(nullptr, handle3.get()); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); |
| mWriter->setLayerDisplayFrame(displayFrame); |
| mWriter->setLayerBuffer(2, handle3->handle, -1); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| mWriter->validateDisplay(); |
| execute(); |
| if (mReader->mCompositionChanges.size() != 0) { |
| GTEST_SUCCEED() << "Composition change requested, skipping test"; |
| return; |
| } |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| // Ensure we can clear multiple buffer slots and then restore the active buffer at the end |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBuffer(0, clearSlotBuffer->handle, -1); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBuffer(1, clearSlotBuffer->handle, -1); |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBuffer(2, nullptr, -1); |
| mWriter->validateDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->presentDisplay(); |
| execute(); |
| ASSERT_EQ(0, mReader->mErrors.size()); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SURFACE_DAMAGE) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| IComposerClient::Rect empty{0, 0, 0, 0}; |
| IComposerClient::Rect unit{0, 0, 1, 1}; |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, empty)); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, unit)); |
| mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>()); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_BLEND_MODE. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_BLEND_MODE) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE); |
| mWriter->setLayerBlendMode(IComposerClient::BlendMode::PREMULTIPLIED); |
| mWriter->setLayerBlendMode(IComposerClient::BlendMode::COVERAGE); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_COLOR. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_COLOR) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerColor(IComposerClient::Color{0xff, 0xff, 0xff, 0xff}); |
| mWriter->setLayerColor(IComposerClient::Color{0, 0, 0, 0}); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_COMPOSITION_TYPE) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::CLIENT); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR); |
| mWriter->setLayerCompositionType(IComposerClient::Composition::CURSOR); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_DATASPACE. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_DATASPACE) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerDataspace(Dataspace::UNKNOWN); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_DISPLAY_FRAME. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_DISPLAY_FRAME) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerDisplayFrame(IComposerClient::Rect{0, 0, 1, 1}); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_PLANE_ALPHA. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_PLANE_ALPHA) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerPlaneAlpha(0.0f); |
| mWriter->setLayerPlaneAlpha(1.0f); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SIDEBAND_STREAM) { |
| if (!mComposer->hasCapability(IComposer::Capability::SIDEBAND_STREAM)) { |
| GTEST_SUCCEED() << "no sideband stream support"; |
| return; |
| } |
| |
| auto handle = allocate(); |
| ASSERT_NE(nullptr, handle.get()); |
| |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerSidebandStream(handle->handle); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_SOURCE_CROP. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_SOURCE_CROP) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerSourceCrop(IComposerClient::FRect{0.0f, 0.0f, 1.0f, 1.0f}); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_TRANSFORM. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_TRANSFORM) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerTransform(static_cast<Transform>(0)); |
| mWriter->setLayerTransform(Transform::FLIP_H); |
| mWriter->setLayerTransform(Transform::FLIP_V); |
| mWriter->setLayerTransform(Transform::ROT_90); |
| mWriter->setLayerTransform(Transform::ROT_180); |
| mWriter->setLayerTransform(Transform::ROT_270); |
| mWriter->setLayerTransform(static_cast<Transform>(Transform::FLIP_H | Transform::ROT_90)); |
| mWriter->setLayerTransform(static_cast<Transform>(Transform::FLIP_V | Transform::ROT_90)); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_VISIBLE_REGION. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_VISIBLE_REGION) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| IComposerClient::Rect empty{0, 0, 0, 0}; |
| IComposerClient::Rect unit{0, 0, 1, 1}; |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, empty)); |
| mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, unit)); |
| mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>()); |
| execute(); |
| } |
| |
| /** |
| * Test IComposerClient::Command::SET_LAYER_Z_ORDER. |
| */ |
| TEST_P(GraphicsComposerHidlCommandTest, SET_LAYER_Z_ORDER) { |
| Layer layer; |
| ASSERT_NO_FATAL_FAILURE(layer = |
| mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount)); |
| |
| mWriter->selectDisplay(mPrimaryDisplay); |
| mWriter->selectLayer(layer); |
| mWriter->setLayerZOrder(10); |
| mWriter->setLayerZOrder(0); |
| execute(); |
| } |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlCommandTest); |
| INSTANTIATE_TEST_SUITE_P( |
| PerInstance, GraphicsComposerHidlCommandTest, |
| testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), |
| android::hardware::PrintInstanceNameToString); |
| |
| GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest); |
| INSTANTIATE_TEST_SUITE_P( |
| PerInstance, GraphicsComposerHidlTest, |
| testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)), |
| android::hardware::PrintInstanceNameToString); |
| |
| } // namespace |
| } // namespace vts |
| } // namespace V2_1 |
| } // namespace composer |
| } // namespace graphics |
| } // namespace hardware |
| } // namespace android |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| |
| using namespace std::chrono_literals; |
| if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) { |
| ALOGE("Failed to stop init.svc.surfaceflinger"); |
| return -1; |
| } |
| |
| return RUN_ALL_TESTS(); |
| } |