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     }
166 
167     struct TestParameters {
168         nsecs_t delayForChange;
169         bool refreshMiss;
170     };
171 
172     void Test_setActiveConfigWithConstraints(const TestParameters& params);
173 
174     void sendRefreshFrame(const VtsDisplay& display, const VsyncPeriodChangeTimeline*);
175 
176     void waitForVsyncPeriodChange(Display display, const VsyncPeriodChangeTimeline& timeline,
177                                   int64_t desiredTimeNanos, int64_t oldPeriodNanos,
178                                   int64_t newPeriodNanos);
179 
180     std::unique_ptr<ComposerClient> mComposerClient;
181     std::vector<VtsDisplay> mDisplays;
182     Display mInvalidDisplayId;
183 
forEachTwoConfigs(Display display,std::function<void (Config,Config)> func)184     void forEachTwoConfigs(Display display, std::function<void(Config, Config)> func) {
185         const auto displayConfigs = mComposerClient->getDisplayConfigs(display);
186         for (const Config config1 : displayConfigs) {
187             for (const Config config2 : displayConfigs) {
188                 if (config1 != config2) {
189                     func(config1, config2);
190                 }
191             }
192         }
193     }
194 
195     void Test_setContentType(const ContentType& contentType, const char* contentTypeStr);
196     void Test_setContentTypeForDisplay(const Display& display,
197                                        const std::vector<ContentType>& capabilities,
198                                        const ContentType& contentType, const char* contentTypeStr);
199 
setActiveConfigWithConstraints(VtsDisplay & display,Config config,const IComposerClient::VsyncPeriodChangeConstraints & constraints,VsyncPeriodChangeTimeline * timeline)200     Error setActiveConfigWithConstraints(
201             VtsDisplay& display, Config config,
202             const IComposerClient::VsyncPeriodChangeConstraints& constraints,
203             VsyncPeriodChangeTimeline* timeline) {
204         const auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config,
205                                                                            constraints, timeline);
206         if (error == Error::NONE) {
207             const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
208                     display.get(), config, IComposerClient::Attribute::WIDTH);
209             const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
210                     display.get(), config, IComposerClient::Attribute::HEIGHT);
211             display.setDimensions(displayWidth, displayHeight);
212         }
213         return error;
214     }
215 
setActiveConfig(VtsDisplay & display,Config config)216     void setActiveConfig(VtsDisplay& display, Config config) {
217         mComposerClient->setActiveConfig(display.get(), config);
218         const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
219                 display.get(), config, IComposerClient::Attribute::WIDTH);
220         const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
221                 display.get(), config, IComposerClient::Attribute::HEIGHT);
222         display.setDimensions(displayWidth, displayHeight);
223     }
224 
225   private:
226     // use the slot count usually set by SF
227     static constexpr uint32_t kBufferSlotCount = 64;
228 
waitForDisplays()229     std::vector<VtsDisplay> waitForDisplays() {
230         while (true) {
231             // Sleep for a small period of time to allow all built-in displays
232             // to post hotplug events
233             std::this_thread::sleep_for(5ms);
234             std::vector<Display> displays = mComposerCallback->getDisplays();
235             if (displays.empty()) {
236                 continue;
237             }
238 
239             std::vector<VtsDisplay> vtsDisplays;
240             vtsDisplays.reserve(displays.size());
241             for (Display display : displays) {
242                 const Config activeConfig = mComposerClient->getActiveConfig(display);
243                 const int32_t displayWidth = mComposerClient->getDisplayAttribute_2_4(
244                         display, activeConfig, IComposerClient::Attribute::WIDTH);
245                 const int32_t displayHeight = mComposerClient->getDisplayAttribute_2_4(
246                         display, activeConfig, IComposerClient::Attribute::HEIGHT);
247                 vtsDisplays.emplace_back(VtsDisplay{display, displayWidth, displayHeight});
248             }
249 
250             return vtsDisplays;
251         }
252     }
253 
254     std::unique_ptr<Composer> mComposer;
255     std::unique_ptr<CommandWriterBase> mWriter;
256     std::unique_ptr<TestCommandReader> mReader;
257     sp<GraphicsComposerCallback> mComposerCallback;
258     std::unique_ptr<Gralloc> mGralloc;
259 };
260 
TEST_P(GraphicsComposerHidlTest,getDisplayCapabilitiesBadDisplay)261 TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
262     std::vector<IComposerClient::DisplayCapability> capabilities;
263     const auto error = mComposerClient->getDisplayCapabilities(mInvalidDisplayId, &capabilities);
264     EXPECT_EQ(Error::BAD_DISPLAY, error);
265 }
266 
TEST_P(GraphicsComposerHidlTest,getDisplayCapabilities)267 TEST_P(GraphicsComposerHidlTest, getDisplayCapabilities) {
268     for (const auto& display : mDisplays) {
269         std::vector<IComposerClient::DisplayCapability> capabilities;
270         EXPECT_EQ(Error::NONE,
271                   mComposerClient->getDisplayCapabilities(display.get(), &capabilities));
272     }
273 }
274 
TEST_P(GraphicsComposerHidlTest,getDisplayConnectionType)275 TEST_P(GraphicsComposerHidlTest, getDisplayConnectionType) {
276     IComposerClient::DisplayConnectionType type;
277     EXPECT_EQ(Error::BAD_DISPLAY,
278               mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type));
279 
280     for (const auto& display : mDisplays) {
281         EXPECT_EQ(Error::NONE, mComposerClient->getDisplayConnectionType(display.get(), &type));
282     }
283 }
284 
TEST_P(GraphicsComposerHidlTest,GetDisplayAttribute_2_4)285 TEST_P(GraphicsComposerHidlTest, GetDisplayAttribute_2_4) {
286     for (const auto& display : mDisplays) {
287         std::vector<Config> configs = mComposerClient->getDisplayConfigs(display.get());
288         for (auto config : configs) {
289             const std::array<IComposerClient::Attribute, 4> requiredAttributes = {{
290                     IComposerClient::Attribute::WIDTH,
291                     IComposerClient::Attribute::HEIGHT,
292                     IComposerClient::Attribute::VSYNC_PERIOD,
293                     IComposerClient::Attribute::CONFIG_GROUP,
294             }};
295             for (auto attribute : requiredAttributes) {
296                 mComposerClient->getRaw()->getDisplayAttribute_2_4(
297                         display.get(), config, attribute,
298                         [&](const auto& tmpError, const auto& value) {
299                             EXPECT_EQ(Error::NONE, tmpError);
300                             EXPECT_NE(-1, value);
301                         });
302             }
303 
304             const std::array<IComposerClient::Attribute, 2> optionalAttributes = {{
305                     IComposerClient::Attribute::DPI_X,
306                     IComposerClient::Attribute::DPI_Y,
307             }};
308             for (auto attribute : optionalAttributes) {
309                 mComposerClient->getRaw()->getDisplayAttribute_2_4(
310                         display.get(), config, attribute, [&](const auto& tmpError, const auto&) {
311                             EXPECT_TRUE(tmpError == Error::NONE || tmpError == Error::UNSUPPORTED);
312                         });
313             }
314         }
315     }
316 }
317 
TEST_P(GraphicsComposerHidlTest,getDisplayVsyncPeriod_BadDisplay)318 TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) {
319     VsyncPeriodNanos vsyncPeriodNanos;
320     EXPECT_EQ(Error::BAD_DISPLAY,
321               mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
322 }
323 
TEST_P(GraphicsComposerHidlTest,getDisplayVsyncPeriod)324 TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod) {
325     for (VtsDisplay& display : mDisplays) {
326         for (Config config : mComposerClient->getDisplayConfigs(display.get())) {
327             VsyncPeriodNanos expectedVsyncPeriodNanos = mComposerClient->getDisplayAttribute_2_4(
328                     display.get(), config,
329                     IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
330 
331             VsyncPeriodChangeTimeline timeline;
332             IComposerClient::VsyncPeriodChangeConstraints constraints;
333 
334             constraints.desiredTimeNanos = systemTime();
335             constraints.seamlessRequired = false;
336             EXPECT_EQ(Error::NONE,
337                       setActiveConfigWithConstraints(display, config, constraints, &timeline));
338 
339             if (timeline.refreshRequired) {
340                 sendRefreshFrame(display, &timeline);
341             }
342             waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos, 0,
343                                      expectedVsyncPeriodNanos);
344 
345             VsyncPeriodNanos vsyncPeriodNanos;
346             int retryCount = 100;
347             do {
348                 std::this_thread::sleep_for(10ms);
349                 vsyncPeriodNanos = 0;
350                 EXPECT_EQ(Error::NONE,
351                           mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
352                 --retryCount;
353             } while (vsyncPeriodNanos != expectedVsyncPeriodNanos && retryCount > 0);
354 
355             EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
356 
357             // Make sure that the vsync period stays the same if the active config is not changed.
358             auto timeout = 1ms;
359             for (int i = 0; i < 10; i++) {
360                 std::this_thread::sleep_for(timeout);
361                 timeout *= 2;
362                 vsyncPeriodNanos = 0;
363                 EXPECT_EQ(Error::NONE,
364                           mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
365                 EXPECT_EQ(vsyncPeriodNanos, expectedVsyncPeriodNanos);
366             }
367         }
368     }
369 }
370 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_BadDisplay)371 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadDisplay) {
372     VsyncPeriodChangeTimeline timeline;
373     IComposerClient::VsyncPeriodChangeConstraints constraints;
374 
375     constraints.seamlessRequired = false;
376     constraints.desiredTimeNanos = systemTime();
377 
378     EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setActiveConfigWithConstraints(
379                                           mInvalidDisplayId, Config(0), constraints, &timeline));
380 }
381 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_BadConfig)382 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_BadConfig) {
383     VsyncPeriodChangeTimeline timeline;
384     IComposerClient::VsyncPeriodChangeConstraints constraints;
385 
386     constraints.seamlessRequired = false;
387     constraints.desiredTimeNanos = systemTime();
388 
389     for (VtsDisplay& display : mDisplays) {
390         Config invalidConfigId = GetInvalidConfigId(display.get());
391         EXPECT_EQ(Error::BAD_CONFIG,
392                   setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline));
393     }
394 }
395 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_SeamlessNotAllowed)396 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_SeamlessNotAllowed) {
397     VsyncPeriodChangeTimeline timeline;
398     IComposerClient::VsyncPeriodChangeConstraints constraints;
399 
400     constraints.seamlessRequired = true;
401     constraints.desiredTimeNanos = systemTime();
402 
403     for (VtsDisplay& display : mDisplays) {
404         forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
405             const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
406                     display.get(), config1,
407                     IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
408             const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4(
409                     display.get(), config2,
410                     IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
411             if (configGroup1 != configGroup2) {
412                 setActiveConfig(display, config1);
413                 sendRefreshFrame(display, nullptr);
414                 EXPECT_EQ(Error::SEAMLESS_NOT_ALLOWED,
415                           setActiveConfigWithConstraints(display, config2, constraints, &timeline));
416             }
417         });
418     }
419 }
420 
toTimePoint(nsecs_t time)421 static inline auto toTimePoint(nsecs_t time) {
422     return std::chrono::time_point<std::chrono::steady_clock>(std::chrono::nanoseconds(time));
423 }
424 
sendRefreshFrame(const VtsDisplay & display,const VsyncPeriodChangeTimeline * timeline)425 void GraphicsComposerHidlTest::sendRefreshFrame(const VtsDisplay& display,
426                                                 const VsyncPeriodChangeTimeline* timeline) {
427     if (timeline != nullptr) {
428         // Refresh time should be before newVsyncAppliedTimeNanos
429         EXPECT_LT(timeline->refreshTimeNanos, timeline->newVsyncAppliedTimeNanos);
430 
431         std::this_thread::sleep_until(toTimePoint(timeline->refreshTimeNanos));
432     }
433 
434     mWriter->selectDisplay(display.get());
435     mComposerClient->setPowerMode(display.get(), V2_1::IComposerClient::PowerMode::ON);
436     mComposerClient->setColorMode_2_3(display.get(), ColorMode::NATIVE, RenderIntent::COLORIMETRIC);
437 
438     IComposerClient::FRect displayCrop = display.getCrop();
439     int32_t displayWidth = static_cast<int32_t>(std::ceilf(displayCrop.right - displayCrop.left));
440     int32_t displayHeight = static_cast<int32_t>(std::ceilf(displayCrop.bottom - displayCrop.top));
441     Layer layer;
442     ASSERT_NO_FATAL_FAILURE(layer = mComposerClient->createLayer(display.get(), kBufferSlotCount));
443 
444     {
445         auto handle = allocate(displayWidth, displayHeight);
446         ASSERT_NE(nullptr, handle.get());
447 
448         mWriter->selectLayer(layer);
449         mWriter->setLayerCompositionType(IComposerClient::Composition::DEVICE);
450         mWriter->setLayerDisplayFrame(display.getFrameRect());
451         mWriter->setLayerPlaneAlpha(1);
452         mWriter->setLayerSourceCrop(display.getCrop());
453         mWriter->setLayerTransform(static_cast<Transform>(0));
454         mWriter->setLayerVisibleRegion(
455                 std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
456         mWriter->setLayerZOrder(10);
457         mWriter->setLayerBlendMode(IComposerClient::BlendMode::NONE);
458         mWriter->setLayerSurfaceDamage(
459                 std::vector<IComposerClient::Rect>(1, display.getFrameRect()));
460         mWriter->setLayerBuffer(0, handle.get(), -1);
461         mWriter->setLayerDataspace(Dataspace::UNKNOWN);
462 
463         mWriter->validateDisplay();
464         execute();
465         ASSERT_EQ(0, mReader->mErrors.size());
466         mReader->mCompositionChanges.clear();
467 
468         mWriter->presentDisplay();
469         execute();
470         ASSERT_EQ(0, mReader->mErrors.size());
471     }
472 
473     {
474         auto handle = allocate(displayWidth, displayHeight);
475         ASSERT_NE(nullptr, handle.get());
476 
477         mWriter->selectLayer(layer);
478         mWriter->setLayerBuffer(0, handle.get(), -1);
479         mWriter->setLayerSurfaceDamage(std::vector<IComposerClient::Rect>(1, {0, 0, 10, 10}));
480         mWriter->validateDisplay();
481         execute();
482         ASSERT_EQ(0, mReader->mErrors.size());
483         mReader->mCompositionChanges.clear();
484 
485         mWriter->presentDisplay();
486         execute();
487     }
488 
489     ASSERT_NO_FATAL_FAILURE(mComposerClient->destroyLayer(display.get(), layer));
490 }
491 
waitForVsyncPeriodChange(Display display,const VsyncPeriodChangeTimeline & timeline,int64_t desiredTimeNanos,int64_t oldPeriodNanos,int64_t newPeriodNanos)492 void GraphicsComposerHidlTest::waitForVsyncPeriodChange(Display display,
493                                                         const VsyncPeriodChangeTimeline& timeline,
494                                                         int64_t desiredTimeNanos,
495                                                         int64_t oldPeriodNanos,
496                                                         int64_t newPeriodNanos) {
497     const auto CHANGE_DEADLINE = toTimePoint(timeline.newVsyncAppliedTimeNanos) + 100ms;
498     while (std::chrono::steady_clock::now() <= CHANGE_DEADLINE) {
499         VsyncPeriodNanos vsyncPeriodNanos;
500         EXPECT_EQ(Error::NONE, mComposerClient->getDisplayVsyncPeriod(display, &vsyncPeriodNanos));
501         if (systemTime() <= desiredTimeNanos) {
502             EXPECT_EQ(vsyncPeriodNanos, oldPeriodNanos);
503         } else if (vsyncPeriodNanos == newPeriodNanos) {
504             break;
505         }
506         std::this_thread::sleep_for(std::chrono::nanoseconds(oldPeriodNanos));
507     }
508 }
509 
Test_setActiveConfigWithConstraints(const TestParameters & params)510 void GraphicsComposerHidlTest::Test_setActiveConfigWithConstraints(const TestParameters& params) {
511     for (VtsDisplay& display : mDisplays) {
512         forEachTwoConfigs(display.get(), [&](Config config1, Config config2) {
513             setActiveConfig(display, config1);
514             sendRefreshFrame(display, nullptr);
515 
516             const auto vsyncPeriod1 = mComposerClient->getDisplayAttribute_2_4(
517                     display.get(), config1,
518                     IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
519             const auto configGroup1 = mComposerClient->getDisplayAttribute_2_4(
520                     display.get(), config1,
521                     IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
522             const auto vsyncPeriod2 = mComposerClient->getDisplayAttribute_2_4(
523                     display.get(), config2,
524                     IComposerClient::IComposerClient::Attribute::VSYNC_PERIOD);
525             const auto configGroup2 = mComposerClient->getDisplayAttribute_2_4(
526                     display.get(), config2,
527                     IComposerClient::IComposerClient::Attribute::CONFIG_GROUP);
528 
529             if (vsyncPeriod1 == vsyncPeriod2) {
530                 return;  // continue
531             }
532 
533             // We don't allow delayed change when changing config groups
534             if (params.delayForChange > 0 && configGroup1 != configGroup2) {
535                 return;  // continue
536             }
537 
538             VsyncPeriodChangeTimeline timeline;
539             IComposerClient::VsyncPeriodChangeConstraints constraints = {
540                     .desiredTimeNanos = systemTime() + params.delayForChange,
541                     .seamlessRequired = false};
542             EXPECT_EQ(Error::NONE,
543                       setActiveConfigWithConstraints(display, config2, constraints, &timeline));
544 
545             EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos >= constraints.desiredTimeNanos);
546             // Refresh rate should change within a reasonable time
547             constexpr std::chrono::nanoseconds kReasonableTimeForChange = 1s;  // 1 second
548             EXPECT_TRUE(timeline.newVsyncAppliedTimeNanos - constraints.desiredTimeNanos <=
549                         kReasonableTimeForChange.count());
550 
551             if (timeline.refreshRequired) {
552                 if (params.refreshMiss) {
553                     // Miss the refresh frame on purpose to make sure the implementation sends a
554                     // callback
555                     std::this_thread::sleep_until(toTimePoint(timeline.refreshTimeNanos) + 100ms);
556                 }
557                 sendRefreshFrame(display, &timeline);
558             }
559             waitForVsyncPeriodChange(display.get(), timeline, constraints.desiredTimeNanos,
560                                      vsyncPeriod1, vsyncPeriod2);
561 
562             // At this point the refresh rate should have changed already, however in rare
563             // cases the implementation might have missed the deadline. In this case a new
564             // timeline should have been provided.
565             auto newTimeline = mComposerCallback->takeLastVsyncPeriodChangeTimeline();
566             if (timeline.refreshRequired && params.refreshMiss) {
567                 EXPECT_TRUE(newTimeline.has_value());
568             }
569 
570             if (newTimeline.has_value()) {
571                 if (newTimeline->refreshRequired) {
572                     sendRefreshFrame(display, &newTimeline.value());
573                 }
574                 waitForVsyncPeriodChange(display.get(), newTimeline.value(),
575                                          constraints.desiredTimeNanos, vsyncPeriod1, vsyncPeriod2);
576             }
577 
578             VsyncPeriodNanos vsyncPeriodNanos;
579             EXPECT_EQ(Error::NONE,
580                       mComposerClient->getDisplayVsyncPeriod(display.get(), &vsyncPeriodNanos));
581             EXPECT_EQ(vsyncPeriodNanos, vsyncPeriod2);
582         });
583     }
584 }
585 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints)586 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints) {
587     Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = false});
588 }
589 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_Delayed)590 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_Delayed) {
591     Test_setActiveConfigWithConstraints({.delayForChange = 300'000'000,  // 300ms
592                                          .refreshMiss = false});
593 }
594 
TEST_P(GraphicsComposerHidlTest,setActiveConfigWithConstraints_MissRefresh)595 TEST_P(GraphicsComposerHidlTest, setActiveConfigWithConstraints_MissRefresh) {
596     Test_setActiveConfigWithConstraints({.delayForChange = 0, .refreshMiss = true});
597 }
598 
TEST_P(GraphicsComposerHidlTest,setAutoLowLatencyModeBadDisplay)599 TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyModeBadDisplay) {
600     EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true));
601     EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false));
602 }
603 
TEST_P(GraphicsComposerHidlTest,setAutoLowLatencyMode)604 TEST_P(GraphicsComposerHidlTest, setAutoLowLatencyMode) {
605     for (const auto& display : mDisplays) {
606         std::vector<DisplayCapability> capabilities;
607         const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities);
608         EXPECT_EQ(Error::NONE, error);
609 
610         const bool allmSupport =
611                 std::find(capabilities.begin(), capabilities.end(),
612                           DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
613 
614         if (!allmSupport) {
615             EXPECT_EQ(Error::UNSUPPORTED,
616                       mComposerClient->setAutoLowLatencyMode(display.get(), true));
617             EXPECT_EQ(Error::UNSUPPORTED,
618                       mComposerClient->setAutoLowLatencyMode(display.get(), false));
619             GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
620                             << std::to_string(display.get()) << ", skipping test";
621             return;
622         }
623 
624         EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), true));
625         EXPECT_EQ(Error::NONE, mComposerClient->setAutoLowLatencyMode(display.get(), false));
626     }
627 }
628 
TEST_P(GraphicsComposerHidlTest,getSupportedContentTypesBadDisplay)629 TEST_P(GraphicsComposerHidlTest, getSupportedContentTypesBadDisplay) {
630     std::vector<ContentType> supportedContentTypes;
631     const auto error =
632             mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes);
633     EXPECT_EQ(Error::BAD_DISPLAY, error);
634 }
635 
TEST_P(GraphicsComposerHidlTest,getSupportedContentTypes)636 TEST_P(GraphicsComposerHidlTest, getSupportedContentTypes) {
637     std::vector<ContentType> supportedContentTypes;
638     for (const auto& display : mDisplays) {
639         supportedContentTypes.clear();
640         const auto error =
641                 mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
642         const bool noneSupported =
643                 std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
644                           ContentType::NONE) != supportedContentTypes.end();
645         EXPECT_EQ(Error::NONE, error);
646         EXPECT_FALSE(noneSupported);
647     }
648 }
649 
TEST_P(GraphicsComposerHidlTest,setContentTypeNoneAlwaysAccepted)650 TEST_P(GraphicsComposerHidlTest, setContentTypeNoneAlwaysAccepted) {
651     for (const auto& display : mDisplays) {
652         const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE);
653         EXPECT_NE(Error::UNSUPPORTED, error);
654     }
655 }
656 
TEST_P(GraphicsComposerHidlTest,setContentTypeBadDisplay)657 TEST_P(GraphicsComposerHidlTest, setContentTypeBadDisplay) {
658     const auto types = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
659                         ContentType::CINEMA, ContentType::GAME};
660     for (auto type : types) {
661         EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->setContentType(mInvalidDisplayId, type));
662     }
663 }
664 
Test_setContentTypeForDisplay(const Display & display,const std::vector<ContentType> & capabilities,const ContentType & contentType,const char * contentTypeStr)665 void GraphicsComposerHidlTest::Test_setContentTypeForDisplay(
666         const Display& display, const std::vector<ContentType>& capabilities,
667         const ContentType& contentType, const char* contentTypeStr) {
668     const bool contentTypeSupport =
669             std::find(capabilities.begin(), capabilities.end(), contentType) != capabilities.end();
670 
671     if (!contentTypeSupport) {
672         EXPECT_EQ(Error::UNSUPPORTED, mComposerClient->setContentType(display, contentType));
673         GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
674                         << std::to_string(display) << ", skipping test";
675         return;
676     }
677 
678     EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, contentType));
679     EXPECT_EQ(Error::NONE, mComposerClient->setContentType(display, ContentType::NONE));
680 }
681 
Test_setContentType(const ContentType & contentType,const char * contentTypeStr)682 void GraphicsComposerHidlTest::Test_setContentType(const ContentType& contentType,
683                                                    const char* contentTypeStr) {
684     for (const auto& display : mDisplays) {
685         std::vector<ContentType> supportedContentTypes;
686         const auto error =
687                 mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
688         EXPECT_EQ(Error::NONE, error);
689 
690         Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
691                                       contentTypeStr);
692     }
693 }
694 
TEST_P(GraphicsComposerHidlTest,setGraphicsContentType)695 TEST_P(GraphicsComposerHidlTest, setGraphicsContentType) {
696     Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
697 }
698 
TEST_P(GraphicsComposerHidlTest,setPhotoContentType)699 TEST_P(GraphicsComposerHidlTest, setPhotoContentType) {
700     Test_setContentType(ContentType::PHOTO, "PHOTO");
701 }
702 
TEST_P(GraphicsComposerHidlTest,setCinemaContentType)703 TEST_P(GraphicsComposerHidlTest, setCinemaContentType) {
704     Test_setContentType(ContentType::CINEMA, "CINEMA");
705 }
706 
TEST_P(GraphicsComposerHidlTest,setGameContentType)707 TEST_P(GraphicsComposerHidlTest, setGameContentType) {
708     Test_setContentType(ContentType::GAME, "GAME");
709 }
710 
711 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerHidlTest);
712 INSTANTIATE_TEST_SUITE_P(
713         PerInstance, GraphicsComposerHidlTest,
714         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
715         android::hardware::PrintInstanceNameToString);
716 
TEST_P(GraphicsComposerHidlTest,getLayerGenericMetadataKeys)717 TEST_P(GraphicsComposerHidlTest, getLayerGenericMetadataKeys) {
718     std::vector<IComposerClient::LayerGenericMetadataKey> keys;
719     mComposerClient->getLayerGenericMetadataKeys(&keys);
720 
721     std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
722     std::unordered_set<std::string> uniqueNames;
723     for (const auto& key : keys) {
724         std::string name(key.name.c_str());
725 
726         // Keys must not start with 'android' or 'com.android'
727         ASSERT_FALSE(name.find("android") == 0);
728         ASSERT_FALSE(name.find("com.android") == 0);
729 
730         // Keys must be in reverse domain name format
731         ASSERT_TRUE(std::regex_match(name, reverseDomainName));
732 
733         // Keys must be unique within this list
734         const auto& [iter, inserted] = uniqueNames.insert(name);
735         ASSERT_TRUE(inserted);
736     }
737 }
738 
739 }  // namespace
740 }  // namespace vts
741 }  // namespace V2_4
742 }  // namespace composer
743 }  // namespace graphics
744 }  // namespace hardware
745 }  // namespace android
746 
main(int argc,char ** argv)747 int main(int argc, char** argv) {
748     ::testing::InitGoogleTest(&argc, argv);
749 
750     using namespace std::chrono_literals;
751     if (!android::base::WaitForProperty("init.svc.surfaceflinger", "stopped", 10s)) {
752         ALOGE("Failed to stop init.svc.surfaceflinger");
753         return -1;
754     }
755 
756     return RUN_ALL_TESTS();
757 }
758