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