1 /**
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 */
16
17 #include <aidl/Gtest.h>
18 #include <aidl/Vintf.h>
19 #include <aidl/android/hardware/graphics/common/BlendMode.h>
20 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
21 #include <aidl/android/hardware/graphics/common/FRect.h>
22 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
23 #include <aidl/android/hardware/graphics/common/Rect.h>
24 #include <aidl/android/hardware/graphics/composer3/Composition.h>
25 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
26 #include <android-base/properties.h>
27 #include <android/binder_process.h>
28 #include <android/hardware/graphics/composer3/ComposerClientReader.h>
29 #include <android/hardware/graphics/composer3/ComposerClientWriter.h>
30 #include <binder/ProcessState.h>
31 #include <gtest/gtest.h>
32 #include <ui/Fence.h>
33 #include <ui/GraphicBuffer.h>
34 #include <ui/PixelFormat.h>
35 #include <algorithm>
36 #include <iterator>
37 #include <mutex>
38 #include <numeric>
39 #include <string>
40 #include <thread>
41 #include <unordered_map>
42 #include "GraphicsComposerCallback.h"
43 #include "VtsComposerClient.h"
44
45 #undef LOG_TAG
46 #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
47
48 namespace aidl::android::hardware::graphics::composer3::vts {
49
50 using namespace std::chrono_literals;
51
52 using ::android::GraphicBuffer;
53 using ::android::sp;
54
55 class GraphicsComposerAidlTest : public ::testing::TestWithParam<std::string> {
56 protected:
SetUp()57 void SetUp() override {
58 mComposerClient = std::make_unique<VtsComposerClient>(GetParam());
59 ASSERT_TRUE(mComposerClient->createClient().isOk());
60
61 const auto& [status, displays] = mComposerClient->getDisplays();
62 ASSERT_TRUE(status.isOk());
63 mDisplays = displays;
64
65 // explicitly disable vsync
66 for (const auto& display : mDisplays) {
67 EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), false).isOk());
68 }
69 mComposerClient->setVsyncAllowed(false);
70 }
71
TearDown()72 void TearDown() override {
73 ASSERT_TRUE(mComposerClient->tearDown(nullptr));
74 mComposerClient.reset();
75 }
76
assertServiceSpecificError(const ScopedAStatus & status,int32_t serviceSpecificError)77 void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
78 ASSERT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
79 ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
80 }
81
Test_setContentTypeForDisplay(int64_t display,const std::vector<ContentType> & supportedContentTypes,ContentType contentType,const char * contentTypeStr)82 void Test_setContentTypeForDisplay(int64_t display,
83 const std::vector<ContentType>& supportedContentTypes,
84 ContentType contentType, const char* contentTypeStr) {
85 const bool contentTypeSupport =
86 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
87 contentType) != supportedContentTypes.end();
88
89 if (!contentTypeSupport) {
90 const auto& status = mComposerClient->setContentType(display, contentType);
91 EXPECT_FALSE(status.isOk());
92 EXPECT_NO_FATAL_FAILURE(
93 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
94 GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
95 << std::to_string(display) << ", skipping test";
96 return;
97 }
98
99 EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
100 EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
101 }
102
Test_setContentType(ContentType contentType,const char * contentTypeStr)103 void Test_setContentType(ContentType contentType, const char* contentTypeStr) {
104 for (const auto& display : mDisplays) {
105 const auto& [status, supportedContentTypes] =
106 mComposerClient->getSupportedContentTypes(display.getDisplayId());
107 EXPECT_TRUE(status.isOk());
108 Test_setContentTypeForDisplay(display.getDisplayId(), supportedContentTypes,
109 contentType, contentTypeStr);
110 }
111 }
112
hasCapability(Capability capability)113 bool hasCapability(Capability capability) {
114 const auto& [status, capabilities] = mComposerClient->getCapabilities();
115 EXPECT_TRUE(status.isOk());
116 return std::any_of(
117 capabilities.begin(), capabilities.end(),
118 [&](const Capability& activeCapability) { return activeCapability == capability; });
119 }
120
getInterfaceVersion()121 int getInterfaceVersion() {
122 const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
123 EXPECT_TRUE(versionStatus.isOk());
124 return version;
125 }
126
getPrimaryDisplay() const127 const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
128
getPrimaryDisplayId() const129 int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
130
getInvalidDisplayId() const131 int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
132
getEditablePrimaryDisplay()133 VtsDisplay& getEditablePrimaryDisplay() { return mDisplays[0]; }
134
135 struct TestParameters {
136 nsecs_t delayForChange;
137 bool refreshMiss;
138 };
139
140 std::unique_ptr<VtsComposerClient> mComposerClient;
141 std::vector<VtsDisplay> mDisplays;
142 // use the slot count usually set by SF
143 static constexpr uint32_t kBufferSlotCount = 64;
144 };
145
TEST_P(GraphicsComposerAidlTest,GetDisplayCapabilities_BadDisplay)146 TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities_BadDisplay) {
147 const auto& [status, _] = mComposerClient->getDisplayCapabilities(getInvalidDisplayId());
148
149 EXPECT_FALSE(status.isOk());
150 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
151 }
152
TEST_P(GraphicsComposerAidlTest,GetDisplayCapabilities)153 TEST_P(GraphicsComposerAidlTest, GetDisplayCapabilities) {
154 for (const auto& display : mDisplays) {
155 const auto& [status, capabilities] =
156 mComposerClient->getDisplayCapabilities(display.getDisplayId());
157
158 EXPECT_TRUE(status.isOk());
159 }
160 }
161
TEST_P(GraphicsComposerAidlTest,DumpDebugInfo)162 TEST_P(GraphicsComposerAidlTest, DumpDebugInfo) {
163 ASSERT_TRUE(mComposerClient->dumpDebugInfo().isOk());
164 }
165
TEST_P(GraphicsComposerAidlTest,CreateClientSingleton)166 TEST_P(GraphicsComposerAidlTest, CreateClientSingleton) {
167 std::shared_ptr<IComposerClient> composerClient;
168 const auto& status = mComposerClient->createClient();
169
170 EXPECT_FALSE(status.isOk());
171 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_NO_RESOURCES));
172 }
173
TEST_P(GraphicsComposerAidlTest,GetDisplayIdentificationData)174 TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
175 const auto& [status0, displayIdentification0] =
176 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
177 if (!status0.isOk() && status0.getExceptionCode() == EX_SERVICE_SPECIFIC &&
178 status0.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
179 GTEST_SUCCEED() << "Display identification data not supported, skipping test";
180 return;
181 }
182 ASSERT_TRUE(status0.isOk()) << "failed to get display identification data";
183 ASSERT_FALSE(displayIdentification0.data.empty());
184
185 constexpr size_t kEdidBlockSize = 128;
186 ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
187 << "EDID blob length is not a multiple of " << kEdidBlockSize;
188
189 const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
190 ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
191 displayIdentification0.data.begin()))
192 << "EDID blob doesn't start with the fixed EDID header";
193 ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
194 displayIdentification0.data.begin() + kEdidBlockSize,
195 static_cast<uint8_t>(0)))
196 << "EDID base block doesn't checksum";
197
198 const auto& [status1, displayIdentification1] =
199 mComposerClient->getDisplayIdentificationData(getPrimaryDisplayId());
200 ASSERT_TRUE(status1.isOk());
201
202 ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
203 ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
204 std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
205 displayIdentification1.data.begin()))
206 << "data is not stable";
207 }
208
TEST_P(GraphicsComposerAidlTest,GetHdrCapabilities)209 TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
210 const auto& [status, hdrCapabilities] =
211 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
212
213 ASSERT_TRUE(status.isOk());
214 EXPECT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
215 }
216
TEST_P(GraphicsComposerAidlTest,GetPerFrameMetadataKeys)217 TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
218 const auto& [status, keys] = mComposerClient->getPerFrameMetadataKeys(getPrimaryDisplayId());
219 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
220 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
221 GTEST_SUCCEED() << "getPerFrameMetadataKeys is not supported";
222 return;
223 }
224
225 ASSERT_TRUE(status.isOk());
226 EXPECT_TRUE(keys.size() >= 0);
227 }
228
TEST_P(GraphicsComposerAidlTest,GetReadbackBufferAttributes)229 TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
230 const auto& [status, _] = mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
231 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
232 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
233 GTEST_SUCCEED() << "getReadbackBufferAttributes is not supported";
234 return;
235 }
236
237 ASSERT_TRUE(status.isOk());
238 }
239
TEST_P(GraphicsComposerAidlTest,GetRenderIntents)240 TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
241 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
242 EXPECT_TRUE(status.isOk());
243
244 for (auto mode : modes) {
245 const auto& [intentStatus, intents] =
246 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
247 EXPECT_TRUE(intentStatus.isOk());
248 bool isHdr;
249 switch (mode) {
250 case ColorMode::BT2100_PQ:
251 case ColorMode::BT2100_HLG:
252 isHdr = true;
253 break;
254 default:
255 isHdr = false;
256 break;
257 }
258 RenderIntent requiredIntent =
259 isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
260
261 const auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
262 EXPECT_NE(intents.cend(), iter);
263 }
264 }
265
TEST_P(GraphicsComposerAidlTest,GetRenderIntents_BadDisplay)266 TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadDisplay) {
267 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
268 ASSERT_TRUE(status.isOk());
269
270 for (auto mode : modes) {
271 const auto& [intentStatus, _] =
272 mComposerClient->getRenderIntents(getInvalidDisplayId(), mode);
273
274 EXPECT_FALSE(intentStatus.isOk());
275 EXPECT_NO_FATAL_FAILURE(
276 assertServiceSpecificError(intentStatus, IComposerClient::EX_BAD_DISPLAY));
277 }
278 }
279
TEST_P(GraphicsComposerAidlTest,GetRenderIntents_BadParameter)280 TEST_P(GraphicsComposerAidlTest, GetRenderIntents_BadParameter) {
281 const auto& [status, _] =
282 mComposerClient->getRenderIntents(getPrimaryDisplayId(), static_cast<ColorMode>(-1));
283
284 EXPECT_FALSE(status.isOk());
285 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
286 }
287
TEST_P(GraphicsComposerAidlTest,GetColorModes)288 TEST_P(GraphicsComposerAidlTest, GetColorModes) {
289 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
290 ASSERT_TRUE(status.isOk());
291
292 const auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
293 EXPECT_NE(colorModes.cend(), native);
294 }
295
TEST_P(GraphicsComposerAidlTest,GetColorMode_BadDisplay)296 TEST_P(GraphicsComposerAidlTest, GetColorMode_BadDisplay) {
297 const auto& [status, _] = mComposerClient->getColorModes(getInvalidDisplayId());
298
299 EXPECT_FALSE(status.isOk());
300 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
301 }
302
TEST_P(GraphicsComposerAidlTest,SetColorMode)303 TEST_P(GraphicsComposerAidlTest, SetColorMode) {
304 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
305 EXPECT_TRUE(status.isOk());
306
307 for (auto mode : colorModes) {
308 const auto& [intentStatus, intents] =
309 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
310 EXPECT_TRUE(intentStatus.isOk()) << "failed to get render intents";
311
312 for (auto intent : intents) {
313 const auto modeStatus =
314 mComposerClient->setColorMode(getPrimaryDisplayId(), mode, intent);
315 EXPECT_TRUE(modeStatus.isOk() ||
316 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
317 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
318 << "failed to set color mode";
319 }
320 }
321
322 const auto modeStatus = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
323 RenderIntent::COLORIMETRIC);
324 EXPECT_TRUE(modeStatus.isOk() ||
325 (modeStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
326 IComposerClient::EX_UNSUPPORTED == modeStatus.getServiceSpecificError()))
327 << "failed to set color mode";
328 }
329
TEST_P(GraphicsComposerAidlTest,SetColorMode_BadDisplay)330 TEST_P(GraphicsComposerAidlTest, SetColorMode_BadDisplay) {
331 const auto& [status, colorModes] = mComposerClient->getColorModes(getPrimaryDisplayId());
332 ASSERT_TRUE(status.isOk());
333
334 for (auto mode : colorModes) {
335 const auto& [intentStatus, intents] =
336 mComposerClient->getRenderIntents(getPrimaryDisplayId(), mode);
337 ASSERT_TRUE(intentStatus.isOk()) << "failed to get render intents";
338
339 for (auto intent : intents) {
340 auto const modeStatus =
341 mComposerClient->setColorMode(getInvalidDisplayId(), mode, intent);
342
343 EXPECT_FALSE(modeStatus.isOk());
344 EXPECT_NO_FATAL_FAILURE(
345 assertServiceSpecificError(modeStatus, IComposerClient::EX_BAD_DISPLAY));
346 }
347 }
348 }
349
TEST_P(GraphicsComposerAidlTest,SetColorMode_BadParameter)350 TEST_P(GraphicsComposerAidlTest, SetColorMode_BadParameter) {
351 auto status = mComposerClient->setColorMode(getPrimaryDisplayId(), static_cast<ColorMode>(-1),
352 RenderIntent::COLORIMETRIC);
353
354 EXPECT_FALSE(status.isOk());
355 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
356
357 status = mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE,
358 static_cast<RenderIntent>(-1));
359
360 EXPECT_FALSE(status.isOk());
361 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
362 }
363
TEST_P(GraphicsComposerAidlTest,GetDisplayedContentSamplingAttributes)364 TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
365 int constexpr kInvalid = -1;
366 const auto& [status, format] =
367 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
368
369 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
370 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
371 SUCCEED() << "Device does not support optional extension. Test skipped";
372 return;
373 }
374
375 ASSERT_TRUE(status.isOk());
376 EXPECT_NE(kInvalid, static_cast<int>(format.format));
377 EXPECT_NE(kInvalid, static_cast<int>(format.dataspace));
378 EXPECT_NE(kInvalid, static_cast<int>(format.componentMask));
379 };
380
TEST_P(GraphicsComposerAidlTest,SetDisplayedContentSamplingEnabled)381 TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
382 int constexpr kMaxFrames = 10;
383 FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
384 auto status = mComposerClient->setDisplayedContentSamplingEnabled(
385 getPrimaryDisplayId(), /*isEnabled*/ true, enableAllComponents, kMaxFrames);
386 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
387 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
388 SUCCEED() << "Device does not support optional extension. Test skipped";
389 return;
390 }
391 EXPECT_TRUE(status.isOk());
392
393 status = mComposerClient->setDisplayedContentSamplingEnabled(
394 getPrimaryDisplayId(), /*isEnabled*/ false, enableAllComponents, kMaxFrames);
395 EXPECT_TRUE(status.isOk());
396 }
397
TEST_P(GraphicsComposerAidlTest,GetDisplayedContentSample)398 TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
399 const auto& [status, displayContentSamplingAttributes] =
400 mComposerClient->getDisplayedContentSamplingAttributes(getPrimaryDisplayId());
401 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
402 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
403 SUCCEED() << "Sampling attributes aren't supported on this device, test skipped";
404 return;
405 }
406
407 int64_t constexpr kMaxFrames = 10;
408 int64_t constexpr kTimestamp = 0;
409 const auto& [sampleStatus, displayContentSample] = mComposerClient->getDisplayedContentSample(
410 getPrimaryDisplayId(), kMaxFrames, kTimestamp);
411 if (!sampleStatus.isOk() && sampleStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
412 sampleStatus.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
413 SUCCEED() << "Device does not support optional extension. Test skipped";
414 return;
415 }
416
417 EXPECT_TRUE(sampleStatus.isOk());
418 const std::vector<std::vector<int64_t>> histogram = {
419 displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
420 displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
421
422 for (size_t i = 0; i < histogram.size(); i++) {
423 const bool shouldHaveHistogram =
424 static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i);
425 EXPECT_EQ(shouldHaveHistogram, !histogram[i].empty());
426 }
427 }
428
TEST_P(GraphicsComposerAidlTest,GetDisplayConnectionType)429 TEST_P(GraphicsComposerAidlTest, GetDisplayConnectionType) {
430 const auto& [status, type] = mComposerClient->getDisplayConnectionType(getInvalidDisplayId());
431
432 EXPECT_FALSE(status.isOk());
433 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
434
435 for (const auto& display : mDisplays) {
436 const auto& [connectionTypeStatus, _] =
437 mComposerClient->getDisplayConnectionType(display.getDisplayId());
438 EXPECT_TRUE(connectionTypeStatus.isOk());
439 }
440 }
441
TEST_P(GraphicsComposerAidlTest,GetDisplayAttribute)442 TEST_P(GraphicsComposerAidlTest, GetDisplayAttribute) {
443 for (const auto& display : mDisplays) {
444 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
445 EXPECT_TRUE(status.isOk());
446
447 for (const auto& config : configs) {
448 const std::array<DisplayAttribute, 4> requiredAttributes = {{
449 DisplayAttribute::WIDTH,
450 DisplayAttribute::HEIGHT,
451 DisplayAttribute::VSYNC_PERIOD,
452 DisplayAttribute::CONFIG_GROUP,
453 }};
454 for (const auto& attribute : requiredAttributes) {
455 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
456 display.getDisplayId(), config, attribute);
457 EXPECT_TRUE(attribStatus.isOk());
458 EXPECT_NE(-1, value);
459 }
460
461 const std::array<DisplayAttribute, 2> optionalAttributes = {{
462 DisplayAttribute::DPI_X,
463 DisplayAttribute::DPI_Y,
464 }};
465 for (const auto& attribute : optionalAttributes) {
466 const auto& [attribStatus, value] = mComposerClient->getDisplayAttribute(
467 display.getDisplayId(), config, attribute);
468 EXPECT_TRUE(attribStatus.isOk() ||
469 (attribStatus.getExceptionCode() == EX_SERVICE_SPECIFIC &&
470 IComposerClient::EX_UNSUPPORTED ==
471 attribStatus.getServiceSpecificError()));
472 }
473 }
474 }
475 }
476
TEST_P(GraphicsComposerAidlTest,CheckConfigsAreValid)477 TEST_P(GraphicsComposerAidlTest, CheckConfigsAreValid) {
478 for (const auto& display : mDisplays) {
479 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
480 EXPECT_TRUE(status.isOk());
481
482 EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
483 return config == IComposerClient::INVALID_CONFIGURATION;
484 }));
485 }
486 }
487
TEST_P(GraphicsComposerAidlTest,GetDisplayVsyncPeriod_BadDisplay)488 TEST_P(GraphicsComposerAidlTest, GetDisplayVsyncPeriod_BadDisplay) {
489 const auto& [status, vsyncPeriodNanos] =
490 mComposerClient->getDisplayVsyncPeriod(getInvalidDisplayId());
491
492 EXPECT_FALSE(status.isOk());
493 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
494 }
495
TEST_P(GraphicsComposerAidlTest,SetActiveConfigWithConstraints_BadDisplay)496 TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadDisplay) {
497 VsyncPeriodChangeConstraints constraints;
498 constraints.seamlessRequired = false;
499 constraints.desiredTimeNanos = systemTime();
500 auto invalidDisplay = VtsDisplay(getInvalidDisplayId());
501
502 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
503 &invalidDisplay, /*config*/ 0, constraints);
504
505 EXPECT_FALSE(status.isOk());
506 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
507 }
508
TEST_P(GraphicsComposerAidlTest,SetActiveConfigWithConstraints_BadConfig)509 TEST_P(GraphicsComposerAidlTest, SetActiveConfigWithConstraints_BadConfig) {
510 VsyncPeriodChangeConstraints constraints;
511 constraints.seamlessRequired = false;
512 constraints.desiredTimeNanos = systemTime();
513
514 for (VtsDisplay& display : mDisplays) {
515 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
516 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
517 &display, kInvalidConfigId, constraints);
518
519 EXPECT_FALSE(status.isOk());
520 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
521 }
522 }
523
TEST_P(GraphicsComposerAidlTest,SetBootDisplayConfig_BadDisplay)524 TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadDisplay) {
525 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
526 GTEST_SUCCEED() << "Boot Display Config not supported";
527 return;
528 }
529 const auto& status = mComposerClient->setBootDisplayConfig(getInvalidDisplayId(), /*config*/ 0);
530
531 EXPECT_FALSE(status.isOk());
532 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
533 }
534
TEST_P(GraphicsComposerAidlTest,SetBootDisplayConfig_BadConfig)535 TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig_BadConfig) {
536 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
537 GTEST_SUCCEED() << "Boot Display Config not supported";
538 return;
539 }
540 for (VtsDisplay& display : mDisplays) {
541 int32_t constexpr kInvalidConfigId = IComposerClient::INVALID_CONFIGURATION;
542 const auto& status =
543 mComposerClient->setBootDisplayConfig(display.getDisplayId(), kInvalidConfigId);
544
545 EXPECT_FALSE(status.isOk());
546 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_CONFIG));
547 }
548 }
549
TEST_P(GraphicsComposerAidlTest,SetBootDisplayConfig)550 TEST_P(GraphicsComposerAidlTest, SetBootDisplayConfig) {
551 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
552 GTEST_SUCCEED() << "Boot Display Config not supported";
553 return;
554 }
555 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
556 EXPECT_TRUE(status.isOk());
557 for (const auto& config : configs) {
558 EXPECT_TRUE(mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config).isOk());
559 }
560 }
561
TEST_P(GraphicsComposerAidlTest,ClearBootDisplayConfig_BadDisplay)562 TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig_BadDisplay) {
563 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
564 GTEST_SUCCEED() << "Boot Display Config not supported";
565 return;
566 }
567 const auto& status = mComposerClient->clearBootDisplayConfig(getInvalidDisplayId());
568
569 EXPECT_FALSE(status.isOk());
570 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
571 }
572
TEST_P(GraphicsComposerAidlTest,ClearBootDisplayConfig)573 TEST_P(GraphicsComposerAidlTest, ClearBootDisplayConfig) {
574 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
575 GTEST_SUCCEED() << "Boot Display Config not supported";
576 return;
577 }
578 EXPECT_TRUE(mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId()).isOk());
579 }
580
TEST_P(GraphicsComposerAidlTest,GetPreferredBootDisplayConfig_BadDisplay)581 TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig_BadDisplay) {
582 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
583 GTEST_SUCCEED() << "Boot Display Config not supported";
584 return;
585 }
586 const auto& [status, _] = mComposerClient->getPreferredBootDisplayConfig(getInvalidDisplayId());
587
588 EXPECT_FALSE(status.isOk());
589 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
590 }
591
TEST_P(GraphicsComposerAidlTest,GetPreferredBootDisplayConfig)592 TEST_P(GraphicsComposerAidlTest, GetPreferredBootDisplayConfig) {
593 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
594 GTEST_SUCCEED() << "Boot Display Config not supported";
595 return;
596 }
597 const auto& [status, preferredDisplayConfig] =
598 mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId());
599 EXPECT_TRUE(status.isOk());
600
601 const auto& [configStatus, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
602
603 EXPECT_TRUE(configStatus.isOk());
604 EXPECT_NE(configs.end(), std::find(configs.begin(), configs.end(), preferredDisplayConfig));
605 }
606
TEST_P(GraphicsComposerAidlTest,BootDisplayConfig_Unsupported)607 TEST_P(GraphicsComposerAidlTest, BootDisplayConfig_Unsupported) {
608 if (!hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
609 const auto& [configStatus, config] =
610 mComposerClient->getActiveConfig(getPrimaryDisplayId());
611 EXPECT_TRUE(configStatus.isOk());
612
613 auto status = mComposerClient->setBootDisplayConfig(getPrimaryDisplayId(), config);
614 EXPECT_FALSE(status.isOk());
615 EXPECT_NO_FATAL_FAILURE(
616 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
617
618 status = mComposerClient->getPreferredBootDisplayConfig(getPrimaryDisplayId()).first;
619 EXPECT_FALSE(status.isOk());
620 EXPECT_NO_FATAL_FAILURE(
621 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
622
623 status = mComposerClient->clearBootDisplayConfig(getPrimaryDisplayId());
624 EXPECT_FALSE(status.isOk());
625 EXPECT_NO_FATAL_FAILURE(
626 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
627 }
628 }
629
TEST_P(GraphicsComposerAidlTest,GetHdrConversionCapabilities)630 TEST_P(GraphicsComposerAidlTest, GetHdrConversionCapabilities) {
631 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
632 GTEST_SUCCEED() << "HDR output conversion not supported";
633 return;
634 }
635 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
636 EXPECT_TRUE(status.isOk());
637 }
638
TEST_P(GraphicsComposerAidlTest,SetHdrConversionStrategy_Passthrough)639 TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Passthrough) {
640 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
641 GTEST_SUCCEED() << "HDR output conversion not supported";
642 return;
643 }
644 common::HdrConversionStrategy hdrConversionStrategy;
645 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::passthrough>(true);
646 const auto& [status, preferredHdrOutputType] =
647 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
648 EXPECT_TRUE(status.isOk());
649 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
650 }
651
TEST_P(GraphicsComposerAidlTest,SetHdrConversionStrategy_Force)652 TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Force) {
653 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
654 GTEST_SUCCEED() << "HDR output conversion not supported";
655 return;
656 }
657 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
658 const auto& [status2, hdrCapabilities] =
659 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
660 const auto& hdrTypes = hdrCapabilities.types;
661 for (auto conversionCapability : conversionCapabilities) {
662 if (conversionCapability.outputType != common::Hdr::INVALID) {
663 if (std::find(hdrTypes.begin(), hdrTypes.end(), conversionCapability.outputType) ==
664 hdrTypes.end()) {
665 continue;
666 }
667 common::HdrConversionStrategy hdrConversionStrategy;
668 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::forceHdrConversion>(
669 conversionCapability.outputType);
670 const auto& [statusSet, preferredHdrOutputType] =
671 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
672 EXPECT_TRUE(statusSet.isOk());
673 EXPECT_EQ(common::Hdr::INVALID, preferredHdrOutputType);
674 }
675 }
676 }
677
TEST_P(GraphicsComposerAidlTest,SetHdrConversionStrategy_Auto)678 TEST_P(GraphicsComposerAidlTest, SetHdrConversionStrategy_Auto) {
679 if (!hasCapability(Capability::HDR_OUTPUT_CONVERSION_CONFIG)) {
680 GTEST_SUCCEED() << "HDR output conversion not supported";
681 return;
682 }
683 const auto& [status, conversionCapabilities] = mComposerClient->getHdrConversionCapabilities();
684 const auto& [status2, hdrCapabilities] =
685 mComposerClient->getHdrCapabilities(getPrimaryDisplayId());
686 if (hdrCapabilities.types.size() <= 0) {
687 return;
688 }
689 std::vector<aidl::android::hardware::graphics::common::Hdr> autoHdrTypes;
690 for (auto conversionCapability : conversionCapabilities) {
691 if (conversionCapability.outputType != common::Hdr::INVALID) {
692 autoHdrTypes.push_back(conversionCapability.outputType);
693 }
694 }
695 common::HdrConversionStrategy hdrConversionStrategy;
696 hdrConversionStrategy.set<common::HdrConversionStrategy::Tag::autoAllowedHdrTypes>(
697 autoHdrTypes);
698 const auto& [statusSet, preferredHdrOutputType] =
699 mComposerClient->setHdrConversionStrategy(hdrConversionStrategy);
700 EXPECT_TRUE(statusSet.isOk());
701 EXPECT_NE(common::Hdr::INVALID, preferredHdrOutputType);
702 }
703
TEST_P(GraphicsComposerAidlTest,SetAutoLowLatencyMode_BadDisplay)704 TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode_BadDisplay) {
705 auto status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ true);
706 EXPECT_FALSE(status.isOk());
707 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
708
709 status = mComposerClient->setAutoLowLatencyMode(getInvalidDisplayId(), /*isEnabled*/ false);
710 EXPECT_FALSE(status.isOk());
711 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
712 }
713
TEST_P(GraphicsComposerAidlTest,SetAutoLowLatencyMode)714 TEST_P(GraphicsComposerAidlTest, SetAutoLowLatencyMode) {
715 for (const auto& display : mDisplays) {
716 const auto& [status, capabilities] =
717 mComposerClient->getDisplayCapabilities(display.getDisplayId());
718 ASSERT_TRUE(status.isOk());
719
720 const bool allmSupport =
721 std::find(capabilities.begin(), capabilities.end(),
722 DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
723
724 if (!allmSupport) {
725 const auto& statusIsOn = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
726 /*isEnabled*/ true);
727 EXPECT_FALSE(statusIsOn.isOk());
728 EXPECT_NO_FATAL_FAILURE(
729 assertServiceSpecificError(statusIsOn, IComposerClient::EX_UNSUPPORTED));
730 const auto& statusIsOff = mComposerClient->setAutoLowLatencyMode(display.getDisplayId(),
731 /*isEnabled*/ false);
732 EXPECT_FALSE(statusIsOff.isOk());
733 EXPECT_NO_FATAL_FAILURE(
734 assertServiceSpecificError(statusIsOff, IComposerClient::EX_UNSUPPORTED));
735 GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
736 << std::to_string(display.getDisplayId()) << ", skipping test";
737 return;
738 }
739
740 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), true).isOk());
741 EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.getDisplayId(), false).isOk());
742 }
743 }
744
TEST_P(GraphicsComposerAidlTest,GetSupportedContentTypes_BadDisplay)745 TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes_BadDisplay) {
746 const auto& [status, _] = mComposerClient->getSupportedContentTypes(getInvalidDisplayId());
747
748 EXPECT_FALSE(status.isOk());
749 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
750 }
751
TEST_P(GraphicsComposerAidlTest,GetSupportedContentTypes)752 TEST_P(GraphicsComposerAidlTest, GetSupportedContentTypes) {
753 for (const auto& display : mDisplays) {
754 const auto& [status, supportedContentTypes] =
755 mComposerClient->getSupportedContentTypes(display.getDisplayId());
756 ASSERT_TRUE(status.isOk());
757
758 const bool noneSupported =
759 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
760 ContentType::NONE) != supportedContentTypes.end();
761
762 EXPECT_FALSE(noneSupported);
763 }
764 }
765
TEST_P(GraphicsComposerAidlTest,SetContentTypeNoneAlwaysAccepted)766 TEST_P(GraphicsComposerAidlTest, SetContentTypeNoneAlwaysAccepted) {
767 for (const auto& display : mDisplays) {
768 EXPECT_TRUE(
769 mComposerClient->setContentType(display.getDisplayId(), ContentType::NONE).isOk());
770 }
771 }
772
TEST_P(GraphicsComposerAidlTest,SetContentType_BadDisplay)773 TEST_P(GraphicsComposerAidlTest, SetContentType_BadDisplay) {
774 constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
775 ContentType::CINEMA, ContentType::GAME};
776 for (const auto& type : types) {
777 const auto& status = mComposerClient->setContentType(getInvalidDisplayId(), type);
778
779 EXPECT_FALSE(status.isOk());
780 EXPECT_NO_FATAL_FAILURE(
781 assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
782 }
783 }
784
TEST_P(GraphicsComposerAidlTest,SetGraphicsContentType)785 TEST_P(GraphicsComposerAidlTest, SetGraphicsContentType) {
786 Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
787 }
788
TEST_P(GraphicsComposerAidlTest,SetPhotoContentType)789 TEST_P(GraphicsComposerAidlTest, SetPhotoContentType) {
790 Test_setContentType(ContentType::PHOTO, "PHOTO");
791 }
792
TEST_P(GraphicsComposerAidlTest,SetCinemaContentType)793 TEST_P(GraphicsComposerAidlTest, SetCinemaContentType) {
794 Test_setContentType(ContentType::CINEMA, "CINEMA");
795 }
796
TEST_P(GraphicsComposerAidlTest,SetGameContentType)797 TEST_P(GraphicsComposerAidlTest, SetGameContentType) {
798 Test_setContentType(ContentType::GAME, "GAME");
799 }
800
TEST_P(GraphicsComposerAidlTest,CreateVirtualDisplay)801 TEST_P(GraphicsComposerAidlTest, CreateVirtualDisplay) {
802 const auto& [status, maxVirtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
803 EXPECT_TRUE(status.isOk());
804
805 if (maxVirtualDisplayCount == 0) {
806 GTEST_SUCCEED() << "no virtual display support";
807 return;
808 }
809
810 const auto& [virtualDisplayStatus, virtualDisplay] = mComposerClient->createVirtualDisplay(
811 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
812 kBufferSlotCount);
813
814 ASSERT_TRUE(virtualDisplayStatus.isOk());
815 EXPECT_TRUE(mComposerClient->destroyVirtualDisplay(virtualDisplay.display).isOk());
816 }
817
TEST_P(GraphicsComposerAidlTest,DestroyVirtualDisplay_BadDisplay)818 TEST_P(GraphicsComposerAidlTest, DestroyVirtualDisplay_BadDisplay) {
819 const auto& [status, maxDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
820 EXPECT_TRUE(status.isOk());
821
822 if (maxDisplayCount == 0) {
823 GTEST_SUCCEED() << "no virtual display support";
824 return;
825 }
826
827 const auto& destroyStatus = mComposerClient->destroyVirtualDisplay(getInvalidDisplayId());
828
829 EXPECT_FALSE(destroyStatus.isOk());
830 EXPECT_NO_FATAL_FAILURE(
831 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
832 }
833
TEST_P(GraphicsComposerAidlTest,CreateLayer)834 TEST_P(GraphicsComposerAidlTest, CreateLayer) {
835 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
836 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
837 return;
838 }
839
840 const auto& [status, layer] =
841 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
842
843 EXPECT_TRUE(status.isOk());
844 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
845 }
846
TEST_P(GraphicsComposerAidlTest,CreateLayer_BadDisplay)847 TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
848 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
849 GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
850 return;
851 }
852
853 const auto& [status, _] =
854 mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
855
856 EXPECT_FALSE(status.isOk());
857 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
858 }
859
TEST_P(GraphicsComposerAidlTest,DestroyLayer_BadDisplay)860 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
861 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
862 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
863 return;
864 }
865
866 const auto& [status, layer] =
867 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
868 EXPECT_TRUE(status.isOk());
869
870 const auto& destroyStatus =
871 mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
872
873 EXPECT_FALSE(destroyStatus.isOk());
874 EXPECT_NO_FATAL_FAILURE(
875 assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
876 ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
877 }
878
TEST_P(GraphicsComposerAidlTest,DestroyLayer_BadLayerError)879 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
880 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
881 GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
882 return;
883 }
884
885 // We haven't created any layers yet, so any id should be invalid
886 const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
887
888 EXPECT_FALSE(status.isOk());
889 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
890 }
891
TEST_P(GraphicsComposerAidlTest,GetActiveConfig_BadDisplay)892 TEST_P(GraphicsComposerAidlTest, GetActiveConfig_BadDisplay) {
893 const auto& [status, _] = mComposerClient->getActiveConfig(getInvalidDisplayId());
894
895 EXPECT_FALSE(status.isOk());
896 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
897 }
898
TEST_P(GraphicsComposerAidlTest,GetDisplayConfig)899 TEST_P(GraphicsComposerAidlTest, GetDisplayConfig) {
900 const auto& [status, _] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
901 EXPECT_TRUE(status.isOk());
902 }
903
TEST_P(GraphicsComposerAidlTest,GetDisplayConfig_BadDisplay)904 TEST_P(GraphicsComposerAidlTest, GetDisplayConfig_BadDisplay) {
905 const auto& [status, _] = mComposerClient->getDisplayConfigs(getInvalidDisplayId());
906
907 EXPECT_FALSE(status.isOk());
908 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
909 }
910
TEST_P(GraphicsComposerAidlTest,GetDisplayName)911 TEST_P(GraphicsComposerAidlTest, GetDisplayName) {
912 const auto& [status, _] = mComposerClient->getDisplayName(getPrimaryDisplayId());
913 EXPECT_TRUE(status.isOk());
914 }
915
TEST_P(GraphicsComposerAidlTest,GetDisplayPhysicalOrientation_BadDisplay)916 TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation_BadDisplay) {
917 const auto& [status, _] = mComposerClient->getDisplayPhysicalOrientation(getInvalidDisplayId());
918
919 EXPECT_FALSE(status.isOk());
920 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
921 }
922
TEST_P(GraphicsComposerAidlTest,GetDisplayPhysicalOrientation)923 TEST_P(GraphicsComposerAidlTest, GetDisplayPhysicalOrientation) {
924 const auto allowedDisplayOrientations = std::array<Transform, 4>{
925 Transform::NONE,
926 Transform::ROT_90,
927 Transform::ROT_180,
928 Transform::ROT_270,
929 };
930
931 const auto& [status, displayOrientation] =
932 mComposerClient->getDisplayPhysicalOrientation(getPrimaryDisplayId());
933
934 EXPECT_TRUE(status.isOk());
935 EXPECT_NE(std::find(allowedDisplayOrientations.begin(), allowedDisplayOrientations.end(),
936 displayOrientation),
937 allowedDisplayOrientations.end());
938 }
939
TEST_P(GraphicsComposerAidlTest,SetClientTargetSlotCount)940 TEST_P(GraphicsComposerAidlTest, SetClientTargetSlotCount) {
941 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
942 .isOk());
943 }
944
TEST_P(GraphicsComposerAidlTest,SetActiveConfig)945 TEST_P(GraphicsComposerAidlTest, SetActiveConfig) {
946 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
947 EXPECT_TRUE(status.isOk());
948
949 for (const auto& config : configs) {
950 auto display = getEditablePrimaryDisplay();
951 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
952 const auto& [configStatus, config1] =
953 mComposerClient->getActiveConfig(getPrimaryDisplayId());
954 EXPECT_TRUE(configStatus.isOk());
955 EXPECT_EQ(config, config1);
956 }
957 }
958
TEST_P(GraphicsComposerAidlTest,SetActiveConfigPowerCycle)959 TEST_P(GraphicsComposerAidlTest, SetActiveConfigPowerCycle) {
960 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
961 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
962
963 const auto& [status, configs] = mComposerClient->getDisplayConfigs(getPrimaryDisplayId());
964 EXPECT_TRUE(status.isOk());
965
966 for (const auto& config : configs) {
967 auto display = getEditablePrimaryDisplay();
968 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
969 const auto& [config1Status, config1] =
970 mComposerClient->getActiveConfig(getPrimaryDisplayId());
971 EXPECT_TRUE(config1Status.isOk());
972 EXPECT_EQ(config, config1);
973
974 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
975 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
976 const auto& [config2Status, config2] =
977 mComposerClient->getActiveConfig(getPrimaryDisplayId());
978 EXPECT_TRUE(config2Status.isOk());
979 EXPECT_EQ(config, config2);
980 }
981 }
982
TEST_P(GraphicsComposerAidlTest,SetPowerModeUnsupported)983 TEST_P(GraphicsComposerAidlTest, SetPowerModeUnsupported) {
984 const auto& [status, capabilities] =
985 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
986 ASSERT_TRUE(status.isOk());
987
988 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
989 DisplayCapability::DOZE) != capabilities.end();
990 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
991 DisplayCapability::SUSPEND) != capabilities.end();
992
993 if (!isDozeSupported) {
994 const auto& powerModeDozeStatus =
995 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE);
996 EXPECT_FALSE(powerModeDozeStatus.isOk());
997 EXPECT_NO_FATAL_FAILURE(
998 assertServiceSpecificError(powerModeDozeStatus, IComposerClient::EX_UNSUPPORTED));
999
1000 const auto& powerModeDozeSuspendStatus =
1001 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1002 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
1003 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1004 IComposerClient::EX_UNSUPPORTED));
1005 }
1006
1007 if (!isSuspendSupported) {
1008 const auto& powerModeSuspendStatus =
1009 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON_SUSPEND);
1010 EXPECT_FALSE(powerModeSuspendStatus.isOk());
1011 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeSuspendStatus,
1012 IComposerClient::EX_UNSUPPORTED));
1013
1014 const auto& powerModeDozeSuspendStatus =
1015 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::DOZE_SUSPEND);
1016 EXPECT_FALSE(powerModeDozeSuspendStatus.isOk());
1017 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(powerModeDozeSuspendStatus,
1018 IComposerClient::EX_UNSUPPORTED));
1019 }
1020 }
1021
TEST_P(GraphicsComposerAidlTest,SetVsyncEnabled)1022 TEST_P(GraphicsComposerAidlTest, SetVsyncEnabled) {
1023 mComposerClient->setVsyncAllowed(true);
1024
1025 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), true).isOk());
1026 usleep(60 * 1000);
1027 EXPECT_TRUE(mComposerClient->setVsync(getPrimaryDisplayId(), false).isOk());
1028
1029 mComposerClient->setVsyncAllowed(false);
1030 }
1031
TEST_P(GraphicsComposerAidlTest,SetPowerMode)1032 TEST_P(GraphicsComposerAidlTest, SetPowerMode) {
1033 const auto& [status, capabilities] =
1034 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1035 ASSERT_TRUE(status.isOk());
1036
1037 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1038 DisplayCapability::DOZE) != capabilities.end();
1039 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1040 DisplayCapability::SUSPEND) != capabilities.end();
1041
1042 std::vector<PowerMode> modes;
1043 modes.push_back(PowerMode::OFF);
1044 modes.push_back(PowerMode::ON);
1045
1046 if (isSuspendSupported) {
1047 modes.push_back(PowerMode::ON_SUSPEND);
1048 }
1049
1050 if (isDozeSupported) {
1051 modes.push_back(PowerMode::DOZE);
1052 }
1053
1054 if (isSuspendSupported && isDozeSupported) {
1055 modes.push_back(PowerMode::DOZE_SUSPEND);
1056 }
1057
1058 for (auto mode : modes) {
1059 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1060 }
1061 }
1062
TEST_P(GraphicsComposerAidlTest,SetPowerModeVariations)1063 TEST_P(GraphicsComposerAidlTest, SetPowerModeVariations) {
1064 const auto& [status, capabilities] =
1065 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1066 ASSERT_TRUE(status.isOk());
1067
1068 const bool isDozeSupported = std::find(capabilities.begin(), capabilities.end(),
1069 DisplayCapability::DOZE) != capabilities.end();
1070 const bool isSuspendSupported = std::find(capabilities.begin(), capabilities.end(),
1071 DisplayCapability::SUSPEND) != capabilities.end();
1072
1073 std::vector<PowerMode> modes;
1074
1075 modes.push_back(PowerMode::OFF);
1076 modes.push_back(PowerMode::ON);
1077 modes.push_back(PowerMode::OFF);
1078 for (auto mode : modes) {
1079 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1080 }
1081 modes.clear();
1082
1083 modes.push_back(PowerMode::OFF);
1084 modes.push_back(PowerMode::OFF);
1085 for (auto mode : modes) {
1086 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1087 }
1088 modes.clear();
1089
1090 modes.push_back(PowerMode::ON);
1091 modes.push_back(PowerMode::ON);
1092 for (auto mode : modes) {
1093 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1094 }
1095 modes.clear();
1096
1097 if (isSuspendSupported) {
1098 modes.push_back(PowerMode::ON_SUSPEND);
1099 modes.push_back(PowerMode::ON_SUSPEND);
1100 for (auto mode : modes) {
1101 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1102 }
1103 modes.clear();
1104 }
1105
1106 if (isDozeSupported) {
1107 modes.push_back(PowerMode::DOZE);
1108 modes.push_back(PowerMode::DOZE);
1109 for (auto mode : modes) {
1110 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1111 }
1112 modes.clear();
1113 }
1114
1115 if (isSuspendSupported && isDozeSupported) {
1116 modes.push_back(PowerMode::DOZE_SUSPEND);
1117 modes.push_back(PowerMode::DOZE_SUSPEND);
1118 for (auto mode : modes) {
1119 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), mode).isOk());
1120 }
1121 modes.clear();
1122 }
1123 }
1124
TEST_P(GraphicsComposerAidlTest,SetPowerMode_BadDisplay)1125 TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadDisplay) {
1126 const auto& status = mComposerClient->setPowerMode(getInvalidDisplayId(), PowerMode::ON);
1127
1128 EXPECT_FALSE(status.isOk());
1129 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
1130 }
1131
TEST_P(GraphicsComposerAidlTest,SetPowerMode_BadParameter)1132 TEST_P(GraphicsComposerAidlTest, SetPowerMode_BadParameter) {
1133 const auto& status =
1134 mComposerClient->setPowerMode(getPrimaryDisplayId(), static_cast<PowerMode>(-1));
1135
1136 EXPECT_FALSE(status.isOk());
1137 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
1138 }
1139
TEST_P(GraphicsComposerAidlTest,GetDataspaceSaturationMatrix)1140 TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix) {
1141 const auto& [status, matrix] =
1142 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::SRGB_LINEAR);
1143 ASSERT_TRUE(status.isOk());
1144 ASSERT_EQ(16, matrix.size()); // matrix should not be empty if call succeeded.
1145
1146 // the last row is known
1147 EXPECT_EQ(0.0f, matrix[12]);
1148 EXPECT_EQ(0.0f, matrix[13]);
1149 EXPECT_EQ(0.0f, matrix[14]);
1150 EXPECT_EQ(1.0f, matrix[15]);
1151 }
1152
TEST_P(GraphicsComposerAidlTest,GetDataspaceSaturationMatrix_BadParameter)1153 TEST_P(GraphicsComposerAidlTest, GetDataspaceSaturationMatrix_BadParameter) {
1154 const auto& [status, matrix] =
1155 mComposerClient->getDataspaceSaturationMatrix(common::Dataspace::UNKNOWN);
1156
1157 EXPECT_FALSE(status.isOk());
1158 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
1159 }
1160
1161 /*
1162 * Test that no two display configs are exactly the same.
1163 */
TEST_P(GraphicsComposerAidlTest,GetDisplayConfigNoRepetitions)1164 TEST_P(GraphicsComposerAidlTest, GetDisplayConfigNoRepetitions) {
1165 for (const auto& display : mDisplays) {
1166 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
1167 for (std::vector<int>::size_type i = 0; i < configs.size(); i++) {
1168 for (std::vector<int>::size_type j = i + 1; j < configs.size(); j++) {
1169 const auto& [widthStatus1, width1] = mComposerClient->getDisplayAttribute(
1170 display.getDisplayId(), configs[i], DisplayAttribute::WIDTH);
1171 const auto& [heightStatus1, height1] = mComposerClient->getDisplayAttribute(
1172 display.getDisplayId(), configs[i], DisplayAttribute::HEIGHT);
1173 const auto& [vsyncPeriodStatus1, vsyncPeriod1] =
1174 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[i],
1175 DisplayAttribute::VSYNC_PERIOD);
1176 const auto& [groupStatus1, group1] = mComposerClient->getDisplayAttribute(
1177 display.getDisplayId(), configs[i], DisplayAttribute::CONFIG_GROUP);
1178
1179 const auto& [widthStatus2, width2] = mComposerClient->getDisplayAttribute(
1180 display.getDisplayId(), configs[j], DisplayAttribute::WIDTH);
1181 const auto& [heightStatus2, height2] = mComposerClient->getDisplayAttribute(
1182 display.getDisplayId(), configs[j], DisplayAttribute::HEIGHT);
1183 const auto& [vsyncPeriodStatus2, vsyncPeriod2] =
1184 mComposerClient->getDisplayAttribute(display.getDisplayId(), configs[j],
1185 DisplayAttribute::VSYNC_PERIOD);
1186 const auto& [groupStatus2, group2] = mComposerClient->getDisplayAttribute(
1187 display.getDisplayId(), configs[j], DisplayAttribute::CONFIG_GROUP);
1188
1189 ASSERT_FALSE(width1 == width2 && height1 == height2 &&
1190 vsyncPeriod1 == vsyncPeriod2 && group1 == group2);
1191 }
1192 }
1193 }
1194 }
1195
TEST_P(GraphicsComposerAidlTest,LayerLifecycleCapabilityNotSupportedOnOldVersions)1196 TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
1197 if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
1198 EXPECT_GE(getInterfaceVersion(), 3);
1199 }
1200 }
1201
1202 class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
1203 protected:
SetUp()1204 void SetUp() override {
1205 GraphicsComposerAidlTest::SetUp();
1206 if (getInterfaceVersion() <= 1) {
1207 GTEST_SKIP() << "Device interface version is expected to be >= 2";
1208 }
1209 }
1210 };
1211
TEST_P(GraphicsComposerAidlV2Test,GetOverlaySupport)1212 TEST_P(GraphicsComposerAidlV2Test, GetOverlaySupport) {
1213 const auto& [status, properties] = mComposerClient->getOverlaySupport();
1214 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
1215 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
1216 GTEST_SUCCEED() << "getOverlaySupport is not supported";
1217 return;
1218 }
1219
1220 ASSERT_TRUE(status.isOk());
1221 for (const auto& i : properties.combinations) {
1222 for (const auto standard : i.standards) {
1223 const auto val = static_cast<int32_t>(standard) &
1224 static_cast<int32_t>(common::Dataspace::STANDARD_MASK);
1225 ASSERT_TRUE(val == static_cast<int32_t>(standard));
1226 }
1227 for (const auto transfer : i.transfers) {
1228 const auto val = static_cast<int32_t>(transfer) &
1229 static_cast<int32_t>(common::Dataspace::TRANSFER_MASK);
1230 ASSERT_TRUE(val == static_cast<int32_t>(transfer));
1231 }
1232 for (const auto range : i.ranges) {
1233 const auto val = static_cast<int32_t>(range) &
1234 static_cast<int32_t>(common::Dataspace::RANGE_MASK);
1235 ASSERT_TRUE(val == static_cast<int32_t>(range));
1236 }
1237 }
1238 }
1239
1240 class GraphicsComposerAidlV3Test : public GraphicsComposerAidlTest {
1241 protected:
SetUp()1242 void SetUp() override {
1243 GraphicsComposerAidlTest::SetUp();
1244 if (getInterfaceVersion() <= 2) {
1245 GTEST_SKIP() << "Device interface version is expected to be >= 3";
1246 }
1247 }
1248 };
1249
TEST_P(GraphicsComposerAidlV3Test,GetDisplayConfigurations)1250 TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigurations) {
1251 for (const auto& display : mDisplays) {
1252 const auto& [status, displayConfigurations] =
1253 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1254 EXPECT_TRUE(status.isOk());
1255 EXPECT_FALSE(displayConfigurations.empty());
1256
1257 for (const auto& displayConfig : displayConfigurations) {
1258 EXPECT_NE(-1, displayConfig.width);
1259 EXPECT_NE(-1, displayConfig.height);
1260 EXPECT_NE(-1, displayConfig.vsyncPeriod);
1261 EXPECT_NE(-1, displayConfig.configGroup);
1262 if (displayConfig.dpi) {
1263 EXPECT_NE(-1.f, displayConfig.dpi->x);
1264 EXPECT_NE(-1.f, displayConfig.dpi->y);
1265 }
1266 if (displayConfig.vrrConfig) {
1267 const auto& vrrConfig = *displayConfig.vrrConfig;
1268 EXPECT_GE(vrrConfig.minFrameIntervalNs, displayConfig.vsyncPeriod);
1269
1270 EXPECT_EQ(1, std::count_if(
1271 displayConfigurations.cbegin(), displayConfigurations.cend(),
1272 [displayConfig](const auto& config) {
1273 return config.configGroup == displayConfig.configGroup;
1274 }))
1275 << "There should be only one VRR mode in one ConfigGroup";
1276
1277 const auto verifyFrameIntervalIsDivisorOfVsync = [&](int32_t frameIntervalNs) {
1278 constexpr auto kThreshold = 0.05f; // 5%
1279 const auto ratio =
1280 static_cast<float>(frameIntervalNs) / displayConfig.vsyncPeriod;
1281 return ratio - std::round(ratio) <= kThreshold;
1282 };
1283
1284 EXPECT_TRUE(verifyFrameIntervalIsDivisorOfVsync(vrrConfig.minFrameIntervalNs));
1285
1286 if (vrrConfig.frameIntervalPowerHints) {
1287 const auto& frameIntervalPowerHints = *vrrConfig.frameIntervalPowerHints;
1288 EXPECT_FALSE(frameIntervalPowerHints.empty());
1289
1290 const auto minFrameInterval = *min_element(frameIntervalPowerHints.cbegin(),
1291 frameIntervalPowerHints.cend());
1292 EXPECT_LE(minFrameInterval->frameIntervalNs,
1293 VtsComposerClient::kMaxFrameIntervalNs);
1294 const auto maxFrameInterval = *max_element(frameIntervalPowerHints.cbegin(),
1295 frameIntervalPowerHints.cend());
1296 EXPECT_GE(maxFrameInterval->frameIntervalNs, vrrConfig.minFrameIntervalNs);
1297
1298 EXPECT_TRUE(std::all_of(frameIntervalPowerHints.cbegin(),
1299 frameIntervalPowerHints.cend(),
1300 [&](const auto& frameIntervalPowerHint) {
1301 return verifyFrameIntervalIsDivisorOfVsync(
1302 frameIntervalPowerHint->frameIntervalNs);
1303 }));
1304 }
1305
1306 if (vrrConfig.notifyExpectedPresentConfig) {
1307 const auto& notifyExpectedPresentConfig =
1308 *vrrConfig.notifyExpectedPresentConfig;
1309 EXPECT_GE(notifyExpectedPresentConfig.headsUpNs, 0);
1310 EXPECT_GE(notifyExpectedPresentConfig.timeoutNs, 0);
1311 }
1312 }
1313 }
1314 }
1315 }
1316
TEST_P(GraphicsComposerAidlV3Test,GetDisplayConfigsIsSubsetOfGetDisplayConfigurations)1317 TEST_P(GraphicsComposerAidlV3Test, GetDisplayConfigsIsSubsetOfGetDisplayConfigurations) {
1318 for (const auto& display : mDisplays) {
1319 const auto& [status, displayConfigurations] =
1320 mComposerClient->getDisplayConfigurations(display.getDisplayId());
1321 EXPECT_TRUE(status.isOk());
1322
1323 const auto& [legacyConfigStatus, legacyConfigs] =
1324 mComposerClient->getDisplayConfigs(display.getDisplayId());
1325 EXPECT_TRUE(legacyConfigStatus.isOk());
1326 EXPECT_FALSE(legacyConfigs.empty());
1327 EXPECT_TRUE(legacyConfigs.size() <= displayConfigurations.size());
1328
1329 for (const auto legacyConfigId : legacyConfigs) {
1330 const auto& legacyWidth = mComposerClient->getDisplayAttribute(
1331 display.getDisplayId(), legacyConfigId, DisplayAttribute::WIDTH);
1332 const auto& legacyHeight = mComposerClient->getDisplayAttribute(
1333 display.getDisplayId(), legacyConfigId, DisplayAttribute::HEIGHT);
1334 const auto& legacyVsyncPeriod = mComposerClient->getDisplayAttribute(
1335 display.getDisplayId(), legacyConfigId, DisplayAttribute::VSYNC_PERIOD);
1336 const auto& legacyConfigGroup = mComposerClient->getDisplayAttribute(
1337 display.getDisplayId(), legacyConfigId, DisplayAttribute::CONFIG_GROUP);
1338 const auto& legacyDpiX = mComposerClient->getDisplayAttribute(
1339 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_X);
1340 const auto& legacyDpiY = mComposerClient->getDisplayAttribute(
1341 display.getDisplayId(), legacyConfigId, DisplayAttribute::DPI_Y);
1342
1343 EXPECT_TRUE(legacyWidth.first.isOk() && legacyHeight.first.isOk() &&
1344 legacyVsyncPeriod.first.isOk() && legacyConfigGroup.first.isOk());
1345
1346 EXPECT_TRUE(std::any_of(
1347 displayConfigurations.begin(), displayConfigurations.end(),
1348 [&](const auto& displayConfiguration) {
1349 const bool requiredAttributesPredicate =
1350 displayConfiguration.configId == legacyConfigId &&
1351 displayConfiguration.width == legacyWidth.second &&
1352 displayConfiguration.height == legacyHeight.second &&
1353 displayConfiguration.vsyncPeriod == legacyVsyncPeriod.second &&
1354 displayConfiguration.configGroup == legacyConfigGroup.second;
1355
1356 if (!requiredAttributesPredicate) {
1357 // Required attributes did not match
1358 return false;
1359 }
1360
1361 // Check optional attributes
1362 const auto& [legacyDpiXStatus, legacyDpiXValue] = legacyDpiX;
1363 const auto& [legacyDpiYStatus, legacyDpiYValue] = legacyDpiY;
1364 if (displayConfiguration.dpi) {
1365 if (!legacyDpiXStatus.isOk() || !legacyDpiYStatus.isOk()) {
1366 // getDisplayAttribute failed for optional attributes
1367 return false;
1368 }
1369
1370 // DPI values in DisplayConfigurations are not scaled (* 1000.f)
1371 // the way they are in the legacy DisplayConfigs.
1372 constexpr float kEpsilon = 0.001f;
1373 return std::abs(displayConfiguration.dpi->x -
1374 legacyDpiXValue / 1000.f) < kEpsilon &&
1375 std::abs(displayConfiguration.dpi->y -
1376 legacyDpiYValue / 1000.f) < kEpsilon;
1377 } else {
1378 return !legacyDpiXStatus.isOk() && !legacyDpiYStatus.isOk() &&
1379 EX_SERVICE_SPECIFIC == legacyDpiXStatus.getExceptionCode() &&
1380 EX_SERVICE_SPECIFIC == legacyDpiYStatus.getExceptionCode() &&
1381 IComposerClient::EX_UNSUPPORTED ==
1382 legacyDpiXStatus.getServiceSpecificError() &&
1383 IComposerClient::EX_UNSUPPORTED ==
1384 legacyDpiYStatus.getServiceSpecificError();
1385 }
1386 }));
1387 }
1388 }
1389 }
1390
1391 // Tests for Command.
1392 class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest {
1393 protected:
TearDown()1394 void TearDown() override {
1395 ASSERT_FALSE(mDisplays.empty());
1396 ASSERT_TRUE(mReader.takeErrors().empty());
1397 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
1398
1399 ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
1400 ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
1401 }
1402
execute()1403 void execute() {
1404 std::vector<CommandResultPayload> payloads;
1405 for (auto& [_, writer] : mWriters) {
1406 executeInternal(writer, payloads);
1407 }
1408 mReader.parse(std::move(payloads));
1409 }
1410
execute(ComposerClientWriter & writer,ComposerClientReader & reader)1411 void execute(ComposerClientWriter& writer, ComposerClientReader& reader) {
1412 std::vector<CommandResultPayload> payloads;
1413 executeInternal(writer, payloads);
1414 reader.parse(std::move(payloads));
1415 }
1416
toTimePoint(nsecs_t time)1417 static inline auto toTimePoint(nsecs_t time) {
1418 return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
1419 }
1420
forEachTwoConfigs(int64_t display,std::function<void (int32_t,int32_t)> func)1421 void forEachTwoConfigs(int64_t display, std::function<void(int32_t, int32_t)> func) {
1422 const auto& [status, displayConfigs] = mComposerClient->getDisplayConfigs(display);
1423 ASSERT_TRUE(status.isOk());
1424 for (const int32_t config1 : displayConfigs) {
1425 for (const int32_t config2 : displayConfigs) {
1426 if (config1 != config2) {
1427 func(config1, config2);
1428 }
1429 }
1430 }
1431 }
1432
waitForVsyncPeriodChange(int64_t display,const VsyncPeriodChangeTimeline & timeline,int64_t desiredTimeNanos,int64_t oldPeriodNanos,int64_t newPeriodNanos)1433 void waitForVsyncPeriodChange(int64_t display, const VsyncPeriodChangeTimeline& timeline,
1434 int64_t desiredTimeNanos, int64_t oldPeriodNanos,
1435 int64_t newPeriodNanos) {
1436 const auto kChangeDeadline = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
1437 while (std::chrono::steady_clock::now() <= kChangeDeadline) {
1438 const auto& [status, vsyncPeriodNanos] =
1439 mComposerClient->getDisplayVsyncPeriod(display);
1440 EXPECT_TRUE(status.isOk());
1441 if (systemTime() <= desiredTimeNanos) {
1442 EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
1443 } else if (vsyncPeriodNanos == newPeriodNanos) {
1444 break;
1445 }
1446 std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
1447 }
1448 }
1449
checkIfCallbackRefreshRateChangedDebugEnabledReceived(std::function<bool (RefreshRateChangedDebugData)> filter)1450 bool checkIfCallbackRefreshRateChangedDebugEnabledReceived(
1451 std::function<bool(RefreshRateChangedDebugData)> filter) {
1452 const auto list = mComposerClient->takeListOfRefreshRateChangedDebugData();
1453 return std::any_of(list.begin(), list.end(), [&](auto refreshRateChangedDebugData) {
1454 return filter(refreshRateChangedDebugData);
1455 });
1456 }
1457
allocate(uint32_t width,uint32_t height,::android::PixelFormat pixelFormat)1458 sp<GraphicBuffer> allocate(uint32_t width, uint32_t height,
1459 ::android::PixelFormat pixelFormat) {
1460 return sp<GraphicBuffer>::make(
1461 width, height, pixelFormat, /*layerCount*/ 1U,
1462 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
1463 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
1464 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY),
1465 "VtsHalGraphicsComposer3_TargetTest");
1466 }
1467
allocate(::android::PixelFormat pixelFormat)1468 sp<GraphicBuffer> allocate(::android::PixelFormat pixelFormat) {
1469 return allocate(static_cast<uint32_t>(getPrimaryDisplay().getDisplayWidth()),
1470 static_cast<uint32_t>(getPrimaryDisplay().getDisplayHeight()), pixelFormat);
1471 }
1472
sendRefreshFrame(const VtsDisplay & display,const VsyncPeriodChangeTimeline * timeline)1473 void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline* timeline) {
1474 if (timeline != nullptr) {
1475 // Refresh time should be before newVsyncAppliedTimeNanos
1476 EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
1477
1478 std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
1479 }
1480
1481 EXPECT_TRUE(mComposerClient->setPowerMode(display.getDisplayId(), PowerMode::ON).isOk());
1482 EXPECT_TRUE(mComposerClient
1483 ->setColorMode(display.getDisplayId(), ColorMode::NATIVE,
1484 RenderIntent::COLORIMETRIC)
1485 .isOk());
1486
1487 auto& writer = getWriter(display.getDisplayId());
1488 const auto& [status, layer] =
1489 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
1490 EXPECT_TRUE(status.isOk());
1491 {
1492 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1493 ASSERT_NE(nullptr, buffer);
1494 ASSERT_EQ(::android::OK, buffer->initCheck());
1495 ASSERT_NE(nullptr, buffer->handle);
1496
1497 configureLayer(display, layer, Composition::DEVICE, display.getFrameRect(),
1498 display.getCrop());
1499 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1500 /*acquireFence*/ -1);
1501 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
1502
1503 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1504 VtsComposerClient::kNoFrameIntervalNs);
1505 execute();
1506 ASSERT_TRUE(mReader.takeErrors().empty());
1507
1508 writer.presentDisplay(display.getDisplayId());
1509 execute();
1510 ASSERT_TRUE(mReader.takeErrors().empty());
1511 }
1512
1513 {
1514 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1515 ASSERT_NE(nullptr, buffer->handle);
1516
1517 writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, buffer->handle,
1518 /*acquireFence*/ -1);
1519 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1520 std::vector<Rect>(1, {0, 0, 10, 10}));
1521 writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
1522 VtsComposerClient::kNoFrameIntervalNs);
1523 execute();
1524 ASSERT_TRUE(mReader.takeErrors().empty());
1525
1526 writer.presentDisplay(display.getDisplayId());
1527 execute();
1528 }
1529
1530 EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
1531 }
1532
presentAndGetFence(std::optional<ClockMonotonicTimestamp> expectedPresentTime,std::optional<int64_t> displayIdOpt={},int32_t frameIntervalNs=VtsComposerClient::kNoFrameIntervalNs)1533 sp<::android::Fence> presentAndGetFence(
1534 std::optional<ClockMonotonicTimestamp> expectedPresentTime,
1535 std::optional<int64_t> displayIdOpt = {},
1536 int32_t frameIntervalNs = VtsComposerClient::kNoFrameIntervalNs) {
1537 const auto displayId = displayIdOpt.value_or(getPrimaryDisplayId());
1538 auto& writer = getWriter(displayId);
1539 writer.validateDisplay(displayId, expectedPresentTime, frameIntervalNs);
1540 execute();
1541 EXPECT_TRUE(mReader.takeErrors().empty());
1542
1543 writer.presentDisplay(displayId);
1544 execute();
1545 EXPECT_TRUE(mReader.takeErrors().empty());
1546
1547 auto presentFence = mReader.takePresentFence(displayId);
1548 // take ownership
1549 const int fenceOwner = presentFence.get();
1550 *presentFence.getR() = -1;
1551 EXPECT_NE(-1, fenceOwner);
1552 return sp<::android::Fence>::make(fenceOwner);
1553 }
1554
getVsyncPeriod()1555 int32_t getVsyncPeriod() {
1556 const auto& [status, activeConfig] =
1557 mComposerClient->getActiveConfig(getPrimaryDisplayId());
1558 EXPECT_TRUE(status.isOk());
1559
1560 const auto& [vsyncPeriodStatus, vsyncPeriod] = mComposerClient->getDisplayAttribute(
1561 getPrimaryDisplayId(), activeConfig, DisplayAttribute::VSYNC_PERIOD);
1562 EXPECT_TRUE(vsyncPeriodStatus.isOk());
1563 return vsyncPeriod;
1564 }
1565
createOnScreenLayer(const VtsDisplay & display,Composition composition=Composition::DEVICE)1566 int64_t createOnScreenLayer(const VtsDisplay& display,
1567 Composition composition = Composition::DEVICE) {
1568 auto& writer = getWriter(display.getDisplayId());
1569 const auto& [status, layer] =
1570 mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
1571 EXPECT_TRUE(status.isOk());
1572 Rect displayFrame{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
1573 FRect cropRect{0, 0, (float)display.getDisplayWidth(), (float)display.getDisplayHeight()};
1574 configureLayer(display, layer, composition, displayFrame, cropRect);
1575
1576 writer.setLayerDataspace(display.getDisplayId(), layer, common::Dataspace::UNKNOWN);
1577 return layer;
1578 }
1579
sendBufferUpdate(int64_t layer)1580 void sendBufferUpdate(int64_t layer) {
1581 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1582 ASSERT_NE(nullptr, buffer->handle);
1583
1584 auto& writer = getWriter(getPrimaryDisplayId());
1585 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
1586 /*acquireFence*/ -1);
1587
1588 const sp<::android::Fence> presentFence =
1589 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1590 presentFence->waitForever(LOG_TAG);
1591 }
1592
hasDisplayCapability(int64_t display,DisplayCapability cap)1593 bool hasDisplayCapability(int64_t display, DisplayCapability cap) {
1594 const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(display);
1595 EXPECT_TRUE(status.isOk());
1596
1597 return std::find(capabilities.begin(), capabilities.end(), cap) != capabilities.end();
1598 }
1599
Test_setActiveConfigWithConstraints(const TestParameters & params)1600 void Test_setActiveConfigWithConstraints(const TestParameters& params) {
1601 for (VtsDisplay& display : mDisplays) {
1602 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
1603 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
1604 sendRefreshFrame(display, nullptr);
1605
1606 const auto displayConfig1 = display.getDisplayConfig(config1);
1607 int32_t vsyncPeriod1 = displayConfig1.vsyncPeriod;
1608 int32_t configGroup1 = displayConfig1.configGroup;
1609
1610 const auto displayConfig2 = display.getDisplayConfig(config2);
1611 int32_t vsyncPeriod2 = displayConfig2.vsyncPeriod;
1612 int32_t configGroup2 = displayConfig2.configGroup;
1613
1614 if (vsyncPeriod1 == vsyncPeriod2) {
1615 return; // continue
1616 }
1617
1618 if ((!displayConfig1.vrrConfigOpt && displayConfig2.vrrConfigOpt) ||
1619 (displayConfig1.vrrConfigOpt && !displayConfig2.vrrConfigOpt)) {
1620 // switching between vrr to non-vrr modes
1621 return; // continue
1622 }
1623
1624 // We don't allow delayed change when changing config groups
1625 if (params.delayForChange > 0 && configGroup1 != configGroup2) {
1626 return; // continue
1627 }
1628
1629 VsyncPeriodChangeConstraints constraints = {
1630 .desiredTimeNanos = systemTime() + params.delayForChange,
1631 .seamlessRequired = false};
1632 const auto& [status, timeline] = mComposerClient->setActiveConfigWithConstraints(
1633 &display, config2, constraints);
1634 EXPECT_TRUE(status.isOk());
1635
1636 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
1637 // Refresh rate should change within a reasonable time
1638 constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
1639 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
1640 kReasonableTimeForChange.count());
1641
1642 if (timeline.refreshRequired) {
1643 if (params.refreshMiss) {
1644 // Miss the refresh frame on purpose to make sure the implementation sends a
1645 // callback
1646 std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) +
1647 100ms);
1648 }
1649 sendRefreshFrame(display, &timeline);
1650 }
1651 waitForVsyncPeriodChange(display.getDisplayId(), timeline,
1652 constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
1653
1654 // At this point the refresh rate should have changed already, however in rare
1655 // cases the implementation might have missed the deadline. In this case a new
1656 // timeline should have been provided.
1657 auto newTimeline = mComposerClient->takeLastVsyncPeriodChangeTimeline();
1658 if (timeline.refreshRequired && params.refreshMiss) {
1659 EXPECT_TRUE(newTimeline.has_value());
1660 }
1661
1662 if (newTimeline.has_value()) {
1663 if (newTimeline->refreshRequired) {
1664 sendRefreshFrame(display, &newTimeline.value());
1665 }
1666 waitForVsyncPeriodChange(display.getDisplayId(), newTimeline.value(),
1667 constraints.desiredTimeNanos, vsyncPeriod1,
1668 vsyncPeriod2);
1669 }
1670
1671 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanos] =
1672 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
1673 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
1674 EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
1675 });
1676 }
1677 }
1678
Test_expectedPresentTime(std::optional<int> framesDelay)1679 void Test_expectedPresentTime(std::optional<int> framesDelay) {
1680 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
1681 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
1682 return;
1683 }
1684
1685 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
1686
1687 const auto vsyncPeriod = getVsyncPeriod();
1688
1689 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1690 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1691 ASSERT_NE(nullptr, buffer1);
1692 ASSERT_NE(nullptr, buffer2);
1693
1694 const auto layer = createOnScreenLayer(getPrimaryDisplay());
1695 auto& writer = getWriter(getPrimaryDisplayId());
1696 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer1->handle,
1697 /*acquireFence*/ -1);
1698 const sp<::android::Fence> presentFence1 =
1699 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
1700 presentFence1->waitForever(LOG_TAG);
1701
1702 auto expectedPresentTime = presentFence1->getSignalTime() + vsyncPeriod;
1703 if (framesDelay.has_value()) {
1704 expectedPresentTime += *framesDelay * vsyncPeriod;
1705 }
1706
1707 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer2->handle,
1708 /*acquireFence*/ -1);
1709 const auto setExpectedPresentTime = [&]() -> std::optional<ClockMonotonicTimestamp> {
1710 if (!framesDelay.has_value()) {
1711 return ComposerClientWriter::kNoTimestamp;
1712 } else if (*framesDelay == 0) {
1713 return ClockMonotonicTimestamp{0};
1714 }
1715 return ClockMonotonicTimestamp{expectedPresentTime};
1716 }();
1717
1718 const sp<::android::Fence> presentFence2 = presentAndGetFence(setExpectedPresentTime);
1719 presentFence2->waitForever(LOG_TAG);
1720
1721 const auto actualPresentTime = presentFence2->getSignalTime();
1722 EXPECT_GE(actualPresentTime, expectedPresentTime - vsyncPeriod / 2);
1723
1724 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
1725 }
1726
forEachNotifyExpectedPresentConfig(std::function<void (VtsDisplay &,const DisplayConfiguration &)> func)1727 void forEachNotifyExpectedPresentConfig(
1728 std::function<void(VtsDisplay&, const DisplayConfiguration&)> func) {
1729 for (VtsDisplay& display : mDisplays) {
1730 const auto displayId = display.getDisplayId();
1731 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
1732 const auto& [status, displayConfigurations] =
1733 mComposerClient->getDisplayConfigurations(displayId);
1734 EXPECT_TRUE(status.isOk());
1735 EXPECT_FALSE(displayConfigurations.empty());
1736 for (const auto& config : displayConfigurations) {
1737 if (config.vrrConfig && config.vrrConfig->notifyExpectedPresentConfig) {
1738 const auto [vsyncPeriodStatus, oldVsyncPeriod] =
1739 mComposerClient->getDisplayVsyncPeriod(displayId);
1740 ASSERT_TRUE(vsyncPeriodStatus.isOk());
1741 const auto& [timelineStatus, timeline] =
1742 mComposerClient->setActiveConfigWithConstraints(
1743 &display, config.configId,
1744 VsyncPeriodChangeConstraints{.seamlessRequired = false});
1745 ASSERT_TRUE(timelineStatus.isOk());
1746 if (timeline.refreshRequired) {
1747 sendRefreshFrame(display, &timeline);
1748 }
1749 waitForVsyncPeriodChange(displayId, timeline, systemTime(), oldVsyncPeriod,
1750 config.vsyncPeriod);
1751 func(display, config);
1752 }
1753 }
1754 EXPECT_TRUE(
1755 mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
1756 }
1757 }
1758
configureLayer(const VtsDisplay & display,int64_t layer,Composition composition,const Rect & displayFrame,const FRect & cropRect)1759 void configureLayer(const VtsDisplay& display, int64_t layer, Composition composition,
1760 const Rect& displayFrame, const FRect& cropRect) {
1761 auto& writer = getWriter(display.getDisplayId());
1762 writer.setLayerCompositionType(display.getDisplayId(), layer, composition);
1763 writer.setLayerDisplayFrame(display.getDisplayId(), layer, displayFrame);
1764 writer.setLayerPlaneAlpha(display.getDisplayId(), layer, /*alpha*/ 1);
1765 writer.setLayerSourceCrop(display.getDisplayId(), layer, cropRect);
1766 writer.setLayerTransform(display.getDisplayId(), layer, static_cast<Transform>(0));
1767 writer.setLayerVisibleRegion(display.getDisplayId(), layer,
1768 std::vector<Rect>(1, displayFrame));
1769 writer.setLayerZOrder(display.getDisplayId(), layer, /*z*/ 10);
1770 writer.setLayerBlendMode(display.getDisplayId(), layer, BlendMode::NONE);
1771 writer.setLayerSurfaceDamage(display.getDisplayId(), layer,
1772 std::vector<Rect>(1, displayFrame));
1773 }
1774 // clang-format off
1775 const std::array<float, 16> kIdentity = {{
1776 1.0f, 0.0f, 0.0f, 0.0f,
1777 0.0f, 1.0f, 0.0f, 0.0f,
1778 0.0f, 0.0f, 1.0f, 0.0f,
1779 0.0f, 0.0f, 0.0f, 1.0f,
1780 }};
1781 // clang-format on
1782
getWriter(int64_t display)1783 ComposerClientWriter& getWriter(int64_t display) {
1784 std::lock_guard guard{mWritersMutex};
1785 auto [it, _] = mWriters.try_emplace(display, display);
1786 return it->second;
1787 }
1788
1789 ComposerClientReader mReader;
1790
1791 private:
executeInternal(ComposerClientWriter & writer,std::vector<CommandResultPayload> & payloads)1792 void executeInternal(ComposerClientWriter& writer,
1793 std::vector<CommandResultPayload>& payloads) {
1794 auto commands = writer.takePendingCommands();
1795 if (commands.empty()) {
1796 return;
1797 }
1798
1799 auto [status, results] = mComposerClient->executeCommands(commands);
1800 ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
1801
1802 payloads.reserve(payloads.size() + results.size());
1803 payloads.insert(payloads.end(), std::make_move_iterator(results.begin()),
1804 std::make_move_iterator(results.end()));
1805 }
1806
1807 // Guards access to the map itself. Callers must ensure not to attempt to
1808 // - modify the same writer from multiple threads
1809 // - insert a new writer into the map during concurrent access, which would invalidate
1810 // references from other threads
1811 std::mutex mWritersMutex;
1812 std::unordered_map<int64_t, ComposerClientWriter> mWriters GUARDED_BY(mWritersMutex);
1813 };
1814
TEST_P(GraphicsComposerAidlCommandTest,SetColorTransform)1815 TEST_P(GraphicsComposerAidlCommandTest, SetColorTransform) {
1816 auto& writer = getWriter(getPrimaryDisplayId());
1817 writer.setColorTransform(getPrimaryDisplayId(), kIdentity.data());
1818 execute();
1819 }
1820
TEST_P(GraphicsComposerAidlCommandTest,SetLayerColorTransform)1821 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
1822 auto& writer = getWriter(getPrimaryDisplayId());
1823 const auto& [status, layer] =
1824 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
1825 EXPECT_TRUE(status.isOk());
1826 writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
1827 execute();
1828
1829 const auto errors = mReader.takeErrors();
1830 if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) {
1831 GTEST_SUCCEED() << "setLayerColorTransform is not supported";
1832 return;
1833 }
1834 }
1835
TEST_P(GraphicsComposerAidlCommandTest,SetDisplayBrightness)1836 TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
1837 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
1838 const auto& [status, capabilities] =
1839 mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
1840 ASSERT_TRUE(status.isOk());
1841 bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
1842 DisplayCapability::BRIGHTNESS) != capabilities.end();
1843 auto& writer = getWriter(getPrimaryDisplayId());
1844 if (!brightnessSupport) {
1845 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
1846 execute();
1847 const auto errors = mReader.takeErrors();
1848 EXPECT_EQ(1, errors.size());
1849 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
1850 GTEST_SUCCEED() << "SetDisplayBrightness is not supported";
1851 return;
1852 }
1853
1854 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.0f, -1.f);
1855 execute();
1856 EXPECT_TRUE(mReader.takeErrors().empty());
1857
1858 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 0.5f, -1.f);
1859 execute();
1860 EXPECT_TRUE(mReader.takeErrors().empty());
1861
1862 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 1.0f, -1.f);
1863 execute();
1864 EXPECT_TRUE(mReader.takeErrors().empty());
1865
1866 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -1.0f, -1.f);
1867 execute();
1868 EXPECT_TRUE(mReader.takeErrors().empty());
1869
1870 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ 2.0f, -1.f);
1871 execute();
1872 {
1873 const auto errors = mReader.takeErrors();
1874 ASSERT_EQ(1, errors.size());
1875 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1876 }
1877
1878 writer.setDisplayBrightness(getPrimaryDisplayId(), /*brightness*/ -2.0f, -1.f);
1879 execute();
1880 {
1881 const auto errors = mReader.takeErrors();
1882 ASSERT_EQ(1, errors.size());
1883 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
1884 }
1885 }
1886
TEST_P(GraphicsComposerAidlCommandTest,SetClientTarget)1887 TEST_P(GraphicsComposerAidlCommandTest, SetClientTarget) {
1888 EXPECT_TRUE(mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kBufferSlotCount)
1889 .isOk());
1890
1891 auto& writer = getWriter(getPrimaryDisplayId());
1892 writer.setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, nullptr, /*acquireFence*/ -1,
1893 Dataspace::UNKNOWN, std::vector<Rect>(), 1.0f);
1894
1895 execute();
1896 }
1897
TEST_P(GraphicsComposerAidlCommandTest,SetOutputBuffer)1898 TEST_P(GraphicsComposerAidlCommandTest, SetOutputBuffer) {
1899 const auto& [status, virtualDisplayCount] = mComposerClient->getMaxVirtualDisplayCount();
1900 EXPECT_TRUE(status.isOk());
1901 if (virtualDisplayCount == 0) {
1902 GTEST_SUCCEED() << "no virtual display support";
1903 return;
1904 }
1905
1906 const auto& [displayStatus, display] = mComposerClient->createVirtualDisplay(
1907 /*width*/ 64, /*height*/ 64, common::PixelFormat::IMPLEMENTATION_DEFINED,
1908 kBufferSlotCount);
1909 EXPECT_TRUE(displayStatus.isOk());
1910
1911 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1912 const auto handle = buffer->handle;
1913 auto& writer = getWriter(display.display);
1914 writer.setOutputBuffer(display.display, /*slot*/ 0, handle, /*releaseFence*/ -1);
1915 execute();
1916 }
1917
TEST_P(GraphicsComposerAidlCommandTest,ValidDisplay)1918 TEST_P(GraphicsComposerAidlCommandTest, ValidDisplay) {
1919 auto& writer = getWriter(getPrimaryDisplayId());
1920 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1921 VtsComposerClient::kNoFrameIntervalNs);
1922 execute();
1923 }
1924
TEST_P(GraphicsComposerAidlCommandTest,AcceptDisplayChanges)1925 TEST_P(GraphicsComposerAidlCommandTest, AcceptDisplayChanges) {
1926 auto& writer = getWriter(getPrimaryDisplayId());
1927 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1928 VtsComposerClient::kNoFrameIntervalNs);
1929 writer.acceptDisplayChanges(getPrimaryDisplayId());
1930 execute();
1931 }
1932
TEST_P(GraphicsComposerAidlCommandTest,PresentDisplay)1933 TEST_P(GraphicsComposerAidlCommandTest, PresentDisplay) {
1934 auto& writer = getWriter(getPrimaryDisplayId());
1935 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1936 VtsComposerClient::kNoFrameIntervalNs);
1937 writer.presentDisplay(getPrimaryDisplayId());
1938 execute();
1939 }
1940
1941 /**
1942 * Test IComposerClient::Command::PRESENT_DISPLAY
1943 *
1944 * Test that IComposerClient::Command::PRESENT_DISPLAY works without
1945 * additional call to validateDisplay when only the layer buffer handle and
1946 * surface damage have been set
1947 */
TEST_P(GraphicsComposerAidlCommandTest,PresentDisplayNoLayerStateChanges)1948 TEST_P(GraphicsComposerAidlCommandTest, PresentDisplayNoLayerStateChanges) {
1949 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
1950
1951 const auto& [renderIntentsStatus, renderIntents] =
1952 mComposerClient->getRenderIntents(getPrimaryDisplayId(), ColorMode::NATIVE);
1953 EXPECT_TRUE(renderIntentsStatus.isOk());
1954 auto& writer = getWriter(getPrimaryDisplayId());
1955 for (auto intent : renderIntents) {
1956 EXPECT_TRUE(mComposerClient->setColorMode(getPrimaryDisplayId(), ColorMode::NATIVE, intent)
1957 .isOk());
1958
1959 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1960 const auto handle = buffer->handle;
1961 ASSERT_NE(nullptr, handle);
1962
1963 const auto& [layerStatus, layer] =
1964 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
1965 EXPECT_TRUE(layerStatus.isOk());
1966
1967 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
1968 getPrimaryDisplay().getDisplayHeight()};
1969 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
1970 (float)getPrimaryDisplay().getDisplayHeight()};
1971 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
1972 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle,
1973 /*acquireFence*/ -1);
1974 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
1975 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1976 VtsComposerClient::kNoFrameIntervalNs);
1977 execute();
1978 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
1979 GTEST_SUCCEED() << "Composition change requested, skipping test";
1980 return;
1981 }
1982
1983 ASSERT_TRUE(mReader.takeErrors().empty());
1984 writer.presentDisplay(getPrimaryDisplayId());
1985 execute();
1986 ASSERT_TRUE(mReader.takeErrors().empty());
1987
1988 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
1989 const auto handle2 = buffer2->handle;
1990 ASSERT_NE(nullptr, handle2);
1991 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle2,
1992 /*acquireFence*/ -1);
1993 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer,
1994 std::vector<Rect>(1, {0, 0, 10, 10}));
1995 writer.presentDisplay(getPrimaryDisplayId());
1996 execute();
1997 }
1998 }
1999
TEST_P(GraphicsComposerAidlCommandTest,SetLayerCursorPosition)2000 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
2001 auto& writer = getWriter(getPrimaryDisplayId());
2002 const auto& [layerStatus, layer] =
2003 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2004 EXPECT_TRUE(layerStatus.isOk());
2005
2006 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2007 const auto handle = buffer->handle;
2008 ASSERT_NE(nullptr, handle);
2009
2010 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
2011
2012 Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
2013 getPrimaryDisplay().getDisplayHeight()};
2014 FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
2015 (float)getPrimaryDisplay().getDisplayHeight()};
2016 configureLayer(getPrimaryDisplay(), layer, Composition::CURSOR, displayFrame, cropRect);
2017 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
2018 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2019 VtsComposerClient::kNoFrameIntervalNs);
2020
2021 execute();
2022
2023 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
2024 GTEST_SUCCEED() << "Composition change requested, skipping test";
2025 return;
2026 }
2027 writer.presentDisplay(getPrimaryDisplayId());
2028 ASSERT_TRUE(mReader.takeErrors().empty());
2029
2030 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 1, /*y*/ 1);
2031 execute();
2032
2033 writer.setLayerCursorPosition(getPrimaryDisplayId(), layer, /*x*/ 0, /*y*/ 0);
2034 writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
2035 VtsComposerClient::kNoFrameIntervalNs);
2036 writer.presentDisplay(getPrimaryDisplayId());
2037 execute();
2038 }
2039
TEST_P(GraphicsComposerAidlCommandTest,SetLayerBuffer)2040 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBuffer) {
2041 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2042 const auto handle = buffer->handle;
2043 ASSERT_NE(nullptr, handle);
2044
2045 auto& writer = getWriter(getPrimaryDisplayId());
2046 const auto& [layerStatus, layer] =
2047 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2048 EXPECT_TRUE(layerStatus.isOk());
2049 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
2050 execute();
2051 }
2052
TEST_P(GraphicsComposerAidlCommandTest,SetLayerBufferMultipleTimes)2053 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
2054 auto& writer = getWriter(getPrimaryDisplayId());
2055 const auto& [layerStatus, layer] =
2056 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2057 EXPECT_TRUE(layerStatus.isOk());
2058
2059 // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
2060 // Android platform code that clears all 3 buffer slots by setting all but the active buffer
2061 // slot to a placeholder buffer, and then restoring the active buffer.
2062
2063 // This is used on HALs that don't support setLayerBufferSlotsToClear (version <= 3.1).
2064
2065 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2066 ASSERT_NE(nullptr, buffer1);
2067 const auto handle1 = buffer1->handle;
2068 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2069 execute();
2070 ASSERT_TRUE(mReader.takeErrors().empty());
2071
2072 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2073 ASSERT_NE(nullptr, buffer2);
2074 const auto handle2 = buffer2->handle;
2075 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2076 execute();
2077 ASSERT_TRUE(mReader.takeErrors().empty());
2078
2079 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2080 ASSERT_NE(nullptr, buffer3);
2081 const auto handle3 = buffer3->handle;
2082 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2083 execute();
2084 ASSERT_TRUE(mReader.takeErrors().empty());
2085
2086 // Older versions of the HAL clear all but the active buffer slot with a placeholder buffer,
2087 // and then restoring the current active buffer at the end
2088 auto clearSlotBuffer = allocate(1u, 1u, ::android::PIXEL_FORMAT_RGB_888);
2089 ASSERT_NE(nullptr, clearSlotBuffer);
2090 auto clearSlotBufferHandle = clearSlotBuffer->handle;
2091
2092 // clear buffer slots 0 and 1 with new layer commands... and then...
2093 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 0,
2094 clearSlotBufferHandle, /*acquireFence*/ -1);
2095 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /* slot */ 1,
2096 clearSlotBufferHandle, /*acquireFence*/ -1);
2097 // ...reset the layer buffer to the current active buffer slot with a final new command
2098 writer.setLayerBufferWithNewCommand(getPrimaryDisplayId(), layer, /*slot*/ 2, nullptr,
2099 /*acquireFence*/ -1);
2100 execute();
2101 ASSERT_TRUE(mReader.takeErrors().empty());
2102 }
2103
TEST_P(GraphicsComposerAidlCommandTest,SetLayerSurfaceDamage)2104 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
2105 auto& writer = getWriter(getPrimaryDisplayId());
2106 const auto& [layerStatus, layer] =
2107 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2108 EXPECT_TRUE(layerStatus.isOk());
2109
2110 Rect empty{0, 0, 0, 0};
2111 Rect unit{0, 0, 1, 1};
2112
2113 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
2114 execute();
2115 ASSERT_TRUE(mReader.takeErrors().empty());
2116
2117 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
2118 execute();
2119 ASSERT_TRUE(mReader.takeErrors().empty());
2120
2121 writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>());
2122 execute();
2123 ASSERT_TRUE(mReader.takeErrors().empty());
2124 }
2125
TEST_P(GraphicsComposerAidlCommandTest,SetLayerBlockingRegion)2126 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
2127 auto& writer = getWriter(getPrimaryDisplayId());
2128 const auto& [layerStatus, layer] =
2129 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2130 EXPECT_TRUE(layerStatus.isOk());
2131
2132 Rect empty{0, 0, 0, 0};
2133 Rect unit{0, 0, 1, 1};
2134
2135 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
2136 execute();
2137 ASSERT_TRUE(mReader.takeErrors().empty());
2138
2139 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
2140 execute();
2141 ASSERT_TRUE(mReader.takeErrors().empty());
2142
2143 writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
2144 execute();
2145 ASSERT_TRUE(mReader.takeErrors().empty());
2146 }
2147
TEST_P(GraphicsComposerAidlCommandTest,SetLayerBlendMode)2148 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
2149 auto& writer = getWriter(getPrimaryDisplayId());
2150 const auto& [layerStatus, layer] =
2151 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2152 EXPECT_TRUE(layerStatus.isOk());
2153
2154 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
2155 execute();
2156 ASSERT_TRUE(mReader.takeErrors().empty());
2157
2158 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::PREMULTIPLIED);
2159 execute();
2160 ASSERT_TRUE(mReader.takeErrors().empty());
2161
2162 writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::COVERAGE);
2163 execute();
2164 ASSERT_TRUE(mReader.takeErrors().empty());
2165 }
2166
TEST_P(GraphicsComposerAidlCommandTest,SetLayerColor)2167 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
2168 auto& writer = getWriter(getPrimaryDisplayId());
2169 const auto& [layerStatus, layer] =
2170 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2171 EXPECT_TRUE(layerStatus.isOk());
2172
2173 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
2174 execute();
2175 ASSERT_TRUE(mReader.takeErrors().empty());
2176
2177 writer.setLayerColor(getPrimaryDisplayId(), layer, Color{0.0f, 0.0f, 0.0f, 0.0f});
2178 execute();
2179 ASSERT_TRUE(mReader.takeErrors().empty());
2180 }
2181
TEST_P(GraphicsComposerAidlCommandTest,SetLayerCompositionType)2182 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
2183 auto& writer = getWriter(getPrimaryDisplayId());
2184 const auto& [layerStatus, layer] =
2185 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2186 EXPECT_TRUE(layerStatus.isOk());
2187
2188 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
2189 execute();
2190 ASSERT_TRUE(mReader.takeErrors().empty());
2191
2192 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::DEVICE);
2193 execute();
2194 ASSERT_TRUE(mReader.takeErrors().empty());
2195
2196 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::SOLID_COLOR);
2197 execute();
2198 ASSERT_TRUE(mReader.takeErrors().empty());
2199
2200 writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CURSOR);
2201 execute();
2202 }
2203
TEST_P(GraphicsComposerAidlCommandTest,DisplayDecoration)2204 TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
2205 for (VtsDisplay& display : mDisplays) {
2206 const auto displayId = display.getDisplayId();
2207 auto& writer = getWriter(displayId);
2208 const auto [layerStatus, layer] =
2209 mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
2210 ASSERT_TRUE(layerStatus.isOk());
2211
2212 const auto [error, support] = mComposerClient->getDisplayDecorationSupport(displayId);
2213
2214 const auto format = (error.isOk() && support) ? support->format
2215 : aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888;
2216 const auto decorBuffer = allocate(static_cast<::android::PixelFormat>(format));
2217 ASSERT_NE(nullptr, decorBuffer);
2218 if (::android::OK != decorBuffer->initCheck()) {
2219 if (support) {
2220 FAIL() << "Device advertised display decoration support with format "
2221 << aidl::android::hardware::graphics::common::toString(format)
2222 << " but failed to allocate it!";
2223 } else {
2224 FAIL() << "Device advertised NO display decoration support, but it should "
2225 << "still be able to allocate "
2226 << aidl::android::hardware::graphics::common::toString(format);
2227 }
2228 }
2229
2230 configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
2231 display.getCrop());
2232 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, decorBuffer->handle,
2233 /*acquireFence*/ -1);
2234 writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
2235 VtsComposerClient::kNoFrameIntervalNs);
2236 execute();
2237 if (support) {
2238 ASSERT_TRUE(mReader.takeErrors().empty());
2239 } else {
2240 const auto errors = mReader.takeErrors();
2241 ASSERT_EQ(1, errors.size());
2242 EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
2243 }
2244 EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
2245 }
2246 }
2247
TEST_P(GraphicsComposerAidlCommandTest,SetLayerDataspace)2248 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
2249 auto& writer = getWriter(getPrimaryDisplayId());
2250 const auto& [layerStatus, layer] =
2251 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2252 EXPECT_TRUE(layerStatus.isOk());
2253
2254 writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
2255 execute();
2256 }
2257
TEST_P(GraphicsComposerAidlCommandTest,SetLayerDisplayFrame)2258 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
2259 auto& writer = getWriter(getPrimaryDisplayId());
2260 const auto& [layerStatus, layer] =
2261 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2262 EXPECT_TRUE(layerStatus.isOk());
2263
2264 writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
2265 execute();
2266 }
2267
TEST_P(GraphicsComposerAidlCommandTest,SetLayerPlaneAlpha)2268 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
2269 auto& writer = getWriter(getPrimaryDisplayId());
2270 const auto& [layerStatus, layer] =
2271 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2272 EXPECT_TRUE(layerStatus.isOk());
2273
2274 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
2275 execute();
2276 ASSERT_TRUE(mReader.takeErrors().empty());
2277
2278 writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 1.0f);
2279 execute();
2280 ASSERT_TRUE(mReader.takeErrors().empty());
2281 }
2282
TEST_P(GraphicsComposerAidlCommandTest,SetLayerSidebandStream)2283 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSidebandStream) {
2284 if (!hasCapability(Capability::SIDEBAND_STREAM)) {
2285 GTEST_SUCCEED() << "no sideband stream support";
2286 return;
2287 }
2288
2289 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2290 const auto handle = buffer->handle;
2291 ASSERT_NE(nullptr, handle);
2292
2293 auto& writer = getWriter(getPrimaryDisplayId());
2294 const auto& [layerStatus, layer] =
2295 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2296 EXPECT_TRUE(layerStatus.isOk());
2297
2298 writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
2299 execute();
2300 }
2301
TEST_P(GraphicsComposerAidlCommandTest,SetLayerSourceCrop)2302 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
2303 auto& writer = getWriter(getPrimaryDisplayId());
2304 const auto& [layerStatus, layer] =
2305 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2306 EXPECT_TRUE(layerStatus.isOk());
2307
2308 writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
2309 execute();
2310 }
2311
TEST_P(GraphicsComposerAidlCommandTest,SetLayerTransform)2312 TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
2313 auto& writer = getWriter(getPrimaryDisplayId());
2314 const auto& [layerStatus, layer] =
2315 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2316 EXPECT_TRUE(layerStatus.isOk());
2317
2318 writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
2319 execute();
2320 ASSERT_TRUE(mReader.takeErrors().empty());
2321
2322 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_H);
2323 execute();
2324 ASSERT_TRUE(mReader.takeErrors().empty());
2325
2326 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::FLIP_V);
2327 execute();
2328 ASSERT_TRUE(mReader.takeErrors().empty());
2329
2330 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_90);
2331 execute();
2332 ASSERT_TRUE(mReader.takeErrors().empty());
2333
2334 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_180);
2335 execute();
2336 ASSERT_TRUE(mReader.takeErrors().empty());
2337
2338 writer.setLayerTransform(getPrimaryDisplayId(), layer, Transform::ROT_270);
2339 execute();
2340 ASSERT_TRUE(mReader.takeErrors().empty());
2341
2342 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2343 static_cast<Transform>(static_cast<int>(Transform::FLIP_H) |
2344 static_cast<int>(Transform::ROT_90)));
2345 execute();
2346 ASSERT_TRUE(mReader.takeErrors().empty());
2347
2348 writer.setLayerTransform(getPrimaryDisplayId(), layer,
2349 static_cast<Transform>(static_cast<int>(Transform::FLIP_V) |
2350 static_cast<int>(Transform::ROT_90)));
2351 execute();
2352 ASSERT_TRUE(mReader.takeErrors().empty());
2353 }
2354
TEST_P(GraphicsComposerAidlCommandTest,SetLayerVisibleRegion)2355 TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
2356 auto& writer = getWriter(getPrimaryDisplayId());
2357 const auto& [layerStatus, layer] =
2358 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2359 EXPECT_TRUE(layerStatus.isOk());
2360
2361 Rect empty{0, 0, 0, 0};
2362 Rect unit{0, 0, 1, 1};
2363
2364 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
2365 execute();
2366 ASSERT_TRUE(mReader.takeErrors().empty());
2367
2368 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, unit));
2369 execute();
2370 ASSERT_TRUE(mReader.takeErrors().empty());
2371
2372 writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>());
2373 execute();
2374 ASSERT_TRUE(mReader.takeErrors().empty());
2375 }
2376
TEST_P(GraphicsComposerAidlCommandTest,SetLayerZOrder)2377 TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
2378 auto& writer = getWriter(getPrimaryDisplayId());
2379
2380 const auto& [layerStatus, layer] =
2381 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2382 EXPECT_TRUE(layerStatus.isOk());
2383
2384 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
2385 execute();
2386 ASSERT_TRUE(mReader.takeErrors().empty());
2387
2388 writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 0);
2389 execute();
2390 ASSERT_TRUE(mReader.takeErrors().empty());
2391 }
2392
TEST_P(GraphicsComposerAidlCommandTest,SetLayerPerFrameMetadata)2393 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
2394 auto& writer = getWriter(getPrimaryDisplayId());
2395 const auto& [layerStatus, layer] =
2396 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2397 EXPECT_TRUE(layerStatus.isOk());
2398
2399 /**
2400 * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
2401 * the D65 white point and the SRGB transfer functions.
2402 * Rendering Intent: Colorimetric
2403 * Primaries:
2404 * x y
2405 * green 0.265 0.690
2406 * blue 0.150 0.060
2407 * red 0.680 0.320
2408 * white (D65) 0.3127 0.3290
2409 */
2410
2411 std::vector<PerFrameMetadata> aidlMetadata;
2412 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
2413 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
2414 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265f});
2415 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690f});
2416 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150f});
2417 aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060f});
2418 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_X, 0.3127f});
2419 aidlMetadata.push_back({PerFrameMetadataKey::WHITE_POINT_Y, 0.3290f});
2420 aidlMetadata.push_back({PerFrameMetadataKey::MAX_LUMINANCE, 100.0f});
2421 aidlMetadata.push_back({PerFrameMetadataKey::MIN_LUMINANCE, 0.1f});
2422 aidlMetadata.push_back({PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
2423 aidlMetadata.push_back({PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
2424 writer.setLayerPerFrameMetadata(getPrimaryDisplayId(), layer, aidlMetadata);
2425 execute();
2426
2427 const auto errors = mReader.takeErrors();
2428 if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
2429 GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
2430 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
2431 return;
2432 }
2433
2434 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
2435 }
2436
TEST_P(GraphicsComposerAidlCommandTest,setLayerBrightness)2437 TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
2438 auto& writer = getWriter(getPrimaryDisplayId());
2439
2440 const auto& [layerStatus, layer] =
2441 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2442
2443 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
2444 execute();
2445 ASSERT_TRUE(mReader.takeErrors().empty());
2446
2447 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 1.f);
2448 execute();
2449 ASSERT_TRUE(mReader.takeErrors().empty());
2450
2451 writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.f);
2452 execute();
2453 ASSERT_TRUE(mReader.takeErrors().empty());
2454
2455 writer.setLayerBrightness(getPrimaryDisplayId(), layer, -1.f);
2456 execute();
2457 {
2458 const auto errors = mReader.takeErrors();
2459 ASSERT_EQ(1, errors.size());
2460 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2461 }
2462
2463 writer.setLayerBrightness(getPrimaryDisplayId(), layer, std::nanf(""));
2464 execute();
2465 {
2466 const auto errors = mReader.takeErrors();
2467 ASSERT_EQ(1, errors.size());
2468 EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, errors[0].errorCode);
2469 }
2470 }
2471
TEST_P(GraphicsComposerAidlCommandTest,SetActiveConfigWithConstraints)2472 TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints) {
2473 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
2474 }
2475
TEST_P(GraphicsComposerAidlCommandTest,SetActiveConfigWithConstraints_Delayed)2476 TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_Delayed) {
2477 Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
2478 .refreshMiss = false});
2479 }
2480
TEST_P(GraphicsComposerAidlCommandTest,SetActiveConfigWithConstraints_MissRefresh)2481 TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_MissRefresh) {
2482 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
2483 }
2484
TEST_P(GraphicsComposerAidlCommandTest,GetDisplayVsyncPeriod)2485 TEST_P(GraphicsComposerAidlCommandTest, GetDisplayVsyncPeriod) {
2486 for (VtsDisplay& display : mDisplays) {
2487 const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
2488 EXPECT_TRUE(status.isOk());
2489
2490 for (int32_t config : configs) {
2491 int32_t expectedVsyncPeriodNanos = display.getDisplayConfig(config).vsyncPeriod;
2492
2493 VsyncPeriodChangeConstraints constraints;
2494
2495 constraints.desiredTimeNanos = systemTime();
2496 constraints.seamlessRequired = false;
2497
2498 const auto& [timelineStatus, timeline] =
2499 mComposerClient->setActiveConfigWithConstraints(&display, config, constraints);
2500 EXPECT_TRUE(timelineStatus.isOk());
2501
2502 if (timeline.refreshRequired) {
2503 sendRefreshFrame(display, &timeline);
2504 }
2505 waitForVsyncPeriodChange(display.getDisplayId(), timeline, constraints.desiredTimeNanos,
2506 /*odPeriodNanos*/ 0, expectedVsyncPeriodNanos);
2507
2508 int32_t vsyncPeriodNanos;
2509 int retryCount = 100;
2510 do {
2511 std::this_thread::sleep_for(10ms);
2512 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2513 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2514
2515 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2516 vsyncPeriodNanos = vsyncPeriodNanosValue;
2517 --retryCount;
2518 } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
2519
2520 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2521
2522 // Make sure that the vsync period stays the same if the active config is not
2523 // changed.
2524 auto timeout = 1ms;
2525 for (int i = 0; i < 10; i++) {
2526 std::this_thread::sleep_for(timeout);
2527 timeout *= 2;
2528 vsyncPeriodNanos = 0;
2529 const auto& [vsyncPeriodNanosStatus, vsyncPeriodNanosValue] =
2530 mComposerClient->getDisplayVsyncPeriod(display.getDisplayId());
2531
2532 EXPECT_TRUE(vsyncPeriodNanosStatus.isOk());
2533 vsyncPeriodNanos = vsyncPeriodNanosValue;
2534 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
2535 }
2536 }
2537 }
2538 }
2539
TEST_P(GraphicsComposerAidlCommandTest,SetActiveConfigWithConstraints_SeamlessNotAllowed)2540 TEST_P(GraphicsComposerAidlCommandTest, SetActiveConfigWithConstraints_SeamlessNotAllowed) {
2541 VsyncPeriodChangeConstraints constraints;
2542 constraints.seamlessRequired = true;
2543 constraints.desiredTimeNanos = systemTime();
2544
2545 for (VtsDisplay& display : mDisplays) {
2546 forEachTwoConfigs(display.getDisplayId(), [&](int32_t config1, int32_t config2) {
2547 int32_t configGroup1 = display.getDisplayConfig(config1).configGroup;
2548 int32_t configGroup2 = display.getDisplayConfig(config2).configGroup;
2549 if (configGroup1 != configGroup2) {
2550 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
2551 sendRefreshFrame(display, nullptr);
2552 const auto& [status, _] = mComposerClient->setActiveConfigWithConstraints(
2553 &display, config2, constraints);
2554 EXPECT_FALSE(status.isOk());
2555 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(
2556 status, IComposerClient::EX_SEAMLESS_NOT_ALLOWED));
2557 }
2558 });
2559 }
2560 }
2561
TEST_P(GraphicsComposerAidlCommandTest,ExpectedPresentTime_NoTimestamp)2562 TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_NoTimestamp) {
2563 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ std::nullopt));
2564 }
2565
TEST_P(GraphicsComposerAidlCommandTest,ExpectedPresentTime_0)2566 TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_0) {
2567 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 0));
2568 }
2569
TEST_P(GraphicsComposerAidlCommandTest,ExpectedPresentTime_5)2570 TEST_P(GraphicsComposerAidlCommandTest, ExpectedPresentTime_5) {
2571 ASSERT_NO_FATAL_FAILURE(Test_expectedPresentTime(/*framesDelay*/ 5));
2572 }
2573
TEST_P(GraphicsComposerAidlCommandTest,SetIdleTimerEnabled_Unsupported)2574 TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Unsupported) {
2575 const bool hasDisplayIdleTimerSupport =
2576 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
2577 if (!hasDisplayIdleTimerSupport) {
2578 const auto& status =
2579 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0);
2580 EXPECT_FALSE(status.isOk());
2581 EXPECT_NO_FATAL_FAILURE(
2582 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2583 }
2584 }
2585
TEST_P(GraphicsComposerAidlCommandTest,SetIdleTimerEnabled_BadParameter)2586 TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_BadParameter) {
2587 const bool hasDisplayIdleTimerSupport =
2588 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
2589 if (!hasDisplayIdleTimerSupport) {
2590 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2591 return;
2592 }
2593
2594 const auto& status =
2595 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ -1);
2596 EXPECT_FALSE(status.isOk());
2597 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
2598 }
2599
TEST_P(GraphicsComposerAidlCommandTest,SetIdleTimerEnabled_Disable)2600 TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Disable) {
2601 const bool hasDisplayIdleTimerSupport =
2602 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
2603 if (!hasDisplayIdleTimerSupport) {
2604 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2605 return;
2606 }
2607
2608 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
2609 std::this_thread::sleep_for(1s);
2610 EXPECT_EQ(0, mComposerClient->getVsyncIdleCount());
2611 }
2612
TEST_P(GraphicsComposerAidlCommandTest,SetIdleTimerEnabled_Timeout_2)2613 TEST_P(GraphicsComposerAidlCommandTest, SetIdleTimerEnabled_Timeout_2) {
2614 const bool hasDisplayIdleTimerSupport =
2615 hasDisplayCapability(getPrimaryDisplayId(), DisplayCapability::DISPLAY_IDLE_TIMER);
2616 if (!hasDisplayIdleTimerSupport) {
2617 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2618 return;
2619 }
2620
2621 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
2622 EXPECT_TRUE(mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 0).isOk());
2623
2624 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2625 ASSERT_NE(nullptr, buffer->handle);
2626
2627 const auto layer = createOnScreenLayer(getPrimaryDisplay());
2628 auto& writer = getWriter(getPrimaryDisplayId());
2629 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
2630 /*acquireFence*/ -1);
2631 int32_t vsyncIdleCount = mComposerClient->getVsyncIdleCount();
2632 auto earlyVsyncIdleTime = systemTime() + std::chrono::nanoseconds(2s).count();
2633 EXPECT_TRUE(
2634 mComposerClient->setIdleTimerEnabled(getPrimaryDisplayId(), /*timeout*/ 2000).isOk());
2635
2636 const sp<::android::Fence> presentFence =
2637 presentAndGetFence(ComposerClientWriter::kNoTimestamp);
2638 presentFence->waitForever(LOG_TAG);
2639
2640 std::this_thread::sleep_for(3s);
2641 if (vsyncIdleCount < mComposerClient->getVsyncIdleCount()) {
2642 EXPECT_GE(mComposerClient->getVsyncIdleTime(), earlyVsyncIdleTime);
2643 }
2644
2645 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
2646 }
2647
2648 class GraphicsComposerAidlCommandV2Test : public GraphicsComposerAidlCommandTest {
2649 protected:
SetUp()2650 void SetUp() override {
2651 GraphicsComposerAidlTest::SetUp();
2652 if (getInterfaceVersion() <= 1) {
2653 GTEST_SKIP() << "Device interface version is expected to be >= 2";
2654 }
2655 }
2656 };
2657 /**
2658 * Test Capability::SKIP_VALIDATE
2659 *
2660 * Capability::SKIP_VALIDATE has been deprecated and should not be enabled.
2661 */
TEST_P(GraphicsComposerAidlCommandV2Test,SkipValidateDeprecatedTest)2662 TEST_P(GraphicsComposerAidlCommandV2Test, SkipValidateDeprecatedTest) {
2663 #pragma clang diagnostic push
2664 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
2665 ASSERT_FALSE(hasCapability(Capability::SKIP_VALIDATE))
2666 << "Found Capability::SKIP_VALIDATE capability.";
2667 #pragma clang diagnostic pop
2668 }
2669
TEST_P(GraphicsComposerAidlCommandV2Test,SetLayerBufferSlotsToClear)2670 TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
2671 auto& writer = getWriter(getPrimaryDisplayId());
2672 // Older HAL versions use a backwards compatible way of clearing buffer slots
2673 // HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
2674 const auto& [layerStatus, layer] =
2675 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
2676 EXPECT_TRUE(layerStatus.isOk());
2677
2678 // setup 3 buffers in the buffer cache, with the last buffer being active
2679 // then emulate the Android platform code that clears all 3 buffer slots
2680
2681 const auto buffer1 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2682 ASSERT_NE(nullptr, buffer1);
2683 const auto handle1 = buffer1->handle;
2684 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle1, /*acquireFence*/ -1);
2685 execute();
2686 ASSERT_TRUE(mReader.takeErrors().empty());
2687
2688 const auto buffer2 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2689 ASSERT_NE(nullptr, buffer2);
2690 const auto handle2 = buffer2->handle;
2691 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 1, handle2, /*acquireFence*/ -1);
2692 execute();
2693 ASSERT_TRUE(mReader.takeErrors().empty());
2694
2695 const auto buffer3 = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2696 ASSERT_NE(nullptr, buffer3);
2697 const auto handle3 = buffer3->handle;
2698 writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 2, handle3, /*acquireFence*/ -1);
2699 execute();
2700 ASSERT_TRUE(mReader.takeErrors().empty());
2701
2702 // Ensure we can clear all 3 buffer slots, even the active buffer - it is assumed the
2703 // current active buffer's slot will be cleared, but still remain the active buffer and no
2704 // errors will occur.
2705 writer.setLayerBufferSlotsToClear(getPrimaryDisplayId(), layer, {0, 1, 2});
2706 execute();
2707 ASSERT_TRUE(mReader.takeErrors().empty());
2708 }
2709
TEST_P(GraphicsComposerAidlCommandV2Test,SetRefreshRateChangedCallbackDebug_Unsupported)2710 TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Unsupported) {
2711 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2712 auto status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(
2713 getPrimaryDisplayId(), /*enabled*/ true);
2714 EXPECT_FALSE(status.isOk());
2715 EXPECT_NO_FATAL_FAILURE(
2716 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2717
2718 status = mComposerClient->setRefreshRateChangedCallbackDebugEnabled(getPrimaryDisplayId(),
2719 /*enabled*/ false);
2720 EXPECT_FALSE(status.isOk());
2721 EXPECT_NO_FATAL_FAILURE(
2722 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
2723 }
2724 }
2725
TEST_P(GraphicsComposerAidlCommandV2Test,SetRefreshRateChangedCallbackDebug_Enabled)2726 TEST_P(GraphicsComposerAidlCommandV2Test, SetRefreshRateChangedCallbackDebug_Enabled) {
2727 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2728 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2729 return;
2730 }
2731
2732 for (VtsDisplay& display : mDisplays) {
2733 const auto displayId = display.getDisplayId();
2734 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2735 // Enable the callback
2736 ASSERT_TRUE(mComposerClient
2737 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2738 /*enabled*/ true)
2739 .isOk());
2740 std::this_thread::sleep_for(100ms);
2741
2742 const auto [status, configId] = mComposerClient->getActiveConfig(display.getDisplayId());
2743 EXPECT_TRUE(status.isOk());
2744
2745 const auto displayFilter = [&](auto refreshRateChangedDebugData) {
2746 bool nonVrrRateMatching = true;
2747 if (std::optional<VrrConfig> vrrConfigOpt =
2748 display.getDisplayConfig(configId).vrrConfigOpt;
2749 getInterfaceVersion() >= 3 && !vrrConfigOpt) {
2750 nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
2751 refreshRateChangedDebugData.vsyncPeriodNanos;
2752 }
2753 const bool isDisplaySame =
2754 display.getDisplayId() == refreshRateChangedDebugData.display;
2755 return nonVrrRateMatching && isDisplaySame;
2756 };
2757
2758 // Check that we immediately got a callback
2759 EXPECT_TRUE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter));
2760
2761 ASSERT_TRUE(mComposerClient
2762 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2763 /*enabled*/ false)
2764 .isOk());
2765 }
2766 }
2767
TEST_P(GraphicsComposerAidlCommandV2Test,SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle)2768 TEST_P(GraphicsComposerAidlCommandV2Test,
2769 SetRefreshRateChangedCallbackDebugEnabled_noCallbackWhenIdle) {
2770 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2771 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2772 return;
2773 }
2774
2775 auto display = getEditablePrimaryDisplay();
2776 const auto displayId = display.getDisplayId();
2777
2778 if (!hasDisplayCapability(displayId, DisplayCapability::DISPLAY_IDLE_TIMER)) {
2779 GTEST_SUCCEED() << "DisplayCapability::DISPLAY_IDLE_TIMER is not supported";
2780 return;
2781 }
2782
2783 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2784 EXPECT_TRUE(mComposerClient->setPeakRefreshRateConfig(&display).isOk());
2785
2786 ASSERT_TRUE(mComposerClient->setIdleTimerEnabled(displayId, /*timeoutMs*/ 500).isOk());
2787 // Enable the callback
2788 ASSERT_TRUE(mComposerClient
2789 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2790 /*enabled*/ true)
2791 .isOk());
2792
2793 const auto displayFilter = [displayId](auto refreshRateChangedDebugData) {
2794 return displayId == refreshRateChangedDebugData.display;
2795 };
2796
2797 int retryCount = 3;
2798 do {
2799 // Wait for 1s so that we enter the idle state
2800 std::this_thread::sleep_for(1s);
2801 if (!checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter)) {
2802 // DID NOT receive a callback, we are in the idle state.
2803 break;
2804 }
2805 } while (--retryCount > 0);
2806
2807 if (retryCount == 0) {
2808 GTEST_SUCCEED() << "Unable to enter the idle mode";
2809 return;
2810 }
2811
2812 // Send the REFRESH_RATE_INDICATOR update
2813 ASSERT_NO_FATAL_FAILURE(sendBufferUpdate(
2814 createOnScreenLayer(getPrimaryDisplay(), Composition::REFRESH_RATE_INDICATOR)));
2815 std::this_thread::sleep_for(1s);
2816 EXPECT_FALSE(checkIfCallbackRefreshRateChangedDebugEnabledReceived(displayFilter))
2817 << "A callback should not be received for REFRESH_RATE_INDICATOR";
2818
2819 EXPECT_TRUE(mComposerClient
2820 ->setRefreshRateChangedCallbackDebugEnabled(displayId,
2821 /*enabled*/ false)
2822 .isOk());
2823 }
2824
TEST_P(GraphicsComposerAidlCommandV2Test,SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints)2825 TEST_P(GraphicsComposerAidlCommandV2Test,
2826 SetRefreshRateChangedCallbackDebugEnabled_SetActiveConfigWithConstraints) {
2827 if (!hasCapability(Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG)) {
2828 GTEST_SUCCEED() << "Capability::REFRESH_RATE_CHANGED_CALLBACK_DEBUG is not supported";
2829 return;
2830 }
2831
2832 VsyncPeriodChangeConstraints constraints;
2833 constraints.seamlessRequired = false;
2834 constraints.desiredTimeNanos = systemTime();
2835
2836 for (VtsDisplay& display : mDisplays) {
2837 const auto displayId = display.getDisplayId();
2838 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2839
2840 // Enable the callback
2841 ASSERT_TRUE(mComposerClient
2842 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ true)
2843 .isOk());
2844
2845 forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
2846 if (display.isRateSameBetweenConfigs(config1, config2)) {
2847 return; // continue
2848 }
2849
2850 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
2851 sendRefreshFrame(display, nullptr);
2852
2853 const auto& [status, timeline] =
2854 mComposerClient->setActiveConfigWithConstraints(&display, config2, constraints);
2855 EXPECT_TRUE(status.isOk());
2856
2857 if (timeline.refreshRequired) {
2858 sendRefreshFrame(display, &timeline);
2859 }
2860
2861 const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
2862 const auto callbackFilter = [displayId,
2863 vsyncPeriod2](auto refreshRateChangedDebugData) {
2864 constexpr int kVsyncThreshold = 1000;
2865 return displayId == refreshRateChangedDebugData.display &&
2866 std::abs(vsyncPeriod2 - refreshRateChangedDebugData.vsyncPeriodNanos) <=
2867 kVsyncThreshold;
2868 };
2869
2870 int retryCount = 3;
2871 do {
2872 std::this_thread::sleep_for(100ms);
2873 if (checkIfCallbackRefreshRateChangedDebugEnabledReceived(callbackFilter)) {
2874 GTEST_SUCCEED() << "Received a callback successfully";
2875 break;
2876 }
2877 } while (--retryCount > 0);
2878
2879 if (retryCount == 0) {
2880 GTEST_FAIL() << "Failed to get a callback for Display " << displayId
2881 << " switching from " << display.printConfig(config1)
2882 << " to " << display.printConfig(config2);
2883 }
2884 });
2885
2886 EXPECT_TRUE(
2887 mComposerClient
2888 ->setRefreshRateChangedCallbackDebugEnabled(displayId, /*enabled*/ false)
2889 .isOk());
2890 }
2891 }
2892
TEST_P(GraphicsComposerAidlCommandTest,MultiThreadedPresent)2893 TEST_P(GraphicsComposerAidlCommandTest, MultiThreadedPresent) {
2894 std::vector<VtsDisplay*> displays;
2895 for (auto& display : mDisplays) {
2896 if (hasDisplayCapability(display.getDisplayId(),
2897 DisplayCapability::MULTI_THREADED_PRESENT)) {
2898 displays.push_back(&display);
2899 }
2900 }
2901
2902 const size_t numDisplays = displays.size();
2903 if (numDisplays <= 1u) {
2904 GTEST_SKIP();
2905 }
2906
2907 // When multi-threaded, use a reader per display. As with mWriters, this mutex
2908 // guards access to the map.
2909 std::mutex readersMutex;
2910 std::unordered_map<int64_t, ComposerClientReader> readers;
2911 std::vector<std::thread> threads;
2912 threads.reserve(numDisplays);
2913
2914 // Each display will have a layer to present. This maps from the display to
2915 // the layer, so we can properly destroy each layer at the end.
2916 std::unordered_map<int64_t, int64_t> layers;
2917
2918 for (auto* const display : displays) {
2919 const int64_t displayId = display->getDisplayId();
2920
2921 // Ensure that all writers and readers have been added to their respective
2922 // maps initially, so that the following loop never modifies the maps. The
2923 // maps are accessed from different threads, and if the maps were modified,
2924 // this would invalidate their iterators, and therefore references to the
2925 // writers and readers.
2926 auto& writer = getWriter(displayId);
2927 {
2928 std::lock_guard guard{readersMutex};
2929 readers.try_emplace(displayId, displayId);
2930 }
2931
2932 EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
2933
2934 const auto& [status, layer] =
2935 mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
2936 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
2937 ASSERT_NE(nullptr, buffer);
2938 ASSERT_EQ(::android::OK, buffer->initCheck());
2939 ASSERT_NE(nullptr, buffer->handle);
2940
2941 configureLayer(*display, layer, Composition::DEVICE, display->getFrameRect(),
2942 display->getCrop());
2943 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
2944 /*acquireFence*/ -1);
2945 writer.setLayerDataspace(displayId, layer, common::Dataspace::UNKNOWN);
2946 layers.try_emplace(displayId, layer);
2947 }
2948
2949 for (auto* const display : displays) {
2950 const int64_t displayId = display->getDisplayId();
2951 auto& writer = getWriter(displayId);
2952 std::unique_lock lock{readersMutex};
2953 auto& reader = readers.at(displayId);
2954 lock.unlock();
2955
2956 writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
2957 VtsComposerClient::kNoFrameIntervalNs);
2958 execute(writer, reader);
2959
2960 threads.emplace_back([this, displayId, &readers, &readersMutex]() {
2961 auto& writer = getWriter(displayId);
2962 std::unique_lock lock{readersMutex};
2963 ComposerClientReader& reader = readers.at(displayId);
2964 lock.unlock();
2965
2966 writer.presentDisplay(displayId);
2967 execute(writer, reader);
2968 ASSERT_TRUE(reader.takeErrors().empty());
2969
2970 auto presentFence = reader.takePresentFence(displayId);
2971 // take ownership
2972 const int fenceOwner = presentFence.get();
2973 *presentFence.getR() = -1;
2974 EXPECT_NE(-1, fenceOwner);
2975 const auto presentFence2 = sp<::android::Fence>::make(fenceOwner);
2976 presentFence2->waitForever(LOG_TAG);
2977 });
2978 }
2979
2980 for (auto& thread : threads) {
2981 thread.join();
2982 }
2983
2984 for (auto& [displayId, layer] : layers) {
2985 auto& writer = getWriter(displayId);
2986 EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
2987 }
2988
2989 std::lock_guard guard{readersMutex};
2990 for (auto& [displayId, reader] : readers) {
2991 ASSERT_TRUE(reader.takeErrors().empty());
2992 ASSERT_TRUE(reader.takeChangedCompositionTypes(displayId).empty());
2993 }
2994 }
2995
2996 class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
2997 protected:
SetUp()2998 void SetUp() override {
2999 GraphicsComposerAidlTest::SetUp();
3000 if (getInterfaceVersion() <= 2) {
3001 GTEST_SKIP() << "Device interface version is expected to be >= 3";
3002 }
3003 }
3004 };
3005
TEST_P(GraphicsComposerAidlCommandV3Test,CreateBatchedCommand)3006 TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
3007 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3008 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3009 return;
3010 }
3011 auto& writer = getWriter(getPrimaryDisplayId());
3012 const auto& [status, layer] =
3013 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3014 EXPECT_TRUE(status.isOk());
3015 execute();
3016 ASSERT_TRUE(mReader.takeErrors().empty());
3017 }
3018
TEST_P(GraphicsComposerAidlCommandV3Test,CreateBatchedCommand_BadDisplay)3019 TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
3020 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3021 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3022 return;
3023 }
3024 auto& writer = getWriter(getInvalidDisplayId());
3025 int64_t layer = 5;
3026 writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3027 LayerLifecycleBatchCommandType::CREATE);
3028 writer.setNewBufferSlotCount(getInvalidDisplayId(), layer, 1);
3029 execute();
3030
3031 const auto errors = mReader.takeErrors();
3032 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
3033 }
3034
TEST_P(GraphicsComposerAidlCommandV3Test,DestroyBatchedCommand)3035 TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
3036 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3037 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3038 return;
3039 }
3040 auto& writer = getWriter(getPrimaryDisplayId());
3041 const auto& [status, layer] =
3042 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3043 EXPECT_TRUE(status.isOk());
3044 execute();
3045 ASSERT_TRUE(mReader.takeErrors().empty());
3046 EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
3047 execute();
3048 ASSERT_TRUE(mReader.takeErrors().empty());
3049 }
3050
TEST_P(GraphicsComposerAidlCommandV3Test,DestroyBatchedCommand_BadDisplay)3051 TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
3052 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3053 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3054 return;
3055 }
3056 auto& writer = getWriter(getPrimaryDisplayId());
3057 const auto& [status, layer] =
3058 mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
3059
3060 EXPECT_TRUE(status.isOk());
3061 execute();
3062 ASSERT_TRUE(mReader.takeErrors().empty());
3063
3064 auto& invalid_writer = getWriter(getInvalidDisplayId());
3065 invalid_writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
3066 LayerLifecycleBatchCommandType::DESTROY);
3067 execute();
3068 const auto errors = mReader.takeErrors();
3069 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
3070 }
3071
TEST_P(GraphicsComposerAidlCommandV3Test,NoCreateDestroyBatchedCommandIncorrectLayer)3072 TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
3073 if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
3074 GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
3075 return;
3076 }
3077
3078 auto& writer = getWriter(getPrimaryDisplayId());
3079 int64_t layer = 5;
3080 writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
3081 LayerLifecycleBatchCommandType::DESTROY);
3082 execute();
3083 const auto errors = mReader.takeErrors();
3084 ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
3085 }
3086
TEST_P(GraphicsComposerAidlCommandV3Test,notifyExpectedPresentTimeout)3087 TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentTimeout) {
3088 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3089 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3090 return;
3091 }
3092 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3093 const DisplayConfiguration& config) {
3094 const auto displayId = display.getDisplayId();
3095 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3096 const auto timeoutNs = config.vrrConfig->notifyExpectedPresentConfig->timeoutNs;
3097
3098 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3099 ASSERT_NE(nullptr, buffer);
3100 const auto layer = createOnScreenLayer(display);
3101 auto& writer = getWriter(displayId);
3102 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3103 /*acquireFence*/ -1);
3104 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3105 displayId, minFrameIntervalNs);
3106 presentFence->waitForever(LOG_TAG);
3107 auto lastPresentTimeNs = presentFence->getSignalTime();
3108
3109 // Frame presents 30ms after timeout
3110 const auto timeout = static_cast<const std::chrono::nanoseconds>(timeoutNs);
3111 const auto vsyncPeriod = config.vsyncPeriod;
3112 int32_t frameAfterTimeoutNs =
3113 vsyncPeriod * static_cast<int32_t>((timeout + 30ms).count() / vsyncPeriod);
3114 auto expectedPresentTimestamp =
3115 ClockMonotonicTimestamp{lastPresentTimeNs + frameAfterTimeoutNs};
3116 std::this_thread::sleep_for(timeout);
3117 mComposerClient->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3118 minFrameIntervalNs);
3119 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, minFrameIntervalNs);
3120 presentFence->waitForever(LOG_TAG);
3121 lastPresentTimeNs = presentFence->getSignalTime();
3122 ASSERT_GE(lastPresentTimeNs, expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2);
3123 mComposerClient->destroyLayer(displayId, layer, &writer);
3124 });
3125 }
3126
TEST_P(GraphicsComposerAidlCommandV3Test,notifyExpectedPresentFrameIntervalChange)3127 TEST_P(GraphicsComposerAidlCommandV3Test, notifyExpectedPresentFrameIntervalChange) {
3128 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3129 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3130 return;
3131 }
3132 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3133 const DisplayConfiguration& config) {
3134 const auto displayId = display.getDisplayId();
3135 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3136 ASSERT_NE(nullptr, buffer);
3137 const auto layer = createOnScreenLayer(display);
3138 auto& writer = getWriter(displayId);
3139 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3140 /*acquireFence*/ -1);
3141 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3142 sp<::android::Fence> presentFence = presentAndGetFence(ComposerClientWriter::kNoTimestamp,
3143 displayId, minFrameIntervalNs);
3144 presentFence->waitForever(LOG_TAG);
3145 auto lastPresentTimeNs = presentFence->getSignalTime();
3146
3147 auto vsyncPeriod = config.vsyncPeriod;
3148 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3149 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3150 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3151 float totalDivisorsPassed = 0.f;
3152 for (int divisor = lowestDivisor; divisor <= highestDivisor; divisor++) {
3153 const auto frameIntervalNs = vsyncPeriod * divisor;
3154 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3155 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3156 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3157 ASSERT_TRUE(mComposerClient
3158 ->notifyExpectedPresent(displayId, expectedPresentTimestamp,
3159 frameIntervalNs)
3160 .isOk());
3161 presentFence = presentAndGetFence(expectedPresentTimestamp, displayId, frameIntervalNs);
3162 presentFence->waitForever(LOG_TAG);
3163 lastPresentTimeNs = presentFence->getSignalTime();
3164 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3165 ++totalDivisorsPassed;
3166 }
3167 }
3168 EXPECT_TRUE(totalDivisorsPassed >
3169 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3170 mComposerClient->destroyLayer(displayId, layer, &writer);
3171 });
3172 }
3173
TEST_P(GraphicsComposerAidlCommandV3Test,frameIntervalChangeAtPresentFrame)3174 TEST_P(GraphicsComposerAidlCommandV3Test, frameIntervalChangeAtPresentFrame) {
3175 if (hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
3176 GTEST_SUCCEED() << "Device has unreliable present fences capability, skipping";
3177 return;
3178 }
3179 forEachNotifyExpectedPresentConfig([&](VtsDisplay& display,
3180 const DisplayConfiguration& config) {
3181 const auto displayId = display.getDisplayId();
3182 const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
3183 ASSERT_NE(nullptr, buffer);
3184 const auto layer = createOnScreenLayer(display);
3185 auto& writer = getWriter(displayId);
3186 writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
3187 /*acquireFence*/ -1);
3188 auto minFrameIntervalNs = config.vrrConfig->minFrameIntervalNs;
3189
3190 auto vsyncPeriod = config.vsyncPeriod;
3191 int32_t highestDivisor = VtsComposerClient::kMaxFrameIntervalNs / vsyncPeriod;
3192 int32_t lowestDivisor = minFrameIntervalNs / vsyncPeriod;
3193 const auto headsUpNs = config.vrrConfig->notifyExpectedPresentConfig->headsUpNs;
3194 float totalDivisorsPassed = 0.f;
3195 int divisor = lowestDivisor;
3196 auto frameIntervalNs = vsyncPeriod * divisor;
3197 sp<::android::Fence> presentFence =
3198 presentAndGetFence(ComposerClientWriter::kNoTimestamp, displayId, frameIntervalNs);
3199 presentFence->waitForever(LOG_TAG);
3200 auto lastPresentTimeNs = presentFence->getSignalTime();
3201 do {
3202 frameIntervalNs = vsyncPeriod * divisor;
3203 ++divisor;
3204 const auto nextFrameIntervalNs = vsyncPeriod * divisor;
3205 const auto frameAfterHeadsUp = frameIntervalNs * (headsUpNs / frameIntervalNs);
3206 auto presentTime = lastPresentTimeNs + frameIntervalNs + frameAfterHeadsUp;
3207 const auto expectedPresentTimestamp = ClockMonotonicTimestamp{presentTime};
3208 presentFence =
3209 presentAndGetFence(expectedPresentTimestamp, displayId, nextFrameIntervalNs);
3210 presentFence->waitForever(LOG_TAG);
3211 lastPresentTimeNs = presentFence->getSignalTime();
3212 if (lastPresentTimeNs >= expectedPresentTimestamp.timestampNanos - vsyncPeriod / 2) {
3213 ++totalDivisorsPassed;
3214 }
3215 } while (divisor < highestDivisor);
3216 EXPECT_TRUE(totalDivisorsPassed >
3217 (static_cast<float>(highestDivisor - lowestDivisor)) * 0.75f);
3218 mComposerClient->destroyLayer(displayId, layer, &writer);
3219 });
3220 }
3221
3222 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
3223 INSTANTIATE_TEST_SUITE_P(
3224 PerInstance, GraphicsComposerAidlCommandTest,
3225 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3226 ::android::PrintInstanceNameToString);
3227 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
3228 INSTANTIATE_TEST_SUITE_P(
3229 PerInstance, GraphicsComposerAidlTest,
3230 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3231 ::android::PrintInstanceNameToString);
3232 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV2Test);
3233 INSTANTIATE_TEST_SUITE_P(
3234 PerInstance, GraphicsComposerAidlV2Test,
3235 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3236 ::android::PrintInstanceNameToString);
3237 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlV3Test);
3238 INSTANTIATE_TEST_SUITE_P(
3239 PerInstance, GraphicsComposerAidlV3Test,
3240 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3241 ::android::PrintInstanceNameToString);
3242 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV2Test);
3243 INSTANTIATE_TEST_SUITE_P(
3244 PerInstance, GraphicsComposerAidlCommandV2Test,
3245 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3246 ::android::PrintInstanceNameToString);
3247 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
3248 INSTANTIATE_TEST_SUITE_P(
3249 PerInstance, GraphicsComposerAidlCommandV3Test,
3250 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
3251 ::android::PrintInstanceNameToString);
3252 } // namespace aidl::android::hardware::graphics::composer3::vts
3253
main(int argc,char ** argv)3254 int main(int argc, char** argv) {
3255 ::testing::InitGoogleTest(&argc, argv);
3256
3257 using namespace std::chrono_literals;
3258 if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
3259 ALOGE("Failed to stop init.svc.surfaceflinger");
3260 return -1;
3261 }
3262
3263 android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
3264
3265 // The binder threadpool we start will inherit sched policy and priority
3266 // of (this) creating thread. We want the binder thread pool to have
3267 // SCHED_FIFO policy and priority 1 (lowest RT priority)
3268 // Once the pool is created we reset this thread's priority back to
3269 // original.
3270 // This thread policy is based on what we do in the SurfaceFlinger while starting
3271 // the thread pool and we need to replicate that for the VTS tests.
3272 int newPriority = 0;
3273 int origPolicy = sched_getscheduler(0);
3274 struct sched_param origSchedParam;
3275
3276 int errorInPriorityModification = sched_getparam(0, &origSchedParam);
3277 if (errorInPriorityModification == 0) {
3278 int policy = SCHED_FIFO;
3279 newPriority = sched_get_priority_min(policy);
3280
3281 struct sched_param param;
3282 param.sched_priority = newPriority;
3283
3284 errorInPriorityModification = sched_setscheduler(0, policy, ¶m);
3285 }
3286
3287 // start the thread pool
3288 android::ProcessState::self()->startThreadPool();
3289
3290 // Reset current thread's policy and priority
3291 if (errorInPriorityModification == 0) {
3292 errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
3293 } else {
3294 ALOGE("Failed to set VtsHalGraphicsComposer3_TargetTest binder threadpool priority to "
3295 "SCHED_FIFO");
3296 }
3297
3298 return RUN_ALL_TESTS();
3299 }
3300