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