blob: 6b43cc817f04ae4f3aa9c7c59d595c2db8d1ff49 [file] [log] [blame]
ramindani431aad42022-02-01 21:44:29 +00001/**
2 * Copyright (c) 2022, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sally Qi2600d342022-08-16 12:46:17 -070016
ramindanid32ae8e2021-10-01 18:48:39 +000017#include <aidl/Gtest.h>
18#include <aidl/Vintf.h>
Ady Abraham3192f3d2021-12-03 16:08:56 -080019#include <aidl/android/hardware/graphics/common/BlendMode.h>
ramindani3335f7a2021-10-25 17:22:35 +000020#include <aidl/android/hardware/graphics/common/BufferUsage.h>
21#include <aidl/android/hardware/graphics/common/FRect.h>
Leon Scroggins IIIde057582022-01-13 12:26:00 -050022#include <aidl/android/hardware/graphics/common/PixelFormat.h>
ramindani3335f7a2021-10-25 17:22:35 +000023#include <aidl/android/hardware/graphics/common/Rect.h>
ramindani3335f7a2021-10-25 17:22:35 +000024#include <aidl/android/hardware/graphics/composer3/Composition.h>
Sasha McIntoshd98818c2024-10-31 15:55:19 -040025#include <aidl/android/hardware/graphics/composer3/OutputType.h>
ramindanid32ae8e2021-10-01 18:48:39 +000026#include <aidl/android/hardware/graphics/composer3/IComposer.h>
27#include <android-base/properties.h>
ramindania9780262021-10-01 18:48:39 +000028#include <android/binder_process.h>
Ady Abraham91c9d1a2021-12-15 18:14:45 -080029#include <android/hardware/graphics/composer3/ComposerClientReader.h>
30#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
ramindanid32ae8e2021-10-01 18:48:39 +000031#include <binder/ProcessState.h>
Sally Qi2d94f522024-10-15 12:53:51 -070032#include <cutils/ashmem.h>
Brian Lindahl5054e3b2024-11-20 09:01:52 -070033#include <gmock/gmock.h>
ramindanid32ae8e2021-10-01 18:48:39 +000034#include <gtest/gtest.h>
Ady Abraham72c5b502021-12-10 17:23:39 -080035#include <ui/Fence.h>
ramindani3335f7a2021-10-25 17:22:35 +000036#include <ui/GraphicBuffer.h>
Brian Lindahl9f9d2f02024-10-24 16:23:57 -060037#include <ui/PictureProfileHandle.h>
ramindani3335f7a2021-10-25 17:22:35 +000038#include <ui/PixelFormat.h>
ramindani0291f112021-11-04 03:45:46 +000039#include <algorithm>
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -040040#include <iterator>
Joen Chene0a962c2023-08-28 09:49:11 +000041#include <mutex>
ramindani592b6512021-10-08 21:15:19 +000042#include <numeric>
ramindanid32ae8e2021-10-01 18:48:39 +000043#include <string>
ramindani1cb794e2021-10-13 20:45:23 +000044#include <thread>
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -040045#include <unordered_map>
ramindani458e53e2022-02-23 17:30:16 +000046#include "GraphicsComposerCallback.h"
47#include "VtsComposerClient.h"
ramindani3335f7a2021-10-25 17:22:35 +000048
ramindanid32ae8e2021-10-01 18:48:39 +000049#undef LOG_TAG
50#define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
51
Brian Lindahl5054e3b2024-11-20 09:01:52 -070052using testing::Ge;
53
ramindanid32ae8e2021-10-01 18:48:39 +000054namespace aidl::android::hardware::graphics::composer3::vts {
ramindanid32ae8e2021-10-01 18:48:39 +000055
ramindani1cb794e2021-10-13 20:45:23 +000056using namespace std::chrono_literals;
57
ramindanidcfe3a82021-11-29 17:00:31 +000058using ::android::GraphicBuffer;
59using ::android::sp;
60
ramindanid32ae8e2021-10-01 18:48:39 +000061class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> {
ramindania9780262021-10-01 18:48:39 +000062 protected:
63 void SetUp() override {
ramindani431aad42022-02-01 21:44:29 +000064 mComposerClient = std::make_unique<VtsComposerClient>(GetParam());
65 ASSERT_TRUE(mComposerClient->createClient().isOk());
Jason Macnake531a092022-01-20 08:49:09 -080066
ramindani431aad42022-02-01 21:44:29 +000067 const auto& [status, displays] = mComposerClient->getDisplays();
Jason Macnake531a092022-01-20 08:49:09 -080068 ASSERT_TRUE(status.isOk());
ramindani431aad42022-02-01 21:44:29 +000069 mDisplays = displays;
ramindanidcfe3a82021-11-29 17:00:31 +000070
ramindani3335f7a2021-10-25 17:22:35 +000071 // explicitly disable vsync
72 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +000073 EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), false).isOk());
ramindani3335f7a2021-10-25 17:22:35 +000074 }
ramindani431aad42022-02-01 21:44:29 +000075 mComposerClient->setVsyncAllowed(false);
ramindania9780262021-10-01 18:48:39 +000076 }
77
ramindani3335f7a2021-10-25 17:22:35 +000078 void TearDown() override {
Ady Abrahama00d2462023-12-26 14:21:20 -080079 ASSERT_TRUE(mComposerClient->tearDown(nullptr));
ramindani431aad42022-02-01 21:44:29 +000080 mComposerClient.reset();
ramindani3335f7a2021-10-25 17:22:35 +000081 }
ramindanic2b8d082021-11-06 02:03:50 +000082
ramindanid5751092022-04-22 22:30:20 +000083 void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
84 ASSERT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
85 ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
86 }
87
ramindani431aad42022-02-01 21:44:29 +000088 void Test_setContentTypeForDisplay(int64_t display,
89 const std::vector<ContentType>& supportedContentTypes,
90 ContentType contentType, const char* contentTypeStr) {
91 const bool contentTypeSupport =
92 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
93 contentType) != supportedContentTypes.end();
ramindanidcfe3a82021-11-29 17:00:31 +000094
95 if (!contentTypeSupport) {
ramindani431aad42022-02-01 21:44:29 +000096 const auto& status = mComposerClient->setContentType(display, contentType);
97 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +000098 EXPECT_NO_FATAL_FAILURE(
99 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindanidcfe3a82021-11-29 17:00:31 +0000100 GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
101 << std::to_string(display) << ", skipping test";
102 return;
103 }
104
105 EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
106 EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
107 }
108
ramindani431aad42022-02-01 21:44:29 +0000109 void Test_setContentType(ContentType contentType, const char* contentTypeStr) {
ramindanidcfe3a82021-11-29 17:00:31 +0000110 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000111 const auto& [status, supportedContentTypes] =
112 mComposerClient->getSupportedContentTypes(display.getDisplayId());
113 EXPECT_TRUE(status.isOk());
114 Test_setContentTypeForDisplay(display.getDisplayId(), supportedContentTypes,
115 contentType, contentTypeStr);
ramindanidcfe3a82021-11-29 17:00:31 +0000116 }
117 }
118
Jason Macnak325e8232022-01-24 14:48:55 -0800119 bool hasCapability(Capability capability) {
ramindani431aad42022-02-01 21:44:29 +0000120 const auto& [status, capabilities] = mComposerClient->getCapabilities();
121 EXPECT_TRUE(status.isOk());
Jason Macnak325e8232022-01-24 14:48:55 -0800122 return std::any_of(
123 capabilities.begin(), capabilities.end(),
124 [&](const Capability& activeCapability) { return activeCapability == capability; });
125 }
126
Brian Lindahl9f9d2f02024-10-24 16:23:57 -0600127 bool hasDisplayCapability(int64_t displayId, DisplayCapability capability) {
128 const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(displayId);
129 EXPECT_TRUE(status.isOk());
130 return std::any_of(capabilities.begin(), capabilities.end(),
131 [&](const DisplayCapability& activeCapability) {
132 return activeCapability == capability;
133 });
134 }
135
ramindani17c71102023-03-20 10:51:14 -0700136 int getInterfaceVersion() {
137 const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
138 EXPECT_TRUE(versionStatus.isOk());
139 return version;
140 }
141
ramindani431aad42022-02-01 21:44:29 +0000142 const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
ramindania9780262021-10-01 18:48:39 +0000143
ramindani431aad42022-02-01 21:44:29 +0000144 int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
ramindania9780262021-10-01 18:48:39 +0000145
ramindani431aad42022-02-01 21:44:29 +0000146 int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
ramindani1cb794e2021-10-13 20:45:23 +0000147
ramindani431aad42022-02-01 21:44:29 +0000148 VtsDisplay& getEditablePrimaryDisplay() { return mDisplays[0]; }
ramindani0291f112021-11-04 03:45:46 +0000149
ramindani3335f7a2021-10-25 17:22:35 +0000150 struct TestParameters {
151 nsecs_t delayForChange;
152 bool refreshMiss;
153 };
154
ramindani431aad42022-02-01 21:44:29 +0000155 std::unique_ptr<VtsComposerClient> mComposerClient;
ramindani1cb794e2021-10-13 20:45:23 +0000156 std::vector<VtsDisplay> mDisplays;
ramindani3335f7a2021-10-25 17:22:35 +0000157 // use the slot count usually set by SF
158 static constexpr uint32_t kBufferSlotCount = 64;
ramindanid32ae8e2021-10-01 18:48:39 +0000159};
160
ramindani431aad42022-02-01 21:44:29 +0000161TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities_BadDisplay) {
162 const auto& [status, _] = mComposerClient->getDisplayCapabilities(getInvalidDisplayId());
ramindani5f696942021-10-14 16:24:18 +0000163
ramindani431aad42022-02-01 21:44:29 +0000164 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000165 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindania9780262021-10-01 18:48:39 +0000166}
167
ramindani431aad42022-02-01 21:44:29 +0000168TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities) {
ramindania9780262021-10-01 18:48:39 +0000169 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000170 const auto& [status, capabilities] =
171 mComposerClient->getDisplayCapabilities(display.getDisplayId());
ramindania9780262021-10-01 18:48:39 +0000172
ramindani431aad42022-02-01 21:44:29 +0000173 EXPECT_TRUE(status.isOk());
ramindania9780262021-10-01 18:48:39 +0000174 }
ramindanid32ae8e2021-10-01 18:48:39 +0000175}
176
ramindani2740bac2021-11-24 22:58:32 +0000177TEST_P(GraphicsComposerAidlTest, DumpDebugInfo) {
ramindani431aad42022-02-01 21:44:29 +0000178 ASSERT_TRUE(mComposerClient->dumpDebugInfo().isOk());
ramindani2740bac2021-11-24 22:58:32 +0000179}
180
181TEST_P(GraphicsComposerAidlTest, CreateClientSingleton) {
182 std::shared_ptr<IComposerClient> composerClient;
ramindani431aad42022-02-01 21:44:29 +0000183 const auto& status = mComposerClient->createClient();
ramindani2740bac2021-11-24 22:58:32 +0000184
ramindani431aad42022-02-01 21:44:29 +0000185 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000186 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_NO_RESOURCES));
ramindani2740bac2021-11-24 22:58:32 +0000187}
188
ramindani592b6512021-10-08 21:15:19 +0000189TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
ramindani431aad42022-02-01 21:44:29 +0000190 const auto& [status0, displayIdentification0] =
191 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000192 if (!status0.isOk() && status0.getExceptionCode() == EX_SERVICE_SPECIFIC &&
193 status0.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani431aad42022-02-01 21:44:29 +0000194 GTEST_SUCCEED() << "Display identification data not supported, skipping test";
ramindani592b6512021-10-08 21:15:19 +0000195 return;
196 }
ramindani431aad42022-02-01 21:44:29 +0000197 ASSERT_TRUE(status0.isOk()) << "failed to get display identification data";
ramindani592b6512021-10-08 21:15:19 +0000198 ASSERT_FALSE(displayIdentification0.data.empty());
199
200 constexpr size_t kEdidBlockSize = 128;
201 ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
202 << "EDID blob length is not a multiple of " << kEdidBlockSize;
203
204 const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
205 ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
206 displayIdentification0.data.begin()))
207 << "EDID blob doesn't start with the fixed EDID header";
208 ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
209 displayIdentification0.data.begin() + kEdidBlockSize,
210 static_cast<uint8_t>(0)))
211 << "EDID base block doesn't checksum";
212
ramindani431aad42022-02-01 21:44:29 +0000213 const auto& [status1, displayIdentification1] =
214 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
215 ASSERT_TRUE(status1.isOk());
ramindani592b6512021-10-08 21:15:19 +0000216
217 ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
218 ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
219 std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
220 displayIdentification1.data.begin()))
221 << "data is not stable";
222}
223
224TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
ramindani431aad42022-02-01 21:44:29 +0000225 const auto& [status, hdrCapabilities] =
226 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000227
ramindani431aad42022-02-01 21:44:29 +0000228 ASSERT_TRUE(status.isOk());
229 EXPECT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
ramindani592b6512021-10-08 21:15:19 +0000230}
231
232TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
ramindani431aad42022-02-01 21:44:29 +0000233 const auto& [status, keys] = mComposerClient->getPerFrameMetadataKeys(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000234 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
235 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindanic2b8d082021-11-06 02:03:50 +0000236 GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
237 return;
ramindani592b6512021-10-08 21:15:19 +0000238 }
ramindani431aad42022-02-01 21:44:29 +0000239
240 ASSERT_TRUE(status.isOk());
241 EXPECT_TRUE(keys.size() >= 0);
ramindani592b6512021-10-08 21:15:19 +0000242}
243
244TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000245 const auto& [status, _] = mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000246 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
247 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani431aad42022-02-01 21:44:29 +0000248 GTEST_SUCCEED() << "getReadbackBufferAttributes is not supported";
249 return;
ramindani592b6512021-10-08 21:15:19 +0000250 }
ramindani431aad42022-02-01 21:44:29 +0000251
252 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000253}
254
255TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
ramindani431aad42022-02-01 21:44:29 +0000256 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
257 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000258
ramindani431aad42022-02-01 21:44:29 +0000259 for (auto mode : modes) {
260 const auto& [intentStatus, intents] =
261 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
262 EXPECT_TRUE(intentStatus.isOk());
ramindani592b6512021-10-08 21:15:19 +0000263 bool isHdr;
264 switch (mode) {
265 case ColorMode::BT2100_PQ:
266 case ColorMode::BT2100_HLG:
267 isHdr = true;
268 break;
269 default:
270 isHdr = false;
271 break;
272 }
273 RenderIntent requiredIntent =
274 isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
275
ramindani431aad42022-02-01 21:44:29 +0000276 const auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
ramindani592b6512021-10-08 21:15:19 +0000277 EXPECT_NE(intents.cend(), iter);
278 }
279}
280
ramindani431aad42022-02-01 21:44:29 +0000281TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadDisplay) {
282 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
283 ASSERT_TRUE(status.isOk());
284
ramindani592b6512021-10-08 21:15:19 +0000285 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +0000286 const auto& [intentStatus, _] =
287 mComposerClient->getRenderIntents(getInvalidDisplayId(), mode);
288
289 EXPECT_FALSE(intentStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000290 EXPECT_NO_FATAL_FAILURE(
291 assertServiceSpecificError(intentStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani592b6512021-10-08 21:15:19 +0000292 }
293}
294
ramindani431aad42022-02-01 21:44:29 +0000295TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadParameter) {
296 const auto& [status, _] =
297 mComposerClient->getRenderIntents(getPrimaryDisplayId(), static_cast<ColorMode>(-1));
298
299 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000300 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000301}
302
303TEST_P(GraphicsComposerAidlTest, GetColorModes) {
ramindani431aad42022-02-01 21:44:29 +0000304 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
305 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000306
ramindani431aad42022-02-01 21:44:29 +0000307 const auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
308 EXPECT_NE(colorModes.cend(), native);
ramindani592b6512021-10-08 21:15:19 +0000309}
310
ramindani431aad42022-02-01 21:44:29 +0000311TEST_P(GraphicsComposerAidlTest, GetColorMode_BadDisplay) {
312 const auto& [status, _] = mComposerClient->getColorModes(getInvalidDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000313
ramindani431aad42022-02-01 21:44:29 +0000314 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000315 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani592b6512021-10-08 21:15:19 +0000316}
317
318TEST_P(GraphicsComposerAidlTest, SetColorMode) {
ramindani431aad42022-02-01 21:44:29 +0000319 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
320 EXPECT_TRUE(status.isOk());
321
ramindani592b6512021-10-08 21:15:19 +0000322 for (auto mode : colorModes) {
ramindani431aad42022-02-01 21:44:29 +0000323 const auto& [intentStatus, intents] =
324 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
325 EXPECT_TRUE(intentStatus.isOk()) << "failed to get render intents";
326
ramindani592b6512021-10-08 21:15:19 +0000327 for (auto intent : intents) {
ramindani431aad42022-02-01 21:44:29 +0000328 const auto modeStatus =
329 mComposerClient->setColorMode(getPrimaryDisplayId(), mode, intent);
330 EXPECT_TRUE(modeStatus.isOk() ||
ramindanid5751092022-04-22 22:30:20 +0000331 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
332 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
ramindani592b6512021-10-08 21:15:19 +0000333 << "failed to set color mode";
334 }
335 }
336
ramindani431aad42022-02-01 21:44:29 +0000337 const auto modeStatus = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
338 RenderIntent::COLORIMETRIC);
339 EXPECT_TRUE(modeStatus.isOk() ||
ramindanid5751092022-04-22 22:30:20 +0000340 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
341 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
ramindani592b6512021-10-08 21:15:19 +0000342 << "failed to set color mode";
343}
344
ramindani431aad42022-02-01 21:44:29 +0000345TEST_P(GraphicsComposerAidlTest, SetColorMode_BadDisplay) {
346 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
347 ASSERT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000348
ramindani431aad42022-02-01 21:44:29 +0000349 for (auto mode : colorModes) {
350 const auto& [intentStatus, intents] =
351 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
352 ASSERT_TRUE(intentStatus.isOk()) << "failed to get render intents";
353
354 for (auto intent : intents) {
355 auto const modeStatus =
356 mComposerClient->setColorMode(getInvalidDisplayId(), mode, intent);
357
358 EXPECT_FALSE(modeStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000359 EXPECT_NO_FATAL_FAILURE(
360 assertServiceSpecificError(modeStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani770d7082021-11-30 00:36:42 +0000361 }
362 }
ramindani592b6512021-10-08 21:15:19 +0000363}
364
ramindani431aad42022-02-01 21:44:29 +0000365TEST_P(GraphicsComposerAidlTest, SetColorMode_BadParameter) {
366 auto status = mComposerClient->setColorMode(getPrimaryDisplayId(), static_cast<ColorMode>(-1),
367 RenderIntent::COLORIMETRIC);
ramindani592b6512021-10-08 21:15:19 +0000368
ramindani431aad42022-02-01 21:44:29 +0000369 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000370 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000371
ramindani431aad42022-02-01 21:44:29 +0000372 status = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
373 static_cast<RenderIntent>(-1));
ramindani592b6512021-10-08 21:15:19 +0000374
ramindani431aad42022-02-01 21:44:29 +0000375 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000376 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindani592b6512021-10-08 21:15:19 +0000377}
378
379TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000380 int constexpr kInvalid = -1;
381 const auto& [status, format] =
382 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
ramindani592b6512021-10-08 21:15:19 +0000383
ramindanid5751092022-04-22 22:30:20 +0000384 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
385 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000386 SUCCEED() << "Device does not support optional extension. Test skipped";
387 return;
388 }
389
ramindani431aad42022-02-01 21:44:29 +0000390 ASSERT_TRUE(status.isOk());
391 EXPECT_NE(kInvalid, static_cast<int>(format.format));
392 EXPECT_NE(kInvalid, static_cast<int>(format.dataspace));
393 EXPECT_NE(kInvalid, static_cast<int>(format.componentMask));
ramindani592b6512021-10-08 21:15:19 +0000394};
395
396TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
ramindani431aad42022-02-01 21:44:29 +0000397 int constexpr kMaxFrames = 10;
ramindani592b6512021-10-08 21:15:19 +0000398 FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
ramindani431aad42022-02-01 21:44:29 +0000399 auto status = mComposerClient->setDisplayedContentSamplingEnabled(
400 getPrimaryDisplayId(), /*isEnabled*/ true, enableAllComponents, kMaxFrames);
ramindanid5751092022-04-22 22:30:20 +0000401 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
402 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000403 SUCCEED() << "Device does not support optional extension. Test skipped";
404 return;
405 }
ramindani431aad42022-02-01 21:44:29 +0000406 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000407
ramindani431aad42022-02-01 21:44:29 +0000408 status = mComposerClient->setDisplayedContentSamplingEnabled(
409 getPrimaryDisplayId(), /*isEnabled*/ false, enableAllComponents, kMaxFrames);
410 EXPECT_TRUE(status.isOk());
ramindani592b6512021-10-08 21:15:19 +0000411}
412
413TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
ramindani431aad42022-02-01 21:44:29 +0000414 const auto& [status, displayContentSamplingAttributes] =
415 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
ramindanid5751092022-04-22 22:30:20 +0000416 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
417 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindanideb059e2021-11-18 01:57:25 +0000418 SUCCEED() << "Sampling attributes aren't supported on this device, test skipped";
419 return;
420 }
ramindani592b6512021-10-08 21:15:19 +0000421
ramindani431aad42022-02-01 21:44:29 +0000422 int64_t constexpr kMaxFrames = 10;
423 int64_t constexpr kTimestamp = 0;
424 const auto& [sampleStatus, displayContentSample] = mComposerClient->getDisplayedContentSample(
425 getPrimaryDisplayId(), kMaxFrames, kTimestamp);
ramindanid5751092022-04-22 22:30:20 +0000426 if (!sampleStatus.isOk() && sampleStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
ramindani431aad42022-02-01 21:44:29 +0000427 sampleStatus.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
ramindani592b6512021-10-08 21:15:19 +0000428 SUCCEED() << "Device does not support optional extension. Test skipped";
429 return;
430 }
431
ramindani431aad42022-02-01 21:44:29 +0000432 EXPECT_TRUE(sampleStatus.isOk());
433 const std::vector<std::vector<int64_t>> histogram = {
ramindani592b6512021-10-08 21:15:19 +0000434 displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
435 displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
436
ramindani3335f7a2021-10-25 17:22:35 +0000437 for (size_t i = 0; i < histogram.size(); i++) {
438 const bool shouldHaveHistogram =
439 static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
440 EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
ramindani592b6512021-10-08 21:15:19 +0000441 }
442}
443
ramindani431aad42022-02-01 21:44:29 +0000444TEST_P(GraphicsComposerAidlTest, GetDisplayConnectionType) {
445 const auto& [status, type] = mComposerClient->getDisplayConnectionType(getInvalidDisplayId());
446
447 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000448 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani431aad42022-02-01 21:44:29 +0000449
ramindani0291f112021-11-04 03:45:46 +0000450 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000451 const auto& [connectionTypeStatus, _] =
452 mComposerClient->getDisplayConnectionType(display.getDisplayId());
453 EXPECT_TRUE(connectionTypeStatus.isOk());
ramindani0291f112021-11-04 03:45:46 +0000454 }
455}
456
ramindani431aad42022-02-01 21:44:29 +0000457TEST_P(GraphicsComposerAidlTest, GetDisplayAttribute) {
ramindani0291f112021-11-04 03:45:46 +0000458 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000459 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
460 EXPECT_TRUE(status.isOk());
461
ramindani0291f112021-11-04 03:45:46 +0000462 for (const auto& config : configs) {
463 const std::array<DisplayAttribute, 4> requiredAttributes = {{
464 DisplayAttribute::WIDTH,
465 DisplayAttribute::HEIGHT,
466 DisplayAttribute::VSYNC_PERIOD,
467 DisplayAttribute::CONFIG_GROUP,
468 }};
ramindani0291f112021-11-04 03:45:46 +0000469 for (const auto& attribute : requiredAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000470 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
471 display.getDisplayId(), config, attribute);
472 EXPECT_TRUE(attribStatus.isOk());
ramindani0291f112021-11-04 03:45:46 +0000473 EXPECT_NE(-1, value);
474 }
475
476 const std::array<DisplayAttribute, 2> optionalAttributes = {{
477 DisplayAttribute::DPI_X,
478 DisplayAttribute::DPI_Y,
479 }};
480 for (const auto& attribute : optionalAttributes) {
ramindani431aad42022-02-01 21:44:29 +0000481 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
482 display.getDisplayId(), config, attribute);
ramindanid5751092022-04-22 22:30:20 +0000483 EXPECT_TRUE(attribStatus.isOk() ||
484 (attribStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
485 IComposerClient::EX_UNSUPPORTED ==
486 attribStatus.getServiceSpecificError()));
ramindani0291f112021-11-04 03:45:46 +0000487 }
488 }
489 }
490}
491
ramindani431aad42022-02-01 21:44:29 +0000492TEST_P(GraphicsComposerAidlTest, CheckConfigsAreValid) {
ramindani0291f112021-11-04 03:45:46 +0000493 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000494 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
495 EXPECT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000496
497 EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
498 return config == IComposerClient::INVALID_CONFIGURATION;
499 }));
500 }
501}
502
ramindani431aad42022-02-01 21:44:29 +0000503TEST_P(GraphicsComposerAidlTest, GetDisplayVsyncPeriod_BadDisplay) {
504 const auto& [status, vsyncPeriodNanos] =
505 mComposerClient->getDisplayVsyncPeriod(getInvalidDisplayId());
506
507 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000508 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000509}
510
ramindani431aad42022-02-01 21:44:29 +0000511TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadDisplay) {
ramindani0291f112021-11-04 03:45:46 +0000512 VsyncPeriodChangeConstraints constraints;
ramindani0291f112021-11-04 03:45:46 +0000513 constraints.seamlessRequired = false;
514 constraints.desiredTimeNanos = systemTime();
ramindani431aad42022-02-01 21:44:29 +0000515 auto invalidDisplay = VtsDisplay(getInvalidDisplayId());
ramindani0291f112021-11-04 03:45:46 +0000516
ramindani431aad42022-02-01 21:44:29 +0000517 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
518 &invalidDisplay, /*config*/ 0, constraints);
519
520 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000521 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000522}
523
ramindani431aad42022-02-01 21:44:29 +0000524TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadConfig) {
ramindani0291f112021-11-04 03:45:46 +0000525 VsyncPeriodChangeConstraints constraints;
ramindani0291f112021-11-04 03:45:46 +0000526 constraints.seamlessRequired = false;
527 constraints.desiredTimeNanos = systemTime();
528
529 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000530 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
531 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
532 &display, kInvalidConfigId, constraints);
533
534 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000535 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
ramindani0291f112021-11-04 03:45:46 +0000536 }
537}
538
ramindani431aad42022-02-01 21:44:29 +0000539TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000540 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
541 GTEST_SUCCEED() << "Boot Display Config not supported";
542 return;
543 }
ramindani431aad42022-02-01 21:44:29 +0000544 const auto& status = mComposerClient->setBootDisplayConfig(getInvalidDisplayId(), /*config*/ 0);
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100545
ramindani431aad42022-02-01 21:44:29 +0000546 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000547 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100548}
549
ramindani431aad42022-02-01 21:44:29 +0000550TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadConfig) {
ramindani476314c2022-03-16 00:17:08 +0000551 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
552 GTEST_SUCCEED() << "Boot Display Config not supported";
553 return;
554 }
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100555 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000556 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
557 const auto& status =
558 mComposerClient->setBootDisplayConfig(display.getDisplayId(), kInvalidConfigId);
559
560 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000561 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100562 }
563}
564
ramindani431aad42022-02-01 21:44:29 +0000565TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000566 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
567 GTEST_SUCCEED() << "Boot Display Config not supported";
568 return;
569 }
ramindani431aad42022-02-01 21:44:29 +0000570 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
571 EXPECT_TRUE(status.isOk());
572 for (const auto& config : configs) {
573 EXPECT_TRUE(mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config).isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100574 }
575}
576
ramindani431aad42022-02-01 21:44:29 +0000577TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000578 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
579 GTEST_SUCCEED() << "Boot Display Config not supported";
580 return;
581 }
ramindani431aad42022-02-01 21:44:29 +0000582 const auto& status = mComposerClient->clearBootDisplayConfig(getInvalidDisplayId());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100583
ramindani431aad42022-02-01 21:44:29 +0000584 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000585 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100586}
587
ramindani431aad42022-02-01 21:44:29 +0000588TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000589 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
590 GTEST_SUCCEED() << "Boot Display Config not supported";
591 return;
592 }
ramindani431aad42022-02-01 21:44:29 +0000593 EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId()).isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100594}
595
ramindani431aad42022-02-01 21:44:29 +0000596TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig_BadDisplay) {
ramindani476314c2022-03-16 00:17:08 +0000597 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
598 GTEST_SUCCEED() << "Boot Display Config not supported";
599 return;
600 }
ramindani431aad42022-02-01 21:44:29 +0000601 const auto& [status, _] = mComposerClient->getPreferredBootDisplayConfig(getInvalidDisplayId());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100602
ramindani431aad42022-02-01 21:44:29 +0000603 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000604 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100605}
606
ramindani431aad42022-02-01 21:44:29 +0000607TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig) {
ramindani476314c2022-03-16 00:17:08 +0000608 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
609 GTEST_SUCCEED() << "Boot Display Config not supported";
610 return;
611 }
ramindani431aad42022-02-01 21:44:29 +0000612 const auto& [status, preferredDisplayConfig] =
613 mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId());
614 EXPECT_TRUE(status.isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100615
ramindani431aad42022-02-01 21:44:29 +0000616 const auto& [configStatus, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
617
618 EXPECT_TRUE(configStatus.isOk());
Kriti Dang4c6e9eb2021-11-17 14:56:29 +0100619 EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig));
620}
621
ramindani476314c2022-03-16 00:17:08 +0000622TEST_P(GraphicsComposerAidlTest, BootDisplayConfig_Unsupported) {
623 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
624 const auto& [configStatus, config] =
625 mComposerClient->getActiveConfig(getPrimaryDisplayId());
626 EXPECT_TRUE(configStatus.isOk());
627
628 auto status = mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config);
629 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000630 EXPECT_NO_FATAL_FAILURE(
631 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000632
633 status = mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId()).first;
634 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000635 EXPECT_NO_FATAL_FAILURE(
636 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000637
638 status = mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId());
639 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000640 EXPECT_NO_FATAL_FAILURE(
641 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani476314c2022-03-16 00:17:08 +0000642 }
643}
644
Kriti Dang3793ebd2022-12-05 13:03:49 +0100645TEST_P(GraphicsComposerAidlTest, GetHdrConversionCapabilities) {
646 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
647 GTEST_SUCCEED() << "HDR output conversion not supported";
648 return;
649 }
650 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
651 EXPECT_TRUE(status.isOk());
652}
653
654TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Passthrough) {
655 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
656 GTEST_SUCCEED() << "HDR output conversion not supported";
657 return;
658 }
659 common::HdrConversionStrategy hdrConversionStrategy;
660 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::passthrough>(true);
Kriti Dang37622762023-02-09 18:15:37 +0100661 const auto& [status, preferredHdrOutputType] =
662 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100663 EXPECT_TRUE(status.isOk());
Kriti Dang37622762023-02-09 18:15:37 +0100664 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100665}
666
667TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) {
668 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
669 GTEST_SUCCEED() << "HDR output conversion not supported";
670 return;
671 }
672 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
Kriti Dang79bbec92023-05-04 17:54:26 +0200673 const auto& [status2, hdrCapabilities] =
674 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
675 const auto& hdrTypes = hdrCapabilities.types;
Kriti Dang3793ebd2022-12-05 13:03:49 +0100676 for (auto conversionCapability : conversionCapabilities) {
Kriti Dang5fcddd72023-03-07 14:55:51 +0100677 if (conversionCapability.outputType != common::Hdr::INVALID) {
Kriti Dang79bbec92023-05-04 17:54:26 +0200678 if (std::find(hdrTypes.begin(), hdrTypes.end(), conversionCapability.outputType) ==
679 hdrTypes.end()) {
680 continue;
681 }
Kriti Dang3793ebd2022-12-05 13:03:49 +0100682 common::HdrConversionStrategy hdrConversionStrategy;
683 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>(
Kriti Dang5fcddd72023-03-07 14:55:51 +0100684 conversionCapability.outputType);
Kriti Dang37622762023-02-09 18:15:37 +0100685 const auto& [statusSet, preferredHdrOutputType] =
Kriti Dang3793ebd2022-12-05 13:03:49 +0100686 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
Kriti Dang37622762023-02-09 18:15:37 +0100687 EXPECT_TRUE(statusSet.isOk());
688 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100689 }
690 }
691}
692
693TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) {
694 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
695 GTEST_SUCCEED() << "HDR output conversion not supported";
696 return;
697 }
698 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
Kriti Dang79bbec92023-05-04 17:54:26 +0200699 const auto& [status2, hdrCapabilities] =
700 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
701 if (hdrCapabilities.types.size() <= 0) {
702 return;
703 }
Kriti Dang3793ebd2022-12-05 13:03:49 +0100704 std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes;
705 for (auto conversionCapability : conversionCapabilities) {
Kriti Dang5fcddd72023-03-07 14:55:51 +0100706 if (conversionCapability.outputType != common::Hdr::INVALID) {
707 autoHdrTypes.push_back(conversionCapability.outputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100708 }
709 }
710 common::HdrConversionStrategy hdrConversionStrategy;
711 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::autoAllowedHdrTypes>(
712 autoHdrTypes);
Kriti Dang37622762023-02-09 18:15:37 +0100713 const auto& [statusSet, preferredHdrOutputType] =
714 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
715 EXPECT_TRUE(statusSet.isOk());
716 EXPECT_NE(common::Hdr::INVALID, preferredHdrOutputType);
Kriti Dang3793ebd2022-12-05 13:03:49 +0100717}
718
ramindani431aad42022-02-01 21:44:29 +0000719TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode_BadDisplay) {
720 auto status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ true);
721 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000722 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani431aad42022-02-01 21:44:29 +0000723
724 status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ false);
725 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000726 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000727}
728
ramindani431aad42022-02-01 21:44:29 +0000729TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode) {
ramindani0291f112021-11-04 03:45:46 +0000730 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000731 const auto& [status, capabilities] =
732 mComposerClient->getDisplayCapabilities(display.getDisplayId());
733 ASSERT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000734
735 const bool allmSupport =
736 std::find(capabilities.begin(), capabilities.end(),
737 DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
738
739 if (!allmSupport) {
ramindani431aad42022-02-01 21:44:29 +0000740 const auto& statusIsOn = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
741 /*isEnabled*/ true);
742 EXPECT_FALSE(statusIsOn.isOk());
ramindanid5751092022-04-22 22:30:20 +0000743 EXPECT_NO_FATAL_FAILURE(
744 assertServiceSpecificError(statusIsOn, IComposerClient::EX_UNSUPPORTED));
ramindani431aad42022-02-01 21:44:29 +0000745 const auto& statusIsOff = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
746 /*isEnabled*/ false);
747 EXPECT_FALSE(statusIsOff.isOk());
ramindanid5751092022-04-22 22:30:20 +0000748 EXPECT_NO_FATAL_FAILURE(
749 assertServiceSpecificError(statusIsOff, IComposerClient::EX_UNSUPPORTED));
ramindani0291f112021-11-04 03:45:46 +0000750 GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
ramindani431aad42022-02-01 21:44:29 +0000751 << std::to_string(display.getDisplayId()) << ", skipping test";
ramindani0291f112021-11-04 03:45:46 +0000752 return;
753 }
754
ramindani431aad42022-02-01 21:44:29 +0000755 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), true).isOk());
756 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), false).isOk());
ramindani0291f112021-11-04 03:45:46 +0000757 }
758}
759
ramindani431aad42022-02-01 21:44:29 +0000760TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes_BadDisplay) {
761 const auto& [status, _] = mComposerClient->getSupportedContentTypes(getInvalidDisplayId());
762
763 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000764 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000765}
766
ramindani431aad42022-02-01 21:44:29 +0000767TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes) {
ramindani0291f112021-11-04 03:45:46 +0000768 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000769 const auto& [status, supportedContentTypes] =
770 mComposerClient->getSupportedContentTypes(display.getDisplayId());
771 ASSERT_TRUE(status.isOk());
ramindani0291f112021-11-04 03:45:46 +0000772
773 const bool noneSupported =
774 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
775 ContentType::NONE) != supportedContentTypes.end();
ramindani431aad42022-02-01 21:44:29 +0000776
ramindani0291f112021-11-04 03:45:46 +0000777 EXPECT_FALSE(noneSupported);
778 }
779}
780
ramindani431aad42022-02-01 21:44:29 +0000781TEST_P(GraphicsComposerAidlTest, SetContentTypeNoneAlwaysAccepted) {
ramindani0291f112021-11-04 03:45:46 +0000782 for (const auto& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +0000783 EXPECT_TRUE(
784 mComposerClient->setContentType(display.getDisplayId(), ContentType::NONE).isOk());
ramindani0291f112021-11-04 03:45:46 +0000785 }
786}
787
ramindani431aad42022-02-01 21:44:29 +0000788TEST_P(GraphicsComposerAidlTest, SetContentType_BadDisplay) {
ramindani0291f112021-11-04 03:45:46 +0000789 constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
790 ContentType::CINEMA, ContentType::GAME};
791 for (const auto& type : types) {
ramindani431aad42022-02-01 21:44:29 +0000792 const auto& status = mComposerClient->setContentType(getInvalidDisplayId(), type);
ramindani0291f112021-11-04 03:45:46 +0000793
ramindani431aad42022-02-01 21:44:29 +0000794 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000795 EXPECT_NO_FATAL_FAILURE(
796 assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani0291f112021-11-04 03:45:46 +0000797 }
798}
799
ramindani431aad42022-02-01 21:44:29 +0000800TEST_P(GraphicsComposerAidlTest, SetGraphicsContentType) {
ramindani0291f112021-11-04 03:45:46 +0000801 Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
802}
803
ramindani431aad42022-02-01 21:44:29 +0000804TEST_P(GraphicsComposerAidlTest, SetPhotoContentType) {
ramindani0291f112021-11-04 03:45:46 +0000805 Test_setContentType(ContentType::PHOTO, "PHOTO");
806}
807
ramindani431aad42022-02-01 21:44:29 +0000808TEST_P(GraphicsComposerAidlTest, SetCinemaContentType) {
ramindani0291f112021-11-04 03:45:46 +0000809 Test_setContentType(ContentType::CINEMA, "CINEMA");
810}
811
ramindani431aad42022-02-01 21:44:29 +0000812TEST_P(GraphicsComposerAidlTest, SetGameContentType) {
ramindani0291f112021-11-04 03:45:46 +0000813 Test_setContentType(ContentType::GAME, "GAME");
814}
815
ramindanic2b8d082021-11-06 02:03:50 +0000816TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
ramindani431aad42022-02-01 21:44:29 +0000817 const auto& [status, maxVirtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
818 EXPECT_TRUE(status.isOk());
819
ramindanic2b8d082021-11-06 02:03:50 +0000820 if (maxVirtualDisplayCount == 0) {
821 GTEST_SUCCEED() << "no virtual display support";
822 return;
823 }
824
ramindani431aad42022-02-01 21:44:29 +0000825 const auto& [virtualDisplayStatus, virtualDisplay] = mComposerClient->createVirtualDisplay(
826 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
827 kBufferSlotCount);
ramindanic2b8d082021-11-06 02:03:50 +0000828
ramindani431aad42022-02-01 21:44:29 +0000829 ASSERT_TRUE(virtualDisplayStatus.isOk());
ramindanic2b8d082021-11-06 02:03:50 +0000830 EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
831}
832
ramindani431aad42022-02-01 21:44:29 +0000833TEST_P(GraphicsComposerAidlTest, DestroyVirtualDisplay_BadDisplay) {
834 const auto& [status, maxDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
835 EXPECT_TRUE(status.isOk());
836
ramindani2740bac2021-11-24 22:58:32 +0000837 if (maxDisplayCount == 0) {
838 GTEST_SUCCEED() << "no virtual display support";
839 return;
840 }
ramindani2740bac2021-11-24 22:58:32 +0000841
ramindani431aad42022-02-01 21:44:29 +0000842 const auto& destroyStatus = mComposerClient->destroyVirtualDisplay(getInvalidDisplayId());
843
844 EXPECT_FALSE(destroyStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000845 EXPECT_NO_FATAL_FAILURE(
846 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000847}
848
849TEST_P(GraphicsComposerAidlTest, CreateLayer) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800850 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
851 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
852 return;
853 }
854
ramindani431aad42022-02-01 21:44:29 +0000855 const auto& [status, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -0800856 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000857
ramindani431aad42022-02-01 21:44:29 +0000858 EXPECT_TRUE(status.isOk());
Ady Abrahama00d2462023-12-26 14:21:20 -0800859 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000860}
861
ramindani431aad42022-02-01 21:44:29 +0000862TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800863 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
864 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
865 return;
866 }
867
868 const auto& [status, _] =
869 mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000870
ramindani431aad42022-02-01 21:44:29 +0000871 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000872 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000873}
874
ramindani431aad42022-02-01 21:44:29 +0000875TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800876 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
877 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
878 return;
879 }
880
ramindani431aad42022-02-01 21:44:29 +0000881 const auto& [status, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -0800882 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
ramindani431aad42022-02-01 21:44:29 +0000883 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000884
Ady Abrahama00d2462023-12-26 14:21:20 -0800885 const auto& destroyStatus =
886 mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000887
ramindani431aad42022-02-01 21:44:29 +0000888 EXPECT_FALSE(destroyStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +0000889 EXPECT_NO_FATAL_FAILURE(
890 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
Ady Abrahama00d2462023-12-26 14:21:20 -0800891 ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000892}
893
ramindani431aad42022-02-01 21:44:29 +0000894TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
Ady Abrahama00d2462023-12-26 14:21:20 -0800895 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
896 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
897 return;
898 }
899
ramindani2740bac2021-11-24 22:58:32 +0000900 // We haven't created any layers yet, so any id should be invalid
Ady Abrahama00d2462023-12-26 14:21:20 -0800901 const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
ramindani2740bac2021-11-24 22:58:32 +0000902
ramindani431aad42022-02-01 21:44:29 +0000903 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000904 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
ramindani2740bac2021-11-24 22:58:32 +0000905}
906
ramindani431aad42022-02-01 21:44:29 +0000907TEST_P(GraphicsComposerAidlTest, GetActiveConfig_BadDisplay) {
908 const auto& [status, _] = mComposerClient->getActiveConfig(getInvalidDisplayId());
ramindani2740bac2021-11-24 22:58:32 +0000909
ramindani431aad42022-02-01 21:44:29 +0000910 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000911 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000912}
913
914TEST_P(GraphicsComposerAidlTest, GetDisplayConfig) {
ramindani431aad42022-02-01 21:44:29 +0000915 const auto& [status, _] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
916 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000917}
918
ramindani431aad42022-02-01 21:44:29 +0000919TEST_P(GraphicsComposerAidlTest, GetDisplayConfig_BadDisplay) {
920 const auto& [status, _] = mComposerClient->getDisplayConfigs(getInvalidDisplayId());
ramindani2740bac2021-11-24 22:58:32 +0000921
ramindani431aad42022-02-01 21:44:29 +0000922 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000923 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindani2740bac2021-11-24 22:58:32 +0000924}
925
926TEST_P(GraphicsComposerAidlTest, GetDisplayName) {
ramindani431aad42022-02-01 21:44:29 +0000927 const auto& [status, _] = mComposerClient->getDisplayName(getPrimaryDisplayId());
928 EXPECT_TRUE(status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000929}
930
ramindani431aad42022-02-01 21:44:29 +0000931TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation_BadDisplay) {
932 const auto& [status, _] = mComposerClient->getDisplayPhysicalOrientation(getInvalidDisplayId());
Ady Abrahamae12e382022-01-13 18:06:21 -0800933
ramindani431aad42022-02-01 21:44:29 +0000934 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000935 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
Ady Abrahamae12e382022-01-13 18:06:21 -0800936}
937
938TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation) {
939 const auto allowedDisplayOrientations = std::array<Transform, 4>{
940 Transform::NONE,
941 Transform::ROT_90,
942 Transform::ROT_180,
943 Transform::ROT_270,
944 };
945
ramindani431aad42022-02-01 21:44:29 +0000946 const auto& [status, displayOrientation] =
947 mComposerClient->getDisplayPhysicalOrientation(getPrimaryDisplayId());
Ady Abrahamae12e382022-01-13 18:06:21 -0800948
ramindani431aad42022-02-01 21:44:29 +0000949 EXPECT_TRUE(status.isOk());
Ady Abrahamae12e382022-01-13 18:06:21 -0800950 EXPECT_NE(std::find(allowedDisplayOrientations.begin(), allowedDisplayOrientations.end(),
951 displayOrientation),
952 allowedDisplayOrientations.end());
953}
954
ramindani2740bac2021-11-24 22:58:32 +0000955TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) {
ramindani431aad42022-02-01 21:44:29 +0000956 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
957 .isOk());
ramindani2740bac2021-11-24 22:58:32 +0000958}
959
960TEST_P(GraphicsComposerAidlTest, SetActiveConfig) {
ramindani431aad42022-02-01 21:44:29 +0000961 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
962 EXPECT_TRUE(status.isOk());
963
964 for (const auto& config : configs) {
965 auto display = getEditablePrimaryDisplay();
966 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
967 const auto& [configStatus, config1] =
968 mComposerClient->getActiveConfig(getPrimaryDisplayId());
969 EXPECT_TRUE(configStatus.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000970 EXPECT_EQ(config, config1);
971 }
972}
973
974TEST_P(GraphicsComposerAidlTest, SetActiveConfigPowerCycle) {
ramindani431aad42022-02-01 21:44:29 +0000975 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
976 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindani2740bac2021-11-24 22:58:32 +0000977
ramindani431aad42022-02-01 21:44:29 +0000978 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
979 EXPECT_TRUE(status.isOk());
980
981 for (const auto& config : configs) {
982 auto display = getEditablePrimaryDisplay();
983 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
984 const auto& [config1Status, config1] =
985 mComposerClient->getActiveConfig(getPrimaryDisplayId());
986 EXPECT_TRUE(config1Status.isOk());
ramindani2740bac2021-11-24 22:58:32 +0000987 EXPECT_EQ(config, config1);
988
ramindani431aad42022-02-01 21:44:29 +0000989 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
990 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
991 const auto& [config2Status, config2] =
992 mComposerClient->getActiveConfig(getPrimaryDisplayId());
993 EXPECT_TRUE(config2Status.isOk());
994 EXPECT_EQ(config, config2);
ramindani2740bac2021-11-24 22:58:32 +0000995 }
996}
997
ramindani2740bac2021-11-24 22:58:32 +0000998TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
ramindani431aad42022-02-01 21:44:29 +0000999 const auto& [status, capabilities] =
1000 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1001 ASSERT_TRUE(status.isOk());
1002
Ady Abraham6679baf2021-12-08 18:28:27 -08001003 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1004 DisplayCapability::DOZE) != capabilities.end();
1005 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1006 DisplayCapability::SUSPEND) != capabilities.end();
ramindani2740bac2021-11-24 22:58:32 +00001007
ramindani431aad42022-02-01 21:44:29 +00001008 if (!isDozeSupported) {
1009 const auto& powerModeDozeStatus =
1010 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE);
1011 EXPECT_FALSE(powerModeDozeStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001012 EXPECT_NO_FATAL_FAILURE(
1013 assertServiceSpecificError(powerModeDozeStatus, IComposerClient::EX_UNSUPPORTED));
ramindani431aad42022-02-01 21:44:29 +00001014
1015 const auto& powerModeDozeSuspendStatus =
1016 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1017 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001018 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1019 IComposerClient::EX_UNSUPPORTED));
ramindani2740bac2021-11-24 22:58:32 +00001020 }
Ady Abraham6679baf2021-12-08 18:28:27 -08001021
1022 if (!isSuspendSupported) {
ramindani431aad42022-02-01 21:44:29 +00001023 const auto& powerModeSuspendStatus =
1024 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON_SUSPEND);
1025 EXPECT_FALSE(powerModeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001026 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeSuspendStatus,
1027 IComposerClient::EX_UNSUPPORTED));
Ady Abraham6679baf2021-12-08 18:28:27 -08001028
ramindani431aad42022-02-01 21:44:29 +00001029 const auto& powerModeDozeSuspendStatus =
1030 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1031 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
ramindanid5751092022-04-22 22:30:20 +00001032 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1033 IComposerClient::EX_UNSUPPORTED));
Ady Abraham6679baf2021-12-08 18:28:27 -08001034 }
ramindani2740bac2021-11-24 22:58:32 +00001035}
1036
1037TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
ramindani431aad42022-02-01 21:44:29 +00001038 mComposerClient->setVsyncAllowed(true);
ramindani2740bac2021-11-24 22:58:32 +00001039
ramindani431aad42022-02-01 21:44:29 +00001040 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), true).isOk());
ramindani2740bac2021-11-24 22:58:32 +00001041 usleep(60 * 1000);
ramindani431aad42022-02-01 21:44:29 +00001042 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), false).isOk());
ramindani2740bac2021-11-24 22:58:32 +00001043
ramindani431aad42022-02-01 21:44:29 +00001044 mComposerClient->setVsyncAllowed(false);
ramindani2740bac2021-11-24 22:58:32 +00001045}
1046
ramindanic2b8d082021-11-06 02:03:50 +00001047TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
ramindani431aad42022-02-01 21:44:29 +00001048 const auto& [status, capabilities] =
1049 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1050 ASSERT_TRUE(status.isOk());
1051
Ady Abraham6679baf2021-12-08 18:28:27 -08001052 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1053 DisplayCapability::DOZE) != capabilities.end();
1054 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1055 DisplayCapability::SUSPEND) != capabilities.end();
1056
ramindanic2b8d082021-11-06 02:03:50 +00001057 std::vector<PowerMode> modes;
1058 modes.push_back(PowerMode::OFF);
ramindanic2b8d082021-11-06 02:03:50 +00001059 modes.push_back(PowerMode::ON);
1060
Ady Abraham6679baf2021-12-08 18:28:27 -08001061 if (isSuspendSupported) {
1062 modes.push_back(PowerMode::ON_SUSPEND);
1063 }
1064
ramindani770d7082021-11-30 00:36:42 +00001065 if (isDozeSupported) {
1066 modes.push_back(PowerMode::DOZE);
Ady Abraham6679baf2021-12-08 18:28:27 -08001067 }
1068
1069 if (isSuspendSupported && isDozeSupported) {
ramindani770d7082021-11-30 00:36:42 +00001070 modes.push_back(PowerMode::DOZE_SUSPEND);
1071 }
1072
ramindanic2b8d082021-11-06 02:03:50 +00001073 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001074 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001075 }
1076}
1077
1078TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
ramindani431aad42022-02-01 21:44:29 +00001079 const auto& [status, capabilities] =
1080 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1081 ASSERT_TRUE(status.isOk());
1082
Ady Abraham6679baf2021-12-08 18:28:27 -08001083 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1084 DisplayCapability::DOZE) != capabilities.end();
1085 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1086 DisplayCapability::SUSPEND) != capabilities.end();
1087
ramindanic2b8d082021-11-06 02:03:50 +00001088 std::vector<PowerMode> modes;
1089
1090 modes.push_back(PowerMode::OFF);
ramindani770d7082021-11-30 00:36:42 +00001091 modes.push_back(PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001092 modes.push_back(PowerMode::OFF);
ramindanic2b8d082021-11-06 02:03:50 +00001093 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001094 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001095 }
ramindani770d7082021-11-30 00:36:42 +00001096 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001097
ramindani770d7082021-11-30 00:36:42 +00001098 modes.push_back(PowerMode::OFF);
1099 modes.push_back(PowerMode::OFF);
1100 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001101 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindani770d7082021-11-30 00:36:42 +00001102 }
ramindanic2b8d082021-11-06 02:03:50 +00001103 modes.clear();
1104
1105 modes.push_back(PowerMode::ON);
1106 modes.push_back(PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001107 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001108 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001109 }
ramindanic2b8d082021-11-06 02:03:50 +00001110 modes.clear();
1111
Ady Abraham6679baf2021-12-08 18:28:27 -08001112 if (isSuspendSupported) {
1113 modes.push_back(PowerMode::ON_SUSPEND);
1114 modes.push_back(PowerMode::ON_SUSPEND);
1115 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001116 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
Ady Abraham6679baf2021-12-08 18:28:27 -08001117 }
1118 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001119 }
1120
ramindanic2b8d082021-11-06 02:03:50 +00001121 if (isDozeSupported) {
ramindanic2b8d082021-11-06 02:03:50 +00001122 modes.push_back(PowerMode::DOZE);
1123 modes.push_back(PowerMode::DOZE);
ramindanic2b8d082021-11-06 02:03:50 +00001124 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001125 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001126 }
ramindanic2b8d082021-11-06 02:03:50 +00001127 modes.clear();
Ady Abraham6679baf2021-12-08 18:28:27 -08001128 }
ramindanic2b8d082021-11-06 02:03:50 +00001129
Ady Abraham6679baf2021-12-08 18:28:27 -08001130 if (isSuspendSupported && isDozeSupported) {
ramindanic2b8d082021-11-06 02:03:50 +00001131 modes.push_back(PowerMode::DOZE_SUSPEND);
1132 modes.push_back(PowerMode::DOZE_SUSPEND);
ramindanic2b8d082021-11-06 02:03:50 +00001133 for (auto mode : modes) {
ramindani431aad42022-02-01 21:44:29 +00001134 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
ramindanic2b8d082021-11-06 02:03:50 +00001135 }
Ady Abraham6679baf2021-12-08 18:28:27 -08001136 modes.clear();
ramindanic2b8d082021-11-06 02:03:50 +00001137 }
1138}
1139
ramindani431aad42022-02-01 21:44:29 +00001140TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadDisplay) {
1141 const auto& status = mComposerClient->setPowerMode(getInvalidDisplayId(), PowerMode::ON);
ramindanic2b8d082021-11-06 02:03:50 +00001142
ramindani431aad42022-02-01 21:44:29 +00001143 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001144 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindanic2b8d082021-11-06 02:03:50 +00001145}
1146
ramindani431aad42022-02-01 21:44:29 +00001147TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadParameter) {
1148 const auto& status =
1149 mComposerClient->setPowerMode(getPrimaryDisplayId(), static_cast<PowerMode>(-1));
ramindanic2b8d082021-11-06 02:03:50 +00001150
ramindani431aad42022-02-01 21:44:29 +00001151 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001152 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindanic2b8d082021-11-06 02:03:50 +00001153}
1154
ramindanic2b8d082021-11-06 02:03:50 +00001155TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
ramindani431aad42022-02-01 21:44:29 +00001156 const auto& [status, matrix] =
1157 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR);
1158 ASSERT_TRUE(status.isOk());
1159 ASSERT_EQ(16, matrix.size()); // matrix should not be empty if call succeeded.
ramindanideb059e2021-11-18 01:57:25 +00001160
ramindanic2b8d082021-11-06 02:03:50 +00001161 // the last row is known
ramindani431aad42022-02-01 21:44:29 +00001162 EXPECT_EQ(0.0f, matrix[12]);
1163 EXPECT_EQ(0.0f, matrix[13]);
1164 EXPECT_EQ(0.0f, matrix[14]);
1165 EXPECT_EQ(1.0f, matrix[15]);
ramindanic2b8d082021-11-06 02:03:50 +00001166}
1167
ramindani431aad42022-02-01 21:44:29 +00001168TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix_BadParameter) {
1169 const auto& [status, matrix] =
1170 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::UNKNOWN);
ramindanic2b8d082021-11-06 02:03:50 +00001171
ramindani431aad42022-02-01 21:44:29 +00001172 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00001173 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindanic2b8d082021-11-06 02:03:50 +00001174}
1175
ramindani12423f52023-06-14 20:04:51 -07001176/*
1177 * Test that no two display configs are exactly the same.
1178 */
1179TEST_P(GraphicsComposerAidlTest, GetDisplayConfigNoRepetitions) {
1180 for (const auto& display : mDisplays) {
1181 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
1182 for (std::vector<int>::size_type i = 0; i < configs.size(); i++) {
1183 for (std::vector<int>::size_type j = i + 1; j < configs.size(); j++) {
1184 const auto& [widthStatus1, width1] = mComposerClient->getDisplayAttribute(
1185 display.getDisplayId(), configs[i], DisplayAttribute::WIDTH);
1186 const auto& [heightStatus1, height1] = mComposerClient->getDisplayAttribute(
1187 display.getDisplayId(), configs[i], DisplayAttribute::HEIGHT);
1188 const auto& [vsyncPeriodStatus1, vsyncPeriod1] =
1189 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[i],
1190 DisplayAttribute::VSYNC_PERIOD);
1191 const auto& [groupStatus1, group1] = mComposerClient->getDisplayAttribute(
1192 display.getDisplayId(), configs[i], DisplayAttribute::CONFIG_GROUP);
1193
1194 const auto& [widthStatus2, width2] = mComposerClient->getDisplayAttribute(
1195 display.getDisplayId(), configs[j], DisplayAttribute::WIDTH);
1196 const auto& [heightStatus2, height2] = mComposerClient->getDisplayAttribute(
1197 display.getDisplayId(), configs[j], DisplayAttribute::HEIGHT);
1198 const auto& [vsyncPeriodStatus2, vsyncPeriod2] =
1199 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[j],
1200 DisplayAttribute::VSYNC_PERIOD);
1201 const auto& [groupStatus2, group2] = mComposerClient->getDisplayAttribute(
1202 display.getDisplayId(), configs[j], DisplayAttribute::CONFIG_GROUP);
1203
1204 ASSERT_FALSE(width1 == width2 && height1 == height2 &&
1205 vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
1206 }
1207 }
1208 }
1209}
1210
Ady Abrahama00d2462023-12-26 14:21:20 -08001211TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
1212 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
1213 EXPECT_GE(getInterfaceVersion(), 3);
1214 }
1215}
1216
ramindani12423f52023-06-14 20:04:51 -07001217class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
1218 protected:
1219 void SetUp() override {
1220 GraphicsComposerAidlTest::SetUp();
1221 if (getInterfaceVersion() <= 1) {
1222 GTEST_SKIP() << "Device interface version is expected to be >= 2";
1223 }
1224 }
1225};
1226
1227TEST_P(GraphicsComposerAidlV2Test, GetOverlaySupport) {
1228 const auto& [status, properties] = mComposerClient->getOverlaySupport();
1229 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
1230 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
1231 GTEST_SUCCEED() << "getOverlaySupport is not supported";
1232 return;
1233 }
1234
1235 ASSERT_TRUE(status.isOk());
1236 for (const auto& i : properties.combinations) {
1237 for (const auto standard : i.standards) {
1238 const auto val = static_cast<int32_t>(standard) &
1239 static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
1240 ASSERT_TRUE(val == static_cast<int32_t>(standard));
1241 }
1242 for (const auto transfer : i.transfers) {
1243 const auto val = static_cast<int32_t>(transfer) &
1244 static_cast<int32_t>(common::Dataspace::TRANSFER_MASK);
1245 ASSERT_TRUE(val == static_cast<int32_t>(transfer));
1246 }
1247 for (const auto range : i.ranges) {
1248 const auto val = static_cast<int32_t>(range) &
1249 static_cast<int32_t>(common::Dataspace::RANGE_MASK);
1250 ASSERT_TRUE(val == static_cast<int32_t>(range));
1251 }
1252 }
1253}
1254
ramindani02fe4772023-06-30 18:04:41 -07001255class GraphicsComposerAidlV3Test : public GraphicsComposerAidlTest {
1256 protected:
1257 void SetUp() override {
1258 GraphicsComposerAidlTest::SetUp();
1259 if (getInterfaceVersion() <= 2) {
1260 GTEST_SKIP() << "Device interface version is expected to be >= 3";
1261 }
1262 }
1263};
1264
1265TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigurations) {
1266 for (const auto& display : mDisplays) {
1267 const auto& [status, displayConfigurations] =
1268 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1269 EXPECT_TRUE(status.isOk());
1270 EXPECT_FALSE(displayConfigurations.empty());
1271
ramindania175f702024-11-22 09:33:50 -08001272 const bool areAllModesARR =
1273 std::all_of(displayConfigurations.cbegin(), displayConfigurations.cend(),
1274 [](const auto& config) { return config.vrrConfig.has_value(); });
1275
1276 const bool areAllModesMRR =
1277 std::all_of(displayConfigurations.cbegin(), displayConfigurations.cend(),
1278 [](const auto& config) { return !config.vrrConfig.has_value(); });
1279
1280 EXPECT_TRUE(areAllModesARR || areAllModesMRR) << "Mixing MRR and ARR modes is not allowed";
1281
ramindani02fe4772023-06-30 18:04:41 -07001282 for (const auto& displayConfig : displayConfigurations) {
1283 EXPECT_NE(-1, displayConfig.width);
1284 EXPECT_NE(-1, displayConfig.height);
1285 EXPECT_NE(-1, displayConfig.vsyncPeriod);
1286 EXPECT_NE(-1, displayConfig.configGroup);
1287 if (displayConfig.dpi) {
ramindani2b2ec502023-08-25 18:47:38 -07001288 EXPECT_NE(-1.f, displayConfig.dpi->x);
1289 EXPECT_NE(-1.f, displayConfig.dpi->y);
ramindani02fe4772023-06-30 18:04:41 -07001290 }
ramindani2704c5f2023-07-18 20:53:24 -07001291 if (displayConfig.vrrConfig) {
1292 const auto& vrrConfig = *displayConfig.vrrConfig;
1293 EXPECT_GE(vrrConfig.minFrameIntervalNs, displayConfig.vsyncPeriod);
1294
ramindani2b2ec502023-08-25 18:47:38 -07001295 EXPECT_EQ(1, std::count_if(
1296 displayConfigurations.cbegin(), displayConfigurations.cend(),
1297 [displayConfig](const auto& config) {
1298 return config.configGroup == displayConfig.configGroup;
1299 }))
1300 << "There should be only one VRR mode in one ConfigGroup";
1301
ramindani2704c5f2023-07-18 20:53:24 -07001302 const auto verifyFrameIntervalIsDivisorOfVsync = [&](int32_t frameIntervalNs) {
1303 constexpr auto kThreshold = 0.05f; // 5%
1304 const auto ratio =
1305 static_cast<float>(frameIntervalNs) / displayConfig.vsyncPeriod;
1306 return ratio - std::round(ratio) <= kThreshold;
1307 };
1308
1309 EXPECT_TRUE(verifyFrameIntervalIsDivisorOfVsync(vrrConfig.minFrameIntervalNs));
1310
1311 if (vrrConfig.frameIntervalPowerHints) {
1312 const auto& frameIntervalPowerHints = *vrrConfig.frameIntervalPowerHints;
1313 EXPECT_FALSE(frameIntervalPowerHints.empty());
1314
1315 const auto minFrameInterval = *min_element(frameIntervalPowerHints.cbegin(),
1316 frameIntervalPowerHints.cend());
1317 EXPECT_LE(minFrameInterval->frameIntervalNs,
1318 VtsComposerClient::kMaxFrameIntervalNs);
ramindanifc93b732024-02-15 21:36:19 +00001319 const auto maxFrameInterval = *max_element(frameIntervalPowerHints.cbegin(),
1320 frameIntervalPowerHints.cend());
1321 EXPECT_GE(maxFrameInterval->frameIntervalNs, vrrConfig.minFrameIntervalNs);
ramindani2704c5f2023-07-18 20:53:24 -07001322
1323 EXPECT_TRUE(std::all_of(frameIntervalPowerHints.cbegin(),
1324 frameIntervalPowerHints.cend(),
1325 [&](const auto& frameIntervalPowerHint) {
1326 return verifyFrameIntervalIsDivisorOfVsync(
1327 frameIntervalPowerHint->frameIntervalNs);
1328 }));
1329 }
1330
1331 if (vrrConfig.notifyExpectedPresentConfig) {
1332 const auto& notifyExpectedPresentConfig =
1333 *vrrConfig.notifyExpectedPresentConfig;
ramindani52416e02023-12-19 16:03:14 -08001334 EXPECT_GE(notifyExpectedPresentConfig.headsUpNs, 0);
1335 EXPECT_GE(notifyExpectedPresentConfig.timeoutNs, 0);
ramindani2704c5f2023-07-18 20:53:24 -07001336 }
1337 }
ramindani02fe4772023-06-30 18:04:41 -07001338 }
1339 }
1340}
1341
1342TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigsIsSubsetOfGetDisplayConfigurations) {
1343 for (const auto& display : mDisplays) {
1344 const auto& [status, displayConfigurations] =
1345 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1346 EXPECT_TRUE(status.isOk());
1347
1348 const auto& [legacyConfigStatus, legacyConfigs] =
1349 mComposerClient->getDisplayConfigs(display.getDisplayId());
1350 EXPECT_TRUE(legacyConfigStatus.isOk());
1351 EXPECT_FALSE(legacyConfigs.empty());
1352 EXPECT_TRUE(legacyConfigs.size() <= displayConfigurations.size());
1353
1354 for (const auto legacyConfigId : legacyConfigs) {
1355 const auto& legacyWidth = mComposerClient->getDisplayAttribute(
1356 display.getDisplayId(), legacyConfigId, DisplayAttribute::WIDTH);
1357 const auto& legacyHeight = mComposerClient->getDisplayAttribute(
1358 display.getDisplayId(), legacyConfigId, DisplayAttribute::HEIGHT);
1359 const auto& legacyVsyncPeriod = mComposerClient->getDisplayAttribute(
1360 display.getDisplayId(), legacyConfigId, DisplayAttribute::VSYNC_PERIOD);
1361 const auto& legacyConfigGroup = mComposerClient->getDisplayAttribute(
1362 display.getDisplayId(), legacyConfigId, DisplayAttribute::CONFIG_GROUP);
1363 const auto& legacyDpiX = mComposerClient->getDisplayAttribute(
1364 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_X);
1365 const auto& legacyDpiY = mComposerClient->getDisplayAttribute(
1366 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_Y);
1367
1368 EXPECT_TRUE(legacyWidth.first.isOk() && legacyHeight.first.isOk() &&
1369 legacyVsyncPeriod.first.isOk() && legacyConfigGroup.first.isOk());
1370
1371 EXPECT_TRUE(std::any_of(
1372 displayConfigurations.begin(), displayConfigurations.end(),
1373 [&](const auto& displayConfiguration) {
1374 const bool requiredAttributesPredicate =
1375 displayConfiguration.configId == legacyConfigId &&
1376 displayConfiguration.width == legacyWidth.second &&
1377 displayConfiguration.height == legacyHeight.second &&
1378 displayConfiguration.vsyncPeriod == legacyVsyncPeriod.second &&
1379 displayConfiguration.configGroup == legacyConfigGroup.second;
1380
1381 if (!requiredAttributesPredicate) {
1382 // Required attributes did not match
1383 return false;
1384 }
1385
1386 // Check optional attributes
1387 const auto& [legacyDpiXStatus, legacyDpiXValue] = legacyDpiX;
1388 const auto& [legacyDpiYStatus, legacyDpiYValue] = legacyDpiY;
1389 if (displayConfiguration.dpi) {
1390 if (!legacyDpiXStatus.isOk() || !legacyDpiYStatus.isOk()) {
1391 // getDisplayAttribute failed for optional attributes
1392 return false;
1393 }
1394
1395 // DPI values in DisplayConfigurations are not scaled (* 1000.f)
1396 // the way they are in the legacy DisplayConfigs.
1397 constexpr float kEpsilon = 0.001f;
1398 return std::abs(displayConfiguration.dpi->x -
1399 legacyDpiXValue / 1000.f) < kEpsilon &&
1400 std::abs(displayConfiguration.dpi->y -
1401 legacyDpiYValue / 1000.f) < kEpsilon;
1402 } else {
1403 return !legacyDpiXStatus.isOk() && !legacyDpiYStatus.isOk() &&
1404 EX_SERVICE_SPECIFIC == legacyDpiXStatus.getExceptionCode() &&
1405 EX_SERVICE_SPECIFIC == legacyDpiYStatus.getExceptionCode() &&
1406 IComposerClient::EX_UNSUPPORTED ==
1407 legacyDpiXStatus.getServiceSpecificError() &&
1408 IComposerClient::EX_UNSUPPORTED ==
1409 legacyDpiYStatus.getServiceSpecificError();
1410 }
1411 }));
1412 }
1413 }
1414}
1415
ramindanidcfe3a82021-11-29 17:00:31 +00001416// Tests for Command.
1417class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
1418 protected:
ramindanidcfe3a82021-11-29 17:00:31 +00001419 void TearDown() override {
Leon Scroggins III94f4b202024-01-09 11:43:45 -05001420 ASSERT_FALSE(mDisplays.empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -08001421 ASSERT_TRUE(mReader.takeErrors().empty());
ramindani431aad42022-02-01 21:44:29 +00001422 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -08001423
Ady Abrahama00d2462023-12-26 14:21:20 -08001424 ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
ramindanidcfe3a82021-11-29 17:00:31 +00001425 ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
1426 }
1427
1428 void execute() {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001429 std::vector<CommandResultPayload> payloads;
1430 for (auto& [_, writer] : mWriters) {
Joen Chene0a962c2023-08-28 09:49:11 +00001431 executeInternal(writer, payloads);
ramindanidcfe3a82021-11-29 17:00:31 +00001432 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001433 mReader.parse(std::move(payloads));
ramindanidcfe3a82021-11-29 17:00:31 +00001434 }
1435
Joen Chene0a962c2023-08-28 09:49:11 +00001436 void execute(ComposerClientWriter& writer, ComposerClientReader& reader) {
1437 std::vector<CommandResultPayload> payloads;
1438 executeInternal(writer, payloads);
1439 reader.parse(std::move(payloads));
1440 }
1441
ramindanidcfe3a82021-11-29 17:00:31 +00001442 static inline auto toTimePoint(nsecs_t time) {
1443 return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
1444 }
1445
ramindanidcfe3a82021-11-29 17:00:31 +00001446 void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
ramindani431aad42022-02-01 21:44:29 +00001447 const auto& [status, displayConfigs] = mComposerClient->getDisplayConfigs(display);
1448 ASSERT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001449 for (const int32_t config1 : displayConfigs) {
1450 for (const int32_t config2 : displayConfigs) {
1451 if (config1 != config2) {
1452 func(config1, config2);
1453 }
1454 }
1455 }
1456 }
1457
1458 void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
1459 int64_t desiredTimeNanos, int64_t oldPeriodNanos,
1460 int64_t newPeriodNanos) {
1461 const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
1462 while (std::chrono::steady_clock::now() <= kChangeDeadline) {
ramindani431aad42022-02-01 21:44:29 +00001463 const auto& [status, vsyncPeriodNanos] =
1464 mComposerClient->getDisplayVsyncPeriod(display);
1465 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001466 if (systemTime() <= desiredTimeNanos) {
1467 EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
1468 } else if (vsyncPeriodNanos == newPeriodNanos) {
1469 break;
1470 }
1471 std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
1472 }
1473 }
1474
ramindani9dd8c482023-02-21 18:07:56 -08001475 bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
1476 std::function<bool(RefreshRateChangedDebugData)> filter) {
1477 const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
1478 return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
1479 return filter(refreshRateChangedDebugData);
1480 });
1481 }
1482
Brian Lindahl25e0d092022-12-09 00:32:11 -07001483 sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
1484 ::android::PixelFormat pixelFormat) {
Brian Lindahl14bd07b2023-01-17 14:54:39 -07001485 return sp<GraphicBuffer>::make(
Brian Lindahl25e0d092022-12-09 00:32:11 -07001486 width, height, pixelFormat, /*layerCount*/ 1U,
1487 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
1488 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
1489 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
Brian Lindahl14bd07b2023-01-17 14:54:39 -07001490 "VtsHalGraphicsComposer3_TargetTest");
Brian Lindahlca3eef22022-12-09 00:32:11 -07001491 }
1492
Brian Lindahl25e0d092022-12-09 00:32:11 -07001493 sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
1494 return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
1495 static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
1496 }
1497
ramindanidcfe3a82021-11-29 17:00:31 +00001498 void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
1499 if (timeline != nullptr) {
1500 // Refresh time should be before newVsyncAppliedTimeNanos
1501 EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
1502
1503 std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
1504 }
1505
ramindani431aad42022-02-01 21:44:29 +00001506 EXPECT_TRUE(mComposerClient->setPowerMode(display.getDisplayId(), PowerMode::ON).isOk());
1507 EXPECT_TRUE(mComposerClient
1508 ->setColorMode(display.getDisplayId(), ColorMode::NATIVE,
1509 RenderIntent::COLORIMETRIC)
1510 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001511
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001512 auto& writer = getWriter(display.getDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08001513 const auto& [status, layer] =
1514 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
1515 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001516 {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001517 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindanidcfe3a82021-11-29 17:00:31 +00001518 ASSERT_NE(nullptr, buffer);
1519 ASSERT_EQ(::android::OK, buffer->initCheck());
1520 ASSERT_NE(nullptr, buffer->handle);
1521
ramindani431aad42022-02-01 21:44:29 +00001522 configureLayer(display, layer, Composition::DEVICE, display.getFrameRect(),
1523 display.getCrop());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001524 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1525 /*acquireFence*/ -1);
1526 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
ramindanidcfe3a82021-11-29 17:00:31 +00001527
ramindanicdcfcaf2023-11-09 10:00:10 -08001528 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1529 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001530 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001531 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001532
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001533 writer.presentDisplay(display.getDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001534 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001535 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001536 }
1537
1538 {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001539 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindanidcfe3a82021-11-29 17:00:31 +00001540 ASSERT_NE(nullptr, buffer->handle);
1541
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001542 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1543 /*acquireFence*/ -1);
1544 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1545 std::vector<Rect>(1, {0, 0, 10, 10}));
ramindanicdcfcaf2023-11-09 10:00:10 -08001546 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1547 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001548 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001549 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00001550
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001551 writer.presentDisplay(display.getDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001552 execute();
1553 }
1554
Ady Abrahama00d2462023-12-26 14:21:20 -08001555 EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001556 }
1557
Ady Abraham72c5b502021-12-10 17:23:39 -08001558 sp<::android::Fence> presentAndGetFence(
ramindanifc93b732024-02-15 21:36:19 +00001559 std::optional<ClockMonotonicTimestamp> expectedPresentTime,
1560 std::optional<int64_t> displayIdOpt = {},
1561 int32_t frameIntervalNs = VtsComposerClient::kNoFrameIntervalNs) {
1562 const auto displayId = displayIdOpt.value_or(getPrimaryDisplayId());
1563 auto& writer = getWriter(displayId);
1564 writer.validateDisplay(displayId, expectedPresentTime, frameIntervalNs);
Ady Abraham72c5b502021-12-10 17:23:39 -08001565 execute();
1566 EXPECT_TRUE(mReader.takeErrors().empty());
1567
ramindanifc93b732024-02-15 21:36:19 +00001568 writer.presentDisplay(displayId);
Ady Abraham72c5b502021-12-10 17:23:39 -08001569 execute();
1570 EXPECT_TRUE(mReader.takeErrors().empty());
1571
ramindanifc93b732024-02-15 21:36:19 +00001572 auto presentFence = mReader.takePresentFence(displayId);
Ady Abraham46219f52021-12-20 09:44:31 -08001573 // take ownership
1574 const int fenceOwner = presentFence.get();
1575 *presentFence.getR() = -1;
1576 EXPECT_NE(-1, fenceOwner);
1577 return sp<::android::Fence>::make(fenceOwner);
Ady Abraham72c5b502021-12-10 17:23:39 -08001578 }
1579
1580 int32_t getVsyncPeriod() {
ramindani431aad42022-02-01 21:44:29 +00001581 const auto& [status, activeConfig] =
1582 mComposerClient->getActiveConfig(getPrimaryDisplayId());
1583 EXPECT_TRUE(status.isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001584
ramindani431aad42022-02-01 21:44:29 +00001585 const auto& [vsyncPeriodStatus, vsyncPeriod] = mComposerClient->getDisplayAttribute(
1586 getPrimaryDisplayId(), activeConfig, DisplayAttribute::VSYNC_PERIOD);
1587 EXPECT_TRUE(vsyncPeriodStatus.isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001588 return vsyncPeriod;
1589 }
1590
ramindanifc93b732024-02-15 21:36:19 +00001591 int64_t createOnScreenLayer(const VtsDisplay& display,
1592 Composition composition = Composition::DEVICE) {
1593 auto& writer = getWriter(display.getDisplayId());
ramindani431aad42022-02-01 21:44:29 +00001594 const auto& [status, layer] =
ramindanifc93b732024-02-15 21:36:19 +00001595 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00001596 EXPECT_TRUE(status.isOk());
ramindanifc93b732024-02-15 21:36:19 +00001597 Rect displayFrame{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
1598 FRect cropRect{0, 0, (float)display.getDisplayWidth(), (float)display.getDisplayHeight()};
1599 configureLayer(display, layer, composition, displayFrame, cropRect);
Ady Abrahama00d2462023-12-26 14:21:20 -08001600
ramindanifc93b732024-02-15 21:36:19 +00001601 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
Ady Abraham72c5b502021-12-10 17:23:39 -08001602 return layer;
1603 }
1604
ramindani9dd8c482023-02-21 18:07:56 -08001605 void sendBufferUpdate(int64_t layer) {
1606 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1607 ASSERT_NE(nullptr, buffer->handle);
1608
1609 auto& writer = getWriter(getPrimaryDisplayId());
1610 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
1611 /*acquireFence*/ -1);
1612
1613 const sp<::android::Fence> presentFence =
1614 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1615 presentFence->waitForever(LOG_TAG);
1616 }
1617
Midas Chiena0b56bd2022-01-13 23:27:33 +08001618 bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
ramindani431aad42022-02-01 21:44:29 +00001619 const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
1620 EXPECT_TRUE(status.isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08001621
1622 return std::find(capabilities.begin(), capabilities.end(), cap) != capabilities.end();
1623 }
1624
ramindanidcfe3a82021-11-29 17:00:31 +00001625 void Test_setActiveConfigWithConstraints(const TestParameters& params) {
1626 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00001627 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
1628 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001629 sendRefreshFrame(display, nullptr);
1630
ramindani3ba73342024-04-01 11:42:33 -07001631 const auto displayConfig1 = display.getDisplayConfig(config1);
1632 int32_t vsyncPeriod1 = displayConfig1.vsyncPeriod;
1633 int32_t configGroup1 = displayConfig1.configGroup;
ramindani431aad42022-02-01 21:44:29 +00001634
ramindani3ba73342024-04-01 11:42:33 -07001635 const auto displayConfig2 = display.getDisplayConfig(config2);
1636 int32_t vsyncPeriod2 = displayConfig2.vsyncPeriod;
1637 int32_t configGroup2 = displayConfig2.configGroup;
ramindanidcfe3a82021-11-29 17:00:31 +00001638
1639 if (vsyncPeriod1 == vsyncPeriod2) {
1640 return; // continue
1641 }
1642
ramindani3ba73342024-04-01 11:42:33 -07001643 if ((!displayConfig1.vrrConfigOpt && displayConfig2.vrrConfigOpt) ||
1644 (displayConfig1.vrrConfigOpt && !displayConfig2.vrrConfigOpt)) {
1645 // switching between vrr to non-vrr modes
1646 return; // continue
1647 }
1648
ramindanidcfe3a82021-11-29 17:00:31 +00001649 // We don't allow delayed change when changing config groups
1650 if (params.delayForChange > 0 && configGroup1 != configGroup2) {
1651 return; // continue
1652 }
1653
ramindanidcfe3a82021-11-29 17:00:31 +00001654 VsyncPeriodChangeConstraints constraints = {
1655 .desiredTimeNanos = systemTime() + params.delayForChange,
1656 .seamlessRequired = false};
ramindani431aad42022-02-01 21:44:29 +00001657 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
1658 &display, config2, constraints);
1659 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001660
1661 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
1662 // Refresh rate should change within a reasonable time
1663 constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
1664 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
1665 kReasonableTimeForChange.count());
1666
1667 if (timeline.refreshRequired) {
1668 if (params.refreshMiss) {
1669 // Miss the refresh frame on purpose to make sure the implementation sends a
1670 // callback
1671 std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
1672 100ms);
1673 }
1674 sendRefreshFrame(display, &timeline);
1675 }
ramindani431aad42022-02-01 21:44:29 +00001676 waitForVsyncPeriodChange(display.getDisplayId(), timeline,
1677 constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
ramindanidcfe3a82021-11-29 17:00:31 +00001678
1679 // At this point the refresh rate should have changed already, however in rare
1680 // cases the implementation might have missed the deadline. In this case a new
1681 // timeline should have been provided.
ramindani431aad42022-02-01 21:44:29 +00001682 auto newTimeline = mComposerClient->takeLastVsyncPeriodChangeTimeline();
ramindanidcfe3a82021-11-29 17:00:31 +00001683 if (timeline.refreshRequired && params.refreshMiss) {
1684 EXPECT_TRUE(newTimeline.has_value());
1685 }
1686
1687 if (newTimeline.has_value()) {
1688 if (newTimeline->refreshRequired) {
1689 sendRefreshFrame(display, &newTimeline.value());
1690 }
ramindani431aad42022-02-01 21:44:29 +00001691 waitForVsyncPeriodChange(display.getDisplayId(), newTimeline.value(),
ramindanidcfe3a82021-11-29 17:00:31 +00001692 constraints.desiredTimeNanos, vsyncPeriod1,
1693 vsyncPeriod2);
1694 }
1695
ramindani431aad42022-02-01 21:44:29 +00001696 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanos] =
1697 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
1698 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001699 EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
1700 });
1701 }
1702 }
1703
Ady Abraham72c5b502021-12-10 17:23:39 -08001704 void Test_expectedPresentTime(std::optional<int> framesDelay) {
Jason Macnak325e8232022-01-24 14:48:55 -08001705 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
1706 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
1707 return;
1708 }
1709
ramindani431aad42022-02-01 21:44:29 +00001710 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001711
1712 const auto vsyncPeriod = getVsyncPeriod();
1713
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001714 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1715 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
Ady Abraham72c5b502021-12-10 17:23:39 -08001716 ASSERT_NE(nullptr, buffer1);
1717 ASSERT_NE(nullptr, buffer2);
1718
ramindanifc93b732024-02-15 21:36:19 +00001719 const auto layer = createOnScreenLayer(getPrimaryDisplay());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001720 auto& writer = getWriter(getPrimaryDisplayId());
1721 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
1722 /*acquireFence*/ -1);
Ady Abraham72c5b502021-12-10 17:23:39 -08001723 const sp<::android::Fence> presentFence1 =
1724 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1725 presentFence1->waitForever(LOG_TAG);
1726
1727 auto expectedPresentTime = presentFence1->getSignalTime() + vsyncPeriod;
1728 if (framesDelay.has_value()) {
1729 expectedPresentTime += *framesDelay * vsyncPeriod;
1730 }
1731
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001732 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
1733 /*acquireFence*/ -1);
Ady Abraham72c5b502021-12-10 17:23:39 -08001734 const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
1735 if (!framesDelay.has_value()) {
1736 return ComposerClientWriter::kNoTimestamp;
1737 } else if (*framesDelay == 0) {
1738 return ClockMonotonicTimestamp{0};
1739 }
1740 return ClockMonotonicTimestamp{expectedPresentTime};
1741 }();
1742
1743 const sp<::android::Fence> presentFence2 = presentAndGetFence(setExpectedPresentTime);
1744 presentFence2->waitForever(LOG_TAG);
1745
1746 const auto actualPresentTime = presentFence2->getSignalTime();
Ady Abrahamdf084f32022-01-10 14:10:23 -08001747 EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2);
Ady Abraham72c5b502021-12-10 17:23:39 -08001748
ramindani431aad42022-02-01 21:44:29 +00001749 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
Ady Abraham72c5b502021-12-10 17:23:39 -08001750 }
1751
ramindanifc93b732024-02-15 21:36:19 +00001752 void forEachNotifyExpectedPresentConfig(
1753 std::function<void(VtsDisplay&, const DisplayConfiguration&)> func) {
1754 for (VtsDisplay& display : mDisplays) {
1755 const auto displayId = display.getDisplayId();
1756 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
1757 const auto& [status, displayConfigurations] =
1758 mComposerClient->getDisplayConfigurations(displayId);
1759 EXPECT_TRUE(status.isOk());
1760 EXPECT_FALSE(displayConfigurations.empty());
1761 for (const auto& config : displayConfigurations) {
1762 if (config.vrrConfig && config.vrrConfig->notifyExpectedPresentConfig) {
1763 const auto [vsyncPeriodStatus, oldVsyncPeriod] =
1764 mComposerClient->getDisplayVsyncPeriod(displayId);
1765 ASSERT_TRUE(vsyncPeriodStatus.isOk());
1766 const auto& [timelineStatus, timeline] =
1767 mComposerClient->setActiveConfigWithConstraints(
1768 &display, config.configId,
1769 VsyncPeriodChangeConstraints{.seamlessRequired = false});
1770 ASSERT_TRUE(timelineStatus.isOk());
1771 if (timeline.refreshRequired) {
1772 sendRefreshFrame(display, &timeline);
1773 }
1774 waitForVsyncPeriodChange(displayId, timeline, systemTime(), oldVsyncPeriod,
1775 config.vsyncPeriod);
1776 func(display, config);
1777 }
1778 }
1779 EXPECT_TRUE(
1780 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
1781 }
1782 }
1783
ramindani431aad42022-02-01 21:44:29 +00001784 void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
1785 const Rect& displayFrame, const FRect& cropRect) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001786 auto& writer = getWriter(display.getDisplayId());
1787 writer.setLayerCompositionType(display.getDisplayId(), layer, composition);
1788 writer.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
1789 writer.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
1790 writer.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
1791 writer.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
1792 writer.setLayerVisibleRegion(display.getDisplayId(), layer,
1793 std::vector<Rect>(1, displayFrame));
1794 writer.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
1795 writer.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
1796 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1797 std::vector<Rect>(1, displayFrame));
ramindani431aad42022-02-01 21:44:29 +00001798 }
ramindanidcfe3a82021-11-29 17:00:31 +00001799 // clang-format off
1800 const std::array<float, 16> kIdentity = {{
1801 1.0f, 0.0f, 0.0f, 0.0f,
1802 0.0f, 1.0f, 0.0f, 0.0f,
1803 0.0f, 0.0f, 1.0f, 0.0f,
1804 0.0f, 0.0f, 0.0f, 1.0f,
1805 }};
1806 // clang-format on
1807
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001808 ComposerClientWriter& getWriter(int64_t display) {
Joen Chene0a962c2023-08-28 09:49:11 +00001809 std::lock_guard guard{mWritersMutex};
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001810 auto [it, _] = mWriters.try_emplace(display, display);
1811 return it->second;
1812 }
1813
Ady Abraham91c9d1a2021-12-15 18:14:45 -08001814 ComposerClientReader mReader;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001815
1816 private:
Joen Chene0a962c2023-08-28 09:49:11 +00001817 void executeInternal(ComposerClientWriter& writer,
1818 std::vector<CommandResultPayload>& payloads) {
1819 auto commands = writer.takePendingCommands();
1820 if (commands.empty()) {
1821 return;
1822 }
1823
1824 auto [status, results] = mComposerClient->executeCommands(commands);
1825 ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
1826
1827 payloads.reserve(payloads.size() + results.size());
1828 payloads.insert(payloads.end(), std::make_move_iterator(results.begin()),
1829 std::make_move_iterator(results.end()));
1830 }
1831
1832 // Guards access to the map itself. Callers must ensure not to attempt to
1833 // - modify the same writer from multiple threads
1834 // - insert a new writer into the map during concurrent access, which would invalidate
1835 // references from other threads
1836 std::mutex mWritersMutex;
1837 std::unordered_map<int64_t, ComposerClientWriter> mWriters GUARDED_BY(mWritersMutex);
ramindanidcfe3a82021-11-29 17:00:31 +00001838};
1839
ramindani431aad42022-02-01 21:44:29 +00001840TEST_P(GraphicsComposerAidlCommandTest, SetColorTransform) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001841 auto& writer = getWriter(getPrimaryDisplayId());
1842 writer.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
ramindanidcfe3a82021-11-29 17:00:31 +00001843 execute();
1844}
1845
1846TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001847 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08001848 const auto& [status, layer] =
1849 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
1850 EXPECT_TRUE(status.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001851 writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
ramindanidcfe3a82021-11-29 17:00:31 +00001852 execute();
1853
Ady Abraham3192f3d2021-12-03 16:08:56 -08001854 const auto errors = mReader.takeErrors();
Jason Macnak062bc9a2022-01-20 15:00:09 -08001855 if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) {
ramindanidcfe3a82021-11-29 17:00:31 +00001856 GTEST_SUCCEED() << "setLayerColorTransform is not supported";
1857 return;
1858 }
1859}
1860
Alec Mouri60564e12021-12-09 18:48:20 -08001861TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
Peter Linb9fbd4e2023-12-14 05:43:25 +00001862 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindani431aad42022-02-01 21:44:29 +00001863 const auto& [status, capabilities] =
1864 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1865 ASSERT_TRUE(status.isOk());
Alec Mouri60564e12021-12-09 18:48:20 -08001866 bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
1867 DisplayCapability::BRIGHTNESS) != capabilities.end();
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001868 auto& writer = getWriter(getPrimaryDisplayId());
Alec Mouri60564e12021-12-09 18:48:20 -08001869 if (!brightnessSupport) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001870 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001871 execute();
1872 const auto errors = mReader.takeErrors();
Liu, Kai16adbf0c2024-05-15 14:58:43 +08001873 ASSERT_EQ(1, errors.size());
Jason Macnak062bc9a2022-01-20 15:00:09 -08001874 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
Alec Mouri60564e12021-12-09 18:48:20 -08001875 GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
1876 return;
1877 }
1878
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001879 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001880 execute();
1881 EXPECT_TRUE(mReader.takeErrors().empty());
1882
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001883 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001884 execute();
1885 EXPECT_TRUE(mReader.takeErrors().empty());
1886
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001887 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001888 execute();
1889 EXPECT_TRUE(mReader.takeErrors().empty());
1890
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001891 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001892 execute();
1893 EXPECT_TRUE(mReader.takeErrors().empty());
1894
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001895 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001896 execute();
1897 {
1898 const auto errors = mReader.takeErrors();
ramindanib3bdf052022-01-12 18:27:05 +00001899 ASSERT_EQ(1, errors.size());
Alec Mouri60564e12021-12-09 18:48:20 -08001900 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1901 }
1902
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001903 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
Alec Mouri60564e12021-12-09 18:48:20 -08001904 execute();
1905 {
1906 const auto errors = mReader.takeErrors();
ramindanib3bdf052022-01-12 18:27:05 +00001907 ASSERT_EQ(1, errors.size());
Alec Mouri60564e12021-12-09 18:48:20 -08001908 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1909 }
1910}
1911
ramindani431aad42022-02-01 21:44:29 +00001912TEST_P(GraphicsComposerAidlCommandTest, SetClientTarget) {
1913 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
1914 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001915
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001916 auto& writer = getWriter(getPrimaryDisplayId());
1917 writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
Alec Mouri8062f1f2023-09-06 02:14:47 +00001918 Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
ramindanidcfe3a82021-11-29 17:00:31 +00001919
1920 execute();
1921}
1922
ramindani431aad42022-02-01 21:44:29 +00001923TEST_P(GraphicsComposerAidlCommandTest, SetOutputBuffer) {
1924 const auto& [status, virtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
1925 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001926 if (virtualDisplayCount == 0) {
1927 GTEST_SUCCEED() << "no virtual display support";
1928 return;
1929 }
1930
ramindani431aad42022-02-01 21:44:29 +00001931 const auto& [displayStatus, display] = mComposerClient->createVirtualDisplay(
1932 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
1933 kBufferSlotCount);
1934 EXPECT_TRUE(displayStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001935
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001936 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00001937 const auto handle = buffer->handle;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001938 auto& writer = getWriter(display.display);
1939 writer.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
ramindanidcfe3a82021-11-29 17:00:31 +00001940 execute();
1941}
1942
ramindani431aad42022-02-01 21:44:29 +00001943TEST_P(GraphicsComposerAidlCommandTest, ValidDisplay) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001944 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001945 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1946 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00001947 execute();
1948}
1949
ramindani431aad42022-02-01 21:44:29 +00001950TEST_P(GraphicsComposerAidlCommandTest, AcceptDisplayChanges) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001951 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001952 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1953 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001954 writer.acceptDisplayChanges(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001955 execute();
1956}
1957
ramindani431aad42022-02-01 21:44:29 +00001958TEST_P(GraphicsComposerAidlCommandTest, PresentDisplay) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001959 auto& writer = getWriter(getPrimaryDisplayId());
ramindanicdcfcaf2023-11-09 10:00:10 -08001960 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1961 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001962 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001963 execute();
1964}
1965
1966/**
1967 * Test IComposerClient::Command::PRESENT_DISPLAY
1968 *
1969 * Test that IComposerClient::Command::PRESENT_DISPLAY works without
1970 * additional call to validateDisplay when only the layer buffer handle and
1971 * surface damage have been set
1972 */
ramindani431aad42022-02-01 21:44:29 +00001973TEST_P(GraphicsComposerAidlCommandTest, PresentDisplayNoLayerStateChanges) {
ramindani431aad42022-02-01 21:44:29 +00001974 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001975
ramindani431aad42022-02-01 21:44:29 +00001976 const auto& [renderIntentsStatus, renderIntents] =
1977 mComposerClient->getRenderIntents(getPrimaryDisplayId(), ColorMode::NATIVE);
1978 EXPECT_TRUE(renderIntentsStatus.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001979 auto& writer = getWriter(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00001980 for (auto intent : renderIntents) {
ramindani431aad42022-02-01 21:44:29 +00001981 EXPECT_TRUE(mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE, intent)
1982 .isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001983
Leon Scroggins IIIde057582022-01-13 12:26:00 -05001984 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00001985 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00001986 ASSERT_NE(nullptr, handle);
1987
ramindani431aad42022-02-01 21:44:29 +00001988 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08001989 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00001990 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00001991
ramindani431aad42022-02-01 21:44:29 +00001992 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
1993 getPrimaryDisplay().getDisplayHeight()};
1994 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
1995 (float)getPrimaryDisplay().getDisplayHeight()};
1996 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001997 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
1998 /*acquireFence*/ -1);
1999 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindanicdcfcaf2023-11-09 10:00:10 -08002000 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2001 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00002002 execute();
ramindani431aad42022-02-01 21:44:29 +00002003 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanidcfe3a82021-11-29 17:00:31 +00002004 GTEST_SUCCEED() << "Composition change requested, skipping test";
2005 return;
2006 }
2007
Ady Abraham3192f3d2021-12-03 16:08:56 -08002008 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002009 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00002010 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002011 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002012
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002013 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002014 const auto handle2 = buffer2->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002015 ASSERT_NE(nullptr, handle2);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002016 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
2017 /*acquireFence*/ -1);
2018 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
2019 std::vector<Rect>(1, {0, 0, 10, 10}));
2020 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00002021 execute();
2022 }
2023}
2024
ramindani431aad42022-02-01 21:44:29 +00002025TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002026 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002027 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002028 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002029 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002030
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002031 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002032 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002033 ASSERT_NE(nullptr, handle);
ramindanidcfe3a82021-11-29 17:00:31 +00002034
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002035 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
ramindani431aad42022-02-01 21:44:29 +00002036
2037 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
2038 getPrimaryDisplay().getDisplayHeight()};
2039 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
2040 (float)getPrimaryDisplay().getDisplayHeight()};
2041 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002042 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindanicdcfcaf2023-11-09 10:00:10 -08002043 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2044 VtsComposerClient::kNoFrameIntervalNs);
ramindanidcfe3a82021-11-29 17:00:31 +00002045
2046 execute();
Ady Abraham46219f52021-12-20 09:44:31 -08002047
ramindani431aad42022-02-01 21:44:29 +00002048 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanidcfe3a82021-11-29 17:00:31 +00002049 GTEST_SUCCEED() << "Composition change requested, skipping test";
2050 return;
2051 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002052 writer.presentDisplay(getPrimaryDisplayId());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002053 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002054
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002055 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002056 execute();
2057
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002058 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
ramindanicdcfcaf2023-11-09 10:00:10 -08002059 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2060 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002061 writer.presentDisplay(getPrimaryDisplayId());
ramindanidcfe3a82021-11-29 17:00:31 +00002062 execute();
2063}
2064
ramindani431aad42022-02-01 21:44:29 +00002065TEST_P(GraphicsComposerAidlCommandTest, SetLayerBuffer) {
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002066 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002067 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002068 ASSERT_NE(nullptr, handle);
2069
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002070 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002071 const auto& [layerStatus, layer] =
2072 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2073 EXPECT_TRUE(layerStatus.isOk());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002074 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
ramindanidcfe3a82021-11-29 17:00:31 +00002075 execute();
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06002076 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002077}
2078
Brian Lindahl25e0d092022-12-09 00:32:11 -07002079TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
Brian Lindahl25e0d092022-12-09 00:32:11 -07002080 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002081 const auto& [layerStatus, layer] =
2082 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2083 EXPECT_TRUE(layerStatus.isOk());
Brian Lindahl25e0d092022-12-09 00:32:11 -07002084
2085 // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
2086 // Android platform code that clears all 3 buffer slots by setting all but the active buffer
2087 // slot to a placeholder buffer, and then restoring the active buffer.
2088
2089 // This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
2090
2091 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2092 ASSERT_NE(nullptr, buffer1);
2093 const auto handle1 = buffer1->handle;
2094 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2095 execute();
2096 ASSERT_TRUE(mReader.takeErrors().empty());
2097
2098 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2099 ASSERT_NE(nullptr, buffer2);
2100 const auto handle2 = buffer2->handle;
2101 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2102 execute();
2103 ASSERT_TRUE(mReader.takeErrors().empty());
2104
2105 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2106 ASSERT_NE(nullptr, buffer3);
2107 const auto handle3 = buffer3->handle;
2108 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2109 execute();
2110 ASSERT_TRUE(mReader.takeErrors().empty());
2111
2112 // Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
2113 // and then restoring the current active buffer at the end
2114 auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
2115 ASSERT_NE(nullptr, clearSlotBuffer);
2116 auto clearSlotBufferHandle = clearSlotBuffer->handle;
2117
2118 // clear buffer slots 0 and 1 with new layer commands... and then...
2119 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
2120 clearSlotBufferHandle, /*acquireFence*/ -1);
2121 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
2122 clearSlotBufferHandle, /*acquireFence*/ -1);
2123 // ...reset the layer buffer to the current active buffer slot with a final new command
2124 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
2125 /*acquireFence*/ -1);
2126 execute();
2127 ASSERT_TRUE(mReader.takeErrors().empty());
2128}
2129
ramindani431aad42022-02-01 21:44:29 +00002130TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002131 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002132 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002133 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002134 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002135
2136 Rect empty{0, 0, 0, 0};
2137 Rect unit{0, 0, 1, 1};
2138
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002139 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
ramindanidcfe3a82021-11-29 17:00:31 +00002140 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002141 ASSERT_TRUE(mReader.takeErrors().empty());
2142
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002143 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002144 execute();
2145 ASSERT_TRUE(mReader.takeErrors().empty());
2146
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002147 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002148 execute();
2149 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002150}
2151
ramindani431aad42022-02-01 21:44:29 +00002152TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002153 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002154 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002155 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002156 EXPECT_TRUE(layerStatus.isOk());
Leon Scroggins III03318152022-01-13 12:24:19 -05002157
2158 Rect empty{0, 0, 0, 0};
2159 Rect unit{0, 0, 1, 1};
2160
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002161 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
Leon Scroggins III03318152022-01-13 12:24:19 -05002162 execute();
2163 ASSERT_TRUE(mReader.takeErrors().empty());
2164
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002165 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Leon Scroggins III03318152022-01-13 12:24:19 -05002166 execute();
2167 ASSERT_TRUE(mReader.takeErrors().empty());
2168
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002169 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
Leon Scroggins III03318152022-01-13 12:24:19 -05002170 execute();
2171 ASSERT_TRUE(mReader.takeErrors().empty());
2172}
2173
ramindani431aad42022-02-01 21:44:29 +00002174TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002175 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002176 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002177 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002178 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002179
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002180 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
ramindanidcfe3a82021-11-29 17:00:31 +00002181 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002182 ASSERT_TRUE(mReader.takeErrors().empty());
2183
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002184 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002185 execute();
2186 ASSERT_TRUE(mReader.takeErrors().empty());
2187
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002188 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002189 execute();
2190 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002191}
2192
ramindani431aad42022-02-01 21:44:29 +00002193TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002194 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002195 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002196 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002197 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002198
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002199 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
ramindanidcfe3a82021-11-29 17:00:31 +00002200 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002201 ASSERT_TRUE(mReader.takeErrors().empty());
2202
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002203 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
Ady Abraham3192f3d2021-12-03 16:08:56 -08002204 execute();
2205 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002206}
2207
ramindani431aad42022-02-01 21:44:29 +00002208TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002209 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002210 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002211 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002212 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002213
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002214 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
ramindanidcfe3a82021-11-29 17:00:31 +00002215 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002216 ASSERT_TRUE(mReader.takeErrors().empty());
2217
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002218 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002219 execute();
2220 ASSERT_TRUE(mReader.takeErrors().empty());
2221
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002222 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002223 execute();
2224 ASSERT_TRUE(mReader.takeErrors().empty());
2225
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002226 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
ramindani431aad42022-02-01 21:44:29 +00002227 execute();
2228}
2229
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002230TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
2231 for (VtsDisplay& display : mDisplays) {
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002232 const auto displayId = display.getDisplayId();
2233 auto& writer = getWriter(displayId);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002234 const auto [layerStatus, layer] =
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002235 mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
2236 ASSERT_TRUE(layerStatus.isOk());
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002237
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002238 const auto [error, support] = mComposerClient->getDisplayDecorationSupport(displayId);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002239
Leon Scroggins III91590872022-02-23 09:51:21 -05002240 const auto format = (error.isOk() && support) ? support->format
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002241 : aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888;
2242 const auto decorBuffer = allocate(static_cast<::android::PixelFormat>(format));
2243 ASSERT_NE(nullptr, decorBuffer);
2244 if (::android::OK != decorBuffer->initCheck()) {
2245 if (support) {
2246 FAIL() << "Device advertised display decoration support with format "
2247 << aidl::android::hardware::graphics::common::toString(format)
2248 << " but failed to allocate it!";
2249 } else {
2250 FAIL() << "Device advertised NO display decoration support, but it should "
2251 << "still be able to allocate "
2252 << aidl::android::hardware::graphics::common::toString(format);
2253 }
2254 }
2255
Midas Chien7d55d422022-06-07 02:32:28 +08002256 configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
Ady Abrahama00d2462023-12-26 14:21:20 -08002257 display.getCrop());
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002258 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, decorBuffer->handle,
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002259 /*acquireFence*/ -1);
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002260 writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
ramindanicdcfcaf2023-11-09 10:00:10 -08002261 VtsComposerClient::kNoFrameIntervalNs);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002262 execute();
2263 if (support) {
2264 ASSERT_TRUE(mReader.takeErrors().empty());
2265 } else {
2266 const auto errors = mReader.takeErrors();
2267 ASSERT_EQ(1, errors.size());
Leon Scroggins III6455e792022-02-24 12:18:58 -05002268 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002269 }
Leon Scroggins IIIc2a83d42024-04-17 14:40:29 -04002270 EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002271 }
2272}
2273
ramindani431aad42022-02-01 21:44:29 +00002274TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002275 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002276 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002277 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002278 EXPECT_TRUE(layerStatus.isOk());
2279
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002280 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
ramindani431aad42022-02-01 21:44:29 +00002281 execute();
2282}
2283
2284TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002285 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002286 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002287 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002288 EXPECT_TRUE(layerStatus.isOk());
2289
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002290 writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
ramindani431aad42022-02-01 21:44:29 +00002291 execute();
2292}
2293
2294TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002295 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002296 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002297 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002298 EXPECT_TRUE(layerStatus.isOk());
2299
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002300 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
ramindani431aad42022-02-01 21:44:29 +00002301 execute();
2302 ASSERT_TRUE(mReader.takeErrors().empty());
2303
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002304 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002305 execute();
2306 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002307}
2308
ramindani431aad42022-02-01 21:44:29 +00002309TEST_P(GraphicsComposerAidlCommandTest, SetLayerSidebandStream) {
Jason Macnak325e8232022-01-24 14:48:55 -08002310 if (!hasCapability(Capability::SIDEBAND_STREAM)) {
ramindanidcfe3a82021-11-29 17:00:31 +00002311 GTEST_SUCCEED() << "no sideband stream support";
2312 return;
2313 }
2314
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002315 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
ramindani3d18f922021-12-13 20:24:47 +00002316 const auto handle = buffer->handle;
ramindanidcfe3a82021-11-29 17:00:31 +00002317 ASSERT_NE(nullptr, handle);
2318
Ady Abrahama00d2462023-12-26 14:21:20 -08002319 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002320 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002321 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002322 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002323
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002324 writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
ramindanidcfe3a82021-11-29 17:00:31 +00002325 execute();
2326}
2327
ramindani431aad42022-02-01 21:44:29 +00002328TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002329 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002330 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002331 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002332 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002333
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002334 writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
ramindanidcfe3a82021-11-29 17:00:31 +00002335 execute();
2336}
2337
ramindani431aad42022-02-01 21:44:29 +00002338TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002339 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002340 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002341 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002342 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002343
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002344 writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
ramindanidcfe3a82021-11-29 17:00:31 +00002345 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002346 ASSERT_TRUE(mReader.takeErrors().empty());
2347
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002348 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002349 execute();
2350 ASSERT_TRUE(mReader.takeErrors().empty());
2351
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002352 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002353 execute();
2354 ASSERT_TRUE(mReader.takeErrors().empty());
2355
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002356 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002357 execute();
2358 ASSERT_TRUE(mReader.takeErrors().empty());
2359
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002360 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002361 execute();
2362 ASSERT_TRUE(mReader.takeErrors().empty());
2363
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002364 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002365 execute();
2366 ASSERT_TRUE(mReader.takeErrors().empty());
2367
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002368 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2369 static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
2370 static_cast<int>(Transform::ROT_90)));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002371 execute();
2372 ASSERT_TRUE(mReader.takeErrors().empty());
2373
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002374 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2375 static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
2376 static_cast<int>(Transform::ROT_90)));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002377 execute();
2378 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002379}
2380
ramindani431aad42022-02-01 21:44:29 +00002381TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002382 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002383 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002384 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002385 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002386
2387 Rect empty{0, 0, 0, 0};
2388 Rect unit{0, 0, 1, 1};
2389
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002390 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
ramindanidcfe3a82021-11-29 17:00:31 +00002391 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002392 ASSERT_TRUE(mReader.takeErrors().empty());
2393
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002394 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
Ady Abraham3192f3d2021-12-03 16:08:56 -08002395 execute();
2396 ASSERT_TRUE(mReader.takeErrors().empty());
2397
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002398 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
Ady Abraham3192f3d2021-12-03 16:08:56 -08002399 execute();
2400 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002401}
2402
ramindani431aad42022-02-01 21:44:29 +00002403TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002404 auto& writer = getWriter(getPrimaryDisplayId());
2405
ramindani431aad42022-02-01 21:44:29 +00002406 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002407 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002408 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002409
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002410 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
ramindanidcfe3a82021-11-29 17:00:31 +00002411 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08002412 ASSERT_TRUE(mReader.takeErrors().empty());
2413
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002414 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
Ady Abraham3192f3d2021-12-03 16:08:56 -08002415 execute();
2416 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcfe3a82021-11-29 17:00:31 +00002417}
2418
ramindani431aad42022-02-01 21:44:29 +00002419TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002420 auto& writer = getWriter(getPrimaryDisplayId());
ramindani431aad42022-02-01 21:44:29 +00002421 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002422 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani431aad42022-02-01 21:44:29 +00002423 EXPECT_TRUE(layerStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002424
ramindanidcfe3a82021-11-29 17:00:31 +00002425 /**
2426 * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
2427 * the D65 white point and the SRGB transfer functions.
2428 * Rendering Intent: Colorimetric
2429 * Primaries:
2430 * x y
2431 * green 0.265 0.690
2432 * blue 0.150 0.060
2433 * red 0.680 0.320
2434 * white (D65) 0.3127 0.3290
2435 */
2436
2437 std::vector<PerFrameMetadata> aidlMetadata;
2438 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
2439 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
2440 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265f});
2441 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690f});
2442 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150f});
2443 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060f});
2444 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_X, 0.3127f});
2445 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_Y, 0.3290f});
2446 aidlMetadata.push_back({PerFrameMetadataKey::MAX_LUMINANCE, 100.0f});
2447 aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
2448 aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
2449 aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002450 writer.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
ramindanidcfe3a82021-11-29 17:00:31 +00002451 execute();
2452
Ady Abraham3192f3d2021-12-03 16:08:56 -08002453 const auto errors = mReader.takeErrors();
2454 if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
ramindanidcfe3a82021-11-29 17:00:31 +00002455 GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
Ady Abrahama00d2462023-12-26 14:21:20 -08002456 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002457 return;
2458 }
2459
Ady Abrahama00d2462023-12-26 14:21:20 -08002460 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002461}
2462
Alec Mourib1f16722022-02-07 13:03:44 -08002463TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002464 auto& writer = getWriter(getPrimaryDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08002465
2466 const auto& [layerStatus, layer] =
2467 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2468
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002469 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002470 execute();
2471 ASSERT_TRUE(mReader.takeErrors().empty());
2472
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002473 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002474 execute();
2475 ASSERT_TRUE(mReader.takeErrors().empty());
2476
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002477 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002478 execute();
2479 ASSERT_TRUE(mReader.takeErrors().empty());
2480
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002481 writer.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
Alec Mouri95e490b2022-01-06 13:46:58 -08002482 execute();
Alec Mourib1f16722022-02-07 13:03:44 -08002483 {
2484 const auto errors = mReader.takeErrors();
2485 ASSERT_EQ(1, errors.size());
2486 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2487 }
2488
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002489 writer.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
Alec Mourib1f16722022-02-07 13:03:44 -08002490 execute();
2491 {
2492 const auto errors = mReader.takeErrors();
2493 ASSERT_EQ(1, errors.size());
2494 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2495 }
Alec Mouri95e490b2022-01-06 13:46:58 -08002496}
2497
ramindani431aad42022-02-01 21:44:29 +00002498TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints) {
ramindanidcfe3a82021-11-29 17:00:31 +00002499 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
2500}
2501
ramindani431aad42022-02-01 21:44:29 +00002502TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_Delayed) {
ramindanidcfe3a82021-11-29 17:00:31 +00002503 Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
2504 .refreshMiss = false});
2505}
2506
ramindani431aad42022-02-01 21:44:29 +00002507TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_MissRefresh) {
ramindanidcfe3a82021-11-29 17:00:31 +00002508 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
2509}
2510
ramindani431aad42022-02-01 21:44:29 +00002511TEST_P(GraphicsComposerAidlCommandTest, GetDisplayVsyncPeriod) {
ramindanidcfe3a82021-11-29 17:00:31 +00002512 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00002513 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
2514 EXPECT_TRUE(status.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002515
ramindani431aad42022-02-01 21:44:29 +00002516 for (int32_t config : configs) {
2517 int32_t expectedVsyncPeriodNanos = display.getDisplayConfig(config).vsyncPeriod;
2518
ramindanidcfe3a82021-11-29 17:00:31 +00002519 VsyncPeriodChangeConstraints constraints;
2520
2521 constraints.desiredTimeNanos = systemTime();
2522 constraints.seamlessRequired = false;
ramindani431aad42022-02-01 21:44:29 +00002523
2524 const auto& [timelineStatus, timeline] =
2525 mComposerClient->setActiveConfigWithConstraints(&display, config, constraints);
2526 EXPECT_TRUE(timelineStatus.isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002527
2528 if (timeline.refreshRequired) {
2529 sendRefreshFrame(display, &timeline);
2530 }
ramindani431aad42022-02-01 21:44:29 +00002531 waitForVsyncPeriodChange(display.getDisplayId(), timeline, constraints.desiredTimeNanos,
2532 /*odPeriodNanos*/ 0, expectedVsyncPeriodNanos);
ramindanidcfe3a82021-11-29 17:00:31 +00002533
2534 int32_t vsyncPeriodNanos;
2535 int retryCount = 100;
2536 do {
2537 std::this_thread::sleep_for(10ms);
ramindani431aad42022-02-01 21:44:29 +00002538 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2539 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2540
2541 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2542 vsyncPeriodNanos = vsyncPeriodNanosValue;
ramindanidcfe3a82021-11-29 17:00:31 +00002543 --retryCount;
2544 } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
2545
2546 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2547
2548 // Make sure that the vsync period stays the same if the active config is not
2549 // changed.
2550 auto timeout = 1ms;
2551 for (int i = 0; i < 10; i++) {
2552 std::this_thread::sleep_for(timeout);
2553 timeout *= 2;
2554 vsyncPeriodNanos = 0;
ramindani431aad42022-02-01 21:44:29 +00002555 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2556 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2557
2558 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2559 vsyncPeriodNanos = vsyncPeriodNanosValue;
ramindanidcfe3a82021-11-29 17:00:31 +00002560 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2561 }
2562 }
2563 }
2564}
2565
ramindani431aad42022-02-01 21:44:29 +00002566TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_SeamlessNotAllowed) {
ramindanidcfe3a82021-11-29 17:00:31 +00002567 VsyncPeriodChangeConstraints constraints;
ramindanidcfe3a82021-11-29 17:00:31 +00002568 constraints.seamlessRequired = true;
2569 constraints.desiredTimeNanos = systemTime();
2570
2571 for (VtsDisplay& display : mDisplays) {
ramindani431aad42022-02-01 21:44:29 +00002572 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
2573 int32_t configGroup1 = display.getDisplayConfig(config1).configGroup;
2574 int32_t configGroup2 = display.getDisplayConfig(config2).configGroup;
ramindanidcfe3a82021-11-29 17:00:31 +00002575 if (configGroup1 != configGroup2) {
ramindani431aad42022-02-01 21:44:29 +00002576 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
ramindanidcfe3a82021-11-29 17:00:31 +00002577 sendRefreshFrame(display, nullptr);
ramindani431aad42022-02-01 21:44:29 +00002578 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
2579 &display, config2, constraints);
2580 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002581 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(
2582 status, IComposerClient::EX_SEAMLESS_NOT_ALLOWED));
ramindanidcfe3a82021-11-29 17:00:31 +00002583 }
2584 });
2585 }
2586}
2587
ramindani431aad42022-02-01 21:44:29 +00002588TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_NoTimestamp) {
2589 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ std::nullopt));
Ady Abraham72c5b502021-12-10 17:23:39 -08002590}
2591
ramindani431aad42022-02-01 21:44:29 +00002592TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_0) {
2593 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 0));
Ady Abraham72c5b502021-12-10 17:23:39 -08002594}
2595
ramindani431aad42022-02-01 21:44:29 +00002596TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_5) {
2597 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 5));
Ady Abraham72c5b502021-12-10 17:23:39 -08002598}
2599
ramindani431aad42022-02-01 21:44:29 +00002600TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Unsupported) {
2601 const bool hasDisplayIdleTimerSupport =
2602 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002603 if (!hasDisplayIdleTimerSupport) {
ramindani431aad42022-02-01 21:44:29 +00002604 const auto& status =
2605 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0);
2606 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002607 EXPECT_NO_FATAL_FAILURE(
2608 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
Midas Chiena0b56bd2022-01-13 23:27:33 +08002609 }
2610}
2611
ramindani431aad42022-02-01 21:44:29 +00002612TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_BadParameter) {
2613 const bool hasDisplayIdleTimerSupport =
2614 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002615 if (!hasDisplayIdleTimerSupport) {
2616 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2617 return;
2618 }
2619
ramindani431aad42022-02-01 21:44:29 +00002620 const auto& status =
2621 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ -1);
2622 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +00002623 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
Midas Chiena0b56bd2022-01-13 23:27:33 +08002624}
2625
ramindani431aad42022-02-01 21:44:29 +00002626TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Disable) {
2627 const bool hasDisplayIdleTimerSupport =
2628 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002629 if (!hasDisplayIdleTimerSupport) {
2630 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2631 return;
2632 }
2633
ramindani431aad42022-02-01 21:44:29 +00002634 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002635 std::this_thread::sleep_for(1s);
ramindani431aad42022-02-01 21:44:29 +00002636 EXPECT_EQ(0, mComposerClient->getVsyncIdleCount());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002637}
2638
ramindani431aad42022-02-01 21:44:29 +00002639TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) {
2640 const bool hasDisplayIdleTimerSupport =
2641 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002642 if (!hasDisplayIdleTimerSupport) {
2643 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2644 return;
2645 }
2646
ramindani431aad42022-02-01 21:44:29 +00002647 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
2648 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002649
Leon Scroggins IIIde057582022-01-13 12:26:00 -05002650 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002651 ASSERT_NE(nullptr, buffer->handle);
2652
ramindanifc93b732024-02-15 21:36:19 +00002653 const auto layer = createOnScreenLayer(getPrimaryDisplay());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04002654 auto& writer = getWriter(getPrimaryDisplayId());
2655 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
2656 /*acquireFence*/ -1);
ramindani431aad42022-02-01 21:44:29 +00002657 int32_t vsyncIdleCount = mComposerClient->getVsyncIdleCount();
Midas Chiena0b56bd2022-01-13 23:27:33 +08002658 auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
ramindani431aad42022-02-01 21:44:29 +00002659 EXPECT_TRUE(
2660 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 2000).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002661
2662 const sp<::android::Fence> presentFence =
ramindani431aad42022-02-01 21:44:29 +00002663 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002664 presentFence->waitForever(LOG_TAG);
2665
2666 std::this_thread::sleep_for(3s);
ramindani431aad42022-02-01 21:44:29 +00002667 if (vsyncIdleCount < mComposerClient->getVsyncIdleCount()) {
2668 EXPECT_GE(mComposerClient->getVsyncIdleTime(), earlyVsyncIdleTime);
Midas Chiena0b56bd2022-01-13 23:27:33 +08002669 }
2670
ramindani431aad42022-02-01 21:44:29 +00002671 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
Midas Chiena0b56bd2022-01-13 23:27:33 +08002672}
2673
ramindani12423f52023-06-14 20:04:51 -07002674class GraphicsComposerAidlCommandV2Test : public GraphicsComposerAidlCommandTest {
2675 protected:
2676 void SetUp() override {
2677 GraphicsComposerAidlTest::SetUp();
2678 if (getInterfaceVersion() <= 1) {
2679 GTEST_SKIP() << "Device interface version is expected to be >= 2";
2680 }
ramindani17c71102023-03-20 10:51:14 -07002681 }
ramindani12423f52023-06-14 20:04:51 -07002682};
2683/**
2684 * Test Capability::SKIP_VALIDATE
2685 *
2686 * Capability::SKIP_VALIDATE has been deprecated and should not be enabled.
2687 */
2688TEST_P(GraphicsComposerAidlCommandV2Test, SkipValidateDeprecatedTest) {
Leon Scroggins III79d7ae82023-10-11 16:03:52 -04002689#pragma clang diagnostic push
2690#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ramindani12423f52023-06-14 20:04:51 -07002691 ASSERT_FALSE(hasCapability(Capability::SKIP_VALIDATE))
2692 << "Found Capability::SKIP_VALIDATE capability.";
Leon Scroggins III79d7ae82023-10-11 16:03:52 -04002693#pragma clang diagnostic pop
ramindani12423f52023-06-14 20:04:51 -07002694}
2695
2696TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
Ady Abrahama00d2462023-12-26 14:21:20 -08002697 auto& writer = getWriter(getPrimaryDisplayId());
ramindani12423f52023-06-14 20:04:51 -07002698 // Older HAL versions use a backwards compatible way of clearing buffer slots
2699 // HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
2700 const auto& [layerStatus, layer] =
Ady Abrahama00d2462023-12-26 14:21:20 -08002701 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
ramindani12423f52023-06-14 20:04:51 -07002702 EXPECT_TRUE(layerStatus.isOk());
ramindani12423f52023-06-14 20:04:51 -07002703
2704 // setup 3 buffers in the buffer cache, with the last buffer being active
2705 // then emulate the Android platform code that clears all 3 buffer slots
2706
2707 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2708 ASSERT_NE(nullptr, buffer1);
2709 const auto handle1 = buffer1->handle;
2710 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2711 execute();
2712 ASSERT_TRUE(mReader.takeErrors().empty());
2713
2714 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2715 ASSERT_NE(nullptr, buffer2);
2716 const auto handle2 = buffer2->handle;
2717 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2718 execute();
2719 ASSERT_TRUE(mReader.takeErrors().empty());
2720
2721 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2722 ASSERT_NE(nullptr, buffer3);
2723 const auto handle3 = buffer3->handle;
2724 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2725 execute();
2726 ASSERT_TRUE(mReader.takeErrors().empty());
2727
2728 // Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
2729 // current active buffer's slot will be cleared, but still remain the active buffer and no
2730 // errors will occur.
2731 writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
2732 execute();
2733 ASSERT_TRUE(mReader.takeErrors().empty());
2734}
2735
2736TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Unsupported) {
ramindani9dd8c482023-02-21 18:07:56 -08002737 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2738 auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
2739 getPrimaryDisplayId(), /*enabled*/ true);
2740 EXPECT_FALSE(status.isOk());
2741 EXPECT_NO_FATAL_FAILURE(
2742 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2743
2744 status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
2745 /*enabled*/ false);
2746 EXPECT_FALSE(status.isOk());
2747 EXPECT_NO_FATAL_FAILURE(
2748 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2749 }
2750}
2751
ramindani12423f52023-06-14 20:04:51 -07002752TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Enabled) {
ramindani9dd8c482023-02-21 18:07:56 -08002753 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2754 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2755 return;
2756 }
2757
ramindania2a6dea2023-12-11 13:42:36 -08002758 for (VtsDisplay& display : mDisplays) {
2759 const auto displayId = display.getDisplayId();
2760 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2761 // Enable the callback
2762 ASSERT_TRUE(mComposerClient
2763 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2764 /*enabled*/ true)
2765 .isOk());
2766 std::this_thread::sleep_for(100ms);
ramindani9dd8c482023-02-21 18:07:56 -08002767
ramindania2a6dea2023-12-11 13:42:36 -08002768 const auto [status, configId] = mComposerClient->getActiveConfig(display.getDisplayId());
2769 EXPECT_TRUE(status.isOk());
ramindani9dd8c482023-02-21 18:07:56 -08002770
ramindania2a6dea2023-12-11 13:42:36 -08002771 const auto displayFilter = [&](auto refreshRateChangedDebugData) {
2772 bool nonVrrRateMatching = true;
2773 if (std::optional<VrrConfig> vrrConfigOpt =
ramindani3ba73342024-04-01 11:42:33 -07002774 display.getDisplayConfig(configId).vrrConfigOpt;
ramindania2a6dea2023-12-11 13:42:36 -08002775 getInterfaceVersion() >= 3 && !vrrConfigOpt) {
2776 nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
2777 refreshRateChangedDebugData.vsyncPeriodNanos;
2778 }
2779 const bool isDisplaySame =
2780 display.getDisplayId() == refreshRateChangedDebugData.display;
2781 return nonVrrRateMatching && isDisplaySame;
2782 };
ramindani9dd8c482023-02-21 18:07:56 -08002783
ramindania2a6dea2023-12-11 13:42:36 -08002784 // Check that we immediately got a callback
2785 EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
2786
2787 ASSERT_TRUE(mComposerClient
2788 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2789 /*enabled*/ false)
2790 .isOk());
2791 }
ramindani9dd8c482023-02-21 18:07:56 -08002792}
2793
ramindani12423f52023-06-14 20:04:51 -07002794TEST_P(GraphicsComposerAidlCommandV2Test,
ramindani9dd8c482023-02-21 18:07:56 -08002795 SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
2796 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2797 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2798 return;
2799 }
2800
2801 auto display = getEditablePrimaryDisplay();
2802 const auto displayId = display.getDisplayId();
2803
2804 if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
2805 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2806 return;
2807 }
2808
2809 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2810 EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());
2811
2812 ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
2813 // Enable the callback
2814 ASSERT_TRUE(mComposerClient
2815 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2816 /*enabled*/ true)
2817 .isOk());
2818
ramindani91518892023-03-03 16:55:09 +00002819 const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
2820 return displayId == refreshRateChangedDebugData.display;
2821 };
ramindani9dd8c482023-02-21 18:07:56 -08002822
2823 int retryCount = 3;
2824 do {
2825 // Wait for 1s so that we enter the idle state
2826 std::this_thread::sleep_for(1s);
ramindani91518892023-03-03 16:55:09 +00002827 if (!checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter)) {
ramindani9dd8c482023-02-21 18:07:56 -08002828 // DID NOT receive a callback, we are in the idle state.
2829 break;
2830 }
2831 } while (--retryCount > 0);
2832
2833 if (retryCount == 0) {
2834 GTEST_SUCCEED() << "Unable to enter the idle mode";
2835 return;
2836 }
2837
2838 // Send the REFRESH_RATE_INDICATOR update
ramindanifc93b732024-02-15 21:36:19 +00002839 ASSERT_NO_FATAL_FAILURE(sendBufferUpdate(
2840 createOnScreenLayer(getPrimaryDisplay(), Composition::REFRESH_RATE_INDICATOR)));
ramindani9dd8c482023-02-21 18:07:56 -08002841 std::this_thread::sleep_for(1s);
ramindani91518892023-03-03 16:55:09 +00002842 EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
ramindani9dd8c482023-02-21 18:07:56 -08002843 << "A callback should not be received for REFRESH_RATE_INDICATOR";
2844
2845 EXPECT_TRUE(mComposerClient
2846 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2847 /*enabled*/ false)
2848 .isOk());
2849}
2850
ramindani12423f52023-06-14 20:04:51 -07002851TEST_P(GraphicsComposerAidlCommandV2Test,
ramindani9dd8c482023-02-21 18:07:56 -08002852 SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
2853 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2854 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2855 return;
2856 }
2857
2858 VsyncPeriodChangeConstraints constraints;
2859 constraints.seamlessRequired = false;
2860 constraints.desiredTimeNanos = systemTime();
2861
2862 for (VtsDisplay& display : mDisplays) {
2863 const auto displayId = display.getDisplayId();
2864 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2865
2866 // Enable the callback
2867 ASSERT_TRUE(mComposerClient
2868 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
2869 .isOk());
2870
2871 forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
ramindani3ba73342024-04-01 11:42:33 -07002872 if (display.isRateSameBetweenConfigs(config1, config2)) {
ramindani9dd8c482023-02-21 18:07:56 -08002873 return; // continue
2874 }
2875
2876 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
2877 sendRefreshFrame(display, nullptr);
2878
2879 const auto& [status, timeline] =
2880 mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
2881 EXPECT_TRUE(status.isOk());
2882
2883 if (timeline.refreshRequired) {
2884 sendRefreshFrame(display, &timeline);
2885 }
2886
ramindani3ba73342024-04-01 11:42:33 -07002887 const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
ramindani91518892023-03-03 16:55:09 +00002888 const auto callbackFilter = [displayId,
2889 vsyncPeriod2](auto refreshRateChangedDebugData) {
2890 constexpr int kVsyncThreshold = 1000;
2891 return displayId == refreshRateChangedDebugData.display &&
2892 std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <=
2893 kVsyncThreshold;
2894 };
ramindani9dd8c482023-02-21 18:07:56 -08002895
2896 int retryCount = 3;
2897 do {
2898 std::this_thread::sleep_for(100ms);
ramindani91518892023-03-03 16:55:09 +00002899 if (checkIfCallbackRefreshRateChangedDebugEnabledReceived(callbackFilter)) {
ramindani9dd8c482023-02-21 18:07:56 -08002900 GTEST_SUCCEED() << "Received a callback successfully";
2901 break;
2902 }
2903 } while (--retryCount > 0);
2904
2905 if (retryCount == 0) {
Ying Weiaf547822024-05-17 16:31:12 +00002906 GTEST_FAIL() << "Failed to get a callback for Display " << displayId
2907 << " switching from " << display.printConfig(config1)
2908 << " to " << display.printConfig(config2);
ramindani9dd8c482023-02-21 18:07:56 -08002909 }
2910 });
2911
2912 EXPECT_TRUE(
2913 mComposerClient
2914 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
2915 .isOk());
2916 }
2917}
2918
Joen Chene0a962c2023-08-28 09:49:11 +00002919TEST_P(GraphicsComposerAidlCommandTest, MultiThreadedPresent) {
2920 std::vector<VtsDisplay*> displays;
2921 for (auto& display : mDisplays) {
2922 if (hasDisplayCapability(display.getDisplayId(),
2923 DisplayCapability::MULTI_THREADED_PRESENT)) {
2924 displays.push_back(&display);
2925 }
2926 }
2927
2928 const size_t numDisplays = displays.size();
2929 if (numDisplays <= 1u) {
2930 GTEST_SKIP();
2931 }
2932
2933 // When multi-threaded, use a reader per display. As with mWriters, this mutex
2934 // guards access to the map.
2935 std::mutex readersMutex;
2936 std::unordered_map<int64_t, ComposerClientReader> readers;
2937 std::vector<std::thread> threads;
2938 threads.reserve(numDisplays);
2939
2940 // Each display will have a layer to present. This maps from the display to
2941 // the layer, so we can properly destroy each layer at the end.
2942 std::unordered_map<int64_t, int64_t> layers;
2943
2944 for (auto* const display : displays) {
2945 const int64_t displayId = display->getDisplayId();
2946
2947 // Ensure that all writers and readers have been added to their respective
2948 // maps initially, so that the following loop never modifies the maps. The
2949 // maps are accessed from different threads, and if the maps were modified,
2950 // this would invalidate their iterators, and therefore references to the
2951 // writers and readers.
2952 auto& writer = getWriter(displayId);
2953 {
2954 std::lock_guard guard{readersMutex};
2955 readers.try_emplace(displayId, displayId);
2956 }
2957
2958 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2959
Ady Abrahama00d2462023-12-26 14:21:20 -08002960 const auto& [status, layer] =
2961 mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
Joen Chene0a962c2023-08-28 09:49:11 +00002962 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2963 ASSERT_NE(nullptr, buffer);
2964 ASSERT_EQ(::android::OK, buffer->initCheck());
2965 ASSERT_NE(nullptr, buffer->handle);
2966
2967 configureLayer(*display, layer, Composition::DEVICE, display->getFrameRect(),
2968 display->getCrop());
2969 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
2970 /*acquireFence*/ -1);
2971 writer.setLayerDataspace(displayId, layer, common::Dataspace::UNKNOWN);
2972 layers.try_emplace(displayId, layer);
2973 }
2974
2975 for (auto* const display : displays) {
2976 const int64_t displayId = display->getDisplayId();
2977 auto& writer = getWriter(displayId);
2978 std::unique_lock lock{readersMutex};
2979 auto& reader = readers.at(displayId);
2980 lock.unlock();
2981
ramindanicdcfcaf2023-11-09 10:00:10 -08002982 writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
2983 VtsComposerClient::kNoFrameIntervalNs);
Joen Chene0a962c2023-08-28 09:49:11 +00002984 execute(writer, reader);
2985
2986 threads.emplace_back([this, displayId, &readers, &readersMutex]() {
2987 auto& writer = getWriter(displayId);
2988 std::unique_lock lock{readersMutex};
2989 ComposerClientReader& reader = readers.at(displayId);
2990 lock.unlock();
2991
2992 writer.presentDisplay(displayId);
2993 execute(writer, reader);
2994 ASSERT_TRUE(reader.takeErrors().empty());
2995
2996 auto presentFence = reader.takePresentFence(displayId);
2997 // take ownership
2998 const int fenceOwner = presentFence.get();
2999 *presentFence.getR() = -1;
3000 EXPECT_NE(-1, fenceOwner);
3001 const auto presentFence2 = sp<::android::Fence>::make(fenceOwner);
3002 presentFence2->waitForever(LOG_TAG);
3003 });
3004 }
3005
3006 for (auto& thread : threads) {
3007 thread.join();
3008 }
3009
3010 for (auto& [displayId, layer] : layers) {
Ady Abrahama00d2462023-12-26 14:21:20 -08003011 auto& writer = getWriter(displayId);
3012 EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
Joen Chene0a962c2023-08-28 09:49:11 +00003013 }
3014
3015 std::lock_guard guard{readersMutex};
3016 for (auto& [displayId, reader] : readers) {
3017 ASSERT_TRUE(reader.takeErrors().empty());
3018 ASSERT_TRUE(reader.takeChangedCompositionTypes(displayId).empty());
3019 }
3020}
3021
Ady Abrahama00d2462023-12-26 14:21:20 -08003022class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003023 protected:
3024 void SetUp() override {
Ady Abrahama00d2462023-12-26 14:21:20 -08003025 GraphicsComposerAidlTest::SetUp();
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003026 if (getInterfaceVersion() <= 2) {
3027 GTEST_SKIP() << "Device interface version is expected to be >= 3";
3028 }
3029 }
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003030};
3031
Ady Abrahama00d2462023-12-26 14:21:20 -08003032TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
3033 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3034 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3035 return;
3036 }
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003037 auto& writer = getWriter(getPrimaryDisplayId());
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003038 const auto& [status, layer] =
3039 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3040 EXPECT_TRUE(status.isOk());
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003041 execute();
3042 ASSERT_TRUE(mReader.takeErrors().empty());
3043}
3044
Ady Abrahama00d2462023-12-26 14:21:20 -08003045TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
3046 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3047 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3048 return;
3049 }
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003050 auto& writer = getWriter(getInvalidDisplayId());
Ady Abrahama00d2462023-12-26 14:21:20 -08003051 int64_t layer = 5;
3052 writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3053 LayerLifecycleBatchCommandType::CREATE);
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003054 writer.setNewBufferSlotCount(getInvalidDisplayId(), layer, 1);
Ady Abrahama00d2462023-12-26 14:21:20 -08003055 execute();
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003056
Ady Abrahama00d2462023-12-26 14:21:20 -08003057 const auto errors = mReader.takeErrors();
3058 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
3059}
3060
3061TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
3062 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3063 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3064 return;
3065 }
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003066 auto& writer = getWriter(getPrimaryDisplayId());
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003067 const auto& [status, layer] =
3068 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3069 EXPECT_TRUE(status.isOk());
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003070 execute();
3071 ASSERT_TRUE(mReader.takeErrors().empty());
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003072 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003073 execute();
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003074 ASSERT_TRUE(mReader.takeErrors().empty());
Ady Abrahama00d2462023-12-26 14:21:20 -08003075}
3076
3077TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
3078 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3079 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3080 return;
3081 }
Ady Abrahama00d2462023-12-26 14:21:20 -08003082 auto& writer = getWriter(getPrimaryDisplayId());
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003083 const auto& [status, layer] =
3084 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
Ady Abrahama00d2462023-12-26 14:21:20 -08003085
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003086 EXPECT_TRUE(status.isOk());
Ady Abrahama00d2462023-12-26 14:21:20 -08003087 execute();
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003088 ASSERT_TRUE(mReader.takeErrors().empty());
Manali Bhutiyanif687f7f2024-03-25 22:07:25 +00003089
3090 auto& invalid_writer = getWriter(getInvalidDisplayId());
3091 invalid_writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3092 LayerLifecycleBatchCommandType::DESTROY);
3093 execute();
3094 const auto errors = mReader.takeErrors();
3095 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003096}
3097
Ady Abrahama00d2462023-12-26 14:21:20 -08003098TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
3099 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3100 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3101 return;
3102 }
3103
Manali Bhutiyani38565cc2023-11-11 06:16:24 +00003104 auto& writer = getWriter(getPrimaryDisplayId());
3105 int64_t layer = 5;
3106 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3107 LayerLifecycleBatchCommandType::DESTROY);
3108 execute();
3109 const auto errors = mReader.takeErrors();
3110 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
3111}
3112
ramindanifc93b732024-02-15 21:36:19 +00003113TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentTimeout) {
3114 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3115 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3116 return;
3117 }
3118 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3119 const DisplayConfiguration& config) {
3120 const auto displayId = display.getDisplayId();
3121 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3122 const auto timeoutNs = config.vrrConfig->notifyExpectedPresentConfig->timeoutNs;
3123
3124 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3125 ASSERT_NE(nullptr, buffer);
3126 const auto layer = createOnScreenLayer(display);
3127 auto& writer = getWriter(displayId);
3128 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3129 /*acquireFence*/ -1);
3130 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3131 displayId, minFrameIntervalNs);
3132 presentFence->waitForever(LOG_TAG);
3133 auto lastPresentTimeNs = presentFence->getSignalTime();
3134
3135 // Frame presents 30ms after timeout
3136 const auto timeout = static_cast<const std::chrono::nanoseconds>(timeoutNs);
3137 const auto vsyncPeriod = config.vsyncPeriod;
3138 int32_t frameAfterTimeoutNs =
3139 vsyncPeriod * static_cast<int32_t>((timeout + 30ms).count() / vsyncPeriod);
3140 auto expectedPresentTimestamp =
3141 ClockMonotonicTimestamp{lastPresentTimeNs + frameAfterTimeoutNs};
3142 std::this_thread::sleep_for(timeout);
3143 mComposerClient->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3144 minFrameIntervalNs);
3145 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, minFrameIntervalNs);
3146 presentFence->waitForever(LOG_TAG);
3147 lastPresentTimeNs = presentFence->getSignalTime();
3148 ASSERT_GE(lastPresentTimeNs, expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2);
3149 mComposerClient->destroyLayer(displayId, layer, &writer);
3150 });
3151}
3152
3153TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentFrameIntervalChange) {
3154 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3155 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3156 return;
3157 }
3158 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3159 const DisplayConfiguration& config) {
3160 const auto displayId = display.getDisplayId();
3161 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3162 ASSERT_NE(nullptr, buffer);
3163 const auto layer = createOnScreenLayer(display);
3164 auto& writer = getWriter(displayId);
3165 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3166 /*acquireFence*/ -1);
3167 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3168 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3169 displayId, minFrameIntervalNs);
3170 presentFence->waitForever(LOG_TAG);
3171 auto lastPresentTimeNs = presentFence->getSignalTime();
3172
3173 auto vsyncPeriod = config.vsyncPeriod;
3174 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3175 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3176 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3177 float totalDivisorsPassed = 0.f;
3178 for (int divisor = lowestDivisor; divisor <= highestDivisor; divisor++) {
3179 const auto frameIntervalNs = vsyncPeriod * divisor;
3180 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3181 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3182 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3183 ASSERT_TRUE(mComposerClient
3184 ->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3185 frameIntervalNs)
3186 .isOk());
3187 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, frameIntervalNs);
3188 presentFence->waitForever(LOG_TAG);
3189 lastPresentTimeNs = presentFence->getSignalTime();
3190 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3191 ++totalDivisorsPassed;
3192 }
3193 }
3194 EXPECT_TRUE(totalDivisorsPassed >
3195 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3196 mComposerClient->destroyLayer(displayId, layer, &writer);
3197 });
3198}
3199
3200TEST_P(GraphicsComposerAidlCommandV3Test, frameIntervalChangeAtPresentFrame) {
3201 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3202 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3203 return;
3204 }
3205 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3206 const DisplayConfiguration& config) {
3207 const auto displayId = display.getDisplayId();
3208 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3209 ASSERT_NE(nullptr, buffer);
3210 const auto layer = createOnScreenLayer(display);
3211 auto& writer = getWriter(displayId);
3212 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3213 /*acquireFence*/ -1);
3214 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3215
3216 auto vsyncPeriod = config.vsyncPeriod;
3217 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3218 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3219 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3220 float totalDivisorsPassed = 0.f;
3221 int divisor = lowestDivisor;
3222 auto frameIntervalNs = vsyncPeriod * divisor;
3223 sp<::android::Fence> presentFence =
3224 presentAndGetFence(ComposerClientWriter::kNoTimestamp, displayId, frameIntervalNs);
3225 presentFence->waitForever(LOG_TAG);
3226 auto lastPresentTimeNs = presentFence->getSignalTime();
3227 do {
3228 frameIntervalNs = vsyncPeriod * divisor;
3229 ++divisor;
3230 const auto nextFrameIntervalNs = vsyncPeriod * divisor;
3231 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3232 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3233 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3234 presentFence =
3235 presentAndGetFence(expectedPresentTimestamp, displayId, nextFrameIntervalNs);
3236 presentFence->waitForever(LOG_TAG);
3237 lastPresentTimeNs = presentFence->getSignalTime();
3238 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3239 ++totalDivisorsPassed;
3240 }
3241 } while (divisor < highestDivisor);
3242 EXPECT_TRUE(totalDivisorsPassed >
3243 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3244 mComposerClient->destroyLayer(displayId, layer, &writer);
3245 });
3246}
3247
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003248class GraphicsComposerAidlCommandV4Test : public GraphicsComposerAidlCommandTest {
3249 protected:
3250 void SetUp() override {
3251 GraphicsComposerAidlTest::SetUp();
3252 if (getInterfaceVersion() <= 3) {
3253 GTEST_SKIP() << "Device interface version is expected to be >= 4";
3254 }
3255 }
3256};
3257
3258TEST_P(GraphicsComposerAidlCommandV4Test, getMaxLayerPictureProfiles_success) {
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003259 for (auto& display : mDisplays) {
3260 int64_t displayId = display.getDisplayId();
3261 if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
3262 continue;
3263 }
3264 const auto& [status, maxProfiles] =
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003265 mComposerClient->getMaxLayerPictureProfiles(displayId);
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003266 EXPECT_TRUE(status.isOk());
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003267 EXPECT_THAT(maxProfiles, Ge(0));
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003268 }
3269}
3270
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003271TEST_P(GraphicsComposerAidlCommandV4Test, getMaxLayerPictureProfiles_unsupported) {
3272 for (auto& display : mDisplays) {
3273 int64_t displayId = display.getDisplayId();
3274 if (hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
3275 continue;
3276 }
3277 const auto& [status, maxProfiles] =
3278 mComposerClient->getMaxLayerPictureProfiles(displayId);
3279 EXPECT_FALSE(status.isOk());
3280 EXPECT_NO_FATAL_FAILURE(
3281 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
3282 }
3283}
3284
3285TEST_P(GraphicsComposerAidlCommandV4Test, setDisplayPictureProfileId_success) {
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003286 for (auto& display : mDisplays) {
3287 int64_t displayId = display.getDisplayId();
3288 if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
3289 continue;
3290 }
3291
3292 auto& writer = getWriter(displayId);
3293 const auto layer = createOnScreenLayer(display);
3294 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3295 ASSERT_NE(nullptr, buffer->handle);
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003296 // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003297 writer.setDisplayPictureProfileId(displayId, PictureProfileId(1));
3298 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3299 /*acquireFence*/ -1);
3300 execute();
3301 ASSERT_TRUE(mReader.takeErrors().empty());
3302 }
3303}
3304
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003305TEST_P(GraphicsComposerAidlCommandV4Test, setLayerPictureProfileId_success) {
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003306 for (auto& display : mDisplays) {
3307 int64_t displayId = display.getDisplayId();
3308 if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
3309 continue;
3310 }
3311 const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
3312 EXPECT_TRUE(status.isOk());
3313 if (maxProfiles == 0) {
3314 continue;
3315 }
3316
3317 auto& writer = getWriter(displayId);
3318 const auto layer = createOnScreenLayer(display);
3319 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3320 ASSERT_NE(nullptr, buffer->handle);
3321 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3322 /*acquireFence*/ -1);
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003323 // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003324 writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(1));
3325 execute();
3326 ASSERT_TRUE(mReader.takeErrors().empty());
3327 }
3328}
3329
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003330TEST_P(GraphicsComposerAidlCommandV4Test, setLayerPictureProfileId_failsWithTooManyProfiles) {
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003331 for (auto& display : mDisplays) {
3332 int64_t displayId = display.getDisplayId();
3333 if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
3334 continue;
3335 }
3336 const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
3337 EXPECT_TRUE(status.isOk());
3338 if (maxProfiles == 0) {
3339 continue;
3340 }
3341
3342 auto& writer = getWriter(displayId);
3343 for (int profileId = 1; profileId <= maxProfiles + 1; ++profileId) {
3344 const auto layer = createOnScreenLayer(display);
3345 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3346 ASSERT_NE(nullptr, buffer->handle);
3347 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3348 /*acquireFence*/ -1);
Brian Lindahl5054e3b2024-11-20 09:01:52 -07003349 // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
Brian Lindahl9f9d2f02024-10-24 16:23:57 -06003350 writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(profileId));
3351 }
3352 execute();
3353 const auto errors = mReader.takeErrors();
3354 ASSERT_TRUE(errors.size() == 1 &&
3355 errors[0].errorCode == IComposerClient::EX_PICTURE_PROFILE_MAX_EXCEEDED);
3356 }
3357}
3358
Sally Qidee4de92024-11-27 11:35:36 -08003359// @NonApiTest = check the status if calling getLuts
3360TEST_P(GraphicsComposerAidlCommandV4Test, GetLuts) {
3361 for (auto& display : mDisplays) {
3362 int64_t displayId = display.getDisplayId();
3363 auto& writer = getWriter(displayId);
3364 const auto layer = createOnScreenLayer(display);
3365 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3366 ASSERT_NE(nullptr, buffer->handle);
3367 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3368 /*acquireFence*/ -1);
3369 Buffer aidlbuffer;
3370 aidlbuffer.handle = ::android::dupToAidl(buffer->handle);
3371 std::vector<Buffer> buffers;
3372 buffers.push_back(std::move(aidlbuffer));
3373 const auto& [status, _] = mComposerClient->getLuts(displayId, buffers);
3374 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
3375 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
3376 GTEST_SKIP() << "getLuts is not supported";
3377 return;
3378 }
3379 ASSERT_TRUE(status.isOk());
3380 }
3381}
3382
Sally Qi2d94f522024-10-15 12:53:51 -07003383TEST_P(GraphicsComposerAidlCommandV4Test, SetUnsupportedLayerLuts) {
3384 auto& writer = getWriter(getPrimaryDisplayId());
3385 const auto& [layerStatus, layer] =
3386 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3387 EXPECT_TRUE(layerStatus.isOk());
3388 const auto& [status, properties] = mComposerClient->getOverlaySupport();
Sally Qi2d94f522024-10-15 12:53:51 -07003389
3390 // TODO (b/362319189): add Lut VTS enforcement
Sally Qic61ffd52024-11-18 13:08:33 -08003391 if ((!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
3392 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) ||
3393 (status.isOk() && !properties.lutProperties)) {
Sally Qi2d94f522024-10-15 12:53:51 -07003394 int32_t size = 7;
3395 size_t bufferSize = static_cast<size_t>(size) * sizeof(float);
3396 int32_t fd = ashmem_create_region("lut_shared_mem", bufferSize);
3397 void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
3398 std::vector<float> buffers = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
3399 memcpy(ptr, buffers.data(), bufferSize);
3400 munmap(ptr, bufferSize);
3401 Luts luts;
3402 luts.offsets = {0};
3403 luts.lutProperties = {
3404 {LutProperties::Dimension::ONE_D, size, {LutProperties::SamplingKey::RGB}}};
3405 luts.pfd = ndk::ScopedFileDescriptor(fd);
3406
Sally Qic61ffd52024-11-18 13:08:33 -08003407 const auto layer = createOnScreenLayer(getPrimaryDisplayId());
3408 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3409 ASSERT_NE(nullptr, buffer->handle);
3410 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
3411 /*acquireFence*/ -1);
Sally Qi2d94f522024-10-15 12:53:51 -07003412 writer.setLayerLuts(getPrimaryDisplayId(), layer, luts);
3413 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
3414 VtsComposerClient::kNoFrameIntervalNs);
3415 execute();
Sally Qic61ffd52024-11-18 13:08:33 -08003416 const auto errors = mReader.takeErrors();
3417 if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) {
3418 GTEST_SUCCEED() << "setLayerLuts is not supported";
3419 return;
3420 }
Sally Qi2d94f522024-10-15 12:53:51 -07003421 // change to client composition
3422 ASSERT_FALSE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
Sally Qi2d94f522024-10-15 12:53:51 -07003423 }
3424}
3425
Sasha McIntoshd98818c2024-10-31 15:55:19 -04003426TEST_P(GraphicsComposerAidlCommandV4Test, GetDisplayConfigurations_hasHdrType) {
3427 for (const auto& display : mDisplays) {
3428 const auto& [status, displayConfigurations] =
3429 mComposerClient->getDisplayConfigurations(display.getDisplayId());
3430 EXPECT_TRUE(status.isOk());
3431 EXPECT_FALSE(displayConfigurations.empty());
3432
3433 for (const auto& displayConfig : displayConfigurations) {
3434 EXPECT_NE(displayConfig.hdrOutputType, OutputType::INVALID);
3435 }
3436 }
3437}
3438
ramindanidcfe3a82021-11-29 17:00:31 +00003439GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
3440INSTANTIATE_TEST_SUITE_P(
3441 PerInstance, GraphicsComposerAidlCommandTest,
3442 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3443 ::android::PrintInstanceNameToString);
ramindanid32ae8e2021-10-01 18:48:39 +00003444GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
3445INSTANTIATE_TEST_SUITE_P(
3446 PerInstance, GraphicsComposerAidlTest,
3447 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3448 ::android::PrintInstanceNameToString);
ramindani12423f52023-06-14 20:04:51 -07003449GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV2Test);
3450INSTANTIATE_TEST_SUITE_P(
3451 PerInstance, GraphicsComposerAidlV2Test,
3452 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3453 ::android::PrintInstanceNameToString);
ramindani02fe4772023-06-30 18:04:41 -07003454GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV3Test);
3455INSTANTIATE_TEST_SUITE_P(
3456 PerInstance, GraphicsComposerAidlV3Test,
3457 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3458 ::android::PrintInstanceNameToString);
ramindani12423f52023-06-14 20:04:51 -07003459GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV2Test);
3460INSTANTIATE_TEST_SUITE_P(
3461 PerInstance, GraphicsComposerAidlCommandV2Test,
3462 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3463 ::android::PrintInstanceNameToString);
Ady Abrahama00d2462023-12-26 14:21:20 -08003464GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
3465INSTANTIATE_TEST_SUITE_P(
3466 PerInstance, GraphicsComposerAidlCommandV3Test,
3467 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3468 ::android::PrintInstanceNameToString);
Sally Qi2d94f522024-10-15 12:53:51 -07003469GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV4Test);
3470INSTANTIATE_TEST_SUITE_P(
3471 PerInstance, GraphicsComposerAidlCommandV4Test,
3472 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3473 ::android::PrintInstanceNameToString);
ramindanid32ae8e2021-10-01 18:48:39 +00003474} // namespace aidl::android::hardware::graphics::composer3::vts
3475
3476int main(int argc, char** argv) {
3477 ::testing::InitGoogleTest(&argc, argv);
3478
3479 using namespace std::chrono_literals;
3480 if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
3481 ALOGE("Failed to stop init.svc.surfaceflinger");
3482 return -1;
3483 }
ramindanibeea10e2021-12-07 21:02:49 +00003484
3485 android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
3486
3487 // The binder threadpool we start will inherit sched policy and priority
3488 // of (this) creating thread. We want the binder thread pool to have
3489 // SCHED_FIFO policy and priority 1 (lowest RT priority)
3490 // Once the pool is created we reset this thread's priority back to
3491 // original.
3492 // This thread policy is based on what we do in the SurfaceFlinger while starting
3493 // the thread pool and we need to replicate that for the VTS tests.
3494 int newPriority = 0;
3495 int origPolicy = sched_getscheduler(0);
3496 struct sched_param origSchedParam;
3497
3498 int errorInPriorityModification = sched_getparam(0, &origSchedParam);
3499 if (errorInPriorityModification == 0) {
3500 int policy = SCHED_FIFO;
3501 newPriority = sched_get_priority_min(policy);
3502
3503 struct sched_param param;
3504 param.sched_priority = newPriority;
3505
3506 errorInPriorityModification = sched_setscheduler(0, policy, &param);
3507 }
3508
3509 // start the thread pool
3510 android::ProcessState::self()->startThreadPool();
3511
3512 // Reset current thread's policy and priority
3513 if (errorInPriorityModification == 0) {
3514 errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
3515 } else {
3516 ALOGE("Failed to set VtsHalGraphicsComposer3_TargetTest binder threadpool priority to "
3517 "SCHED_FIFO");
3518 }
3519
ramindanid32ae8e2021-10-01 18:48:39 +00003520 return RUN_ALL_TESTS();
Leon Scroggins III45095052023-03-23 18:23:15 -04003521}