Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0c41558b authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

graphics: Clean up VTS boilerplate for composer

This CL makes the V2_1::vts::Composer class more reusable, and cleans up
the 2.2 boilerplate.

Bug: 74619554
Test: VtsHalGraphicsComposerV2_2TargetTest
Change-Id: Iff2905d40afe16a0b9ce735f1285d5bdc6b4cec7
parent 8800012b
Loading
Loading
Loading
Loading
+10 −12
Original line number Original line Diff line number Diff line
@@ -25,21 +25,19 @@ namespace composer {
namespace V2_1 {
namespace V2_1 {
namespace vts {
namespace vts {


Composer::Composer() {
Composer::Composer() : Composer(::testing::VtsHalHidlTargetTestBase::getService<IComposer>()) {}
    mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>();
    init();
}


Composer::Composer(const std::string& name) {
Composer::Composer(const std::string& name)
    mComposer = ::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name);
    : Composer(::testing::VtsHalHidlTargetTestBase::getService<IComposer>(name)) {}
    init();
}


void Composer::init() {
Composer::Composer(const sp<IComposer>& composer) : mComposer(composer) {
    // ASSERT_* can only be used in functions returning void.
    [this] {
        ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
        ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";


        std::vector<IComposer::Capability> capabilities = getCapabilities();
        std::vector<IComposer::Capability> capabilities = getCapabilities();
        mCapabilities.insert(capabilities.begin(), capabilities.end());
        mCapabilities.insert(capabilities.begin(), capabilities.end());
    }();
}
}


sp<IComposer> Composer::getRaw() const {
sp<IComposer> Composer::getRaw() const {
+4 −4
Original line number Original line Diff line number Diff line
@@ -57,10 +57,10 @@ class Composer {
    std::unique_ptr<ComposerClient> createClient();
    std::unique_ptr<ComposerClient> createClient();


   protected:
   protected:
    sp<IComposer> mComposer;
    explicit Composer(const sp<IComposer>& composer);


   private:
   private:
    void init();
    const sp<IComposer> mComposer;


    std::unordered_set<IComposer::Capability> mCapabilities;
    std::unordered_set<IComposer::Capability> mCapabilities;
};
};
@@ -68,7 +68,7 @@ class Composer {
// A wrapper to IComposerClient.
// A wrapper to IComposerClient.
class ComposerClient {
class ComposerClient {
   public:
   public:
    ComposerClient(const sp<IComposerClient>& client);
    explicit ComposerClient(const sp<IComposerClient>& client);
    ~ComposerClient();
    ~ComposerClient();


    sp<IComposerClient> getRaw() const;
    sp<IComposerClient> getRaw() const;
@@ -116,7 +116,7 @@ class ComposerClient {
    std::unordered_map<Display, DisplayResource> mDisplayResources;
    std::unordered_map<Display, DisplayResource> mDisplayResources;


   private:
   private:
    sp<IComposerClient> mClient;
    const sp<IComposerClient> mClient;
};
};


}  // namespace vts
}  // namespace vts
+55 −60
Original line number Original line Diff line number Diff line
@@ -27,28 +27,27 @@ namespace composer {
namespace V2_2 {
namespace V2_2 {
namespace vts {
namespace vts {


using android::hardware::details::canCastInterface;
using details::canCastInterface;
using android::hardware::details::getDescriptor;
using details::getDescriptor;
using android::hardware::graphics::composer::V2_2::IComposerClient;


std::unique_ptr<ComposerClient_v2_2> Composer_v2_2::createClient_v2_2() {
std::unique_ptr<ComposerClient> Composer::createClient() {
    std::unique_ptr<ComposerClient_v2_2> client;
    std::unique_ptr<ComposerClient> client;
    mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
    getRaw()->createClient([&](const auto& tmpError, const auto& tmpClient) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
        ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
        ALOGV("tmpClient is a %s", getDescriptor(&(*tmpClient)).c_str());
        ALOGV("tmpClient is a %s", getDescriptor(&(*tmpClient)).c_str());
        ASSERT_TRUE(canCastInterface(
        ASSERT_TRUE(canCastInterface(
            &(*tmpClient), "android.hardware.graphics.composer@2.2::IComposerClient", false))
            &(*tmpClient), "android.hardware.graphics.composer@2.2::IComposerClient", false))
            << "Cannot create 2.2 IComposerClient";
            << "Cannot create 2.2 IComposerClient";
        client = std::make_unique<ComposerClient_v2_2>(IComposerClient::castFrom(tmpClient, true));
        client = std::make_unique<ComposerClient>(IComposerClient::castFrom(tmpClient, true));
    });
    });


    return client;
    return client;
}
}


std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient_v2_2::getPerFrameMetadataKeys(
std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient::getPerFrameMetadataKeys(
    Display display) {
    Display display) {
    std::vector<IComposerClient::PerFrameMetadataKey> keys;
    std::vector<IComposerClient::PerFrameMetadataKey> keys;
    mClient_v2_2->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
    mClient->getPerFrameMetadataKeys(display, [&](const auto& tmpError, const auto& tmpKeys) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR metadata keys";
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR metadata keys";
        keys = tmpKeys;
        keys = tmpKeys;
    });
    });
@@ -56,26 +55,25 @@ std::vector<IComposerClient::PerFrameMetadataKey> ComposerClient_v2_2::getPerFra
    return keys;
    return keys;
}
}


void ComposerClient_v2_2::execute_v2_2(V2_1::vts::TestCommandReader* reader,
void ComposerClient::execute(V2_1::vts::TestCommandReader* reader, CommandWriterBase* writer) {
                                       V2_2::CommandWriterBase* writer) {
    bool queueChanged = false;
    bool queueChanged = false;
    uint32_t commandLength = 0;
    uint32_t commandLength = 0;
    hidl_vec<hidl_handle> commandHandles;
    hidl_vec<hidl_handle> commandHandles;
    ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
    ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));


    if (queueChanged) {
    if (queueChanged) {
        auto ret = mClient_v2_2->setInputCommandQueue(*writer->getMQDescriptor());
        auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
        ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
        ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
        return;
        return;
    }
    }


    mClient_v2_2->executeCommands(commandLength, commandHandles,
    mClient->executeCommands(commandLength, commandHandles,
                             [&](const auto& tmpError, const auto& tmpOutQueueChanged,
                             [&](const auto& tmpError, const auto& tmpOutQueueChanged,
                                 const auto& tmpOutLength, const auto& tmpOutHandles) {
                                 const auto& tmpOutLength, const auto& tmpOutHandles) {
                                 ASSERT_EQ(Error::NONE, tmpError);
                                 ASSERT_EQ(Error::NONE, tmpError);


                                 if (tmpOutQueueChanged) {
                                 if (tmpOutQueueChanged) {
                                          mClient_v2_2->getOutputCommandQueue(
                                     mClient->getOutputCommandQueue(
                                         [&](const auto& tmpError, const auto& tmpDescriptor) {
                                         [&](const auto& tmpError, const auto& tmpDescriptor) {
                                             ASSERT_EQ(Error::NONE, tmpError);
                                             ASSERT_EQ(Error::NONE, tmpError);
                                             reader->setMQDescriptor(tmpDescriptor);
                                             reader->setMQDescriptor(tmpDescriptor);
@@ -87,12 +85,12 @@ void ComposerClient_v2_2::execute_v2_2(V2_1::vts::TestCommandReader* reader,
                             });
                             });
}
}


Display ComposerClient_v2_2::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
Display ComposerClient::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
                                                 PixelFormat formatHint,
                                                 PixelFormat formatHint,
                                                 uint32_t outputBufferSlotCount,
                                                 uint32_t outputBufferSlotCount,
                                                 PixelFormat* outFormat) {
                                                 PixelFormat* outFormat) {
    Display display = 0;
    Display display = 0;
    mClient_v2_2->createVirtualDisplay_2_2(
    mClient->createVirtualDisplay_2_2(
        width, height, formatHint, outputBufferSlotCount,
        width, height, formatHint, outputBufferSlotCount,
        [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
        [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
            ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
            ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
@@ -106,29 +104,27 @@ Display ComposerClient_v2_2::createVirtualDisplay_2_2(uint32_t width, uint32_t h
    return display;
    return display;
}
}


bool ComposerClient_v2_2::getClientTargetSupport_2_2(Display display, uint32_t width,
bool ComposerClient::getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
                                                     uint32_t height, PixelFormat format,
                                                PixelFormat format, Dataspace dataspace) {
                                                     Dataspace dataspace) {
    Error error = mClient->getClientTargetSupport_2_2(display, width, height, format, dataspace);
    Error error =
        mClient_v2_2->getClientTargetSupport_2_2(display, width, height, format, dataspace);
    return error == Error::NONE;
    return error == Error::NONE;
}
}


void ComposerClient_v2_2::setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode) {
void ComposerClient::setPowerMode_2_2(Display display, IComposerClient::PowerMode mode) {
    Error error = mClient_v2_2->setPowerMode_2_2(display, mode);
    Error error = mClient->setPowerMode_2_2(display, mode);
    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set power mode";
    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set power mode";
}
}


void ComposerClient_v2_2::setReadbackBuffer(Display display, const native_handle_t* buffer,
void ComposerClient::setReadbackBuffer(Display display, const native_handle_t* buffer,
                                       int32_t /* releaseFence */) {
                                       int32_t /* releaseFence */) {
    // Ignoring fence, HIDL doesn't care
    // Ignoring fence, HIDL doesn't care
    Error error = mClient_v2_2->setReadbackBuffer(display, buffer, nullptr);
    Error error = mClient->setReadbackBuffer(display, buffer, nullptr);
    ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer";
    ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer";
}
}


void ComposerClient_v2_2::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                                 Dataspace* outDataspace) {
                                                 Dataspace* outDataspace) {
    mClient_v2_2->getReadbackBufferAttributes(
    mClient->getReadbackBufferAttributes(
        display,
        display,
        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
        [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
            ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
@@ -137,42 +133,41 @@ void ComposerClient_v2_2::getReadbackBufferAttributes(Display display, PixelForm
        });
        });
}
}


void ComposerClient_v2_2::getReadbackBufferFence(Display display, int32_t* outFence) {
void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
    hidl_handle handle;
    hidl_handle handle;
    mClient_v2_2->getReadbackBufferFence(display, [&](const auto& tmpError, const auto& tmpHandle) {
    mClient->getReadbackBufferFence(display, [&](const auto& tmpError, const auto& tmpHandle) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback fence";
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback fence";
        handle = tmpHandle;
        handle = tmpHandle;
    });
    });
    *outFence = 0;
    *outFence = 0;
}
}


std::vector<ColorMode> ComposerClient_v2_2::getColorModes(Display display) {
std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
    std::vector<ColorMode> modes;
    std::vector<ColorMode> modes;
    mClient_v2_2->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
    mClient->getColorModes_2_2(display, [&](const auto& tmpError, const auto& tmpModes) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color modes";
        modes = tmpModes;
        modes = tmpModes;
    });
    });
    return modes;
    return modes;
}
}


std::vector<RenderIntent> ComposerClient_v2_2::getRenderIntents(Display display, ColorMode mode) {
std::vector<RenderIntent> ComposerClient::getRenderIntents(Display display, ColorMode mode) {
    std::vector<RenderIntent> intents;
    std::vector<RenderIntent> intents;
    mClient_v2_2->getRenderIntents(
    mClient->getRenderIntents(display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
        display, mode, [&](const auto& tmpError, const auto& tmpIntents) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get render intents";
        intents = tmpIntents;
        intents = tmpIntents;
    });
    });
    return intents;
    return intents;
}
}


