graphics: more reusable libVtsHalGraphicsComposerTestUtils

Versioned library names, versioned include paths, and others.

Test: make VtsHalGraphicsComposerV2_1TargetTest
Change-Id: Ic266763c9ef25e09bc2c97026f2e1324609f48c6
diff --git a/graphics/composer/2.1/utils/vts/ComposerVts.cpp b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
new file mode 100644
index 0000000..2f531b4
--- /dev/null
+++ b/graphics/composer/2.1/utils/vts/ComposerVts.cpp
@@ -0,0 +1,324 @@
+/*
+ * 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.
+ */
+
+#include <composer-vts/2.1/ComposerVts.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace vts {
+
+Composer::Composer() {
+    mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
+    init();
+}
+
+Composer::Composer(const std::string& name) {
+    mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name);
+    init();
+}
+
+void Composer::init() {
+    ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
+
+    std::vector<IComposer::Capability> capabilities = getCapabilities();
+    mCapabilities.insert(capabilities.begin(), capabilities.end());
+}
+
+sp<IComposer> Composer::getRaw() const {
+    return mComposer;
+}
+
+bool Composer::hasCapability(IComposer::Capability capability) const {
+    return mCapabilities.count(capability) > 0;
+}
+
+std::vector<IComposer::Capability> Composer::getCapabilities() {
+    std::vector<IComposer::Capability> capabilities;
+    mComposer->getCapabilities(
+        [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
+
+    return capabilities;
+}
+
+std::string Composer::dumpDebugInfo() {
+    std::string debugInfo;
+    mComposer->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+    return debugInfo;
+}
+
+std::unique_ptr<ComposerClient> Composer::createClient() {
+    std::unique_ptr<ComposerClient> client;
+    mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
+        client = std::make_unique<ComposerClient>(tmpClient);
+    });
+
+    return client;
+}
+
+ComposerClient::ComposerClient(const sp<IComposerClient>& client) : mClient(client) {}
+
+ComposerClient::~ComposerClient() {
+    for (auto it : mDisplayResources) {
+        Display display = it.first;
+        DisplayResource& resource = it.second;
+
+        for (auto layer : resource.layers) {
+            EXPECT_EQ(Error::NONE, mClient->destroyLayer(display, layer))
+                << "failed to destroy layer " << layer;
+        }
+
+        if (resource.isVirtual) {
+            EXPECT_EQ(Error::NONE, mClient->destroyVirtualDisplay(display))
+                << "failed to destroy virtual display " << display;
+        }
+    }
+    mDisplayResources.clear();
+}
+
+sp<IComposerClient> ComposerClient::getRaw() const {
+    return mClient;
+}
+
+void ComposerClient::registerCallback(const sp<IComposerCallback>& callback) {
+    mClient->registerCallback(callback);
+}
+
+uint32_t ComposerClient::getMaxVirtualDisplayCount() {
+    return mClient->getMaxVirtualDisplayCount();
+}
+
+Display ComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
+                                             PixelFormat formatHint, uint32_t outputBufferSlotCount,
+                                             PixelFormat* outFormat) {
+    Display display = 0;
+    mClient->createVirtualDisplay(
+        width, height, formatHint, outputBufferSlotCount,
+        [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
+            display = tmpDisplay;
+            *outFormat = tmpFormat;
+
+            ASSERT_TRUE(mDisplayResources.insert({display, DisplayResource(true)}).second)
+                << "duplicated virtual display id " << display;
+        });
+
+    return display;
+}
+
+void ComposerClient::destroyVirtualDisplay(Display display) {
+    Error error = mClient->destroyVirtualDisplay(display);
+    ASSERT_EQ(Error::NONE, error) << "failed to destroy virtual display " << display;
+
+    mDisplayResources.erase(display);
+}
+
+Layer ComposerClient::createLayer(Display display, uint32_t bufferSlotCount) {
+    Layer layer = 0;
+    mClient->createLayer(display, bufferSlotCount, [&](const auto& tmpError, const auto& tmpLayer) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to create layer";
+        layer = tmpLayer;
+
+        auto resourceIt = mDisplayResources.find(display);
+        if (resourceIt == mDisplayResources.end()) {
+            resourceIt = mDisplayResources.insert({display, DisplayResource(false)}).first;
+        }
+
+        ASSERT_TRUE(resourceIt->second.layers.insert(layer).second)
+            << "duplicated layer id " << layer;
+    });
+
+    return layer;
+}
+
+void ComposerClient::destroyLayer(Display display, Layer layer) {
+    Error error = mClient->destroyLayer(display, layer);
+    ASSERT_EQ(Error::NONE, error) << "failed to destroy layer " << layer;
+
+    auto resourceIt = mDisplayResources.find(display);
+    ASSERT_NE(mDisplayResources.end(), resourceIt);
+    resourceIt->second.layers.erase(layer);
+}
+
+Config ComposerClient::getActiveConfig(Display display) {
+    Config config = 0;
+    mClient->getActiveConfig(display, [&](const auto& tmpError, const auto& tmpConfig) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get active config";
+        config = tmpConfig;
+    });
+
+    return config;
+}
+
+bool ComposerClient::getClientTargetSupport(Display display, uint32_t width, uint32_t height,
+                                            PixelFormat format, Dataspace dataspace) {
+    Error error = mClient->getClientTargetSupport(display, width, height, format, dataspace);
+    return error == Error::NONE;
+}
+
+std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
+    std::vector<ColorMode> modes;
+    mClient->getColorModes(display, [&](const auto& tmpError, const auto& tmpMode) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color mode";
+        modes = tmpMode;
+    });
+
+    return modes;
+}
+
+int32_t ComposerClient::getDisplayAttribute(Display display, Config config,
+                                            IComposerClient::Attribute attribute) {
+    int32_t value = 0;
+    mClient->getDisplayAttribute(
+        display, config, attribute, [&](const auto& tmpError, const auto& tmpValue) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get display attribute";
+            value = tmpValue;
+        });
+
+    return value;
+}
+
+std::vector<Config> ComposerClient::getDisplayConfigs(Display display) {
+    std::vector<Config> configs;
+    mClient->getDisplayConfigs(display, [&](const auto& tmpError, const auto& tmpConfigs) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display configs";
+        configs = tmpConfigs;
+    });
+
+    return configs;
+}
+
+std::string ComposerClient::getDisplayName(Display display) {
+    std::string name;
+    mClient->getDisplayName(display, [&](const auto& tmpError, const auto& tmpName) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display name";
+        name = tmpName.c_str();
+    });
+
+    return name;
+}
+
+IComposerClient::DisplayType ComposerClient::getDisplayType(Display display) {
+    IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
+    mClient->getDisplayType(display, [&](const auto& tmpError, const auto& tmpType) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display type";
+        type = tmpType;
+    });
+
+    return type;
+}
+
+bool ComposerClient::getDozeSupport(Display display) {
+    bool support = false;
+    mClient->getDozeSupport(display, [&](const auto& tmpError, const auto& tmpSupport) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to get doze support";
+        support = tmpSupport;
+    });
+
+    return support;
+}
+
+std::vector<Hdr> ComposerClient::getHdrCapabilities(Display display, float* outMaxLuminance,
+                                                    float* outMaxAverageLuminance,
+                                                    float* outMinLuminance) {
+    std::vector<Hdr> types;
+    mClient->getHdrCapabilities(
+        display, [&](const auto& tmpError, const auto& tmpTypes, const auto& tmpMaxLuminance,
+                     const auto& tmpMaxAverageLuminance, const auto& tmpMinLuminance) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
+            types = tmpTypes;
+            *outMaxLuminance = tmpMaxLuminance;
+            *outMaxAverageLuminance = tmpMaxAverageLuminance;
+            *outMinLuminance = tmpMinLuminance;
+        });
+
+    return types;
+}
+
+void ComposerClient::setClientTargetSlotCount(Display display, uint32_t clientTargetSlotCount) {
+    Error error = mClient->setClientTargetSlotCount(display, clientTargetSlotCount);
+    ASSERT_EQ(Error::NONE, error) << "failed to set client target slot count";
+}
+
+void ComposerClient::setActiveConfig(Display display, Config config) {
+    Error error = mClient->setActiveConfig(display, config);
+    ASSERT_EQ(Error::NONE, error) << "failed to set active config";
+}
+
+void ComposerClient::setColorMode(Display display, ColorMode mode) {
+    Error error = mClient->setColorMode(display, mode);
+    ASSERT_EQ(Error::NONE, error) << "failed to set color mode";
+}
+
+void ComposerClient::setPowerMode(Display display, IComposerClient::PowerMode mode) {
+    Error error = mClient->setPowerMode(display, mode);
+    ASSERT_EQ(Error::NONE, error) << "failed to set power mode";
+}
+
+void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
+    IComposerClient::Vsync vsync =
+        (enabled) ? IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE;
+    Error error = mClient->setVsyncEnabled(display, vsync);
+    ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
+
+    // give the hwbinder thread some time to handle any pending vsync callback
+    if (!enabled) {
+        usleep(5 * 1000);
+    }
+}
+
+void ComposerClient::execute(TestCommandReader* reader, CommandWriterBase* writer) {
+    bool queueChanged = false;
+    uint32_t commandLength = 0;
+    hidl_vec<hidl_handle> commandHandles;
+    ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
+
+    if (queueChanged) {
+        auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
+        ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
+        return;
+    }
+
+    mClient->executeCommands(commandLength, commandHandles,
+                             [&](const auto& tmpError, const auto& tmpOutQueueChanged,
+                                 const auto& tmpOutLength, const auto& tmpOutHandles) {
+                                 ASSERT_EQ(Error::NONE, tmpError);
+
+                                 if (tmpOutQueueChanged) {
+                                     mClient->getOutputCommandQueue(
+                                         [&](const auto& tmpError, const auto& tmpDescriptor) {
+                                             ASSERT_EQ(Error::NONE, tmpError);
+                                             reader->setMQDescriptor(tmpDescriptor);
+                                         });
+                                 }
+
+                                 ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles));
+                                 reader->parse();
+                             });
+}
+
+}  // namespace vts
+}  // namespace V2_1
+}  // namespace composer
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android