IComposerClient wrapper for VTS tests
A wrapper helps with implementation details of IComposerClient and
improves re-usability with readback and base tests.
Changes from the original wrapper (ag/16578214):
Changed the createClient to return ScopedAStatus
as it helps more with the singleton test.
And updated getDisplays to go through all the configurations
and save it in the DisplayResources as we use
the properties like width, height, vsync later
in the test and we avoid querying to the composerClient for this.
With readback tests updated setReadbackBuffer method to use
const native_handle_t* buffer instead of const native_handle* buffer
BUG: 199413815
Test: atest VtsHalGraphicsComposer3_TargetTest
Change-Id: Ia33c9489bf15a52edcae55a91ec56666df3726c1
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
index bd2c3b1..139b5e8 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/Android.bp
@@ -35,6 +35,9 @@
"VtsHalGraphicsComposer3_TargetTest.cpp",
"VtsHalGraphicsComposer3_ReadbackTest.cpp",
"composer-vts/GraphicsComposerCallback.cpp",
+ "composer-vts/ReadbackVts.cpp",
+ "composer-vts/RenderEngineVts.cpp",
+ "composer-vts/VtsComposerClient.cpp",
],
shared_libs: [
@@ -72,15 +75,19 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.allocator@4.0",
- "android.hardware.graphics.composer@3-vts",
"android.hardware.graphics.mapper@2.0-vts",
"android.hardware.graphics.mapper@2.1-vts",
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0-vts",
"libaidlcommonsupport",
+ "libarect",
+ "libbase",
+ "libfmq",
"libgtest",
+ "libmath",
"librenderengine",
"libshaders",
+ "libsync",
"libtonemap",
],
cflags: [
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
deleted file mode 100644
index df038db..0000000
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/Android.bp
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * Copyright (c) 2021, 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.
- */
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "hardware_interfaces_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["hardware_interfaces_license"],
-}
-
-cc_library_static {
- name: "android.hardware.graphics.composer@3-vts",
- defaults: ["hidl_defaults"],
- srcs: [
- "GraphicsComposerCallback.cpp",
- "ReadbackVts.cpp",
- "RenderEngineVts.cpp",
- ],
- header_libs: [
- "android.hardware.graphics.composer3-command-buffer",
- ],
- static_libs: [
- "android.hardware.graphics.composer3-V1-ndk",
- "android.hardware.graphics.common-V3-ndk",
- "android.hardware.common-V2-ndk",
- "android.hardware.common.fmq-V1-ndk",
- "libarect",
- "libgtest",
- "libbase",
- "libfmq",
- "libsync",
- "libmath",
- "libaidlcommonsupport",
- "libnativewindow",
- "librenderengine",
- "libshaders",
- "libtonemap",
- "android.hardware.graphics.mapper@2.0-vts",
- "android.hardware.graphics.mapper@2.1-vts",
- "android.hardware.graphics.mapper@3.0-vts",
- "android.hardware.graphics.mapper@4.0-vts",
- ],
- shared_libs: [
- "libbinder_ndk",
- "libhidlbase",
- "libui",
- "android.hardware.graphics.composer3-V1-ndk",
- ],
- export_static_lib_headers: [
- "android.hardware.graphics.mapper@2.1-vts",
- "librenderengine",
- ],
- cflags: [
- "-O0",
- "-g",
- "-DLOG_TAG=\"ComposerVts\"",
- "-Wconversion",
- ],
- export_header_lib_headers: [
- "android.hardware.graphics.composer3-command-buffer",
- ],
- export_include_dirs: ["include"],
-}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/VtsComposerClient.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/VtsComposerClient.cpp
new file mode 100644
index 0000000..8c882d0
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/VtsComposerClient.cpp
@@ -0,0 +1,502 @@
+/**
+ * Copyright (c) 2022, 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 "include/VtsComposerClient.h"
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/logging.h>
+#include <log/log_main.h>
+
+#undef LOG_TAG
+#define LOG_TAG "VtsComposerClient"
+
+using namespace std::chrono_literals;
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+VtsComposerClient::VtsComposerClient(const std::string& name) {
+ SpAIBinder binder(AServiceManager_waitForService(name.c_str()));
+ ALOGE_IF(binder == nullptr, "Could not initialize the service binder");
+ if (binder != nullptr) {
+ mComposer = IComposer::fromBinder(binder);
+ ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
+ }
+}
+
+ScopedAStatus VtsComposerClient::createClient() {
+ if (mComposer == nullptr) {
+ ALOGE("IComposer not initialized");
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
+ }
+ auto status = mComposer->createClient(&mComposerClient);
+ if (!status.isOk() || mComposerClient == nullptr) {
+ ALOGE("Failed to create client for IComposerClient with %s",
+ status.getDescription().c_str());
+ return status;
+ }
+ mComposerCallback = SharedRefBase::make<GraphicsComposerCallback>();
+ if (mComposerCallback == nullptr) {
+ ALOGE("Unable to create ComposerCallback");
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::INVALID_CONFIGURATION);
+ }
+ return mComposerClient->registerCallback(mComposerCallback);
+}
+
+bool VtsComposerClient::tearDown() {
+ return verifyComposerCallbackParams() && destroyAllLayers();
+}
+
+std::pair<ScopedAStatus, VirtualDisplay> VtsComposerClient::createVirtualDisplay(
+ int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount) {
+ VirtualDisplay outVirtualDisplay;
+ auto status = mComposerClient->createVirtualDisplay(width, height, pixelFormat, bufferSlotCount,
+ &outVirtualDisplay);
+ if (!status.isOk()) {
+ return {std::move(status), outVirtualDisplay};
+ }
+ return {addDisplayToDisplayResources(outVirtualDisplay.display, /*isVirtual*/ true),
+ outVirtualDisplay};
+}
+
+ScopedAStatus VtsComposerClient::destroyVirtualDisplay(int64_t display) {
+ auto status = mComposerClient->destroyVirtualDisplay(display);
+ if (!status.isOk()) {
+ return status;
+ }
+ mDisplayResources.erase(display);
+ return status;
+}
+
+std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
+ int32_t bufferSlotCount) {
+ int64_t outLayer;
+ auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
+
+ if (!status.isOk()) {
+ return {std::move(status), outLayer};
+ }
+ return {addLayerToDisplayResources(display, outLayer), outLayer};
+}
+
+ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
+ auto status = mComposerClient->destroyLayer(display, layer);
+
+ if (!status.isOk()) {
+ return status;
+ }
+ removeLayerFromDisplayResources(display, layer);
+ return status;
+}
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
+ int32_t outConfig;
+ return {mComposerClient->getActiveConfig(display, &outConfig), outConfig};
+}
+
+ScopedAStatus VtsComposerClient::setActiveConfig(VtsDisplay* vtsDisplay, int32_t config) {
+ auto status = mComposerClient->setActiveConfig(vtsDisplay->getDisplayId(), config);
+ if (!status.isOk()) {
+ return status;
+ }
+ return updateDisplayProperties(vtsDisplay, config);
+}
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayAttribute(
+ int64_t display, int32_t config, DisplayAttribute displayAttribute) {
+ int32_t outDisplayAttribute;
+ return {mComposerClient->getDisplayAttribute(display, config, displayAttribute,
+ &outDisplayAttribute),
+ outDisplayAttribute};
+}
+
+ScopedAStatus VtsComposerClient::setPowerMode(int64_t display, PowerMode powerMode) {
+ return mComposerClient->setPowerMode(display, powerMode);
+}
+
+ScopedAStatus VtsComposerClient::setVsync(int64_t display, bool enable) {
+ return mComposerClient->setVsyncEnabled(display, enable);
+}
+
+void VtsComposerClient::setVsyncAllowed(bool isAllowed) {
+ mComposerCallback->setVsyncAllowed(isAllowed);
+}
+
+std::pair<ScopedAStatus, std::vector<float>> VtsComposerClient::getDataspaceSaturationMatrix(
+ Dataspace dataspace) {
+ std::vector<float> outMatrix;
+ return {mComposerClient->getDataspaceSaturationMatrix(dataspace, &outMatrix), outMatrix};
+}
+
+std::pair<ScopedAStatus, std::vector<CommandResultPayload>> VtsComposerClient::executeCommands(
+ const std::vector<DisplayCommand>& commands) {
+ std::vector<CommandResultPayload> outResultPayload;
+ return {mComposerClient->executeCommands(commands, &outResultPayload),
+ std::move(outResultPayload)};
+}
+
+std::optional<VsyncPeriodChangeTimeline> VtsComposerClient::takeLastVsyncPeriodChangeTimeline() {
+ return mComposerCallback->takeLastVsyncPeriodChangeTimeline();
+}
+
+ScopedAStatus VtsComposerClient::setContentType(int64_t display, ContentType contentType) {
+ return mComposerClient->setContentType(display, contentType);
+}
+
+std::pair<ScopedAStatus, VsyncPeriodChangeTimeline>
+VtsComposerClient::setActiveConfigWithConstraints(VtsDisplay* vtsDisplay, int32_t config,
+ const VsyncPeriodChangeConstraints& constraints) {
+ VsyncPeriodChangeTimeline outTimeline;
+ auto status = mComposerClient->setActiveConfigWithConstraints(
+ vtsDisplay->getDisplayId(), config, constraints, &outTimeline);
+ if (!status.isOk()) {
+ return {std::move(status), outTimeline};
+ }
+ return {updateDisplayProperties(vtsDisplay, config), outTimeline};
+}
+
+std::pair<ScopedAStatus, std::vector<DisplayCapability>> VtsComposerClient::getDisplayCapabilities(
+ int64_t display) {
+ std::vector<DisplayCapability> outCapabilities;
+ return {mComposerClient->getDisplayCapabilities(display, &outCapabilities), outCapabilities};
+}
+
+ScopedAStatus VtsComposerClient::dumpDebugInfo() {
+ std::string debugInfo;
+ return mComposer->dumpDebugInfo(&debugInfo);
+}
+
+std::pair<ScopedAStatus, DisplayIdentification> VtsComposerClient::getDisplayIdentificationData(
+ int64_t display) {
+ DisplayIdentification outDisplayIdentification;
+ return {mComposerClient->getDisplayIdentificationData(display, &outDisplayIdentification),
+ outDisplayIdentification};
+}
+
+std::pair<ScopedAStatus, HdrCapabilities> VtsComposerClient::getHdrCapabilities(int64_t display) {
+ HdrCapabilities outHdrCapabilities;
+ return {mComposerClient->getHdrCapabilities(display, &outHdrCapabilities), outHdrCapabilities};
+}
+
+std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>>
+VtsComposerClient::getPerFrameMetadataKeys(int64_t display) {
+ std::vector<PerFrameMetadataKey> outPerFrameMetadataKeys;
+ return {mComposerClient->getPerFrameMetadataKeys(display, &outPerFrameMetadataKeys),
+ outPerFrameMetadataKeys};
+}
+
+std::pair<ScopedAStatus, ReadbackBufferAttributes> VtsComposerClient::getReadbackBufferAttributes(
+ int64_t display) {
+ ReadbackBufferAttributes outReadbackBufferAttributes;
+ return {mComposerClient->getReadbackBufferAttributes(display, &outReadbackBufferAttributes),
+ outReadbackBufferAttributes};
+}
+
+ScopedAStatus VtsComposerClient::setReadbackBuffer(int64_t display, const native_handle_t* buffer,
+ const ScopedFileDescriptor& releaseFence) {
+ return mComposerClient->setReadbackBuffer(display, ::android::dupToAidl(buffer), releaseFence);
+}
+
+std::pair<ScopedAStatus, ScopedFileDescriptor> VtsComposerClient::getReadbackBufferFence(
+ int64_t display) {
+ ScopedFileDescriptor outReleaseFence;
+ return {mComposerClient->getReadbackBufferFence(display, &outReleaseFence),
+ std::move(outReleaseFence)};
+}
+
+std::pair<ScopedAStatus, std::vector<ColorMode>> VtsComposerClient::getColorModes(int64_t display) {
+ std::vector<ColorMode> outColorModes;
+ return {mComposerClient->getColorModes(display, &outColorModes), outColorModes};
+}
+
+std::pair<ScopedAStatus, std::vector<RenderIntent>> VtsComposerClient::getRenderIntents(
+ int64_t display, ColorMode colorMode) {
+ std::vector<RenderIntent> outRenderIntents;
+ return {mComposerClient->getRenderIntents(display, colorMode, &outRenderIntents),
+ outRenderIntents};
+}
+
+ScopedAStatus VtsComposerClient::setColorMode(int64_t display, ColorMode colorMode,
+ RenderIntent renderIntent) {
+ return mComposerClient->setColorMode(display, colorMode, renderIntent);
+}
+
+std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
+VtsComposerClient::getDisplayedContentSamplingAttributes(int64_t display) {
+ DisplayContentSamplingAttributes outAttributes;
+ return {mComposerClient->getDisplayedContentSamplingAttributes(display, &outAttributes),
+ outAttributes};
+}
+
+ScopedAStatus VtsComposerClient::setDisplayedContentSamplingEnabled(
+ int64_t display, bool isEnabled, FormatColorComponent formatColorComponent,
+ int64_t maxFrames) {
+ return mComposerClient->setDisplayedContentSamplingEnabled(display, isEnabled,
+ formatColorComponent, maxFrames);
+}
+
+std::pair<ScopedAStatus, DisplayContentSample> VtsComposerClient::getDisplayedContentSample(
+ int64_t display, int64_t maxFrames, int64_t timestamp) {
+ DisplayContentSample outDisplayContentSample;
+ return {mComposerClient->getDisplayedContentSample(display, maxFrames, timestamp,
+ &outDisplayContentSample),
+ outDisplayContentSample};
+}
+
+std::pair<ScopedAStatus, DisplayConnectionType> VtsComposerClient::getDisplayConnectionType(
+ int64_t display) {
+ DisplayConnectionType outDisplayConnectionType;
+ return {mComposerClient->getDisplayConnectionType(display, &outDisplayConnectionType),
+ outDisplayConnectionType};
+}
+
+std::pair<ScopedAStatus, std::vector<int32_t>> VtsComposerClient::getDisplayConfigs(
+ int64_t display) {
+ std::vector<int32_t> outConfigs;
+ return {mComposerClient->getDisplayConfigs(display, &outConfigs), outConfigs};
+}
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getDisplayVsyncPeriod(int64_t display) {
+ int32_t outVsyncPeriodNanos;
+ return {mComposerClient->getDisplayVsyncPeriod(display, &outVsyncPeriodNanos),
+ outVsyncPeriodNanos};
+}
+
+ScopedAStatus VtsComposerClient::setAutoLowLatencyMode(int64_t display, bool isEnabled) {
+ return mComposerClient->setAutoLowLatencyMode(display, isEnabled);
+}
+
+std::pair<ScopedAStatus, std::vector<ContentType>> VtsComposerClient::getSupportedContentTypes(
+ int64_t display) {
+ std::vector<ContentType> outContentTypes;
+ return {mComposerClient->getSupportedContentTypes(display, &outContentTypes), outContentTypes};
+}
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxVirtualDisplayCount() {
+ int32_t outMaxVirtualDisplayCount;
+ return {mComposerClient->getMaxVirtualDisplayCount(&outMaxVirtualDisplayCount),
+ outMaxVirtualDisplayCount};
+}
+
+std::pair<ScopedAStatus, std::string> VtsComposerClient::getDisplayName(int64_t display) {
+ std::string outDisplayName;
+ return {mComposerClient->getDisplayName(display, &outDisplayName), outDisplayName};
+}
+
+ScopedAStatus VtsComposerClient::setClientTargetSlotCount(int64_t display,
+ int32_t bufferSlotCount) {
+ return mComposerClient->setClientTargetSlotCount(display, bufferSlotCount);
+}
+
+std::pair<ScopedAStatus, std::vector<Capability>> VtsComposerClient::getCapabilities() {
+ std::vector<Capability> outCapabilities;
+ return {mComposer->getCapabilities(&outCapabilities), outCapabilities};
+}
+
+ScopedAStatus VtsComposerClient::setBootDisplayConfig(int64_t display, int32_t config) {
+ return mComposerClient->setBootDisplayConfig(display, config);
+}
+
+ScopedAStatus VtsComposerClient::clearBootDisplayConfig(int64_t display) {
+ return mComposerClient->clearBootDisplayConfig(display);
+}
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getPreferredBootDisplayConfig(
+ int64_t display) {
+ int32_t outConfig;
+ return {mComposerClient->getPreferredBootDisplayConfig(display, &outConfig), outConfig};
+}
+
+std::pair<ScopedAStatus, common::Transform> VtsComposerClient::getDisplayPhysicalOrientation(
+ int64_t display) {
+ common::Transform outDisplayOrientation;
+ return {mComposerClient->getDisplayPhysicalOrientation(display, &outDisplayOrientation),
+ outDisplayOrientation};
+}
+
+ScopedAStatus VtsComposerClient::setIdleTimerEnabled(int64_t display, int32_t timeoutMs) {
+ return mComposerClient->setIdleTimerEnabled(display, timeoutMs);
+}
+
+int32_t VtsComposerClient::getVsyncIdleCount() {
+ return mComposerCallback->getVsyncIdleCount();
+}
+
+int64_t VtsComposerClient::getVsyncIdleTime() {
+ return mComposerCallback->getVsyncIdleTime();
+}
+
+int64_t VtsComposerClient::getInvalidDisplayId() {
+ // 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
+ int64_t id = std::numeric_limits<int64_t>::max();
+ std::vector<int64_t> displays = mComposerCallback->getDisplays();
+ while (id > 0) {
+ if (std::none_of(displays.begin(), displays.end(),
+ [id](const auto& display) { return id == display; })) {
+ return id;
+ }
+ id--;
+ }
+
+ // 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
+ EXPECT_NE(0, id);
+ return id;
+}
+
+std::pair<ScopedAStatus, std::vector<VtsDisplay>> VtsComposerClient::getDisplays() {
+ while (true) {
+ // Sleep for a small period of time to allow all built-in displays
+ // to post hotplug events
+ std::this_thread::sleep_for(5ms);
+ std::vector<int64_t> displays = mComposerCallback->getDisplays();
+ if (displays.empty()) {
+ continue;
+ }
+
+ std::vector<VtsDisplay> vtsDisplays;
+ vtsDisplays.reserve(displays.size());
+ for (int64_t display : displays) {
+ auto vtsDisplay = VtsDisplay{display};
+ auto configs = getDisplayConfigs(display);
+ if (!configs.first.isOk()) {
+ ALOGE("Unable to get the displays for test, failed to get the configs "
+ "for display %" PRId64,
+ display);
+ return {std::move(configs.first), vtsDisplays};
+ }
+ for (int config : configs.second) {
+ auto status = updateDisplayProperties(&vtsDisplay, config);
+ if (!status.isOk()) {
+ ALOGE("Unable to get the displays for test, failed to update the properties "
+ "for display %" PRId64,
+ display);
+ return {std::move(status), vtsDisplays};
+ }
+ }
+ vtsDisplays.emplace_back(vtsDisplay);
+ addDisplayToDisplayResources(display, /*isVirtual*/ false);
+ }
+
+ return {ScopedAStatus::ok(), vtsDisplays};
+ }
+}
+
+ScopedAStatus VtsComposerClient::updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config) {
+ const auto width =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::WIDTH);
+ const auto height =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::HEIGHT);
+ const auto vsyncPeriod =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::VSYNC_PERIOD);
+ const auto configGroup =
+ getDisplayAttribute(vtsDisplay->getDisplayId(), config, DisplayAttribute::CONFIG_GROUP);
+ if (width.first.isOk() && height.first.isOk() && vsyncPeriod.first.isOk() &&
+ configGroup.first.isOk()) {
+ vtsDisplay->setDimensions(width.second, height.second);
+ vtsDisplay->addDisplayConfig(config, {vsyncPeriod.second, configGroup.second});
+ return ScopedAStatus::ok();
+ }
+
+ LOG(ERROR) << "Failed to update display property for width: " << width.first.isOk()
+ << ", height: " << height.first.isOk() << ", vsync: " << vsyncPeriod.first.isOk()
+ << ", config: " << configGroup.first.isOk();
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_CONFIG);
+}
+
+ScopedAStatus VtsComposerClient::addDisplayToDisplayResources(int64_t display, bool isVirtual) {
+ if (mDisplayResources.insert({display, DisplayResource(isVirtual)}).second) {
+ return ScopedAStatus::ok();
+ }
+
+ ALOGE("Duplicate display id %" PRId64, display);
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_DISPLAY);
+}
+
+ScopedAStatus VtsComposerClient::addLayerToDisplayResources(int64_t display, int64_t layer) {
+ auto resource = mDisplayResources.find(display);
+ if (resource == mDisplayResources.end()) {
+ resource = mDisplayResources.insert({display, DisplayResource(false)}).first;
+ }
+
+ if (!resource->second.layers.insert(layer).second) {
+ ALOGE("Duplicate layer id %" PRId64, layer);
+ return ScopedAStatus::fromServiceSpecificError(IComposerClient::EX_BAD_LAYER);
+ }
+ return ScopedAStatus::ok();
+}
+
+void VtsComposerClient::removeLayerFromDisplayResources(int64_t display, int64_t layer) {
+ auto resource = mDisplayResources.find(display);
+ if (resource != mDisplayResources.end()) {
+ resource->second.layers.erase(layer);
+ }
+}
+
+bool VtsComposerClient::verifyComposerCallbackParams() {
+ bool isValid = true;
+ if (mComposerCallback != nullptr) {
+ if (mComposerCallback->getInvalidHotplugCount() != 0) {
+ ALOGE("Invalid hotplug count");
+ isValid = false;
+ }
+ if (mComposerCallback->getInvalidRefreshCount() != 0) {
+ ALOGE("Invalid refresh count");
+ isValid = false;
+ }
+ if (mComposerCallback->getInvalidVsyncCount() != 0) {
+ ALOGE("Invalid vsync count");
+ isValid = false;
+ }
+ if (mComposerCallback->getInvalidVsyncPeriodChangeCount() != 0) {
+ ALOGE("Invalid vsync period change count");
+ isValid = false;
+ }
+ if (mComposerCallback->getInvalidSeamlessPossibleCount() != 0) {
+ ALOGE("Invalid seamless possible count");
+ isValid = false;
+ }
+ }
+ return isValid;
+}
+
+bool VtsComposerClient::destroyAllLayers() {
+ for (const auto& it : mDisplayResources) {
+ const auto& [display, resource] = it;
+
+ for (auto layer : resource.layers) {
+ const auto status = destroyLayer(display, layer);
+ if (!status.isOk()) {
+ ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
+ layer, status.getDescription().c_str());
+ return false;
+ }
+ }
+
+ if (resource.isVirtual) {
+ const auto status = destroyVirtualDisplay(display);
+ if (!status.isOk()) {
+ ALOGE("Unable to destroy the display %" PRId64 " failed with error %s", display,
+ status.getDescription().c_str());
+ return false;
+ }
+ }
+ }
+ mDisplayResources.clear();
+ return true;
+}
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
index f25f36d..ced1020 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/GraphicsComposerCallback.h
@@ -15,18 +15,11 @@
*/
#pragma once
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
#include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h>
#include <android-base/thread_annotations.h>
#include <mutex>
#include <unordered_set>
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion
-
namespace aidl::android::hardware::graphics::composer3::vts {
class GraphicsComposerCallback : public BnComposerCallback {
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
index a3ce795..da2e5c1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h
@@ -20,7 +20,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-#include <GraphicsComposerCallback.h>
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
@@ -28,8 +27,9 @@
#include <mapper-vts/2.1/MapperVts.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>
-
#include <memory>
+#include "GraphicsComposerCallback.h"
+#include "VtsComposerClient.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
index a776a27..4afac68 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/RenderEngineVts.h
@@ -19,7 +19,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-#include <ReadbackVts.h>
#include <mapper-vts/2.1/MapperVts.h>
#include <math/half.h>
#include <math/vec3.h>
@@ -30,6 +29,7 @@
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
+#include "ReadbackVts.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/VtsComposerClient.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/VtsComposerClient.h
new file mode 100644
index 0000000..b53edf8
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/VtsComposerClient.h
@@ -0,0 +1,240 @@
+/**
+ * Copyright (c) 2022, 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.
+ */
+#pragma once
+
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <android-base/properties.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <algorithm>
+#include <numeric>
+#include <string>
+#include <thread>
+#include <unordered_map>
+#include "GraphicsComposerCallback.h"
+
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::FRect;
+using aidl::android::hardware::graphics::common::PixelFormat;
+using aidl::android::hardware::graphics::common::Rect;
+using namespace ::ndk;
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+class VtsDisplay;
+/**
+ * A wrapper to IComposerClient.
+ * This wrapper manages the IComposerClient instance and manages the resources for
+ * the tests with respect to the IComposerClient calls.
+ */
+class VtsComposerClient {
+ public:
+ VtsComposerClient(const std::string& name);
+
+ ScopedAStatus createClient();
+
+ bool tearDown();
+
+ std::pair<ScopedAStatus, VirtualDisplay> createVirtualDisplay(int32_t width, int32_t height,
+ PixelFormat pixelFormat,
+ int32_t bufferSlotCount);
+
+ ScopedAStatus destroyVirtualDisplay(int64_t display);
+
+ std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount);
+
+ ScopedAStatus destroyLayer(int64_t display, int64_t layer);
+
+ std::pair<ScopedAStatus, int32_t> getActiveConfig(int64_t display);
+
+ ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config);
+
+ std::pair<ScopedAStatus, int32_t> getDisplayAttribute(int64_t display, int32_t config,
+ DisplayAttribute displayAttribute);
+
+ ScopedAStatus setPowerMode(int64_t display, PowerMode powerMode);
+
+ ScopedAStatus setVsync(int64_t display, bool enable);
+
+ void setVsyncAllowed(bool isAllowed);
+
+ std::pair<ScopedAStatus, std::vector<float>> getDataspaceSaturationMatrix(Dataspace dataspace);
+
+ std::pair<ScopedAStatus, std::vector<CommandResultPayload>> executeCommands(
+ const std::vector<DisplayCommand>& commands);
+
+ std::optional<VsyncPeriodChangeTimeline> takeLastVsyncPeriodChangeTimeline();
+
+ ScopedAStatus setContentType(int64_t display, ContentType contentType);
+
+ std::pair<ScopedAStatus, VsyncPeriodChangeTimeline> setActiveConfigWithConstraints(
+ VtsDisplay* vtsDisplay, int32_t config,
+ const VsyncPeriodChangeConstraints& constraints);
+
+ std::pair<ScopedAStatus, std::vector<DisplayCapability>> getDisplayCapabilities(
+ int64_t display);
+
+ ScopedAStatus dumpDebugInfo();
+
+ std::pair<ScopedAStatus, DisplayIdentification> getDisplayIdentificationData(int64_t display);
+
+ std::pair<ScopedAStatus, HdrCapabilities> getHdrCapabilities(int64_t display);
+
+ std::pair<ScopedAStatus, std::vector<PerFrameMetadataKey>> getPerFrameMetadataKeys(
+ int64_t display);
+
+ std::pair<ScopedAStatus, ReadbackBufferAttributes> getReadbackBufferAttributes(int64_t display);
+
+ ScopedAStatus setReadbackBuffer(int64_t display, const native_handle_t* buffer,
+ const ScopedFileDescriptor& releaseFence);
+
+ std::pair<ScopedAStatus, ScopedFileDescriptor> getReadbackBufferFence(int64_t display);
+
+ std::pair<ScopedAStatus, std::vector<ColorMode>> getColorModes(int64_t display);
+
+ std::pair<ScopedAStatus, std::vector<RenderIntent>> getRenderIntents(int64_t display,
+ ColorMode colorMode);
+
+ ScopedAStatus setColorMode(int64_t display, ColorMode colorMode, RenderIntent renderIntent);
+
+ std::pair<ScopedAStatus, DisplayContentSamplingAttributes>
+ getDisplayedContentSamplingAttributes(int64_t display);
+
+ ScopedAStatus setDisplayedContentSamplingEnabled(int64_t display, bool isEnabled,
+ FormatColorComponent formatColorComponent,
+ int64_t maxFrames);
+
+ std::pair<ScopedAStatus, DisplayContentSample> getDisplayedContentSample(int64_t display,
+ int64_t maxFrames,
+ int64_t timestamp);
+
+ std::pair<ScopedAStatus, DisplayConnectionType> getDisplayConnectionType(int64_t display);
+
+ std::pair<ScopedAStatus, std::vector<int32_t>> getDisplayConfigs(int64_t display);
+
+ std::pair<ScopedAStatus, int32_t> getDisplayVsyncPeriod(int64_t display);
+
+ ScopedAStatus setAutoLowLatencyMode(int64_t display, bool isEnabled);
+
+ std::pair<ScopedAStatus, std::vector<ContentType>> getSupportedContentTypes(int64_t display);
+
+ std::pair<ScopedAStatus, int32_t> getMaxVirtualDisplayCount();
+
+ std::pair<ScopedAStatus, std::string> getDisplayName(int64_t display);
+
+ ScopedAStatus setClientTargetSlotCount(int64_t display, int32_t bufferSlotCount);
+
+ std::pair<ScopedAStatus, std::vector<Capability>> getCapabilities();
+
+ ScopedAStatus setBootDisplayConfig(int64_t display, int32_t config);
+
+ ScopedAStatus clearBootDisplayConfig(int64_t display);
+
+ std::pair<ScopedAStatus, int32_t> getPreferredBootDisplayConfig(int64_t display);
+
+ std::pair<ScopedAStatus, common::Transform> getDisplayPhysicalOrientation(int64_t display);
+
+ ScopedAStatus setIdleTimerEnabled(int64_t display, int32_t timeoutMs);
+
+ int32_t getVsyncIdleCount();
+
+ int64_t getVsyncIdleTime();
+
+ int64_t getInvalidDisplayId();
+
+ std::pair<ScopedAStatus, std::vector<VtsDisplay>> getDisplays();
+
+ private:
+ ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config);
+
+ ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual);
+
+ ScopedAStatus addLayerToDisplayResources(int64_t display, int64_t layer);
+
+ void removeLayerFromDisplayResources(int64_t display, int64_t layer);
+
+ bool destroyAllLayers();
+
+ bool verifyComposerCallbackParams();
+
+ // Keep track of displays and layers. When a test fails/ends,
+ // the VtsComposerClient::tearDown should be called from the
+ // test tearDown to clean up the resources for the test.
+ struct DisplayResource {
+ DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}
+
+ bool isVirtual;
+ std::unordered_set<int64_t> layers;
+ };
+
+ std::shared_ptr<IComposer> mComposer;
+ std::shared_ptr<IComposerClient> mComposerClient;
+ std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
+ std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+};
+
+class VtsDisplay {
+ public:
+ VtsDisplay(int64_t displayId) : mDisplayId(displayId) {}
+
+ int64_t getDisplayId() const { return mDisplayId; }
+
+ FRect getCrop() const {
+ return {0, 0, static_cast<float>(mDisplayWidth), static_cast<float>(mDisplayHeight)};
+ }
+
+ Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; }
+
+ void setDimensions(int32_t displayWidth, int32_t displayHeight) {
+ mDisplayWidth = displayWidth;
+ mDisplayHeight = displayHeight;
+ }
+
+ int32_t getDisplayWidth() const { return mDisplayWidth; }
+
+ int32_t getDisplayHeight() const { return mDisplayHeight; }
+
+ struct DisplayConfig {
+ DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_)
+ : vsyncPeriod(vsyncPeriod_), configGroup(configGroup_) {}
+ int32_t vsyncPeriod;
+ int32_t configGroup;
+ };
+
+ void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
+ displayConfigs.insert({config, displayConfig});
+ }
+
+ DisplayConfig getDisplayConfig(int32_t config) { return displayConfigs.find(config)->second; }
+
+ private:
+ int64_t mDisplayId;
+ int32_t mDisplayWidth;
+ int32_t mDisplayHeight;
+ std::unordered_map<int32_t, DisplayConfig> displayConfigs;
+};
+} // namespace aidl::android::hardware::graphics::composer3::vts
\ No newline at end of file
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index d429b76..02405ba 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -194,7 +194,7 @@
void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) {
ZOrder zorder;
- zorder.z = z;
+ zorder.z = static_cast<int32_t>(z);
getLayerCommand(display, layer).z.emplace(std::move(zorder));
}
@@ -233,9 +233,9 @@
std::optional<LayerCommand> mLayerCommand;
std::vector<DisplayCommand> mCommands;
- Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) {
+ Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) {
Buffer bufferCommand;
- bufferCommand.slot = slot;
+ bufferCommand.slot = static_cast<int32_t>(slot);
if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle));
if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence);
return bufferCommand;