1 /*
2 * Copyright 2019 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 #define LOG_TAG "[email protected]"
18
19 #include <algorithm>
20 #include <regex>
21 #include <thread>
22
23 #include <android-base/logging.h>
24 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
25 #include <composer-command-buffer/2.4/ComposerCommandBuffer.h>
26 #include <composer-vts/2.4/ComposerVts.h>
27 #include <composer-vts/2.4/GraphicsComposerCallback.h>
28 #include <composer-vts/2.4/TestCommandReader.h>
29 #include <gtest/gtest.h>
30 #include <hidl/GtestPrinter.h>
31 #include <hidl/ServiceManagement.h>
32 #include <mapper-vts/2.0/MapperVts.h>
33 #include <mapper-vts/3.0/MapperVts.h>
34 #include <mapper-vts/4.0/MapperVts.h>
35 #include <utils/Timers.h>
36
37 namespace android {
38 namespace hardware {
39 namespace graphics {
40 namespace composer {
41 namespace V2_4 {
42 namespace vts {
43 namespace {
44
45 using namespace std::chrono_literals;
46
47 using common::V1_0::BufferUsage;
48 using common::V1_1::RenderIntent;
49 using common::V1_2::ColorMode;
50 using common::V1_2::Dataspace;
51 using common::V1_2::PixelFormat;
52 using mapper::V2_0::IMapper;
53 using V2_1::Layer;
54 using V2_2::Transform;
55 using V2_2::vts::Gralloc;
56
57 using ContentType = IComposerClient::ContentType;
58 using DisplayCapability = IComposerClient::DisplayCapability;
59
60 class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
61 protected:
SetUp()62 void SetUp() override {
63 ASSERT_NO_FATAL_FAILURE(
64 mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
65 ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
66
67 mComposerCallback = new GraphicsComposerCallback;
68 mComposerClient->registerCallback_2_4(mComposerCallback);
69
70 // assume the first display is primary and is never removed
71 mPrimaryDisplay = waitForFirstDisplay();
72
73 mInvalidDisplayId = GetInvalidDisplayId();
74
75 // explicitly disable vsync
76 mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
77 mComposerCallback->setVsyncAllowed(false);
78
79 mWriter = std::make_unique<CommandWriterBase>(1024);
80 mReader = std::make_unique<TestCommandReader>();
81 }
82
TearDown()83 void TearDown() override {
84 ASSERT_EQ(0, mReader->mErrors.size());
85 ASSERT_EQ(0, mReader->mCompositionChanges.size());
86 if (mComposerCallback != nullptr) {
87 EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
88 EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
89 EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
90 EXPECT_EQ(0, mComposerCallback->getInvalidVsync_2_4Count());
91 EXPECT_EQ(0, mComposerCallback->getInvalidVsyncPeriodChangeCount());
92 EXPECT_EQ(0, mComposerCallback->getInvalidSeamlessPossibleCount());
93 }
94 }
95
96 // returns an invalid display id (one that has not been registered to a
97 // display. Currently assuming that a device will never have close to
98 // std::numeric_limit<uint64_t>::max() displays registered while running tests
GetInvalidDisplayId()99 Display GetInvalidDisplayId() {
100 std::vector<Display> validDisplays = mComposerCallback->getDisplays();
101 uint64_t id = std::numeric_limits<uint64_t>::max();
102 while (id > 0) {
103 if (std::find(validDisplays.begin(), validDisplays.end(), id) == validDisplays.end()) {
104 return id;
105 }
106 id--;
107 }
108
109 return 0;
110 }
111
112 // returns an invalid config id (one that has not been registered to a
113 // display). Currently assuming that a device will never have close to
114 // std::numeric_limit<uint64_t>::max() configs registered while running tests
GetInvalidConfigId(Display display)115 Display GetInvalidConfigId(Display display) {
116 std::vector<Config> validConfigs = mComposerClient->getDisplayConfigs(display);
117 uint64_t id = std::numeric_limits<uint64_t>::max();
118 while (id > 0) {
119 if (std::find(validConfigs.begin(), validConfigs.end(), id) == validConfigs.end()) {
120 return id;
121 }
122 id--;
123 }
124
125 return 0;
126 }
127
execute()128 void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
129
forEachTwoConfigs(Display display,std::function<void (Config,Config)> func)130 void forEachTwoConfigs(Display display, std::function<void(Config, Config)> func) {
131 const auto displayConfigs = mComposerClient->getDisplayConfigs(display);
132 for (const Config config1 : displayConfigs) {
133 for (const Config config2 : displayConfigs) {
134 if (config1 != config2) {
135 func(config1, config2);
136 }
137 }
138 }
139 }
140
141 // use the slot count usually set by SF
142 static constexpr uint32_t kBufferSlotCount = 64;
143
144 void Test_setContentType(const ContentType& contentType, const char* contentTypeStr);
145 void Test_setContentTypeForDisplay(const Display& display,
146 const std::vector<ContentType>& capabilities,
147 const ContentType& contentType, const char* contentTypeStr);
148
149 std::unique_ptr<Composer> mComposer;
150 std::unique_ptr<ComposerClient> mComposerClient;
151 sp<GraphicsComposerCallback> mComposerCallback;
152 // the first display and is assumed never to be removed
153 Display mPrimaryDisplay;
154 Display mInvalidDisplayId;
155 std::unique_ptr<CommandWriterBase> mWriter;
156 std::unique_ptr<TestCommandReader> mReader;
157
158 private:
waitForFirstDisplay()159 Display waitForFirstDisplay() {
160 while (true) {
161 std::vector<Display> displays = mComposerCallback->getDisplays();
162 if (displays.empty()) {
163 usleep(5 * 1000);
164 continue;
165 }
166
167 return displays[0];
168 }
169 }
170 };
171
172 // Tests for IComposerClient::Command.
173 class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
174 protected:
SetUp()175 void SetUp() override {
176 ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
177
178 ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
179
180 const Config activeConfig = mComposerClient->getActiveConfig(mPrimaryDisplay);
181 mDisplayWidth = mComposerClient->getDisplayAttribute_2_4(mPrimaryDisplay, activeConfig,
182 IComposerClient::Attribute::WIDTH);
183 mDisplayHeight = mComposerClient->getDisplayAttribute_2_4(
184 mPrimaryDisplay, activeConfig, IComposerClient::Attribute::HEIGHT);
185
186 mWriter = std::make_unique<CommandWriterBase>(1024);
187 mReader = std::make_unique<TestCommandReader>();
188 }
189
TearDown()190 void TearDown() override {
191 ASSERT_EQ(0, mReader->mErrors.size());
192 ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown());
193 }
194
allocate()195 const native_handle_t* allocate() {
196 return mGralloc->allocate(
197 /*width*/ 64, /*height*/ 64, /*layerCount*/ 1,
198 static_cast<common::V1_1::PixelFormat>(PixelFormat::RGBA_8888),
199 static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN));
200 }
201
execute()202 void execute() { mComposerClient->execute(mReader.get(), mWriter.get()); }
203
204 struct TestParameters {
205 nsecs_t delayForChange;
206 bool refreshMiss;
207 };
208
209 void Test_setActiveConfigWithConstraints(const TestParameters& params);
210
211 void sendRefreshFrame(const VsyncPeriodChangeTimeline*);
212
213 void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
214 int64_t desiredTimeNanos, int64_t oldPeriodNanos,
215 int64_t newPeriodNanos);
216
217 std::unique_ptr<CommandWriterBase> mWriter;
218 std::unique_ptr<TestCommandReader> mReader;
219 int32_t mDisplayWidth;
220 int32_t mDisplayHeight;
221
222 private:
223 std::unique_ptr<Gralloc> mGralloc;
224 };
225
TEST_P(GraphicsComposerHidlTest,getDisplayCapabilitiesBadDisplay)226 TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
227 std::vector<IComposerClient::DisplayCapability> capabilities;
228 const auto error = mComposerClient->getDisplayCapabilities(mInvalidDisplayId, &capabilities);
229 EXPECT_EQ(Error::BAD_DISPLAY, error);
230 }
231
TEST_P(GraphicsComposerHidlTest,getDisplayCapabilities)232 TEST_P(GraphicsComposerHidlTest, getDisplayCapabilities) {
233 for (Display display : mComposerCallback->getDisplays()) {
234 std::vector<IComposerClient::DisplayCapability> capabilities;
235 EXPECT_EQ(Error::NONE, mComposerClient->getDisplayCapabilities(display, &capabilities));
236 }
237 }
238
TEST_P(GraphicsComposerHidlTest,getDisplayConnectionType)239 TEST_P(GraphicsComposerHidlTest, getDisplayConnectionType) {
240 IComposerClient::DisplayConnectionType type;
241 EXPECT_EQ(Error::BAD_DISPLAY,
242 mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type));
243
244 for (Display display : mComposerCallback->getDisplays()) {
245 EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display, &type));
246 }
247 }
248
TEST_P(GraphicsComposerHidlTest,GetDisplayAttribute_2_4)249 TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) {
250 std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
251 for (auto config : configs) {
252 const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
253 IComposerClient::Attribute::WIDTH,
254 IComposerClient::Attribute::HEIGHT,
255 IComposerClient::Attribute::VSYNC_PERIOD,
256 IComposerClient::Attribute::CONFIG_GROUP,
257 }};
258 for (auto attribute : requiredAttributes) {
259 mComposerClient->getRaw()->getDisplayAttribute_2_4(
260 mPrimaryDisplay, config, attribute,
261 [&](const auto& tmpError, const auto& value) {
262 EXPECT_EQ(Error::NONE, tmpError);
263 EXPECT_NE(-1, value);
264 });
265 }
266
267 const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
268 IComposerClient::Attribute::DPI_X,
269 IComposerClient::Attribute::DPI_Y,
270 }};
271 for (auto attribute : optionalAttributes) {
272 mComposerClient->getRaw()->getDisplayAttribute_2_4(
273 mPrimaryDisplay, config, attribute, [&](const auto& tmpError, const auto&) {
274 EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
275 });
276 }
277 }
278 }
279
TEST_P(GraphicsComposerHidlTest,getDisplayVsyncPeriod_BadDisplay)280 TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) {
281 VsyncPeriodNanos vsyncPeriodNanos;
282 EXPECT_EQ(Error::BAD_DISPLAY,
283 mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
284 }
285
TEST_P(GraphicsComposerHidlCommandTest,getDisplayVsyncPeriod)286 TEST_P(GraphicsComposerHidlCommandTest, getDisplayVsyncPeriod) {
287 for (Display display : mComposerCallback->getDisplays()) {
288 for (Config config : mComposerClient->getDisplayConfigs(display)) {
289 VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
290 display, config, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
291
292 VsyncPeriodChangeTimeline timeline;
293 IComposerClient::VsyncPeriodChangeConstraints constraints;
294
295 constraints.desiredTimeNanos = systemTime();
296 constraints.seamlessRequired = false;
297 EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
298 display, config, constraints, &timeline));
299
300 if (timeline.refreshRequired) {
301 sendRefreshFrame(&timeline);
302 }
303 waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, 0,
304 expectedVsyncPeriodNanos);
305
306 VsyncPeriodNanos vsyncPeriodNanos;
307 int retryCount = 100;
308 do {
309 std::this_thread::sleep_for(10ms);
310 vsyncPeriodNanos = 0;
311 EXPECT_EQ(Error::NONE,
312 mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
313 --retryCount;
314 } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
315
316 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
317
318 // Make sure that the vsync period stays the same if the active config is not changed.
319 auto timeout = 1ms;
320 for (int i = 0; i < 10; i++) {
321 std::this_thread::sleep_for(timeout);
322 timeout *= 2;
323 vsyncPeriodNanos = 0;
324 EXPECT_EQ(Error::NONE,
325 mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
326 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
327 }
328 }
329 }
330 }
331
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_BadDisplay)332 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadDisplay) {
333 VsyncPeriodChangeTimeline timeline;
334 IComposerClient::VsyncPeriodChangeConstraints constraints;
335
336 constraints.seamlessRequired = false;
337 constraints.desiredTimeNanos = systemTime();
338
339 EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigWithConstraints(
340 mInvalidDisplayId, Config(0), constraints, &timeline));
341 }
342
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_BadConfig)343 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) {
344 VsyncPeriodChangeTimeline timeline;
345 IComposerClient::VsyncPeriodChangeConstraints constraints;
346
347 constraints.seamlessRequired = false;
348 constraints.desiredTimeNanos = systemTime();
349
350 for (Display display : mComposerCallback->getDisplays()) {
351 Config invalidConfigId = GetInvalidConfigId(display);
352 EXPECT_EQ(Error::BAD_CONFIG, mComposerClient->setActiveConfigWithConstraints(
353 display, invalidConfigId, constraints, &timeline));
354 }
355 }
356
TEST_P(GraphicsComposerHidlCommandTest,setActiveConfigWithConstraints_SeamlessNotAllowed)357 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
358 VsyncPeriodChangeTimeline timeline;
359 IComposerClient::VsyncPeriodChangeConstraints constraints;
360
361 constraints.seamlessRequired = true;
362 constraints.desiredTimeNanos = systemTime();
363
364 for (Display display : mComposerCallback->getDisplays()) {
365 forEachTwoConfigs(display, [&](Config config1, Config config2) {
366 const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
367 display, config1, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
368 const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4(
369 display, config2, IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
370 if (configGroup1 != configGroup2) {
371 mComposerClient->setActiveConfig(display, config1);
372 sendRefreshFrame(nullptr);
373 EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
374 mComposerClient->setActiveConfigWithConstraints(display, config2,
375 constraints, &timeline));
376 }
377 });
378 }
379 }
380
toTimePoint(nsecs_t time)381 static inline auto toTimePoint(nsecs_t time) {
382 return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
383 }
384
sendRefreshFrame(const VsyncPeriodChangeTimeline * timeline)385 void GraphicsComposerHidlCommandTest::sendRefreshFrame(const VsyncPeriodChangeTimeline* timeline) {
386 if (timeline != nullptr) {
387 // Refresh time should be before newVsyncAppliedTimeNanos
388 EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
389
390 std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
391 }
392
393 mWriter->selectDisplay(mPrimaryDisplay);
394 mComposerClient->setPowerMode(mPrimaryDisplay, V2_1::IComposerClient::PowerMode::ON);
395 mComposerClient->setColorMode_2_3(mPrimaryDisplay, ColorMode::NATIVE,
396 RenderIntent::COLORIMETRIC);
397
398 auto handle = allocate();
399 ASSERT_NE(nullptr, handle);
400
401 IComposerClient::Rect displayFrame{0, 0, mDisplayWidth, mDisplayHeight};
402
403 Layer layer;
404 ASSERT_NO_FATAL_FAILURE(
405 layer = mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
406 mWriter->selectLayer(layer);
407 mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
408 mWriter->setLayerDisplayFrame(displayFrame);
409 mWriter->setLayerPlaneAlpha(1);
410 mWriter->setLayerSourceCrop({0, 0, (float)mDisplayWidth, (float)mDisplayHeight});
411 mWriter->setLayerTransform(static_cast<Transform>(0));
412 mWriter->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, displayFrame));
413 mWriter->setLayerZOrder(10);
414 mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
415 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, displayFrame));
416 mWriter->setLayerBuffer(0, handle, -1);
417 mWriter->setLayerDataspace(Dataspace::UNKNOWN);
418
419 mWriter->validateDisplay();
420 execute();
421 ASSERT_EQ(0, mReader->mErrors.size());
422 mReader->mCompositionChanges.clear();
423
424 mWriter->presentDisplay();
425 execute();
426 ASSERT_EQ(0, mReader->mErrors.size());
427
428 mWriter->selectLayer(layer);
429 auto handle2 = allocate();
430 ASSERT_NE(nullptr, handle2);
431
432 mWriter->setLayerBuffer(0, handle2, -1);
433 mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, {0, 0, 10, 10}));
434 mWriter->validateDisplay();
435 execute();
436 ASSERT_EQ(0, mReader->mErrors.size());
437 mReader->mCompositionChanges.clear();
438
439 mWriter->presentDisplay();
440 execute();
441 }
442
waitForVsyncPeriodChange(Display display,const VsyncPeriodChangeTimeline & timeline,int64_t desiredTimeNanos,int64_t oldPeriodNanos,int64_t newPeriodNanos)443 void GraphicsComposerHidlCommandTest::waitForVsyncPeriodChange(
444 Display display, const VsyncPeriodChangeTimeline& timeline, int64_t desiredTimeNanos,
445 int64_t oldPeriodNanos, int64_t newPeriodNanos) {
446 const auto CHANGE_DEADLINE = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
447 while (std::chrono::steady_clock::now() <= CHANGE_DEADLINE) {
448 VsyncPeriodNanos vsyncPeriodNanos;
449 EXPECT_EQ(Error::NONE, mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
450 if (systemTime() <= desiredTimeNanos) {
451 EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
452 } else if (vsyncPeriodNanos == newPeriodNanos) {
453 break;
454 }
455 std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
456 }
457 }
458
Test_setActiveConfigWithConstraints(const TestParameters & params)459 void GraphicsComposerHidlCommandTest::Test_setActiveConfigWithConstraints(
460 const TestParameters& params) {
461 for (Display display : mComposerCallback->getDisplays()) {
462 forEachTwoConfigs(display, [&](Config config1, Config config2) {
463 mComposerClient->setActiveConfig(display, config1);
464 sendRefreshFrame(nullptr);
465
466 int32_t vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
467 display, config1, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
468 int32_t vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
469 display, config2, IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
470
471 if (vsyncPeriod1 == vsyncPeriod2) {
472 return; // continue
473 }
474
475 VsyncPeriodChangeTimeline timeline;
476 IComposerClient::VsyncPeriodChangeConstraints constraints = {
477 .desiredTimeNanos = systemTime() + params.delayForChange,
478 .seamlessRequired = false};
479 EXPECT_EQ(Error::NONE, mComposerClient->setActiveConfigWithConstraints(
480 display, config2, constraints, &timeline));
481
482 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
483 // Refresh rate should change within a reasonable time
484 constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s; // 1 second
485 EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
486 kReasonableTimeForChange.count());
487
488 if (timeline.refreshRequired) {
489 if (params.refreshMiss) {
490 // Miss the refresh frame on purpose to make sure the implementation sends a
491 // callback
492 std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms);
493 }
494 sendRefreshFrame(&timeline);
495 }
496 waitForVsyncPeriodChange(display, timeline, constraints.desiredTimeNanos, vsyncPeriod1,
497 vsyncPeriod2);
498
499 // At this point the refresh rate should have changed already, however in rare
500 // cases the implementation might have missed the deadline. In this case a new
501 // timeline should have been provided.
502 auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
503 if (timeline.refreshRequired && params.refreshMiss) {
504 EXPECT_TRUE(newTimeline.has_value());
505 }
506
507 if (newTimeline.has_value()) {
508 if (newTimeline->refreshRequired) {
509 sendRefreshFrame(&newTimeline.value());
510 }
511 waitForVsyncPeriodChange(display, newTimeline.value(), constraints.desiredTimeNanos,
512 vsyncPeriod1, vsyncPeriod2);
513 }
514
515 VsyncPeriodNanos vsyncPeriodNanos;
516 EXPECT_EQ(Error::NONE,
517 mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
518 EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
519 });
520 }
521 }
522
TEST_P(GraphicsComposerHidlCommandTest,setActiveConfigWithConstraints)523 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints) {
524 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
525 }
526
TEST_P(GraphicsComposerHidlCommandTest,setActiveConfigWithConstraints_Delayed)527 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_Delayed) {
528 Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000, // 300ms
529 .refreshMiss = false});
530 }
531
TEST_P(GraphicsComposerHidlCommandTest,setActiveConfigWithConstraints_MissRefresh)532 TEST_P(GraphicsComposerHidlCommandTest, setActiveConfigWithConstraints_MissRefresh) {
533 Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
534 }
535
TEST_P(GraphicsComposerHidlTest,setAutoLowLatencyModeBadDisplay)536 TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) {
537 EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true));
538 EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false));
539 }
540
TEST_P(GraphicsComposerHidlTest,setAutoLowLatencyMode)541 TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
542 for (Display display : mComposerCallback->getDisplays()) {
543 std::vector<DisplayCapability> capabilities;
544 const auto error = mComposerClient->getDisplayCapabilities(display, &capabilities);
545 EXPECT_EQ(Error::NONE, error);
546
547 const bool allmSupport =
548 std::find(capabilities.begin(), capabilities.end(),
549 DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
550
551 if (!allmSupport) {
552 EXPECT_EQ(Error::UNSUPPORTED,
553 mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
554 EXPECT_EQ(Error::UNSUPPORTED,
555 mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
556 GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
557 << std::to_string(display) << ", skipping test";
558 return;
559 }
560
561 EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, true));
562 EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(mPrimaryDisplay, false));
563 }
564 }
565
TEST_P(GraphicsComposerHidlTest,getSupportedContentTypesBadDisplay)566 TEST_P(GraphicsComposerHidlTest, getSupportedContentTypesBadDisplay) {
567 std::vector<ContentType> supportedContentTypes;
568 const auto error =
569 mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes);
570 EXPECT_EQ(Error::BAD_DISPLAY, error);
571 }
572
TEST_P(GraphicsComposerHidlTest,getSupportedContentTypes)573 TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
574 std::vector<ContentType> supportedContentTypes;
575 for (Display display : mComposerCallback->getDisplays()) {
576 supportedContentTypes.clear();
577 const auto error =
578 mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
579 const bool noneSupported =
580 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
581 ContentType::NONE) != supportedContentTypes.end();
582 EXPECT_EQ(Error::NONE, error);
583 EXPECT_FALSE(noneSupported);
584 }
585 }
586
TEST_P(GraphicsComposerHidlTest,setContentTypeNoneAlwaysAccepted)587 TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) {
588 for (Display display : mComposerCallback->getDisplays()) {
589 const auto error = mComposerClient->setContentType(display, ContentType::NONE);
590 EXPECT_NE(Error::UNSUPPORTED, error);
591 }
592 }
593
TEST_P(GraphicsComposerHidlTest,setContentTypeBadDisplay)594 TEST_P(GraphicsComposerHidlTest, setContentTypeBadDisplay) {
595 const auto types = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
596 ContentType::CINEMA, ContentType::GAME};
597 for (auto type : types) {
598 EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setContentType(mInvalidDisplayId, type));
599 }
600 }
601
Test_setContentTypeForDisplay(const Display & display,const std::vector<ContentType> & capabilities,const ContentType & contentType,const char * contentTypeStr)602 void GraphicsComposerHidlTest::Test_setContentTypeForDisplay(
603 const Display& display, const std::vector<ContentType>& capabilities,
604 const ContentType& contentType, const char* contentTypeStr) {
605 const bool contentTypeSupport =
606 std::find(capabilities.begin(), capabilities.end(), contentType) != capabilities.end();
607
608 if (!contentTypeSupport) {
609 EXPECT_EQ(Error::UNSUPPORTED, mComposerClient->setContentType(display, contentType));
610 GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
611 << std::to_string(display) << ", skipping test";
612 return;
613 }
614
615 EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, contentType));
616 EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, ContentType::NONE));
617 }
618
Test_setContentType(const ContentType & contentType,const char * contentTypeStr)619 void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType,
620 const char* contentTypeStr) {
621 for (Display display : mComposerCallback->getDisplays()) {
622 std::vector<ContentType> supportedContentTypes;
623 const auto error =
624 mComposerClient->getSupportedContentTypes(display, &supportedContentTypes);
625 EXPECT_EQ(Error::NONE, error);
626
627 Test_setContentTypeForDisplay(display, supportedContentTypes, contentType, contentTypeStr);
628 }
629 }
630
TEST_P(GraphicsComposerHidlTest,setGraphicsContentType)631 TEST_P(GraphicsComposerHidlTest, setGraphicsContentType) {
632 Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
633 }
634
TEST_P(GraphicsComposerHidlTest,setPhotoContentType)635 TEST_P(GraphicsComposerHidlTest, setPhotoContentType) {
636 Test_setContentType(ContentType::PHOTO, "PHOTO");
637 }
638
TEST_P(GraphicsComposerHidlTest,setCinemaContentType)639 TEST_P(GraphicsComposerHidlTest, setCinemaContentType) {
640 Test_setContentType(ContentType::CINEMA, "CINEMA");
641 }
642
TEST_P(GraphicsComposerHidlTest,setGameContentType)643 TEST_P(GraphicsComposerHidlTest, setGameContentType) {
644 Test_setContentType(ContentType::GAME, "GAME");
645 }
646
647 INSTANTIATE_TEST_SUITE_P(
648 PerInstance, GraphicsComposerHidlTest,
649 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
650 android::hardware::PrintInstanceNameToString);
651
652 INSTANTIATE_TEST_SUITE_P(
653 PerInstance, GraphicsComposerHidlCommandTest,
654 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
655 android::hardware::PrintInstanceNameToString);
656
TEST_P(GraphicsComposerHidlCommandTest,getLayerGenericMetadataKeys)657 TEST_P(GraphicsComposerHidlCommandTest, getLayerGenericMetadataKeys) {
658 std::vector<IComposerClient::LayerGenericMetadataKey> keys;
659 mComposerClient->getLayerGenericMetadataKeys(&keys);
660
661 std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
662 std::unordered_set<std::string> uniqueNames;
663 for (const auto& key : keys) {
664 std::string name(key.name.c_str());
665
666 // Keys must not start with 'android' or 'com.android'
667 ASSERT_FALSE(name.find("android") == 0);
668 ASSERT_FALSE(name.find("com.android") == 0);
669
670 // Keys must be in reverse domain name format
671 ASSERT_TRUE(std::regex_match(name, reverseDomainName));
672
673 // Keys must be unique within this list
674 const auto& [iter, inserted] = uniqueNames.insert(name);
675 ASSERT_TRUE(inserted);
676 }
677 }
678
679 } // namespace
680 } // namespace vts
681 } // namespace V2_4
682 } // namespace composer
683 } // namespace graphics
684 } // namespace hardware
685 } // namespace android
686