void ComposerClient_v2_2::setColorMode(Display display, ColorMode mode, RenderIntent intent) {
void ComposerClient::setColorMode(Display display, ColorMode mode, RenderIntent intent) {
    Error error = mClient_v2_2->setColorMode_2_2(display, mode, intent);
    Error error = mClient->setColorMode_2_2(display, mode, intent);
    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
    ASSERT_TRUE(error == Error::NONE || error == Error::UNSUPPORTED) << "failed to set color mode";
}
}


std::array<float, 16> ComposerClient_v2_2::getDataspaceSaturationMatrix(Dataspace dataspace) {
std::array<float, 16> ComposerClient::getDataspaceSaturationMatrix(Dataspace dataspace) {
    std::array<float, 16> matrix;
    std::array<float, 16> matrix;
    mClient_v2_2->getDataspaceSaturationMatrix(
    mClient->getDataspaceSaturationMatrix(
        dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
        dataspace, [&](const auto& tmpError, const auto& tmpMatrix) {
            ASSERT_EQ(Error::NONE, tmpError) << "failed to get datasapce saturation matrix";
            ASSERT_EQ(Error::NONE, tmpError) << "failed to get datasapce saturation matrix";
            std::copy_n(tmpMatrix.data(), matrix.size(), matrix.begin());
            std::copy_n(tmpMatrix.data(), matrix.size(), matrix.begin());
+18 −23
Original line number Original line Diff line number Diff line
@@ -36,34 +36,29 @@ namespace composer {
namespace V2_2 {
namespace V2_2 {
namespace vts {
namespace vts {


using android::hardware::graphics::common::V1_0::Hdr;
using common::V1_0::Hdr;
using android::hardware::graphics::common::V1_1::ColorMode;
using common::V1_1::ColorMode;
using android::hardware::graphics::common::V1_1::Dataspace;
using common::V1_1::Dataspace;
using android::hardware::graphics::common::V1_1::PixelFormat;
using common::V1_1::PixelFormat;
using android::hardware::graphics::common::V1_1::RenderIntent;
using common::V1_1::RenderIntent;
using android::hardware::graphics::composer::V2_2::IComposer;

using android::hardware::graphics::composer::V2_2::IComposerClient;
class ComposerClient;


class ComposerClient_v2_2;
// A wrapper to IComposer.

class Composer : public V2_1::vts::Composer {
// Only thing I need for Composer_v2_2 is to create a v2_2 ComposerClient
// Everything else is the same
class Composer_v2_2 : public V2_1::vts::Composer {
   public:
   public:
    Composer_v2_2() : V2_1::vts::Composer(){};
    using V2_1::vts::Composer::Composer;
    explicit Composer_v2_2(const std::string& name) : V2_1::vts::Composer(name){};


    std::unique_ptr<ComposerClient_v2_2> createClient_v2_2();
    std::unique_ptr<ComposerClient> createClient();
};
};


// A wrapper to IComposerClient.
// A wrapper to IComposerClient.
class ComposerClient_v2_2
class ComposerClient : public V2_1::vts::ComposerClient {
    : public android::hardware::graphics::composer::V2_1::vts::ComposerClient {
   public:
   public:
    ComposerClient_v2_2(const sp<IComposerClient>& client)
    explicit ComposerClient(const sp<IComposerClient>& client)
        : V2_1::vts::ComposerClient(client), mClient_v2_2(client){};
        : V2_1::vts::ComposerClient(client), mClient(client) {}


    void execute_v2_2(V2_1::vts::TestCommandReader* reader, V2_2::CommandWriterBase* writer);
    void execute(V2_1::vts::TestCommandReader* reader, CommandWriterBase* writer);


    std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display);
    std::vector<IComposerClient::PerFrameMetadataKey> getPerFrameMetadataKeys(Display display);


@@ -71,7 +66,7 @@ class ComposerClient_v2_2
                                     uint32_t outputBufferSlotCount, PixelFormat* outFormat);
                                     uint32_t outputBufferSlotCount, PixelFormat* outFormat);
    bool getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
    bool getClientTargetSupport_2_2(Display display, uint32_t width, uint32_t height,
                                    PixelFormat format, Dataspace dataspace);
                                    PixelFormat format, Dataspace dataspace);
    void setPowerMode_2_2(Display display, V2_2::IComposerClient::PowerMode mode);
    void setPowerMode_2_2(Display display, IComposerClient::PowerMode mode);
    void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
    void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
    void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
                                     Dataspace* outDataspace);
                                     Dataspace* outDataspace);
@@ -84,7 +79,7 @@ class ComposerClient_v2_2
    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace);
    std::array<float, 16> getDataspaceSaturationMatrix(Dataspace dataspace);


   private:
   private:
    sp<V2_2::IComposerClient> mClient_v2_2;
    const sp<IComposerClient> mClient;
};
};


}  // namespace vts
}  // namespace vts
+16 −18
Original line number Original line Diff line number Diff line
@@ -32,17 +32,15 @@ namespace V2_2 {
namespace vts {
namespace vts {
namespace {
namespace {


using android::hardware::graphics::common::V1_0::BufferUsage;
using common::V1_0::BufferUsage;
using android::hardware::graphics::common::V1_0::ColorTransform;
using common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Transform;
using common::V1_0::Transform;
using android::hardware::graphics::common::V1_1::ColorMode;
using common::V1_1::ColorMode;
using android::hardware::graphics::common::V1_1::Dataspace;
using common::V1_1::Dataspace;
using android::hardware::graphics::common::V1_1::PixelFormat;
using common::V1_1::PixelFormat;
using android::hardware::graphics::common::V1_1::RenderIntent;
using common::V1_1::RenderIntent;
using android::hardware::graphics::composer::V2_2::IComposerClient;
using mapper::V2_1::IMapper;
using android::hardware::graphics::mapper::V2_1::IMapper;
using mapper::V2_1::vts::Gralloc;
using android::hardware::graphics::mapper::V2_1::vts::Gralloc;
using GrallocError = android::hardware::graphics::mapper::V2_0::Error;


// Test environment for graphics.composer
// Test environment for graphics.composer
class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
@@ -65,9 +63,9 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
   protected:
   protected:
    void SetUp() override {
    void SetUp() override {
        ASSERT_NO_FATAL_FAILURE(
        ASSERT_NO_FATAL_FAILURE(
            mComposer = std::make_unique<Composer_v2_2>(
            mComposer = std::make_unique<Composer>(
                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient_v2_2());
        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());


        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
        mComposerClient->registerCallback(mComposerCallback);
        mComposerClient->registerCallback(mComposerCallback);
@@ -91,8 +89,8 @@ class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    // use the slot count usually set by SF
    // use the slot count usually set by SF
    static constexpr uint32_t kBufferSlotCount = 64;
    static constexpr uint32_t kBufferSlotCount = 64;


    std::unique_ptr<Composer_v2_2> mComposer;
    std::unique_ptr<Composer> mComposer;
    std::unique_ptr<ComposerClient_v2_2> mComposerClient;
    std::unique_ptr<ComposerClient> mComposerClient;
    sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
    sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
    // the first display and is assumed never to be removed
    // the first display and is assumed never to be removed
    Display mPrimaryDisplay;
    Display mPrimaryDisplay;
@@ -119,7 +117,7 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {


        ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
        ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());


        mWriter = std::make_unique<V2_2::CommandWriterBase>(1024);
        mWriter = std::make_unique<CommandWriterBase>(1024);
        mReader = std::make_unique<V2_1::vts::TestCommandReader>();
        mReader = std::make_unique<V2_1::vts::TestCommandReader>();
    }
    }


@@ -137,9 +135,9 @@ class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
        return mGralloc->allocate(info);
        return mGralloc->allocate(info);
    }
    }


    void execute() { mComposerClient->execute_v2_2(mReader.get(), mWriter.get()); }
    void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }


    std::unique_ptr<V2_2::CommandWriterBase> mWriter;
    std::unique_ptr<CommandWriterBase> mWriter;
    std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
    std::unique_ptr<V2_1::vts::TestCommandReader> mReader;


   private:
   private: