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