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