1 /*
2 * Copyright (C) 2017 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 #pragma clang diagnostic ignored "-Wextra"
21
22 // #define LOG_NDEBUG 0
23 #undef LOG_TAG
24 #define LOG_TAG "FakeHwcTest"
25
26 #include "FakeComposerClient.h"
27 #include "FakeComposerService.h"
28 #include "FakeComposerUtils.h"
29 #include "MockComposerHal.h"
30
31 #include <binder/Parcel.h>
32 #include <gui/DisplayEventReceiver.h>
33 #include <gui/ISurfaceComposer.h>
34 #include <gui/LayerDebugInfo.h>
35 #include <gui/LayerState.h>
36 #include <gui/Surface.h>
37 #include <gui/SurfaceComposerClient.h>
38
39 #include <android/hidl/manager/1.0/IServiceManager.h>
40 #include <android/looper.h>
41 #include <android/native_window.h>
42 #include <binder/ProcessState.h>
43 #include <hwbinder/ProcessState.h>
44 #include <log/log.h>
45 #include <private/gui/ComposerService.h>
46 #include <ui/DisplayMode.h>
47 #include <ui/DynamicDisplayInfo.h>
48 #include <utils/Looper.h>
49
50 #include <gmock/gmock.h>
51 #include <gtest/gtest.h>
52
53 #include <limits>
54 #include <thread>
55
56 using namespace std::chrono_literals;
57
58 using namespace android;
59 using namespace android::hardware;
60
61 using namespace sftest;
62
63 namespace {
64
65 // Mock test helpers
66 using ::testing::_;
67 using ::testing::DoAll;
68 using ::testing::Return;
69 using ::testing::SetArgPointee;
70
71 using Transaction = SurfaceComposerClient::Transaction;
72 using Attribute = V2_4::IComposerClient::Attribute;
73 using Display = V2_1::Display;
74
75 ///////////////////////////////////////////////
physicalIdFromHwcDisplayId(Display hwcId)76 constexpr PhysicalDisplayId physicalIdFromHwcDisplayId(Display hwcId) {
77 return PhysicalDisplayId::fromPort(hwcId);
78 }
79 constexpr PhysicalDisplayId kPrimaryDisplayId = physicalIdFromHwcDisplayId(PRIMARY_DISPLAY);
80 constexpr PhysicalDisplayId kExternalDisplayId = physicalIdFromHwcDisplayId(EXTERNAL_DISPLAY);
81
82 struct TestColor {
83 public:
84 uint8_t r;
85 uint8_t g;
86 uint8_t b;
87 uint8_t a;
88 };
89
90 constexpr static TestColor RED = {195, 63, 63, 255};
91 constexpr static TestColor LIGHT_RED = {255, 177, 177, 255};
92 constexpr static TestColor GREEN = {63, 195, 63, 255};
93 constexpr static TestColor BLUE = {63, 63, 195, 255};
94 constexpr static TestColor LIGHT_GRAY = {200, 200, 200, 255};
95
96 // Fill an RGBA_8888 formatted surface with a single color.
fillSurfaceRGBA8(const sp<SurfaceControl> & sc,const TestColor & color,bool unlock=true)97 static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, const TestColor& color,
98 bool unlock = true) {
99 ANativeWindow_Buffer outBuffer;
100 sp<Surface> s = sc->getSurface();
101 ASSERT_TRUE(s != nullptr);
102 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, nullptr));
103 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits);
104 for (int y = 0; y < outBuffer.height; y++) {
105 for (int x = 0; x < outBuffer.width; x++) {
106 uint8_t* pixel = img + (4 * (y * outBuffer.stride + x));
107 pixel[0] = color.r;
108 pixel[1] = color.g;
109 pixel[2] = color.b;
110 pixel[3] = color.a;
111 }
112 }
113 if (unlock) {
114 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
115 }
116 }
117
makeSimpleRect(int left,int top,int right,int bottom)118 inline RenderState makeSimpleRect(int left, int top, int right, int bottom) {
119 RenderState res;
120 res.mDisplayFrame = hwc_rect_t{left, top, right, bottom};
121 res.mPlaneAlpha = 1.0f;
122 res.mSwapCount = 0;
123 res.mSourceCrop = hwc_frect_t{0.f, 0.f, static_cast<float>(right - left),
124 static_cast<float>(bottom - top)};
125 return res;
126 }
127
makeSimpleRect(unsigned int left,unsigned int top,unsigned int right,unsigned int bottom)128 inline RenderState makeSimpleRect(unsigned int left, unsigned int top, unsigned int right,
129 unsigned int bottom) {
130 EXPECT_LE(left, static_cast<unsigned int>(INT_MAX));
131 EXPECT_LE(top, static_cast<unsigned int>(INT_MAX));
132 EXPECT_LE(right, static_cast<unsigned int>(INT_MAX));
133 EXPECT_LE(bottom, static_cast<unsigned int>(INT_MAX));
134 return makeSimpleRect(static_cast<int>(left), static_cast<int>(top), static_cast<int>(right),
135 static_cast<int>(bottom));
136 }
137
138 ///////////////////////////////////////////////
139 template <typename FakeComposerService>
140 class DisplayTest : public ::testing::Test {
141 protected:
142 struct TestConfig {
143 int32_t id;
144 int32_t w;
145 int32_t h;
146 int32_t vsyncPeriod;
147 int32_t group;
148 };
149
processDisplayEvents(int,int,void * data)150 static int processDisplayEvents(int /*fd*/, int /*events*/, void* data) {
151 auto self = static_cast<DisplayTest*>(data);
152
153 ssize_t n;
154 DisplayEventReceiver::Event buffer[1];
155
156 while ((n = self->mReceiver->getEvents(buffer, 1)) > 0) {
157 for (int i = 0; i < n; i++) {
158 self->mReceivedDisplayEvents.push_back(buffer[i]);
159 }
160 }
161 ALOGD_IF(n < 0, "Error reading events (%s)", strerror(-n));
162 return 1;
163 }
164
getDisplayAttributeNoMock(Display display,Config config,V2_4::IComposerClient::Attribute attribute,int32_t * outValue)165 Error getDisplayAttributeNoMock(Display display, Config config,
166 V2_4::IComposerClient::Attribute attribute, int32_t* outValue) {
167 mFakeComposerClient->setMockHal(nullptr);
168 auto ret =
169 mFakeComposerClient->getDisplayAttribute_2_4(display, config, attribute, outValue);
170 mFakeComposerClient->setMockHal(mMockComposer.get());
171 return ret;
172 }
173
setExpectationsForConfigs(Display display,std::vector<TestConfig> testConfigs,Config activeConfig,V2_4::VsyncPeriodNanos defaultVsyncPeriod)174 void setExpectationsForConfigs(Display display, std::vector<TestConfig> testConfigs,
175 Config activeConfig, V2_4::VsyncPeriodNanos defaultVsyncPeriod) {
176 std::vector<Config> configIds;
177 for (size_t i = 0; i < testConfigs.size(); i++) {
178 configIds.push_back(testConfigs[i].id);
179
180 EXPECT_CALL(*mMockComposer,
181 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::WIDTH, _))
182 .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].w), Return(Error::NONE)));
183 EXPECT_CALL(*mMockComposer,
184 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::HEIGHT, _))
185 .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].h), Return(Error::NONE)));
186 EXPECT_CALL(*mMockComposer,
187 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::VSYNC_PERIOD,
188 _))
189 .WillRepeatedly(DoAll(SetArgPointee<3>(testConfigs[i].vsyncPeriod),
190 Return(Error::NONE)));
191 EXPECT_CALL(*mMockComposer,
192 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::CONFIG_GROUP,
193 _))
194 .WillRepeatedly(
195 DoAll(SetArgPointee<3>(testConfigs[i].group), Return(Error::NONE)));
196 EXPECT_CALL(*mMockComposer,
197 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::DPI_X, _))
198 .WillRepeatedly(Return(Error::UNSUPPORTED));
199 EXPECT_CALL(*mMockComposer,
200 getDisplayAttribute_2_4(display, testConfigs[i].id, Attribute::DPI_Y, _))
201 .WillRepeatedly(Return(Error::UNSUPPORTED));
202 }
203
204 EXPECT_CALL(*mMockComposer, getDisplayConfigs(display, _))
205 .WillRepeatedly(DoAll(SetArgPointee<1>(hidl_vec<Config>(configIds)),
206 Return(V2_1::Error::NONE)));
207
208 EXPECT_CALL(*mMockComposer, getActiveConfig(display, _))
209 .WillRepeatedly(DoAll(SetArgPointee<1>(activeConfig), Return(V2_1::Error::NONE)));
210
211 EXPECT_CALL(*mMockComposer, getDisplayVsyncPeriod(display, _))
212 .WillRepeatedly(
213 DoAll(SetArgPointee<1>(defaultVsyncPeriod), Return(V2_4::Error::NONE)));
214 }
215
SetUp()216 void SetUp() override {
217 mMockComposer = std::make_unique<MockComposerHal>();
218 mFakeComposerClient = new FakeComposerClient();
219 mFakeComposerClient->setMockHal(mMockComposer.get());
220
221 sp<V2_4::hal::ComposerClient> client = new V2_4::hal::ComposerClient(mFakeComposerClient);
222 mFakeService = new FakeComposerService(client);
223 ASSERT_EQ(android::OK, mFakeService->registerAsService("mock"));
224
225 android::hardware::ProcessState::self()->startThreadPool();
226 android::ProcessState::self()->startThreadPool();
227
228 setExpectationsForConfigs(PRIMARY_DISPLAY,
229 {{
230 .id = 1,
231 .w = 1920,
232 .h = 1024,
233 .vsyncPeriod = 16'666'666,
234 .group = 0,
235 }},
236 1, 16'666'666);
237
238 startSurfaceFlinger();
239
240 // Fake composer wants to enable VSync injection
241 mFakeComposerClient->onSurfaceFlingerStart();
242
243 mComposerClient = new SurfaceComposerClient;
244 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
245
246 mReceiver.reset(new DisplayEventReceiver(ISurfaceComposer::eVsyncSourceApp,
247 ISurfaceComposer::EventRegistration::modeChanged));
248 mLooper = new Looper(false);
249 mLooper->addFd(mReceiver->getFd(), 0, ALOOPER_EVENT_INPUT, processDisplayEvents, this);
250 }
251
TearDown()252 void TearDown() override {
253 mLooper = nullptr;
254 mReceiver = nullptr;
255
256 mComposerClient->dispose();
257 mComposerClient = nullptr;
258
259 // Fake composer needs to release SurfaceComposerClient before the stop.
260 mFakeComposerClient->onSurfaceFlingerStop();
261 stopSurfaceFlinger();
262
263 mFakeComposerClient->setMockHal(nullptr);
264
265 mFakeService = nullptr;
266 // TODO: Currently deleted in FakeComposerClient::removeClient(). Devise better lifetime
267 // management.
268 mMockComposer = nullptr;
269 }
270
waitForDisplayTransaction(Display display)271 void waitForDisplayTransaction(Display display) {
272 // Both a refresh and a vsync event are needed to apply pending display
273 // transactions.
274 mFakeComposerClient->refreshDisplay(display);
275 mFakeComposerClient->runVSyncAndWait();
276
277 // Extra vsync and wait to avoid a 10% flake due to a race.
278 mFakeComposerClient->runVSyncAndWait();
279 }
280
waitForHotplugEvent(Display displayId,bool connected)281 bool waitForHotplugEvent(Display displayId, bool connected) {
282 return waitForHotplugEvent(PhysicalDisplayId(displayId), connected);
283 }
284
waitForHotplugEvent(PhysicalDisplayId displayId,bool connected)285 bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) {
286 int waitCount = 20;
287 while (waitCount--) {
288 while (!mReceivedDisplayEvents.empty()) {
289 auto event = mReceivedDisplayEvents.front();
290 mReceivedDisplayEvents.pop_front();
291
292 ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG,
293 "event hotplug: displayId %s, connected %d",
294 to_string(event.header.displayId).c_str(), event.hotplug.connected);
295
296 if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG &&
297 event.header.displayId == displayId && event.hotplug.connected == connected) {
298 return true;
299 }
300 }
301
302 mLooper->pollOnce(1);
303 }
304 return false;
305 }
306
waitForModeChangedEvent(Display display,int32_t modeId)307 bool waitForModeChangedEvent(Display display, int32_t modeId) {
308 PhysicalDisplayId displayId(display);
309 int waitCount = 20;
310 while (waitCount--) {
311 while (!mReceivedDisplayEvents.empty()) {
312 auto event = mReceivedDisplayEvents.front();
313 mReceivedDisplayEvents.pop_front();
314
315 ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE,
316 "event mode: displayId %s, modeId %d",
317 to_string(event.header.displayId).c_str(), event.modeChange.modeId);
318
319 if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE &&
320 event.header.displayId == displayId && event.modeChange.modeId == modeId) {
321 return true;
322 }
323 }
324
325 mLooper->pollOnce(1);
326 }
327 return false;
328 }
329
Test_HotplugOneConfig()330 void Test_HotplugOneConfig() {
331 ALOGD("DisplayTest::Test_Hotplug_oneConfig");
332
333 setExpectationsForConfigs(EXTERNAL_DISPLAY,
334 {{.id = 1,
335 .w = 200,
336 .h = 400,
337 .vsyncPeriod = 16'666'666,
338 .group = 0}},
339 1, 16'666'666);
340
341 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
342 V2_1::IComposerCallback::Connection::CONNECTED);
343 waitForDisplayTransaction(EXTERNAL_DISPLAY);
344 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
345
346 {
347 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
348 EXPECT_FALSE(display == nullptr);
349
350 ui::DisplayMode mode;
351 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
352 const ui::Size& resolution = mode.resolution;
353 EXPECT_EQ(ui::Size(200, 400), resolution);
354 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
355
356 auto surfaceControl =
357 mComposerClient->createSurface(String8("Display Test Surface Foo"),
358 resolution.getWidth(), resolution.getHeight(),
359 PIXEL_FORMAT_RGBA_8888, 0);
360 EXPECT_TRUE(surfaceControl != nullptr);
361 EXPECT_TRUE(surfaceControl->isValid());
362 fillSurfaceRGBA8(surfaceControl, BLUE);
363
364 {
365 TransactionScope ts(*mFakeComposerClient);
366 ts.setDisplayLayerStack(display, 0);
367
368 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
369 }
370 }
371
372 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
373 V2_1::IComposerCallback::Connection::DISCONNECTED);
374 waitForDisplayTransaction(EXTERNAL_DISPLAY);
375 mFakeComposerClient->clearFrames();
376 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
377
378 {
379 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
380 EXPECT_TRUE(display == nullptr);
381
382 ui::DisplayMode mode;
383 EXPECT_NE(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
384 }
385 }
386
Test_HotplugTwoSeparateConfigs()387 void Test_HotplugTwoSeparateConfigs() {
388 ALOGD("DisplayTest::Test_HotplugTwoSeparateConfigs");
389
390 setExpectationsForConfigs(EXTERNAL_DISPLAY,
391 {{.id = 1,
392 .w = 200,
393 .h = 400,
394 .vsyncPeriod = 16'666'666,
395 .group = 0},
396 {.id = 2,
397 .w = 800,
398 .h = 1600,
399 .vsyncPeriod = 11'111'111,
400 .group = 1}},
401 1, 16'666'666);
402
403 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
404 V2_1::IComposerCallback::Connection::CONNECTED);
405 waitForDisplayTransaction(EXTERNAL_DISPLAY);
406 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
407
408 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
409 EXPECT_FALSE(display == nullptr);
410
411 ui::DisplayMode mode;
412 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
413 EXPECT_EQ(ui::Size(200, 400), mode.resolution);
414 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
415
416 mFakeComposerClient->clearFrames();
417 {
418 const ui::Size& resolution = mode.resolution;
419 auto surfaceControl =
420 mComposerClient->createSurface(String8("Display Test Surface Foo"),
421 resolution.getWidth(), resolution.getHeight(),
422 PIXEL_FORMAT_RGBA_8888, 0);
423 EXPECT_TRUE(surfaceControl != nullptr);
424 EXPECT_TRUE(surfaceControl->isValid());
425 fillSurfaceRGBA8(surfaceControl, BLUE);
426
427 {
428 TransactionScope ts(*mFakeComposerClient);
429 ts.setDisplayLayerStack(display, 0);
430
431 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
432 }
433 }
434
435 ui::DynamicDisplayInfo info;
436 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
437 const auto& modes = info.supportedDisplayModes;
438 EXPECT_EQ(modes.size(), 2);
439
440 // change active mode
441
442 if (mIs2_4Client) {
443 EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 2, _, _))
444 .WillOnce(Return(V2_4::Error::NONE));
445 } else {
446 EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 2))
447 .WillOnce(Return(V2_1::Error::NONE));
448 }
449
450 for (int i = 0; i < modes.size(); i++) {
451 const auto& mode = modes[i];
452 if (mode.resolution.getWidth() == 800) {
453 EXPECT_EQ(NO_ERROR,
454 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
455 mode.refreshRate,
456 mode.refreshRate,
457 mode.refreshRate,
458 mode.refreshRate));
459 waitForDisplayTransaction(EXTERNAL_DISPLAY);
460 EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i));
461 break;
462 }
463 }
464
465 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
466 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
467 EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate);
468
469 mFakeComposerClient->clearFrames();
470 {
471 const ui::Size& resolution = mode.resolution;
472 auto surfaceControl =
473 mComposerClient->createSurface(String8("Display Test Surface Foo"),
474 resolution.getWidth(), resolution.getHeight(),
475 PIXEL_FORMAT_RGBA_8888, 0);
476 EXPECT_TRUE(surfaceControl != nullptr);
477 EXPECT_TRUE(surfaceControl->isValid());
478 fillSurfaceRGBA8(surfaceControl, BLUE);
479
480 {
481 TransactionScope ts(*mFakeComposerClient);
482 ts.setDisplayLayerStack(display, 0);
483
484 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
485 }
486 }
487
488 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
489 V2_1::IComposerCallback::Connection::DISCONNECTED);
490 waitForDisplayTransaction(EXTERNAL_DISPLAY);
491 mFakeComposerClient->clearFrames();
492 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
493 }
494
Test_HotplugTwoConfigsSameGroup()495 void Test_HotplugTwoConfigsSameGroup() {
496 ALOGD("DisplayTest::Test_HotplugTwoConfigsSameGroup");
497
498 setExpectationsForConfigs(EXTERNAL_DISPLAY,
499 {{.id = 2,
500 .w = 800,
501 .h = 1600,
502 .vsyncPeriod = 16'666'666,
503 .group = 31},
504 {.id = 3,
505 .w = 800,
506 .h = 1600,
507 .vsyncPeriod = 11'111'111,
508 .group = 31}},
509 2, 16'666'666);
510
511 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
512 V2_1::IComposerCallback::Connection::CONNECTED);
513 waitForDisplayTransaction(EXTERNAL_DISPLAY);
514 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
515
516 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
517 EXPECT_FALSE(display == nullptr);
518
519 ui::DisplayMode mode;
520 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
521 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
522 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
523
524 mFakeComposerClient->clearFrames();
525 {
526 const ui::Size& resolution = mode.resolution;
527 auto surfaceControl =
528 mComposerClient->createSurface(String8("Display Test Surface Foo"),
529 resolution.getWidth(), resolution.getHeight(),
530 PIXEL_FORMAT_RGBA_8888, 0);
531 EXPECT_TRUE(surfaceControl != nullptr);
532 EXPECT_TRUE(surfaceControl->isValid());
533 fillSurfaceRGBA8(surfaceControl, BLUE);
534
535 {
536 TransactionScope ts(*mFakeComposerClient);
537 ts.setDisplayLayerStack(display, 0);
538
539 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
540 }
541 }
542
543 ui::DynamicDisplayInfo info;
544 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
545 const auto& modes = info.supportedDisplayModes;
546 EXPECT_EQ(modes.size(), 2);
547
548 // change active mode
549 if (mIs2_4Client) {
550 EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 3, _, _))
551 .WillOnce(Return(V2_4::Error::NONE));
552 } else {
553 EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 3))
554 .WillOnce(Return(V2_1::Error::NONE));
555 }
556
557 for (int i = 0; i < modes.size(); i++) {
558 const auto& mode = modes[i];
559 if (mode.refreshRate == 1e9f / 11'111'111) {
560 EXPECT_EQ(NO_ERROR,
561 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
562 mode.refreshRate,
563 mode.refreshRate,
564 mode.refreshRate,
565 mode.refreshRate));
566 waitForDisplayTransaction(EXTERNAL_DISPLAY);
567 EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i));
568 break;
569 }
570 }
571
572 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
573 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
574 EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate);
575
576 mFakeComposerClient->clearFrames();
577 {
578 const ui::Size& resolution = mode.resolution;
579 auto surfaceControl =
580 mComposerClient->createSurface(String8("Display Test Surface Foo"),
581 resolution.getWidth(), resolution.getHeight(),
582 PIXEL_FORMAT_RGBA_8888, 0);
583 EXPECT_TRUE(surfaceControl != nullptr);
584 EXPECT_TRUE(surfaceControl->isValid());
585 fillSurfaceRGBA8(surfaceControl, BLUE);
586
587 {
588 TransactionScope ts(*mFakeComposerClient);
589 ts.setDisplayLayerStack(display, 0);
590
591 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
592 }
593 }
594
595 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
596 V2_1::IComposerCallback::Connection::DISCONNECTED);
597 waitForDisplayTransaction(EXTERNAL_DISPLAY);
598 mFakeComposerClient->clearFrames();
599 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
600 }
601
Test_HotplugThreeConfigsMixedGroups()602 void Test_HotplugThreeConfigsMixedGroups() {
603 ALOGD("DisplayTest::Test_HotplugThreeConfigsMixedGroups");
604
605 setExpectationsForConfigs(EXTERNAL_DISPLAY,
606 {{.id = 2,
607 .w = 800,
608 .h = 1600,
609 .vsyncPeriod = 16'666'666,
610 .group = 0},
611 {.id = 3,
612 .w = 800,
613 .h = 1600,
614 .vsyncPeriod = 11'111'111,
615 .group = 0},
616 {.id = 4,
617 .w = 1600,
618 .h = 3200,
619 .vsyncPeriod = 8'333'333,
620 .group = 1},
621 {.id = 5,
622 .w = 1600,
623 .h = 3200,
624 .vsyncPeriod = 11'111'111,
625 .group = 1}},
626 2, 16'666'666);
627
628 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
629 V2_1::IComposerCallback::Connection::CONNECTED);
630 waitForDisplayTransaction(EXTERNAL_DISPLAY);
631 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true));
632
633 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kExternalDisplayId);
634 EXPECT_FALSE(display == nullptr);
635
636 ui::DisplayMode mode;
637 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
638 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
639 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
640
641 mFakeComposerClient->clearFrames();
642 {
643 const ui::Size& resolution = mode.resolution;
644 auto surfaceControl =
645 mComposerClient->createSurface(String8("Display Test Surface Foo"),
646 resolution.getWidth(), resolution.getHeight(),
647 PIXEL_FORMAT_RGBA_8888, 0);
648 EXPECT_TRUE(surfaceControl != nullptr);
649 EXPECT_TRUE(surfaceControl->isValid());
650 fillSurfaceRGBA8(surfaceControl, BLUE);
651
652 {
653 TransactionScope ts(*mFakeComposerClient);
654 ts.setDisplayLayerStack(display, 0);
655
656 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
657 }
658 }
659
660 ui::DynamicDisplayInfo info;
661 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
662 const auto& modes = info.supportedDisplayModes;
663 EXPECT_EQ(modes.size(), 4);
664
665 // change active mode to 800x1600@90Hz
666 if (mIs2_4Client) {
667 EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 3, _, _))
668 .WillOnce(Return(V2_4::Error::NONE));
669 } else {
670 EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 3))
671 .WillOnce(Return(V2_1::Error::NONE));
672 }
673
674 for (size_t i = 0; i < modes.size(); i++) {
675 const auto& mode = modes[i];
676 if (mode.resolution.getWidth() == 800 && mode.refreshRate == 1e9f / 11'111'111) {
677 EXPECT_EQ(NO_ERROR,
678 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
679 modes[i].refreshRate,
680 modes[i].refreshRate,
681 modes[i].refreshRate,
682 modes[i].refreshRate));
683 waitForDisplayTransaction(EXTERNAL_DISPLAY);
684 EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i));
685 break;
686 }
687 }
688
689 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
690 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
691 EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate);
692
693 mFakeComposerClient->clearFrames();
694 {
695 const ui::Size& resolution = mode.resolution;
696 auto surfaceControl =
697 mComposerClient->createSurface(String8("Display Test Surface Foo"),
698 resolution.getWidth(), resolution.getHeight(),
699 PIXEL_FORMAT_RGBA_8888, 0);
700 EXPECT_TRUE(surfaceControl != nullptr);
701 EXPECT_TRUE(surfaceControl->isValid());
702 fillSurfaceRGBA8(surfaceControl, BLUE);
703
704 {
705 TransactionScope ts(*mFakeComposerClient);
706 ts.setDisplayLayerStack(display, 0);
707
708 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
709 }
710 }
711
712 // change active mode to 1600x3200@120Hz
713 if (mIs2_4Client) {
714 EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 4, _, _))
715 .WillOnce(Return(V2_4::Error::NONE));
716 } else {
717 EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 4))
718 .WillOnce(Return(V2_1::Error::NONE));
719 }
720
721 for (int i = 0; i < modes.size(); i++) {
722 const auto& mode = modes[i];
723 if (mode.refreshRate == 1e9f / 8'333'333) {
724 EXPECT_EQ(NO_ERROR,
725 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
726 mode.refreshRate,
727 mode.refreshRate,
728 mode.refreshRate,
729 mode.refreshRate));
730 waitForDisplayTransaction(EXTERNAL_DISPLAY);
731 EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i));
732 break;
733 }
734 }
735
736 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
737 EXPECT_EQ(ui::Size(1600, 3200), mode.resolution);
738 EXPECT_EQ(1e9f / 8'333'333, mode.refreshRate);
739
740 mFakeComposerClient->clearFrames();
741 {
742 const ui::Size& resolution = mode.resolution;
743 auto surfaceControl =
744 mComposerClient->createSurface(String8("Display Test Surface Foo"),
745 resolution.getWidth(), resolution.getHeight(),
746 PIXEL_FORMAT_RGBA_8888, 0);
747 EXPECT_TRUE(surfaceControl != nullptr);
748 EXPECT_TRUE(surfaceControl->isValid());
749 fillSurfaceRGBA8(surfaceControl, BLUE);
750
751 {
752 TransactionScope ts(*mFakeComposerClient);
753 ts.setDisplayLayerStack(display, 0);
754
755 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
756 }
757 }
758
759 // change active mode to 1600x3200@90Hz
760 if (mIs2_4Client) {
761 EXPECT_CALL(*mMockComposer, setActiveConfigWithConstraints(EXTERNAL_DISPLAY, 5, _, _))
762 .WillOnce(Return(V2_4::Error::NONE));
763 } else {
764 EXPECT_CALL(*mMockComposer, setActiveConfig(EXTERNAL_DISPLAY, 5))
765 .WillOnce(Return(V2_1::Error::NONE));
766 }
767
768 for (int i = 0; i < modes.size(); i++) {
769 const auto& mode = modes[i];
770 if (mode.resolution.getWidth() == 1600 && mode.refreshRate == 1e9f / 11'111'111) {
771 EXPECT_EQ(NO_ERROR,
772 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
773 mode.refreshRate,
774 mode.refreshRate,
775 mode.refreshRate,
776 mode.refreshRate));
777 waitForDisplayTransaction(EXTERNAL_DISPLAY);
778 EXPECT_TRUE(waitForModeChangedEvent(EXTERNAL_DISPLAY, i));
779 break;
780 }
781 }
782
783 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
784 EXPECT_EQ(ui::Size(1600, 3200), mode.resolution);
785 EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate);
786
787 mFakeComposerClient->clearFrames();
788 {
789 const ui::Size& resolution = mode.resolution;
790 auto surfaceControl =
791 mComposerClient->createSurface(String8("Display Test Surface Foo"),
792 resolution.getWidth(), resolution.getHeight(),
793 PIXEL_FORMAT_RGBA_8888, 0);
794 EXPECT_TRUE(surfaceControl != nullptr);
795 EXPECT_TRUE(surfaceControl->isValid());
796 fillSurfaceRGBA8(surfaceControl, BLUE);
797
798 {
799 TransactionScope ts(*mFakeComposerClient);
800 ts.setDisplayLayerStack(display, 0);
801
802 ts.setLayer(surfaceControl, INT32_MAX - 2).show(surfaceControl);
803 }
804 }
805
806 mFakeComposerClient->hotplugDisplay(EXTERNAL_DISPLAY,
807 V2_1::IComposerCallback::Connection::DISCONNECTED);
808 waitForDisplayTransaction(EXTERNAL_DISPLAY);
809 mFakeComposerClient->clearFrames();
810 EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false));
811 }
812
Test_HotplugPrimaryDisplay()813 void Test_HotplugPrimaryDisplay() {
814 ALOGD("DisplayTest::HotplugPrimaryDisplay");
815
816 mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY,
817 V2_1::IComposerCallback::Connection::DISCONNECTED);
818
819 waitForDisplayTransaction(PRIMARY_DISPLAY);
820
821 EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false));
822 {
823 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId);
824 EXPECT_TRUE(display == nullptr);
825
826 ui::DisplayMode mode;
827 auto result = SurfaceComposerClient::getActiveDisplayMode(display, &mode);
828 EXPECT_NE(NO_ERROR, result);
829 }
830
831 mFakeComposerClient->clearFrames();
832
833 setExpectationsForConfigs(PRIMARY_DISPLAY,
834 {{.id = 1,
835 .w = 400,
836 .h = 200,
837 .vsyncPeriod = 16'666'666,
838 .group = 0}},
839 1, 16'666'666);
840
841 mFakeComposerClient->hotplugDisplay(PRIMARY_DISPLAY,
842 V2_1::IComposerCallback::Connection::CONNECTED);
843
844 waitForDisplayTransaction(PRIMARY_DISPLAY);
845
846 EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true));
847
848 {
849 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId);
850 EXPECT_FALSE(display == nullptr);
851
852 ui::DisplayMode mode;
853 auto result = SurfaceComposerClient::getActiveDisplayMode(display, &mode);
854 EXPECT_EQ(NO_ERROR, result);
855 ASSERT_EQ(ui::Size(400, 200), mode.resolution);
856 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
857 }
858 }
859
Test_SubsequentHotplugConnectUpdatesDisplay(Display hwcDisplayId)860 void Test_SubsequentHotplugConnectUpdatesDisplay(Display hwcDisplayId) {
861 ALOGD("DisplayTest::Test_SubsequentHotplugConnectUpdatesDisplay");
862
863 // Send a hotplug connected event to set up the initial display modes.
864 // The primary display is already connected so this will update it.
865 // If we're running the test of an external display this will create it.
866 setExpectationsForConfigs(hwcDisplayId,
867 {{.id = 1,
868 .w = 800,
869 .h = 1600,
870 .vsyncPeriod = 11'111'111,
871 .group = 1}},
872 /* activeConfig */ 1, 11'111'111);
873
874 mFakeComposerClient->hotplugDisplay(hwcDisplayId,
875 V2_1::IComposerCallback::Connection::CONNECTED);
876 waitForDisplayTransaction(hwcDisplayId);
877 EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true));
878
879 const auto displayId = physicalIdFromHwcDisplayId(hwcDisplayId);
880 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(displayId);
881 EXPECT_FALSE(display == nullptr);
882
883 // Verify that the active mode and the supported moded are updated
884 {
885 ui::DisplayMode mode;
886 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
887 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
888 EXPECT_EQ(1e9f / 11'111'111, mode.refreshRate);
889
890 ui::DynamicDisplayInfo info;
891 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
892 const auto& modes = info.supportedDisplayModes;
893 EXPECT_EQ(modes.size(), 1);
894 }
895
896 // Send another hotplug connected event
897 setExpectationsForConfigs(hwcDisplayId,
898 {
899 {.id = 1,
900 .w = 800,
901 .h = 1600,
902 .vsyncPeriod = 16'666'666,
903 .group = 1},
904 {.id = 2,
905 .w = 800,
906 .h = 1600,
907 .vsyncPeriod = 11'111'111,
908 .group = 1},
909 {.id = 3,
910 .w = 800,
911 .h = 1600,
912 .vsyncPeriod = 8'333'333,
913 .group = 1},
914 },
915 /* activeConfig */ 1, 16'666'666);
916
917 mFakeComposerClient->hotplugDisplay(hwcDisplayId,
918 V2_1::IComposerCallback::Connection::CONNECTED);
919 waitForDisplayTransaction(hwcDisplayId);
920 EXPECT_TRUE(waitForHotplugEvent(hwcDisplayId, true));
921
922 // Verify that the active mode and the supported moded are updated
923 {
924 ui::DisplayMode mode;
925 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
926 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
927 EXPECT_EQ(1e9f / 16'666'666, mode.refreshRate);
928 }
929
930 ui::DynamicDisplayInfo info;
931 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getDynamicDisplayInfo(display, &info));
932 const auto& modes = info.supportedDisplayModes;
933 EXPECT_EQ(modes.size(), 3);
934
935 EXPECT_EQ(ui::Size(800, 1600), modes[0].resolution);
936 EXPECT_EQ(1e9f / 16'666'666, modes[0].refreshRate);
937
938 EXPECT_EQ(ui::Size(800, 1600), modes[1].resolution);
939 EXPECT_EQ(1e9f / 11'111'111, modes[1].refreshRate);
940
941 EXPECT_EQ(ui::Size(800, 1600), modes[2].resolution);
942 EXPECT_EQ(1e9f / 8'333'333, modes[2].refreshRate);
943
944 // Verify that we are able to switch to any of the modes
945 for (int i = modes.size() - 1; i >= 0; i--) {
946 const auto hwcId = i + 1;
947 // Set up HWC expectations for the mode change
948 if (mIs2_4Client) {
949 EXPECT_CALL(*mMockComposer,
950 setActiveConfigWithConstraints(hwcDisplayId, hwcId, _, _))
951 .WillOnce(Return(V2_4::Error::NONE));
952 } else {
953 EXPECT_CALL(*mMockComposer, setActiveConfig(hwcDisplayId, hwcId))
954 .WillOnce(Return(V2_1::Error::NONE));
955 }
956
957 EXPECT_EQ(NO_ERROR,
958 SurfaceComposerClient::setDesiredDisplayModeSpecs(display, i, false,
959 modes[i].refreshRate,
960 modes[i].refreshRate,
961 modes[i].refreshRate,
962 modes[i].refreshRate));
963 // We need to refresh twice - once to apply the pending mode change request,
964 // and once to process the change.
965 waitForDisplayTransaction(hwcDisplayId);
966 waitForDisplayTransaction(hwcDisplayId);
967 EXPECT_TRUE(waitForModeChangedEvent(hwcDisplayId, i))
968 << "Failure while switching to mode " << i;
969
970 ui::DisplayMode mode;
971 EXPECT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
972 EXPECT_EQ(ui::Size(800, 1600), mode.resolution);
973 EXPECT_EQ(modes[i].refreshRate, mode.refreshRate);
974 }
975 }
976
977 sp<V2_1::IComposer> mFakeService;
978 sp<SurfaceComposerClient> mComposerClient;
979
980 std::unique_ptr<MockComposerHal> mMockComposer;
981 FakeComposerClient* mFakeComposerClient;
982
983 std::unique_ptr<DisplayEventReceiver> mReceiver;
984 sp<Looper> mLooper;
985 std::deque<DisplayEventReceiver::Event> mReceivedDisplayEvents;
986
987 static constexpr bool mIs2_4Client =
988 std::is_same<FakeComposerService, FakeComposerService_2_4>::value;
989 };
990
991 using DisplayTest_2_1 = DisplayTest<FakeComposerService_2_1>;
992
993 // Tests that VSYNC injection can be safely toggled while invalidating.
TEST_F(DisplayTest_2_1,VsyncInjection)994 TEST_F(DisplayTest_2_1, VsyncInjection) {
995 const auto flinger = ComposerService::getComposerService();
996 bool enable = true;
997
998 for (int i = 0; i < 100; i++) {
999 flinger->enableVSyncInjections(enable);
1000 enable = !enable;
1001
1002 constexpr uint32_t kForceInvalidate = 1004;
1003 android::Parcel data, reply;
1004 data.writeInterfaceToken(String16("android.ui.ISurfaceComposer"));
1005 EXPECT_EQ(NO_ERROR,
1006 android::IInterface::asBinder(flinger)->transact(kForceInvalidate, data, &reply));
1007
1008 std::this_thread::sleep_for(5ms);
1009 }
1010 }
1011
TEST_F(DisplayTest_2_1,HotplugOneConfig)1012 TEST_F(DisplayTest_2_1, HotplugOneConfig) {
1013 Test_HotplugOneConfig();
1014 }
1015
TEST_F(DisplayTest_2_1,HotplugTwoSeparateConfigs)1016 TEST_F(DisplayTest_2_1, HotplugTwoSeparateConfigs) {
1017 Test_HotplugTwoSeparateConfigs();
1018 }
1019
TEST_F(DisplayTest_2_1,HotplugTwoConfigsSameGroup)1020 TEST_F(DisplayTest_2_1, HotplugTwoConfigsSameGroup) {
1021 Test_HotplugTwoConfigsSameGroup();
1022 }
1023
TEST_F(DisplayTest_2_1,HotplugThreeConfigsMixedGroups)1024 TEST_F(DisplayTest_2_1, HotplugThreeConfigsMixedGroups) {
1025 Test_HotplugThreeConfigsMixedGroups();
1026 }
1027
TEST_F(DisplayTest_2_1,HotplugPrimaryOneConfig)1028 TEST_F(DisplayTest_2_1, HotplugPrimaryOneConfig) {
1029 Test_HotplugPrimaryDisplay();
1030 }
1031
TEST_F(DisplayTest_2_1,SubsequentHotplugConnectUpdatesPrimaryDisplay)1032 TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
1033 Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
1034 }
1035
TEST_F(DisplayTest_2_1,SubsequentHotplugConnectUpdatesExternalDisplay)1036 TEST_F(DisplayTest_2_1, SubsequentHotplugConnectUpdatesExternalDisplay) {
1037 Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
1038 }
1039
1040 using DisplayTest_2_2 = DisplayTest<FakeComposerService_2_2>;
1041
TEST_F(DisplayTest_2_2,HotplugOneConfig)1042 TEST_F(DisplayTest_2_2, HotplugOneConfig) {
1043 Test_HotplugOneConfig();
1044 }
1045
TEST_F(DisplayTest_2_2,HotplugTwoSeparateConfigs)1046 TEST_F(DisplayTest_2_2, HotplugTwoSeparateConfigs) {
1047 Test_HotplugTwoSeparateConfigs();
1048 }
1049
TEST_F(DisplayTest_2_2,HotplugTwoConfigsSameGroup)1050 TEST_F(DisplayTest_2_2, HotplugTwoConfigsSameGroup) {
1051 Test_HotplugTwoConfigsSameGroup();
1052 }
1053
TEST_F(DisplayTest_2_2,HotplugThreeConfigsMixedGroups)1054 TEST_F(DisplayTest_2_2, HotplugThreeConfigsMixedGroups) {
1055 Test_HotplugThreeConfigsMixedGroups();
1056 }
1057
TEST_F(DisplayTest_2_2,HotplugPrimaryOneConfig)1058 TEST_F(DisplayTest_2_2, HotplugPrimaryOneConfig) {
1059 Test_HotplugPrimaryDisplay();
1060 }
1061
TEST_F(DisplayTest_2_2,SubsequentHotplugConnectUpdatesPrimaryDisplay)1062 TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
1063 Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
1064 }
1065
TEST_F(DisplayTest_2_2,SubsequentHotplugConnectUpdatesExternalDisplay)1066 TEST_F(DisplayTest_2_2, SubsequentHotplugConnectUpdatesExternalDisplay) {
1067 Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
1068 }
1069
1070 using DisplayTest_2_3 = DisplayTest<FakeComposerService_2_3>;
1071
TEST_F(DisplayTest_2_3,HotplugOneConfig)1072 TEST_F(DisplayTest_2_3, HotplugOneConfig) {
1073 Test_HotplugOneConfig();
1074 }
1075
TEST_F(DisplayTest_2_3,HotplugTwoSeparateConfigs)1076 TEST_F(DisplayTest_2_3, HotplugTwoSeparateConfigs) {
1077 Test_HotplugTwoSeparateConfigs();
1078 }
1079
TEST_F(DisplayTest_2_3,HotplugTwoConfigsSameGroup)1080 TEST_F(DisplayTest_2_3, HotplugTwoConfigsSameGroup) {
1081 Test_HotplugTwoConfigsSameGroup();
1082 }
1083
TEST_F(DisplayTest_2_3,HotplugThreeConfigsMixedGroups)1084 TEST_F(DisplayTest_2_3, HotplugThreeConfigsMixedGroups) {
1085 Test_HotplugThreeConfigsMixedGroups();
1086 }
1087
TEST_F(DisplayTest_2_3,HotplugPrimaryOneConfig)1088 TEST_F(DisplayTest_2_3, HotplugPrimaryOneConfig) {
1089 Test_HotplugPrimaryDisplay();
1090 }
1091
TEST_F(DisplayTest_2_3,SubsequentHotplugConnectUpdatesPrimaryDisplay)1092 TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
1093 Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
1094 }
1095
TEST_F(DisplayTest_2_3,SubsequentHotplugConnectUpdatesExternalDisplay)1096 TEST_F(DisplayTest_2_3, SubsequentHotplugConnectUpdatesExternalDisplay) {
1097 Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
1098 }
1099
1100 using DisplayTest_2_4 = DisplayTest<FakeComposerService_2_4>;
1101
TEST_F(DisplayTest_2_4,HotplugOneConfig)1102 TEST_F(DisplayTest_2_4, HotplugOneConfig) {
1103 Test_HotplugOneConfig();
1104 }
1105
TEST_F(DisplayTest_2_4,HotplugTwoSeparateConfigs)1106 TEST_F(DisplayTest_2_4, HotplugTwoSeparateConfigs) {
1107 Test_HotplugTwoSeparateConfigs();
1108 }
1109
TEST_F(DisplayTest_2_4,HotplugTwoConfigsSameGroup)1110 TEST_F(DisplayTest_2_4, HotplugTwoConfigsSameGroup) {
1111 Test_HotplugTwoConfigsSameGroup();
1112 }
1113
TEST_F(DisplayTest_2_4,HotplugThreeConfigsMixedGroups)1114 TEST_F(DisplayTest_2_4, HotplugThreeConfigsMixedGroups) {
1115 Test_HotplugThreeConfigsMixedGroups();
1116 }
1117
TEST_F(DisplayTest_2_4,HotplugPrimaryOneConfig)1118 TEST_F(DisplayTest_2_4, HotplugPrimaryOneConfig) {
1119 Test_HotplugPrimaryDisplay();
1120 }
1121
TEST_F(DisplayTest_2_4,SubsequentHotplugConnectUpdatesPrimaryDisplay)1122 TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesPrimaryDisplay) {
1123 Test_SubsequentHotplugConnectUpdatesDisplay(PRIMARY_DISPLAY);
1124 }
1125
TEST_F(DisplayTest_2_4,SubsequentHotplugConnectUpdatesExternalDisplay)1126 TEST_F(DisplayTest_2_4, SubsequentHotplugConnectUpdatesExternalDisplay) {
1127 Test_SubsequentHotplugConnectUpdatesDisplay(EXTERNAL_DISPLAY);
1128 }
1129
1130 ////////////////////////////////////////////////
1131
1132 template <typename FakeComposerService>
1133 class TransactionTest : public ::testing::Test {
1134 protected:
1135 // Layer array indexing constants.
1136 constexpr static int BG_LAYER = 0;
1137 constexpr static int FG_LAYER = 1;
1138
SetUpTestCase()1139 static void SetUpTestCase() {
1140 // TODO: See TODO comment at DisplayTest::SetUp for background on
1141 // the lifetime of the FakeComposerClient.
1142 sFakeComposer = new FakeComposerClient;
1143 sp<V2_4::hal::ComposerClient> client = new V2_4::hal::ComposerClient(sFakeComposer);
1144 sp<V2_1::IComposer> fakeService = new FakeComposerService(client);
1145 (void)fakeService->registerAsService("mock");
1146
1147 android::hardware::ProcessState::self()->startThreadPool();
1148 android::ProcessState::self()->startThreadPool();
1149
1150 startSurfaceFlinger();
1151
1152 // Fake composer wants to enable VSync injection
1153 sFakeComposer->onSurfaceFlingerStart();
1154 }
1155
TearDownTestCase()1156 static void TearDownTestCase() {
1157 // Fake composer needs to release SurfaceComposerClient before the stop.
1158 sFakeComposer->onSurfaceFlingerStop();
1159 stopSurfaceFlinger();
1160 // TODO: This is deleted when the ComposerClient calls
1161 // removeClient. Devise better lifetime control.
1162 sFakeComposer = nullptr;
1163 }
1164
SetUp()1165 void SetUp() override {
1166 ALOGI("TransactionTest::SetUp");
1167 mComposerClient = new SurfaceComposerClient;
1168 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
1169
1170 ALOGI("TransactionTest::SetUp - display");
1171 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(kPrimaryDisplayId);
1172 ASSERT_FALSE(display == nullptr);
1173
1174 ui::DisplayMode mode;
1175 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
1176
1177 const ui::Size& resolution = mode.resolution;
1178 mDisplayWidth = resolution.getWidth();
1179 mDisplayHeight = resolution.getHeight();
1180
1181 // Background surface
1182 mBGSurfaceControl =
1183 mComposerClient->createSurface(String8("BG Test Surface"), mDisplayWidth,
1184 mDisplayHeight, PIXEL_FORMAT_RGBA_8888, 0);
1185 ASSERT_TRUE(mBGSurfaceControl != nullptr);
1186 ASSERT_TRUE(mBGSurfaceControl->isValid());
1187 fillSurfaceRGBA8(mBGSurfaceControl, BLUE);
1188
1189 // Foreground surface
1190 mFGSurfaceControl = mComposerClient->createSurface(String8("FG Test Surface"), 64, 64,
1191 PIXEL_FORMAT_RGBA_8888, 0);
1192 ASSERT_TRUE(mFGSurfaceControl != nullptr);
1193 ASSERT_TRUE(mFGSurfaceControl->isValid());
1194
1195 fillSurfaceRGBA8(mFGSurfaceControl, RED);
1196
1197 Transaction t;
1198 t.setDisplayLayerStack(display, 0);
1199
1200 t.setLayer(mBGSurfaceControl, INT32_MAX - 2);
1201 t.show(mBGSurfaceControl);
1202
1203 t.setLayer(mFGSurfaceControl, INT32_MAX - 1);
1204 t.setPosition(mFGSurfaceControl, 64, 64);
1205 t.show(mFGSurfaceControl);
1206
1207 // Synchronous transaction will stop this thread, so we set up a
1208 // delayed, off-thread vsync request before closing the
1209 // transaction. In the test code this is usually done with
1210 // TransactionScope. Leaving here in the 'vanilla' form for
1211 // reference.
1212 ASSERT_EQ(0, sFakeComposer->getFrameCount());
1213 sFakeComposer->runVSyncAfter(1ms);
1214 t.apply();
1215 sFakeComposer->waitUntilFrame(1);
1216
1217 // Reference data. This is what the HWC should see.
1218 static_assert(BG_LAYER == 0 && FG_LAYER == 1, "Unexpected enum values for array indexing");
1219 mBaseFrame.push_back(makeSimpleRect(0u, 0u, mDisplayWidth, mDisplayHeight));
1220 mBaseFrame[BG_LAYER].mSwapCount = 1;
1221 mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
1222 mBaseFrame[FG_LAYER].mSwapCount = 1;
1223
1224 auto frame = sFakeComposer->getFrameRects(0);
1225 ASSERT_TRUE(framesAreSame(mBaseFrame, frame));
1226 }
1227
TearDown()1228 void TearDown() override {
1229 ALOGD("TransactionTest::TearDown");
1230
1231 mComposerClient->dispose();
1232 mBGSurfaceControl = 0;
1233 mFGSurfaceControl = 0;
1234 mComposerClient = 0;
1235
1236 sFakeComposer->runVSyncAndWait();
1237 mBaseFrame.clear();
1238 sFakeComposer->clearFrames();
1239 ASSERT_EQ(0, sFakeComposer->getFrameCount());
1240
1241 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1242 std::vector<LayerDebugInfo> layers;
1243 status_t result = sf->getLayerDebugInfo(&layers);
1244 if (result != NO_ERROR) {
1245 ALOGE("Failed to get layers %s %d", strerror(-result), result);
1246 } else {
1247 // If this fails, the test being torn down leaked layers.
1248 EXPECT_EQ(0u, layers.size());
1249 if (layers.size() > 0) {
1250 for (auto layer = layers.begin(); layer != layers.end(); ++layer) {
1251 std::cout << to_string(*layer).c_str();
1252 }
1253 // To ensure the next test has clean slate, will run the class
1254 // tear down and setup here.
1255 TearDownTestCase();
1256 SetUpTestCase();
1257 }
1258 }
1259 ALOGD("TransactionTest::TearDown - complete");
1260 }
1261
Test_LayerMove()1262 void Test_LayerMove() {
1263 ALOGD("TransactionTest::LayerMove");
1264
1265 // The scope opens and closes a global transaction and, at the
1266 // same time, makes sure the SurfaceFlinger progresses one frame
1267 // after the transaction closes. The results of the transaction
1268 // should be available in the latest frame stored by the fake
1269 // composer.
1270 {
1271 TransactionScope ts(*sFakeComposer);
1272 ts.setPosition(mFGSurfaceControl, 128, 128);
1273 // NOTE: No changes yet, so vsync will do nothing, HWC does not get any calls.
1274 // (How to verify that? Throw in vsync and wait a 2x frame time? Separate test?)
1275 //
1276 // sFakeComposer->runVSyncAndWait();
1277 }
1278
1279 fillSurfaceRGBA8(mFGSurfaceControl, GREEN);
1280 sFakeComposer->runVSyncAndWait();
1281
1282 ASSERT_EQ(3, sFakeComposer->getFrameCount()); // Make sure the waits didn't time out and
1283 // there's no extra frames.
1284
1285 // NOTE: Frame 0 is produced in the SetUp.
1286 auto frame1Ref = mBaseFrame;
1287 frame1Ref[FG_LAYER].mDisplayFrame =
1288 hwc_rect_t{128, 128, 128 + 64, 128 + 64}; // Top-most layer moves.
1289 EXPECT_TRUE(framesAreSame(frame1Ref, sFakeComposer->getFrameRects(1)));
1290
1291 auto frame2Ref = frame1Ref;
1292 frame2Ref[FG_LAYER].mSwapCount++;
1293 EXPECT_TRUE(framesAreSame(frame2Ref, sFakeComposer->getFrameRects(2)));
1294 }
1295
Test_LayerCrop()1296 void Test_LayerCrop() {
1297 // TODO: Add scaling to confirm that crop happens in buffer space?
1298 {
1299 TransactionScope ts(*sFakeComposer);
1300 Rect cropRect(16, 16, 32, 32);
1301 ts.setCrop(mFGSurfaceControl, cropRect);
1302 }
1303 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1304
1305 auto referenceFrame = mBaseFrame;
1306 referenceFrame[FG_LAYER].mSourceCrop = hwc_frect_t{16.f, 16.f, 32.f, 32.f};
1307 referenceFrame[FG_LAYER].mDisplayFrame = hwc_rect_t{64 + 16, 64 + 16, 64 + 32, 64 + 32};
1308 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1309 }
1310
Test_LayerSetLayer()1311 void Test_LayerSetLayer() {
1312 {
1313 TransactionScope ts(*sFakeComposer);
1314 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
1315 }
1316 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1317
1318 // The layers will switch order, but both are rendered because the background layer is
1319 // transparent (RGBA8888).
1320 std::vector<RenderState> referenceFrame(2);
1321 referenceFrame[0] = mBaseFrame[FG_LAYER];
1322 referenceFrame[1] = mBaseFrame[BG_LAYER];
1323 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1324 }
1325
Test_LayerSetLayerOpaque()1326 void Test_LayerSetLayerOpaque() {
1327 {
1328 TransactionScope ts(*sFakeComposer);
1329 ts.setLayer(mFGSurfaceControl, INT_MAX - 3);
1330 ts.setFlags(mBGSurfaceControl, layer_state_t::eLayerOpaque,
1331 layer_state_t::eLayerOpaque);
1332 }
1333 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1334
1335 // The former foreground layer is now covered with opaque layer - it should have disappeared
1336 std::vector<RenderState> referenceFrame(1);
1337 referenceFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1338 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1339 }
1340
Test_SetLayerStack()1341 void Test_SetLayerStack() {
1342 ALOGD("TransactionTest::SetLayerStack");
1343 {
1344 TransactionScope ts(*sFakeComposer);
1345 ts.setLayerStack(mFGSurfaceControl, 1);
1346 }
1347
1348 // Foreground layer should have disappeared.
1349 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1350 std::vector<RenderState> refFrame(1);
1351 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1352 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
1353 }
1354
Test_LayerShowHide()1355 void Test_LayerShowHide() {
1356 ALOGD("TransactionTest::LayerShowHide");
1357 {
1358 TransactionScope ts(*sFakeComposer);
1359 ts.hide(mFGSurfaceControl);
1360 }
1361
1362 // Foreground layer should have disappeared.
1363 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1364 std::vector<RenderState> refFrame(1);
1365 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1366 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
1367
1368 {
1369 TransactionScope ts(*sFakeComposer);
1370 ts.show(mFGSurfaceControl);
1371 }
1372
1373 // Foreground layer should be back
1374 ASSERT_EQ(3, sFakeComposer->getFrameCount());
1375 EXPECT_TRUE(framesAreSame(mBaseFrame, sFakeComposer->getLatestFrame()));
1376 }
1377
Test_LayerSetAlpha()1378 void Test_LayerSetAlpha() {
1379 {
1380 TransactionScope ts(*sFakeComposer);
1381 ts.setAlpha(mFGSurfaceControl, 0.75f);
1382 }
1383
1384 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1385 auto referenceFrame = mBaseFrame;
1386 referenceFrame[FG_LAYER].mPlaneAlpha = 0.75f;
1387 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1388 }
1389
Test_LayerSetFlags()1390 void Test_LayerSetFlags() {
1391 {
1392 TransactionScope ts(*sFakeComposer);
1393 ts.setFlags(mFGSurfaceControl, layer_state_t::eLayerHidden,
1394 layer_state_t::eLayerHidden);
1395 }
1396
1397 // Foreground layer should have disappeared.
1398 ASSERT_EQ(2, sFakeComposer->getFrameCount());
1399 std::vector<RenderState> refFrame(1);
1400 refFrame[BG_LAYER] = mBaseFrame[BG_LAYER];
1401 EXPECT_TRUE(framesAreSame(refFrame, sFakeComposer->getLatestFrame()));
1402 }
1403
Test_LayerSetMatrix()1404 void Test_LayerSetMatrix() {
1405 struct matrixTestData {
1406 float matrix[4];
1407 hwc_transform_t expectedTransform;
1408 hwc_rect_t expectedDisplayFrame;
1409 };
1410
1411 // The matrix operates on the display frame and is applied before
1412 // the position is added. So, the foreground layer rect is (0, 0,
1413 // 64, 64) is first transformed, potentially yielding negative
1414 // coordinates and then the position (64, 64) is added yielding
1415 // the final on-screen rectangles given.
1416
1417 const matrixTestData MATRIX_TESTS[7] = // clang-format off
1418 {{{-1.f, 0.f, 0.f, 1.f}, HWC_TRANSFORM_FLIP_H, {0, 64, 64, 128}},
1419 {{1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_FLIP_V, {64, 0, 128, 64}},
1420 {{0.f, 1.f, -1.f, 0.f}, HWC_TRANSFORM_ROT_90, {0, 64, 64, 128}},
1421 {{-1.f, 0.f, 0.f, -1.f}, HWC_TRANSFORM_ROT_180, {0, 0, 64, 64}},
1422 {{0.f, -1.f, 1.f, 0.f}, HWC_TRANSFORM_ROT_270, {64, 0, 128, 64}},
1423 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_H_ROT_90, {64, 64, 128, 128}},
1424 {{0.f, 1.f, 1.f, 0.f}, HWC_TRANSFORM_FLIP_V_ROT_90, {64, 64, 128, 128}}};
1425 // clang-format on
1426 constexpr int TEST_COUNT = sizeof(MATRIX_TESTS) / sizeof(matrixTestData);
1427
1428 for (int i = 0; i < TEST_COUNT; i++) {
1429 // TODO: How to leverage the HWC2 stringifiers?
1430 const matrixTestData& xform = MATRIX_TESTS[i];
1431 SCOPED_TRACE(i);
1432 {
1433 TransactionScope ts(*sFakeComposer);
1434 ts.setMatrix(mFGSurfaceControl, xform.matrix[0], xform.matrix[1], xform.matrix[2],
1435 xform.matrix[3]);
1436 }
1437
1438 auto referenceFrame = mBaseFrame;
1439 referenceFrame[FG_LAYER].mTransform = xform.expectedTransform;
1440 referenceFrame[FG_LAYER].mDisplayFrame = xform.expectedDisplayFrame;
1441
1442 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1443 }
1444 }
1445
Test_SetRelativeLayer()1446 void Test_SetRelativeLayer() {
1447 constexpr int RELATIVE_LAYER = 2;
1448 auto relativeSurfaceControl = mComposerClient->createSurface(String8("Test Surface"), 64,
1449 64, PIXEL_FORMAT_RGBA_8888, 0);
1450 fillSurfaceRGBA8(relativeSurfaceControl, LIGHT_RED);
1451
1452 // Now we stack the surface above the foreground surface and make sure it is visible.
1453 {
1454 TransactionScope ts(*sFakeComposer);
1455 ts.setPosition(relativeSurfaceControl, 64, 64);
1456 ts.show(relativeSurfaceControl);
1457 ts.setRelativeLayer(relativeSurfaceControl, mFGSurfaceControl, 1);
1458 }
1459 auto referenceFrame = mBaseFrame;
1460 // NOTE: All three layers will be visible as the surfaces are
1461 // transparent because of the RGBA format.
1462 referenceFrame.push_back(makeSimpleRect(64, 64, 64 + 64, 64 + 64));
1463 referenceFrame[RELATIVE_LAYER].mSwapCount = 1;
1464 EXPECT_TRUE(framesAreSame(referenceFrame, sFakeComposer->getLatestFrame()));
1465
1466 // A call to setLayer will override a call to setRelativeLayer
1467 {
1468 TransactionScope ts(*sFakeComposer);
1469 ts.setLayer(relativeSurfaceControl, 0);
1470 }
1471
1472 // Previous top layer will now appear at the bottom.
1473 auto referenceFrame2 = mBaseFrame;
1474 referenceFrame2.insert(referenceFrame2.begin(), referenceFrame[RELATIVE_LAYER]);
1475 EXPECT_EQ(3, sFakeComposer->getFrameCount());
1476 EXPECT_TRUE(framesAreSame(referenceFrame2, sFakeComposer->getLatestFrame()));
1477 }
1478
1479 sp<SurfaceComposerClient> mComposerClient;
1480 sp<SurfaceControl> mBGSurfaceControl;
1481 sp<SurfaceControl> mFGSurfaceControl;
1482 std::vector<RenderState> mBaseFrame;
1483 uint32_t mDisplayWidth;
1484 uint32_t mDisplayHeight;
1485
1486 static inline FakeComposerClient* sFakeComposer;
1487 };
1488
1489 using TransactionTest_2_1 = TransactionTest<FakeComposerService_2_1>;
1490
TEST_F(TransactionTest_2_1,DISABLED_LayerMove)1491 TEST_F(TransactionTest_2_1, DISABLED_LayerMove) {
1492 Test_LayerMove();
1493 }
1494
TEST_F(TransactionTest_2_1,DISABLED_LayerCrop)1495 TEST_F(TransactionTest_2_1, DISABLED_LayerCrop) {
1496 Test_LayerCrop();
1497 }
1498
TEST_F(TransactionTest_2_1,DISABLED_LayerSetLayer)1499 TEST_F(TransactionTest_2_1, DISABLED_LayerSetLayer) {
1500 Test_LayerSetLayer();
1501 }
1502
TEST_F(TransactionTest_2_1,DISABLED_LayerSetLayerOpaque)1503 TEST_F(TransactionTest_2_1, DISABLED_LayerSetLayerOpaque) {
1504 Test_LayerSetLayerOpaque();
1505 }
1506
TEST_F(TransactionTest_2_1,DISABLED_SetLayerStack)1507 TEST_F(TransactionTest_2_1, DISABLED_SetLayerStack) {
1508 Test_SetLayerStack();
1509 }
1510
TEST_F(TransactionTest_2_1,DISABLED_LayerShowHide)1511 TEST_F(TransactionTest_2_1, DISABLED_LayerShowHide) {
1512 Test_LayerShowHide();
1513 }
1514
TEST_F(TransactionTest_2_1,DISABLED_LayerSetAlpha)1515 TEST_F(TransactionTest_2_1, DISABLED_LayerSetAlpha) {
1516 Test_LayerSetAlpha();
1517 }
1518
TEST_F(TransactionTest_2_1,DISABLED_LayerSetFlags)1519 TEST_F(TransactionTest_2_1, DISABLED_LayerSetFlags) {
1520 Test_LayerSetFlags();
1521 }
1522
TEST_F(TransactionTest_2_1,DISABLED_LayerSetMatrix)1523 TEST_F(TransactionTest_2_1, DISABLED_LayerSetMatrix) {
1524 Test_LayerSetMatrix();
1525 }
1526
TEST_F(TransactionTest_2_1,DISABLED_SetRelativeLayer)1527 TEST_F(TransactionTest_2_1, DISABLED_SetRelativeLayer) {
1528 Test_SetRelativeLayer();
1529 }
1530
1531 template <typename FakeComposerService>
1532 class ChildLayerTest : public TransactionTest<FakeComposerService> {
1533 using Base = TransactionTest<FakeComposerService>;
1534
1535 protected:
1536 constexpr static int CHILD_LAYER = 2;
1537
SetUp()1538 void SetUp() override {
1539 Base::SetUp();
1540 mChild = Base::mComposerClient->createSurface(String8("Child surface"), 10, 10,
1541 PIXEL_FORMAT_RGBA_8888, 0,
1542 Base::mFGSurfaceControl->getHandle());
1543 fillSurfaceRGBA8(mChild, LIGHT_GRAY);
1544
1545 Base::sFakeComposer->runVSyncAndWait();
1546 Base::mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
1547 Base::mBaseFrame[CHILD_LAYER].mSwapCount = 1;
1548 ASSERT_EQ(2, Base::sFakeComposer->getFrameCount());
1549 ASSERT_TRUE(framesAreSame(Base::mBaseFrame, Base::sFakeComposer->getLatestFrame()));
1550 }
1551
TearDown()1552 void TearDown() override {
1553 mChild = 0;
1554 Base::TearDown();
1555 }
1556
Test_Positioning()1557 void Test_Positioning() {
1558 {
1559 TransactionScope ts(*Base::sFakeComposer);
1560 ts.show(mChild);
1561 ts.setPosition(mChild, 10, 10);
1562 // Move to the same position as in the original setup.
1563 ts.setPosition(Base::mFGSurfaceControl, 64, 64);
1564 }
1565
1566 auto referenceFrame = Base::mBaseFrame;
1567 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{64, 64, 64 + 64, 64 + 64};
1568 referenceFrame[CHILD_LAYER].mDisplayFrame =
1569 hwc_rect_t{64 + 10, 64 + 10, 64 + 10 + 10, 64 + 10 + 10};
1570 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1571
1572 {
1573 TransactionScope ts(*Base::sFakeComposer);
1574 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1575 }
1576
1577 auto referenceFrame2 = Base::mBaseFrame;
1578 referenceFrame2[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 64, 0 + 64};
1579 referenceFrame2[CHILD_LAYER].mDisplayFrame =
1580 hwc_rect_t{0 + 10, 0 + 10, 0 + 10 + 10, 0 + 10 + 10};
1581 EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame()));
1582 }
1583
Test_Cropping()1584 void Test_Cropping() {
1585 {
1586 TransactionScope ts(*Base::sFakeComposer);
1587 ts.show(mChild);
1588 ts.setPosition(mChild, 0, 0);
1589 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1590 ts.setCrop(Base::mFGSurfaceControl, Rect(0, 0, 5, 5));
1591 }
1592 // NOTE: The foreground surface would be occluded by the child
1593 // now, but is included in the stack because the child is
1594 // transparent.
1595 auto referenceFrame = Base::mBaseFrame;
1596 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
1597 referenceFrame[Base::FG_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
1598 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 0 + 5, 0 + 5};
1599 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 5.f, 5.f};
1600 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1601 }
1602
Test_Constraints()1603 void Test_Constraints() {
1604 {
1605 TransactionScope ts(*Base::sFakeComposer);
1606 ts.show(mChild);
1607 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1608 ts.setPosition(mChild, 63, 63);
1609 }
1610 auto referenceFrame = Base::mBaseFrame;
1611 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1612 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{63, 63, 64, 64};
1613 referenceFrame[CHILD_LAYER].mSourceCrop = hwc_frect_t{0.f, 0.f, 1.f, 1.f};
1614 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1615 }
1616
Test_Scaling()1617 void Test_Scaling() {
1618 {
1619 TransactionScope ts(*Base::sFakeComposer);
1620 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1621 }
1622 auto referenceFrame = Base::mBaseFrame;
1623 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1624 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1625 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1626
1627 {
1628 TransactionScope ts(*Base::sFakeComposer);
1629 ts.setMatrix(Base::mFGSurfaceControl, 2.0, 0, 0, 2.0);
1630 }
1631
1632 auto referenceFrame2 = Base::mBaseFrame;
1633 referenceFrame2[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 128, 128};
1634 referenceFrame2[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 20, 20};
1635 EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame()));
1636 }
1637
Test_LayerAlpha()1638 void Test_LayerAlpha() {
1639 {
1640 TransactionScope ts(*Base::sFakeComposer);
1641 ts.show(mChild);
1642 ts.setPosition(mChild, 0, 0);
1643 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1644 ts.setAlpha(mChild, 0.5);
1645 }
1646
1647 auto referenceFrame = Base::mBaseFrame;
1648 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1649 referenceFrame[CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1650 referenceFrame[CHILD_LAYER].mPlaneAlpha = 0.5f;
1651 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1652
1653 {
1654 TransactionScope ts(*Base::sFakeComposer);
1655 ts.setAlpha(Base::mFGSurfaceControl, 0.5);
1656 }
1657
1658 auto referenceFrame2 = referenceFrame;
1659 referenceFrame2[Base::FG_LAYER].mPlaneAlpha = 0.5f;
1660 referenceFrame2[CHILD_LAYER].mPlaneAlpha = 0.25f;
1661 EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame()));
1662 }
1663
1664 sp<SurfaceControl> mChild;
1665 };
1666
1667 using ChildLayerTest_2_1 = ChildLayerTest<FakeComposerService_2_1>;
1668
TEST_F(ChildLayerTest_2_1,DISABLED_Positioning)1669 TEST_F(ChildLayerTest_2_1, DISABLED_Positioning) {
1670 Test_Positioning();
1671 }
1672
TEST_F(ChildLayerTest_2_1,DISABLED_Cropping)1673 TEST_F(ChildLayerTest_2_1, DISABLED_Cropping) {
1674 Test_Cropping();
1675 }
1676
TEST_F(ChildLayerTest_2_1,DISABLED_Constraints)1677 TEST_F(ChildLayerTest_2_1, DISABLED_Constraints) {
1678 Test_Constraints();
1679 }
1680
TEST_F(ChildLayerTest_2_1,DISABLED_Scaling)1681 TEST_F(ChildLayerTest_2_1, DISABLED_Scaling) {
1682 Test_Scaling();
1683 }
1684
TEST_F(ChildLayerTest_2_1,DISABLED_LayerAlpha)1685 TEST_F(ChildLayerTest_2_1, DISABLED_LayerAlpha) {
1686 Test_LayerAlpha();
1687 }
1688
1689 template <typename FakeComposerService>
1690 class ChildColorLayerTest : public ChildLayerTest<FakeComposerService> {
1691 using Base = ChildLayerTest<FakeComposerService>;
1692
1693 protected:
SetUp()1694 void SetUp() override {
1695 Base::SetUp();
1696 Base::mChild =
1697 Base::mComposerClient->createSurface(String8("Child surface"), 0, 0,
1698 PIXEL_FORMAT_RGBA_8888,
1699 ISurfaceComposerClient::eFXSurfaceEffect,
1700 Base::mFGSurfaceControl->getHandle());
1701 {
1702 TransactionScope ts(*Base::sFakeComposer);
1703 ts.setColor(Base::mChild,
1704 {LIGHT_GRAY.r / 255.0f, LIGHT_GRAY.g / 255.0f, LIGHT_GRAY.b / 255.0f});
1705 ts.setCrop(Base::mChild, Rect(0, 0, 10, 10));
1706 }
1707
1708 Base::sFakeComposer->runVSyncAndWait();
1709 Base::mBaseFrame.push_back(makeSimpleRect(64, 64, 64 + 10, 64 + 10));
1710 Base::mBaseFrame[Base::CHILD_LAYER].mSourceCrop = hwc_frect_t{0.0f, 0.0f, 0.0f, 0.0f};
1711 Base::mBaseFrame[Base::CHILD_LAYER].mSwapCount = 0;
1712 ASSERT_EQ(2, Base::sFakeComposer->getFrameCount());
1713 ASSERT_TRUE(framesAreSame(Base::mBaseFrame, Base::sFakeComposer->getLatestFrame()));
1714 }
1715
Test_LayerAlpha()1716 void Test_LayerAlpha() {
1717 {
1718 TransactionScope ts(*Base::sFakeComposer);
1719 ts.show(Base::mChild);
1720 ts.setPosition(Base::mChild, 0, 0);
1721 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1722 ts.setAlpha(Base::mChild, 0.5);
1723 }
1724
1725 auto referenceFrame = Base::mBaseFrame;
1726 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1727 referenceFrame[Base::CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1728 referenceFrame[Base::CHILD_LAYER].mPlaneAlpha = 0.5f;
1729 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1730
1731 {
1732 TransactionScope ts(*Base::sFakeComposer);
1733 ts.setAlpha(Base::mFGSurfaceControl, 0.5);
1734 }
1735
1736 auto referenceFrame2 = referenceFrame;
1737 referenceFrame2[Base::FG_LAYER].mPlaneAlpha = 0.5f;
1738 referenceFrame2[Base::CHILD_LAYER].mPlaneAlpha = 0.25f;
1739 EXPECT_TRUE(framesAreSame(referenceFrame2, Base::sFakeComposer->getLatestFrame()));
1740 }
1741
Test_LayerZeroAlpha()1742 void Test_LayerZeroAlpha() {
1743 {
1744 TransactionScope ts(*Base::sFakeComposer);
1745 ts.show(Base::mChild);
1746 ts.setPosition(Base::mChild, 0, 0);
1747 ts.setPosition(Base::mFGSurfaceControl, 0, 0);
1748 ts.setAlpha(Base::mChild, 0.5);
1749 }
1750
1751 auto referenceFrame = Base::mBaseFrame;
1752 referenceFrame[Base::FG_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 64, 64};
1753 referenceFrame[Base::CHILD_LAYER].mDisplayFrame = hwc_rect_t{0, 0, 10, 10};
1754 referenceFrame[Base::CHILD_LAYER].mPlaneAlpha = 0.5f;
1755 EXPECT_TRUE(framesAreSame(referenceFrame, Base::sFakeComposer->getLatestFrame()));
1756
1757 {
1758 TransactionScope ts(*Base::sFakeComposer);
1759 ts.setAlpha(Base::mFGSurfaceControl, 0.0f);
1760 }
1761
1762 std::vector<RenderState> refFrame(1);
1763 refFrame[Base::BG_LAYER] = Base::mBaseFrame[Base::BG_LAYER];
1764
1765 EXPECT_TRUE(framesAreSame(refFrame, Base::sFakeComposer->getLatestFrame()));
1766 }
1767 };
1768
1769 using ChildColorLayerTest_2_1 = ChildColorLayerTest<FakeComposerService_2_1>;
1770
TEST_F(ChildColorLayerTest_2_1,DISABLED_LayerAlpha)1771 TEST_F(ChildColorLayerTest_2_1, DISABLED_LayerAlpha) {
1772 Test_LayerAlpha();
1773 }
1774
TEST_F(ChildColorLayerTest_2_1,DISABLED_LayerZeroAlpha)1775 TEST_F(ChildColorLayerTest_2_1, DISABLED_LayerZeroAlpha) {
1776 Test_LayerZeroAlpha();
1777 }
1778 } // namespace
1779
main(int argc,char ** argv)1780 int main(int argc, char** argv) {
1781 ::testing::InitGoogleTest(&argc, argv);
1782
1783 auto* fakeEnvironment = new sftest::FakeHwcEnvironment;
1784 ::testing::AddGlobalTestEnvironment(fakeEnvironment);
1785 ::testing::InitGoogleMock(&argc, argv);
1786 return RUN_ALL_TESTS();
1787 }
1788
1789 // TODO(b/129481165): remove the #pragma below and fix conversion issues
1790 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
1791