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