blob: d1bbb5bd6edc8265e938bd49669f83841a1edcfd [file] [log] [blame]
Lloyd Piquef58625d2017-12-19 13:22:33 -08001/*
2 * Copyright (C) 2018 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#undef LOG_TAG
18#define LOG_TAG "LibSurfaceFlingerUnittests"
19
20#include <gmock/gmock.h>
21#include <gtest/gtest.h>
22
23#include <log/log.h>
24
25#include "TestableSurfaceFlinger.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080026#include "mock/DisplayHardware/MockComposer.h"
27#include "mock/DisplayHardware/MockDisplaySurface.h"
28#include "mock/MockEventControlThread.h"
29#include "mock/MockEventThread.h"
30#include "mock/MockMessageQueue.h"
31#include "mock/MockNativeWindowSurface.h"
32#include "mock/MockSurfaceInterceptor.h"
33#include "mock/RenderEngine/MockRenderEngine.h"
34#include "mock/gui/MockGraphicBufferConsumer.h"
35#include "mock/gui/MockGraphicBufferProducer.h"
36#include "mock/system/window/MockNativeWindow.h"
Lloyd Piquef58625d2017-12-19 13:22:33 -080037
38namespace android {
39namespace {
40
Lloyd Piquee39cad22017-12-20 17:01:29 -080041using testing::_;
42using testing::ByMove;
43using testing::DoAll;
44using testing::Mock;
45using testing::Return;
46using testing::SetArgPointee;
47
Lloyd Piqued883d5a2018-04-27 19:32:30 -070048using android::Hwc2::ColorMode;
Lloyd Piquee39cad22017-12-20 17:01:29 -080049using android::Hwc2::Error;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070050using android::Hwc2::Hdr;
Lloyd Piquee39cad22017-12-20 17:01:29 -080051using android::Hwc2::IComposer;
52using android::Hwc2::IComposerClient;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070053using android::Hwc2::PerFrameMetadataKey;
54using android::Hwc2::RenderIntent;
Lloyd Piquee39cad22017-12-20 17:01:29 -080055
Lloyd Piquefc12f562018-01-22 18:44:59 -080056using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
57using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
Lloyd Pique1fa4d462018-01-22 18:03:16 -080058using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
Lloyd Piquefc12f562018-01-22 18:44:59 -080059using HWC2Display = TestableSurfaceFlinger::HWC2Display;
Lloyd Piquebc792092018-01-17 11:52:30 -080060
Lloyd Piquefc12f562018-01-22 18:44:59 -080061constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
Lloyd Piquee39cad22017-12-20 17:01:29 -080062constexpr int32_t DEFAULT_DPI = 320;
Lloyd Piquefc12f562018-01-22 18:44:59 -080063constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
Lloyd Piquee39cad22017-12-20 17:01:29 -080064
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -080065constexpr int HWC_POWER_MODE_LEET = 1337; // An out of range power mode value
66
Lloyd Piquefc12f562018-01-22 18:44:59 -080067/* ------------------------------------------------------------------------
68 * Boolean avoidance
69 *
70 * To make calls and template instantiations more readable, we define some
71 * local enums along with an implicit bool conversion.
72 */
73
74#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
75
76BOOL_SUBSTITUTE(Critical);
77BOOL_SUBSTITUTE(Async);
78BOOL_SUBSTITUTE(Secure);
79
80/* ------------------------------------------------------------------------
81 *
82 */
Lloyd Pique1fa4d462018-01-22 18:03:16 -080083
Lloyd Piquef58625d2017-12-19 13:22:33 -080084class DisplayTransactionTest : public testing::Test {
Lloyd Piquefc12f562018-01-22 18:44:59 -080085public:
Lloyd Piquef58625d2017-12-19 13:22:33 -080086 DisplayTransactionTest();
87 ~DisplayTransactionTest() override;
88
Lloyd Pique1fa4d462018-01-22 18:03:16 -080089 // --------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -080090 // Mock/Fake injection
Lloyd Piquef58625d2017-12-19 13:22:33 -080091
Lloyd Piquefc12f562018-01-22 18:44:59 -080092 void injectMockComposer(int virtualDisplayCount);
93 void injectFakeBufferQueueFactory();
94 void injectFakeNativeWindowSurfaceFactory();
Lloyd Pique1fa4d462018-01-22 18:03:16 -080095
96 // --------------------------------------------------------------------
97 // Postcondition helpers
98
Lloyd Piquefc12f562018-01-22 18:44:59 -080099 bool hasHwcDisplay(hwc2_display_t displayId);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800100 bool hasTransactionFlagSet(int flag);
101 bool hasDisplayDevice(sp<IBinder> displayToken);
102 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
103 bool hasCurrentDisplayState(sp<IBinder> displayToken);
104 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
105 bool hasDrawingDisplayState(sp<IBinder> displayToken);
106 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
107
108 // --------------------------------------------------------------------
109 // Test instances
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800110
Lloyd Piquef58625d2017-12-19 13:22:33 -0800111 TestableSurfaceFlinger mFlinger;
Lloyd Piquee39cad22017-12-20 17:01:29 -0800112 mock::EventThread* mEventThread = new mock::EventThread();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800113 mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800114
115 // These mocks are created by the test, but are destroyed by SurfaceFlinger
116 // by virtue of being stored into a std::unique_ptr. However we still need
117 // to keep a reference to them for use in setting up call expectations.
118 RE::mock::RenderEngine* mRenderEngine = new RE::mock::RenderEngine();
Lloyd Piquefc12f562018-01-22 18:44:59 -0800119 Hwc2::mock::Composer* mComposer = nullptr;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800120 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
121 mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800122
123 // These mocks are created only when expected to be created via a factory.
124 sp<mock::GraphicBufferConsumer> mConsumer;
125 sp<mock::GraphicBufferProducer> mProducer;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800126 mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
127 sp<mock::NativeWindow> mNativeWindow;
128 RE::mock::Surface* mRenderSurface = nullptr;
Lloyd Piquef58625d2017-12-19 13:22:33 -0800129};
130
131DisplayTransactionTest::DisplayTransactionTest() {
132 const ::testing::TestInfo* const test_info =
133 ::testing::UnitTest::GetInstance()->current_test_info();
134 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Lloyd Piquee39cad22017-12-20 17:01:29 -0800135
Lloyd Piquefc12f562018-01-22 18:44:59 -0800136 // Default to no wide color display support configured
137 mFlinger.mutableHasWideColorDisplay() = false;
138 mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
139
140 // Default to using HWC virtual displays
141 mFlinger.mutableUseHwcVirtualDisplays() = true;
142
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800143 mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
144 ADD_FAILURE() << "Unexpected request to create a buffer queue.";
145 });
146
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800147 mFlinger.setCreateNativeWindowSurface([](auto) {
148 ADD_FAILURE() << "Unexpected request to create a native window surface.";
149 return nullptr;
150 });
151
152 mFlinger.mutableEventControlThread().reset(mEventControlThread);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800153 mFlinger.mutableEventThread().reset(mEventThread);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800154 mFlinger.mutableEventQueue().reset(mMessageQueue);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800155 mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800156 mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800157
Lloyd Piquefc12f562018-01-22 18:44:59 -0800158 injectMockComposer(0);
Lloyd Piquef58625d2017-12-19 13:22:33 -0800159}
160
161DisplayTransactionTest::~DisplayTransactionTest() {
162 const ::testing::TestInfo* const test_info =
163 ::testing::UnitTest::GetInstance()->current_test_info();
164 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
165}
166
Lloyd Piquefc12f562018-01-22 18:44:59 -0800167void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
168 mComposer = new Hwc2::mock::Composer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800169 EXPECT_CALL(*mComposer, getCapabilities())
170 .WillOnce(Return(std::vector<IComposer::Capability>()));
171 EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
172 mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
Lloyd Piquef58625d2017-12-19 13:22:33 -0800173
Lloyd Piquee39cad22017-12-20 17:01:29 -0800174 Mock::VerifyAndClear(mComposer);
175}
176
Lloyd Piquefc12f562018-01-22 18:44:59 -0800177void DisplayTransactionTest::injectFakeBufferQueueFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800178 // This setup is only expected once per test.
179 ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
180
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800181 mConsumer = new mock::GraphicBufferConsumer();
182 mProducer = new mock::GraphicBufferProducer();
183
184 mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
185 *outProducer = mProducer;
186 *outConsumer = mConsumer;
187 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800188}
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800189
Lloyd Piquefc12f562018-01-22 18:44:59 -0800190void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800191 // This setup is only expected once per test.
192 ASSERT_TRUE(mNativeWindowSurface == nullptr);
193
194 mNativeWindowSurface = new mock::NativeWindowSurface();
195 mNativeWindow = new mock::NativeWindow();
196
197 mFlinger.setCreateNativeWindowSurface(
198 [this](auto) { return std::unique_ptr<NativeWindowSurface>(mNativeWindowSurface); });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800199}
200
Lloyd Piquefc12f562018-01-22 18:44:59 -0800201bool DisplayTransactionTest::hasHwcDisplay(hwc2_display_t displayId) {
202 return mFlinger.mutableHwcDisplaySlots().count(displayId) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800203}
204
205bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
206 return mFlinger.mutableTransactionFlags() & flag;
207}
208
209bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
210 return mFlinger.mutableDisplays().indexOfKey(displayToken) >= 0;
211}
212
213sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
214 return mFlinger.mutableDisplays().valueFor(displayToken);
215}
216
217bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
218 return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
219}
220
221const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
222 return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
223}
224
225bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
226 return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
227}
228
229const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
230 return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
231}
232
233/* ------------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -0800234 *
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800235 */
236
Lloyd Piquefc12f562018-01-22 18:44:59 -0800237template <DisplayDevice::DisplayType type, DisplayDevice::DisplayType hwcId, int width, int height,
238 Critical critical, Async async, Secure secure, int grallocUsage>
239struct DisplayVariant {
240 // The display width and height
241 static constexpr int WIDTH = width;
242 static constexpr int HEIGHT = height;
243
244 static constexpr int GRALLOC_USAGE = grallocUsage;
245
246 // The type for this display
247 static constexpr DisplayDevice::DisplayType TYPE = type;
248 static constexpr DisplayDevice::DisplayType HWCOMPOSER_ID = hwcId;
249
250 // When creating native window surfaces for the framebuffer, whether those should be critical
251 static constexpr Critical CRITICAL = critical;
252
253 // When creating native window surfaces for the framebuffer, whether those should be async
254 static constexpr Async ASYNC = async;
255
256 // Whether the display should be treated as secure
257 static constexpr Secure SECURE = secure;
258
259 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
260 auto injector = FakeDisplayDeviceInjector(test->mFlinger, TYPE, HWCOMPOSER_ID);
261 injector.setSecure(static_cast<bool>(SECURE));
262 return injector;
263 }
264
265 // Called by tests to set up any native window creation call expectations.
266 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
267 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
268 .WillOnce(Return(test->mNativeWindow));
269 EXPECT_CALL(*test->mNativeWindow, perform(19)).WillRepeatedly(Return(NO_ERROR));
270
271 // For simplicity, we only expect to create a single render surface for
272 // each test.
273 ASSERT_TRUE(test->mRenderSurface == nullptr);
274 test->mRenderSurface = new RE::mock::Surface();
275 EXPECT_CALL(*test->mRenderEngine, createSurface())
276 .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(test->mRenderSurface))));
277 EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
278 EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
279 EXPECT_CALL(*test->mRenderSurface, setNativeWindow(test->mNativeWindow.get())).Times(1);
280 EXPECT_CALL(*test->mRenderSurface, queryWidth()).WillOnce(Return(WIDTH));
281 EXPECT_CALL(*test->mRenderSurface, queryHeight()).WillOnce(Return(HEIGHT));
282 }
283
284 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
285 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
286 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
287 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
288 .WillRepeatedly(Return(NO_ERROR));
289 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
290 .WillRepeatedly(Return(NO_ERROR));
291 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
292 .WillRepeatedly(Return(NO_ERROR));
293 }
294
295 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
296 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
297 }
298};
299
300template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant>
301struct HwcDisplayVariant {
302 // The display id supplied by the HWC
303 static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
304
305 // The HWC display type
306 static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
307
308 // The HWC active configuration id
309 // TODO(b/69807179): SurfaceFlinger does not correctly get the active
310 // config. Once it does, change this to non-zero so that it is properly
311 // covered.
312 // static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
313 static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
314
315 static void injectPendingHotplugEvent(DisplayTransactionTest* test,
316 HWC2::Connection connection) {
317 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
318 HotplugEvent{HWC_DISPLAY_ID, connection});
319 }
320
321 // Called by tests to inject a HWC display setup
322 static void injectHwcDisplay(DisplayTransactionTest* test) {
323 FakeHwcDisplayInjector(DisplayVariant::TYPE, HWC_DISPLAY_TYPE)
324 .setHwcDisplayId(HWC_DISPLAY_ID)
325 .setWidth(DisplayVariant::WIDTH)
326 .setHeight(DisplayVariant::HEIGHT)
327 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
328 .inject(&test->mFlinger, test->mComposer);
329 }
330
331 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
332 EXPECT_CALL(*test->mComposer, getDisplayType(HWC_DISPLAY_ID, _))
333 .WillOnce(DoAll(SetArgPointee<1>(static_cast<IComposerClient::DisplayType>(
334 HWC_DISPLAY_TYPE)),
335 Return(Error::NONE)));
336 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
337 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
338 .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
339 Return(Error::NONE)));
340 EXPECT_CALL(*test->mComposer,
341 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
342 IComposerClient::Attribute::WIDTH, _))
343 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
344 EXPECT_CALL(*test->mComposer,
345 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
346 IComposerClient::Attribute::HEIGHT, _))
347 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
348 EXPECT_CALL(*test->mComposer,
349 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
350 IComposerClient::Attribute::VSYNC_PERIOD, _))
351 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
352 EXPECT_CALL(*test->mComposer,
353 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
354 IComposerClient::Attribute::DPI_X, _))
355 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
356 EXPECT_CALL(*test->mComposer,
357 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
358 IComposerClient::Attribute::DPI_Y, _))
359 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
360 }
361
362 // Called by tests to set up HWC call expectations
363 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
364 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
365 .WillOnce(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
366 }
367};
368
369struct NonHwcDisplayVariant {
370 static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
371
372 static void injectHwcDisplay(DisplayTransactionTest*) {}
373
374 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
375 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
376 }
377};
378
379// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
380constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
381 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
382
383template <hwc2_display_t hwcDisplayId, DisplayDevice::DisplayType type, int width, int height,
384 Critical critical>
385struct PhysicalDisplayVariant
386 : public DisplayVariant<type, type, width, height, critical, Async::FALSE, Secure::TRUE,
387 GRALLOC_USAGE_PHYSICAL_DISPLAY>,
388 public HwcDisplayVariant<hwcDisplayId, HWC2::DisplayType::Physical,
389 DisplayVariant<type, type, width, height, critical, Async::FALSE,
390 Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};
391
Lloyd Pique9d9cf402018-02-16 17:47:13 -0800392// An invalid display
393using InvalidDisplayVariant =
394 DisplayVariant<DisplayDevice::DISPLAY_ID_INVALID, DisplayDevice::DISPLAY_ID_INVALID, 0, 0,
395 Critical::FALSE, Async::FALSE, Secure::FALSE, 0>;
396
Lloyd Piquefc12f562018-01-22 18:44:59 -0800397// A primary display is a physical display that is critical
398using PrimaryDisplayVariant =
399 PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
400
401// An external display is physical display that is not critical.
402using ExternalDisplayVariant =
403 PhysicalDisplayVariant<1002, DisplayDevice::DISPLAY_EXTERNAL, 1920, 1280, Critical::FALSE>;
404
405using TertiaryDisplayVariant =
406 PhysicalDisplayVariant<1003, DisplayDevice::DISPLAY_EXTERNAL, 1600, 1200, Critical::FALSE>;
407
408// A virtual display not supported by the HWC.
409constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
410
411template <int width, int height, Secure secure>
412struct NonHwcVirtualDisplayVariant
413 : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
414 width, height, Critical::FALSE, Async::TRUE, secure,
415 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>,
416 public NonHwcDisplayVariant {
417 using Base = DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
418 width, height, Critical::FALSE, Async::TRUE, secure,
419 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
420
421 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
422 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
423 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
424 }
425};
426
427// A virtual display supported by the HWC.
428constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
429
430template <int width, int height, Secure secure>
431struct HwcVirtualDisplayVariant
432 : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
433 height, Critical::FALSE, Async::TRUE, secure,
434 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
435 public HwcDisplayVariant<1010, HWC2::DisplayType::Virtual,
436 NonHwcVirtualDisplayVariant<width, height, secure>> {
437 using Base =
438 DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
439 height, Critical::FALSE, Async::TRUE, secure, GRALLOC_USAGE_HW_COMPOSER>;
440 using Self = HwcVirtualDisplayVariant<width, height, secure>;
441
442 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
443 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
444 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
445 }
446
447 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
448 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
449 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
450 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
451 }
452};
453
454// For this variant, SurfaceFlinger should not configure itself with wide
455// display support, so the display should not be configured for wide-color
456// support.
457struct WideColorSupportNotConfiguredVariant {
458 static constexpr bool WIDE_COLOR_SUPPORTED = false;
459
460 static void injectConfigChange(DisplayTransactionTest* test) {
461 test->mFlinger.mutableHasWideColorDisplay() = false;
462 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
463 }
464
465 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
466 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
467 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
468 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
469 }
470};
471
472// For this variant, SurfaceFlinger should configure itself with wide display
473// support, and the display should respond with an non-empty list of supported
474// color modes. Wide-color support should be configured.
475template <typename Display>
476struct WideColorP3ColorimetricSupportedVariant {
477 static constexpr bool WIDE_COLOR_SUPPORTED = true;
478
479 static void injectConfigChange(DisplayTransactionTest* test) {
480 test->mFlinger.mutableHasWideColorDisplay() = true;
481 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
482 }
483
484 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
485 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
486 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
487 Return(Error::NONE)));
488 EXPECT_CALL(*test->mComposer,
489 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
490 .WillOnce(DoAll(SetArgPointee<2>(
491 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
492 Return(Error::NONE)));
493 EXPECT_CALL(*test->mComposer,
494 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
495 RenderIntent::COLORIMETRIC))
496 .WillOnce(Return(Error::NONE));
497 }
498};
499
Lloyd Piquefc12f562018-01-22 18:44:59 -0800500// For this variant, SurfaceFlinger should configure itself with wide display
501// support, but the display should respond with an empty list of supported color
502// modes. Wide-color support for the display should not be configured.
503template <typename Display>
504struct WideColorNotSupportedVariant {
505 static constexpr bool WIDE_COLOR_SUPPORTED = false;
506
507 static void injectConfigChange(DisplayTransactionTest* test) {
508 test->mFlinger.mutableHasWideColorDisplay() = true;
509 }
510
511 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
512 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
513 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
514 EXPECT_CALL(*test->mComposer,
515 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::NATIVE,
516 RenderIntent::COLORIMETRIC))
517 .WillOnce(Return(Error::NONE));
518 }
519};
520
521// For this variant, the display is not a HWC display, so no HDR support should
522// be configured.
523struct NonHwcDisplayHdrSupportVariant {
524 static constexpr bool HDR10_SUPPORTED = false;
525 static constexpr bool HDR_HLG_SUPPORTED = false;
526 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
527 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
528 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
529 }
530};
531
532// For this variant, the composer should respond with a non-empty list of HDR
533// modes containing HDR10, so HDR10 support should be configured.
534template <typename Display>
535struct Hdr10SupportedVariant {
536 static constexpr bool HDR10_SUPPORTED = true;
537 static constexpr bool HDR_HLG_SUPPORTED = false;
538 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
539 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
540 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
541 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
542 Return(Error::NONE)));
543 }
544};
545
546// For this variant, the composer should respond with a non-empty list of HDR
547// modes containing HLG, so HLG support should be configured.
548template <typename Display>
549struct HdrHlgSupportedVariant {
550 static constexpr bool HDR10_SUPPORTED = false;
551 static constexpr bool HDR_HLG_SUPPORTED = true;
552 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
553 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
554 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
555 .WillOnce(
556 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
557 }
558};
559
560// For this variant, the composer should respond with a non-empty list of HDR
561// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
562template <typename Display>
563struct HdrDolbyVisionSupportedVariant {
564 static constexpr bool HDR10_SUPPORTED = false;
565 static constexpr bool HDR_HLG_SUPPORTED = false;
566 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
567 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
568 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
569 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
570 Return(Error::NONE)));
571 }
572};
573
574// For this variant, the composer should respond with am empty list of HDR
575// modes, so no HDR support should be configured.
576template <typename Display>
577struct HdrNotSupportedVariant {
578 static constexpr bool HDR10_SUPPORTED = false;
579 static constexpr bool HDR_HLG_SUPPORTED = false;
580 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
581 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
582 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
583 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
584 }
585};
586
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700587struct NonHwcPerFrameMetadataSupportVariant {
588 static constexpr int PER_FRAME_METADATA_KEYS = 0;
589 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
590 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_, _)).Times(0);
591 }
592};
593
594template <typename Display>
595struct NoPerFrameMetadataSupportVariant {
596 static constexpr int PER_FRAME_METADATA_KEYS = 0;
597 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
598 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID, _))
599 .WillOnce(DoAll(SetArgPointee<1>(std::vector<PerFrameMetadataKey>()),
600 Return(Error::NONE)));
601 }
602};
603
604template <typename Display>
605struct Smpte2086PerFrameMetadataSupportVariant {
606 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::SMPTE2086;
607 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
608 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID, _))
609 .WillOnce(DoAll(SetArgPointee<1>(std::vector<PerFrameMetadataKey>({
610 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
611 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
612 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
613 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
614 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
615 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
616 PerFrameMetadataKey::WHITE_POINT_X,
617 PerFrameMetadataKey::WHITE_POINT_Y,
618 PerFrameMetadataKey::MAX_LUMINANCE,
619 PerFrameMetadataKey::MIN_LUMINANCE,
620 })),
621 Return(Error::NONE)));
622 }
623};
624
625template <typename Display>
626struct Cta861_3_PerFrameMetadataSupportVariant {
627 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::CTA861_3;
628 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
629 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID, _))
630 .WillOnce(DoAll(SetArgPointee<1>(std::vector<PerFrameMetadataKey>({
631 PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
632 PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
633 })),
634 Return(Error::NONE)));
635 }
636};
637
Lloyd Piquefc12f562018-01-22 18:44:59 -0800638/* ------------------------------------------------------------------------
639 * Typical display configurations to test
640 */
641
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700642template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
643 typename PerFrameMetadataSupportPolicy>
Lloyd Piquefc12f562018-01-22 18:44:59 -0800644struct Case {
645 using Display = DisplayPolicy;
646 using WideColorSupport = WideColorSupportPolicy;
647 using HdrSupport = HdrSupportPolicy;
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700648 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800649};
650
651using SimplePrimaryDisplayCase =
652 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700653 HdrNotSupportedVariant<PrimaryDisplayVariant>,
654 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800655using SimpleExternalDisplayCase =
656 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700657 HdrNotSupportedVariant<ExternalDisplayVariant>,
658 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800659using SimpleTertiaryDisplayCase =
660 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700661 HdrNotSupportedVariant<TertiaryDisplayVariant>,
662 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800663using NonHwcVirtualDisplayCase =
664 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700665 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
666 NonHwcPerFrameMetadataSupportVariant>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800667using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
668using HwcVirtualDisplayCase =
669 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700670 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
671 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800672using WideColorP3ColorimetricDisplayCase =
673 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700674 HdrNotSupportedVariant<PrimaryDisplayVariant>,
675 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800676using Hdr10DisplayCase =
677 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700678 Hdr10SupportedVariant<PrimaryDisplayVariant>,
679 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800680using HdrHlgDisplayCase =
681 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700682 HdrHlgSupportedVariant<PrimaryDisplayVariant>,
683 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800684using HdrDolbyVisionDisplayCase =
685 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700686 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>,
687 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
688using HdrSmpte2086DisplayCase =
689 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
690 HdrNotSupportedVariant<PrimaryDisplayVariant>,
691 Smpte2086PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
692using HdrCta861_3_DisplayCase =
693 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
694 HdrNotSupportedVariant<PrimaryDisplayVariant>,
695 Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Pique9d9cf402018-02-16 17:47:13 -0800696using InvalidDisplayCase = Case<InvalidDisplayVariant, WideColorSupportNotConfiguredVariant,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700697 NonHwcDisplayHdrSupportVariant,
698 NoPerFrameMetadataSupportVariant<InvalidDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800699/* ------------------------------------------------------------------------
Lloyd Pique6cf11032018-01-22 18:57:44 -0800700 *
701 * SurfaceFlinger::onHotplugReceived
702 */
703
704TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
705 constexpr int currentSequenceId = 123;
706 constexpr hwc2_display_t displayId1 = 456;
707 constexpr hwc2_display_t displayId2 = 654;
708
709 // --------------------------------------------------------------------
710 // Preconditions
711
712 // Set the current sequence id for accepted events
713 mFlinger.mutableComposerSequenceId() = currentSequenceId;
714
715 // Set the main thread id so that the current thread does not appear to be
716 // the main thread.
717 mFlinger.mutableMainThreadId() = std::thread::id();
718
719 // --------------------------------------------------------------------
720 // Call Expectations
721
722 // We expect invalidate() to be invoked once to trigger display transaction
723 // processing.
724 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
725
726 // --------------------------------------------------------------------
727 // Invocation
728
729 // Simulate two hotplug events (a connect and a disconnect)
730 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Connected);
731 mFlinger.onHotplugReceived(currentSequenceId, displayId2, HWC2::Connection::Disconnected);
732
733 // --------------------------------------------------------------------
734 // Postconditions
735
736 // The display transaction needed flag should be set.
737 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
738
739 // All events should be in the pending event queue.
740 const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
741 ASSERT_EQ(2u, pendingEvents.size());
742 EXPECT_EQ(displayId1, pendingEvents[0].display);
743 EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
744 EXPECT_EQ(displayId2, pendingEvents[1].display);
745 EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
746}
747
748TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
749 constexpr int currentSequenceId = 123;
750 constexpr int otherSequenceId = 321;
751 constexpr hwc2_display_t displayId = 456;
752
753 // --------------------------------------------------------------------
754 // Preconditions
755
756 // Set the current sequence id for accepted events
757 mFlinger.mutableComposerSequenceId() = currentSequenceId;
758
759 // Set the main thread id so that the current thread does not appear to be
760 // the main thread.
761 mFlinger.mutableMainThreadId() = std::thread::id();
762
763 // --------------------------------------------------------------------
764 // Call Expectations
765
766 // We do not expect any calls to invalidate().
767 EXPECT_CALL(*mMessageQueue, invalidate()).Times(0);
768
769 // --------------------------------------------------------------------
770 // Invocation
771
772 // Call with an unexpected sequence id
773 mFlinger.onHotplugReceived(otherSequenceId, displayId, HWC2::Connection::Invalid);
774
775 // --------------------------------------------------------------------
776 // Postconditions
777
778 // The display transaction needed flag should not be set
779 EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded));
780
781 // There should be no pending events
782 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
783}
784
785TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
786 constexpr int currentSequenceId = 123;
787 constexpr hwc2_display_t displayId1 = 456;
788
789 // --------------------------------------------------------------------
790 // Note:
791 // --------------------------------------------------------------------
792 // This test case is a bit tricky. We want to verify that
793 // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we
794 // don't really want to provide coverage for everything the later function
795 // does as there are specific tests for it.
796 // --------------------------------------------------------------------
797
798 // --------------------------------------------------------------------
799 // Preconditions
800
801 // Set the current sequence id for accepted events
802 mFlinger.mutableComposerSequenceId() = currentSequenceId;
803
804 // Set the main thread id so that the current thread does appear to be the
805 // main thread.
806 mFlinger.mutableMainThreadId() = std::this_thread::get_id();
807
808 // --------------------------------------------------------------------
809 // Call Expectations
810
811 // We expect invalidate() to be invoked once to trigger display transaction
812 // processing.
813 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
814
815 // --------------------------------------------------------------------
816 // Invocation
817
818 // Simulate a disconnect on a display id that is not connected. This should
819 // be enqueued by onHotplugReceived(), and dequeued by
820 // processDisplayHotplugEventsLocked(), but then ignored as invalid.
821 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Disconnected);
822
823 // --------------------------------------------------------------------
824 // Postconditions
825
826 // The display transaction needed flag should be set.
827 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
828
829 // There should be no event queued on return, as it should have been
830 // processed.
831 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
832}
833
834/* ------------------------------------------------------------------------
Lloyd Piquea482f992018-01-22 19:00:34 -0800835 * SurfaceFlinger::createDisplay
836 */
837
838TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
839 const String8 name("virtual.test");
840
841 // --------------------------------------------------------------------
842 // Call Expectations
843
844 // The call should notify the interceptor that a display was created.
845 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
846
847 // --------------------------------------------------------------------
848 // Invocation
849
850 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
851
852 // --------------------------------------------------------------------
853 // Postconditions
854
855 // The display should have been added to the current state
856 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
857 const auto& display = getCurrentDisplayState(displayToken);
858 EXPECT_EQ(DisplayDevice::DISPLAY_VIRTUAL, display.type);
859 EXPECT_EQ(false, display.isSecure);
860 EXPECT_EQ(name.string(), display.displayName);
861
862 // --------------------------------------------------------------------
863 // Cleanup conditions
864
865 // Destroying the display invalidates the display state.
866 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
867}
868
869TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForSecureDisplay) {
870 const String8 name("virtual.test");
871
872 // --------------------------------------------------------------------
873 // Call Expectations
874
875 // The call should notify the interceptor that a display was created.
876 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
877
878 // --------------------------------------------------------------------
879 // Invocation
880
881 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
882
883 // --------------------------------------------------------------------
884 // Postconditions
885
886 // The display should have been added to the current state
887 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
888 const auto& display = getCurrentDisplayState(displayToken);
889 EXPECT_EQ(DisplayDevice::DISPLAY_VIRTUAL, display.type);
890 EXPECT_EQ(true, display.isSecure);
891 EXPECT_EQ(name.string(), display.displayName);
892
893 // --------------------------------------------------------------------
894 // Cleanup conditions
895
896 // Destroying the display invalidates the display state.
897 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
898}
899
900/* ------------------------------------------------------------------------
901 * SurfaceFlinger::destroyDisplay
902 */
903
904TEST_F(DisplayTransactionTest, destroyDisplayClearsCurrentStateForDisplay) {
905 using Case = NonHwcVirtualDisplayCase;
906
907 // --------------------------------------------------------------------
908 // Preconditions
909
910 // A virtual display exists
911 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
912 existing.inject();
913
914 // --------------------------------------------------------------------
915 // Call Expectations
916
917 // The call should notify the interceptor that a display was created.
918 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
919
920 // Destroying the display invalidates the display state.
921 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
922
923 // --------------------------------------------------------------------
924 // Invocation
925
926 mFlinger.destroyDisplay(existing.token());
927
928 // --------------------------------------------------------------------
929 // Postconditions
930
931 // The display should have been removed from the current state
932 EXPECT_FALSE(hasCurrentDisplayState(existing.token()));
933
934 // Ths display should still exist in the drawing state
935 EXPECT_TRUE(hasDrawingDisplayState(existing.token()));
936
937 // The display transaction needed flasg should be set
938 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
939}
940
941TEST_F(DisplayTransactionTest, destroyDisplayHandlesUnknownDisplay) {
942 // --------------------------------------------------------------------
943 // Preconditions
944
945 sp<BBinder> displayToken = new BBinder();
946
947 // --------------------------------------------------------------------
948 // Invocation
949
950 mFlinger.destroyDisplay(displayToken);
951}
952
953/* ------------------------------------------------------------------------
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -0800954 * SurfaceFlinger::resetDisplayState
955 */
956
957TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
958 using Case = NonHwcVirtualDisplayCase;
959
960 // --------------------------------------------------------------------
961 // Preconditions
962
963 // vsync is enabled and available
964 mFlinger.mutablePrimaryHWVsyncEnabled() = true;
965 mFlinger.mutableHWVsyncAvailable() = true;
966
967 // A display exists
968 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
969 existing.inject();
970
971 // --------------------------------------------------------------------
972 // Call Expectations
973
974 // The call disable vsyncs
975 EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
976
977 // The call clears the current render engine surface
978 EXPECT_CALL(*mRenderEngine, resetCurrentSurface());
979
980 // --------------------------------------------------------------------
981 // Invocation
982
983 mFlinger.resetDisplayState();
984
985 // --------------------------------------------------------------------
986 // Postconditions
987
988 // vsyncs should be off and not available.
989 EXPECT_FALSE(mFlinger.mutablePrimaryHWVsyncEnabled());
990 EXPECT_FALSE(mFlinger.mutableHWVsyncAvailable());
991
992 // The display should have been removed from the display map.
993 EXPECT_FALSE(hasDisplayDevice(existing.token()));
994
995 // The display should still exist in the current state
996 EXPECT_TRUE(hasCurrentDisplayState(existing.token()));
997
998 // The display should have been removed from the drawing state
999 EXPECT_FALSE(hasDrawingDisplayState(existing.token()));
1000}
1001
1002/* ------------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -08001003 * SurfaceFlinger::setupNewDisplayDeviceInternal
1004 */
1005
1006class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
1007public:
1008 template <typename T>
1009 void setupNewDisplayDeviceInternalTest();
1010};
1011
1012template <typename Case>
1013void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
1014 const sp<BBinder> displayToken = new BBinder();
1015 const sp<mock::DisplaySurface> displaySurface = new mock::DisplaySurface();
1016 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001017
1018 // --------------------------------------------------------------------
1019 // Preconditions
1020
Lloyd Piquefc12f562018-01-22 18:44:59 -08001021 // Wide color displays support is configured appropriately
1022 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001023
Lloyd Piquefc12f562018-01-22 18:44:59 -08001024 // The display is setup with the HWC.
1025 Case::Display::injectHwcDisplay(this);
1026
1027 // SurfaceFlinger will use a test-controlled factory for native window
1028 // surfaces.
1029 injectFakeNativeWindowSurfaceFactory();
1030
1031 // --------------------------------------------------------------------
1032 // Call Expectations
1033
1034 // Various native window calls will be made.
1035 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1036
1037 // TODO(b/69807179): SurfaceFlinger does not correctly get the active config.
1038 // Case::Display::setupHwcGetActiveConfigCallExpectations(this)
1039
1040 Case::WideColorSupport::setupComposerCallExpectations(this);
1041 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001042 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquefc12f562018-01-22 18:44:59 -08001043
1044 // --------------------------------------------------------------------
1045 // Invocation
1046
1047 auto state = DisplayDeviceState(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
1048 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, Case::Display::TYPE, state,
1049 displaySurface, producer);
1050
1051 // --------------------------------------------------------------------
1052 // Postconditions
1053
1054 ASSERT_TRUE(device != nullptr);
1055 EXPECT_EQ(Case::Display::TYPE, device->getDisplayType());
1056 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
1057 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
1058 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
1059 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
1060 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
1061 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
1062 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
1063 EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveConfig());
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001064 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
1065 device->getSupportedPerFrameMetadata());
Lloyd Piquefc12f562018-01-22 18:44:59 -08001066}
1067
1068TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
1069 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
1070}
1071
1072TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
1073 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
1074}
1075
1076TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1077 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1078}
1079
1080TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
1081 // We need to resize this so that the HWC thinks the virtual display
1082 // is something it created.
1083 mFlinger.mutableHwcDisplayData().resize(3);
1084
1085 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
1086}
1087
1088TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1089 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1090}
1091
Lloyd Piquefc12f562018-01-22 18:44:59 -08001092TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1093 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1094}
1095
1096TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1097 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1098}
1099
1100TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1101 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1102}
1103
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001104TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
1105 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
1106}
1107
1108TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
1109 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
1110}
1111
Lloyd Piquefc12f562018-01-22 18:44:59 -08001112/* ------------------------------------------------------------------------
1113 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1114 */
1115
1116class HandleTransactionLockedTest : public DisplayTransactionTest {
1117public:
1118 template <typename Case>
1119 void setupCommonPreconditions();
1120
1121 template <typename Case>
1122 void setupCommonCallExpectationsForConnectProcessing();
1123
1124 template <typename Case>
1125 void setupCommonCallExpectationsForDisconnectProcessing();
1126
1127 template <typename Case>
1128 void processesHotplugConnectCommon();
1129
1130 template <typename Case>
1131 void ignoresHotplugConnectCommon();
1132
1133 template <typename Case>
1134 void processesHotplugDisconnectCommon();
1135
1136 template <typename Case>
1137 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1138
1139 template <typename Case>
1140 void verifyPhysicalDisplayIsConnected();
1141
1142 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1143};
1144
1145template <typename Case>
1146void HandleTransactionLockedTest::setupCommonPreconditions() {
1147 // Wide color displays support is configured appropriately
1148 Case::WideColorSupport::injectConfigChange(this);
1149
1150 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1151 injectFakeBufferQueueFactory();
1152
1153 // SurfaceFlinger will use a test-controlled factory for native window
1154 // surfaces.
1155 injectFakeNativeWindowSurfaceFactory();
1156}
1157
1158template <typename Case>
1159void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1160 Case::Display::setupHwcHotplugCallExpectations(this);
1161
1162 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1163 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1164 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1165 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1166
1167 Case::WideColorSupport::setupComposerCallExpectations(this);
1168 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001169 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquefc12f562018-01-22 18:44:59 -08001170
1171 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1172 EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, true)).Times(1);
1173}
1174
1175template <typename Case>
1176void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1177 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
1178 EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, false)).Times(1);
1179}
1180
1181template <typename Case>
1182void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1183 // The display device should have been set up in the list of displays.
1184 ASSERT_TRUE(hasDisplayDevice(displayToken));
1185 const auto& device = getDisplayDevice(displayToken);
1186 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
1187 EXPECT_EQ(Case::Display::TYPE == DisplayDevice::DISPLAY_PRIMARY, device->isPrimary());
1188
1189 // The display should have been set up in the current display state
1190 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1191 const auto& current = getCurrentDisplayState(displayToken);
1192 EXPECT_EQ(Case::Display::TYPE, current.type);
1193
1194 // The display should have been set up in the drawing display state
1195 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1196 const auto& draw = getDrawingDisplayState(displayToken);
1197 EXPECT_EQ(Case::Display::TYPE, draw.type);
1198}
1199
1200template <typename Case>
1201void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1202 // HWComposer should have an entry for the display
1203 EXPECT_TRUE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1204
1205 // The display should be set up as a built-in display.
1206 static_assert(0 <= Case::Display::TYPE &&
1207 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
1208 "Must use a valid physical display type index for the fixed-size array");
1209 auto& displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1210 ASSERT_TRUE(displayToken != nullptr);
1211
1212 verifyDisplayIsConnected<Case>(displayToken);
1213}
1214
1215void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
1216 EXPECT_FALSE(hasDisplayDevice(displayToken));
1217 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
1218 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
1219}
1220
1221template <typename Case>
1222void HandleTransactionLockedTest::processesHotplugConnectCommon() {
1223 // --------------------------------------------------------------------
1224 // Preconditions
1225
1226 setupCommonPreconditions<Case>();
1227
1228 // A hotplug connect event is enqueued for a display
1229 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001230
1231 // --------------------------------------------------------------------
1232 // Call Expectations
1233
1234 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001235
Lloyd Piquefc12f562018-01-22 18:44:59 -08001236 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001237
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001238 // --------------------------------------------------------------------
1239 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08001240
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001241 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08001242
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001243 // --------------------------------------------------------------------
1244 // Postconditions
1245
Lloyd Piquefc12f562018-01-22 18:44:59 -08001246 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001247
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001248 // --------------------------------------------------------------------
1249 // Cleanup conditions
1250
Lloyd Piquefc12f562018-01-22 18:44:59 -08001251 EXPECT_CALL(*mComposer,
1252 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001253 .WillOnce(Return(Error::NONE));
1254 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08001255}
1256
Lloyd Piquefc12f562018-01-22 18:44:59 -08001257template <typename Case>
1258void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
1259 // --------------------------------------------------------------------
1260 // Preconditions
1261
1262 setupCommonPreconditions<Case>();
1263
1264 // A hotplug connect event is enqueued for a display
1265 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1266
1267 // --------------------------------------------------------------------
1268 // Invocation
1269
1270 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1271
1272 // --------------------------------------------------------------------
1273 // Postconditions
1274
1275 // HWComposer should not have an entry for the display
1276 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1277}
1278
1279template <typename Case>
1280void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
1281 // --------------------------------------------------------------------
1282 // Preconditions
1283
1284 setupCommonPreconditions<Case>();
1285
1286 // A hotplug disconnect event is enqueued for a display
1287 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1288
1289 // The display is already completely set up.
1290 Case::Display::injectHwcDisplay(this);
1291 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1292 existing.inject();
1293
1294 // --------------------------------------------------------------------
1295 // Call Expectations
1296
1297 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1298
1299 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1300
1301 // --------------------------------------------------------------------
1302 // Invocation
1303
1304 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1305
1306 // --------------------------------------------------------------------
1307 // Postconditions
1308
1309 // HWComposer should not have an entry for the display
1310 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1311
1312 // The display should not be set up as a built-in display.
1313 ASSERT_TRUE(0 <= Case::Display::TYPE &&
1314 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
1315 auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1316 EXPECT_TRUE(displayToken == nullptr);
1317
1318 // The existing token should have been removed
1319 verifyDisplayIsNotConnected(existing.token());
1320}
1321
1322TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
1323 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1324}
1325
1326TEST_F(HandleTransactionLockedTest,
1327 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
1328 // Inject an external display.
1329 ExternalDisplayVariant::injectHwcDisplay(this);
1330
1331 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1332}
1333
1334TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
1335 // Inject a primary display.
1336 PrimaryDisplayVariant::injectHwcDisplay(this);
1337
1338 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
1339}
1340
1341TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
1342 // Inject both a primary and external display.
1343 PrimaryDisplayVariant::injectHwcDisplay(this);
1344 ExternalDisplayVariant::injectHwcDisplay(this);
1345
1346 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1347
1348 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
1349}
1350
1351TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
1352 // Inject a primary display.
1353 PrimaryDisplayVariant::injectHwcDisplay(this);
1354
1355 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
1356
1357 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
1358}
1359
1360TEST_F(HandleTransactionLockedTest, processHotplugDisconnectPrimaryDisplay) {
1361 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
1362}
1363
1364TEST_F(HandleTransactionLockedTest, processHotplugDisconnectExternalDisplay) {
1365 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
1366}
1367
1368TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
1369 using Case = SimplePrimaryDisplayCase;
1370
1371 // --------------------------------------------------------------------
1372 // Preconditions
1373
1374 setupCommonPreconditions<Case>();
1375
1376 // A hotplug connect event is enqueued for a display
1377 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1378 // A hotplug disconnect event is also enqueued for the same display
1379 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1380
1381 // --------------------------------------------------------------------
1382 // Call Expectations
1383
1384 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1385
1386 setupCommonCallExpectationsForConnectProcessing<Case>();
1387 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1388
1389 EXPECT_CALL(*mComposer,
1390 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1391 .WillOnce(Return(Error::NONE));
1392 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1393
1394 // --------------------------------------------------------------------
1395 // Invocation
1396
1397 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1398
1399 // --------------------------------------------------------------------
1400 // Postconditions
1401
1402 // HWComposer should not have an entry for the display
1403 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1404
1405 // The display should not be set up as a primary built-in display.
1406 ASSERT_TRUE(0 <= Case::Display::TYPE &&
1407 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
1408 auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1409 EXPECT_TRUE(displayToken == nullptr);
1410}
1411
1412TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
1413 using Case = SimplePrimaryDisplayCase;
1414
1415 // --------------------------------------------------------------------
1416 // Preconditions
1417
1418 setupCommonPreconditions<Case>();
1419
1420 // The display is already completely set up.
1421 Case::Display::injectHwcDisplay(this);
1422 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1423 existing.inject();
1424
1425 // A hotplug disconnect event is enqueued for a display
1426 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1427 // A hotplug connect event is also enqueued for the same display
1428 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1429
1430 // --------------------------------------------------------------------
1431 // Call Expectations
1432
1433 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1434
1435 setupCommonCallExpectationsForConnectProcessing<Case>();
1436 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1437
1438 // --------------------------------------------------------------------
1439 // Invocation
1440
1441 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1442
1443 // --------------------------------------------------------------------
1444 // Postconditions
1445
1446 // The existing token should have been removed
1447 verifyDisplayIsNotConnected(existing.token());
1448 static_assert(0 <= Case::Display::TYPE &&
1449 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
1450 "Display type must be a built-in display");
1451 EXPECT_NE(existing.token(), mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE]);
1452
1453 // A new display should be connected in its place
1454
1455 verifyPhysicalDisplayIsConnected<Case>();
1456
1457 // --------------------------------------------------------------------
1458 // Cleanup conditions
1459
1460 EXPECT_CALL(*mComposer,
1461 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1462 .WillOnce(Return(Error::NONE));
1463 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1464}
1465
1466TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
1467 using Case = HwcVirtualDisplayCase;
1468
1469 // --------------------------------------------------------------------
1470 // Preconditions
1471
1472 // The HWC supports at least one virtual display
1473 injectMockComposer(1);
1474
1475 setupCommonPreconditions<Case>();
1476
1477 // A virtual display was added to the current state, and it has a
1478 // surface(producer)
1479 sp<BBinder> displayToken = new BBinder();
1480 DisplayDeviceState info(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
1481 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
1482 info.surface = surface;
1483 mFlinger.mutableCurrentState().displays.add(displayToken, info);
1484
1485 // --------------------------------------------------------------------
1486 // Call Expectations
1487
1488 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1489 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1490
1491 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
1492 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
1493 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
1494 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
1495 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
1496 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
1497 Return(NO_ERROR)));
1498 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
1499 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
1500
1501 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
1502
1503 EXPECT_CALL(*mProducer, connect(_, _, _, _)).Times(1);
1504 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
1505
1506 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
1507 Case::WideColorSupport::setupComposerCallExpectations(this);
1508 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001509 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquefc12f562018-01-22 18:44:59 -08001510
1511 // --------------------------------------------------------------------
1512 // Invocation
1513
1514 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1515
1516 // --------------------------------------------------------------------
1517 // Postconditions
1518
1519 // The display device should have been set up in the list of displays.
1520 verifyDisplayIsConnected<Case>(displayToken);
1521
1522 // --------------------------------------------------------------------
1523 // Cleanup conditions
1524
1525 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
1526 .WillOnce(Return(Error::NONE));
1527 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1528}
1529
1530TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
1531 using Case = HwcVirtualDisplayCase;
1532
1533 // --------------------------------------------------------------------
1534 // Preconditions
1535
1536 // The HWC supports at least one virtual display
1537 injectMockComposer(1);
1538
1539 setupCommonPreconditions<Case>();
1540
1541 // A virtual display was added to the current state, but it does not have a
1542 // surface.
1543 sp<BBinder> displayToken = new BBinder();
1544 DisplayDeviceState info(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
1545 mFlinger.mutableCurrentState().displays.add(displayToken, info);
1546
1547 // --------------------------------------------------------------------
1548 // Call Expectations
1549
1550 // --------------------------------------------------------------------
1551 // Invocation
1552
1553 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1554
1555 // --------------------------------------------------------------------
1556 // Postconditions
1557
1558 // There will not be a display device set up.
1559 EXPECT_FALSE(hasDisplayDevice(displayToken));
1560
1561 // The drawing display state will be set from the current display state.
1562 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1563 const auto& draw = getDrawingDisplayState(displayToken);
1564 EXPECT_EQ(Case::Display::TYPE, draw.type);
1565}
1566
1567TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
1568 using Case = HwcVirtualDisplayCase;
1569
1570 // --------------------------------------------------------------------
1571 // Preconditions
1572
1573 // A virtual display is set up but is removed from the current state.
1574 mFlinger.mutableHwcDisplayData().resize(3);
1575 Case::Display::injectHwcDisplay(this);
1576 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1577 existing.inject();
1578 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
1579
1580 // --------------------------------------------------------------------
1581 // Call Expectations
1582
1583 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1584
1585 // --------------------------------------------------------------------
1586 // Invocation
1587
1588 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1589
1590 // --------------------------------------------------------------------
1591 // Postconditions
1592
1593 // The existing token should have been removed
1594 verifyDisplayIsNotConnected(existing.token());
1595}
1596
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001597TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
1598 using Case = NonHwcVirtualDisplayCase;
1599
1600 constexpr uint32_t oldLayerStack = 0u;
1601 constexpr uint32_t newLayerStack = 123u;
1602
1603 // --------------------------------------------------------------------
1604 // Preconditions
1605
1606 // A display is set up
1607 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1608 display.inject();
1609
1610 // There is a change to the layerStack state
1611 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
1612 display.mutableCurrentDisplayState().layerStack = newLayerStack;
1613
1614 // --------------------------------------------------------------------
1615 // Invocation
1616
1617 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1618
1619 // --------------------------------------------------------------------
1620 // Postconditions
1621
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001622 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001623}
1624
1625TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
1626 using Case = NonHwcVirtualDisplayCase;
1627
1628 constexpr int oldTransform = 0;
1629 constexpr int newTransform = 2;
1630
1631 // --------------------------------------------------------------------
1632 // Preconditions
1633
1634 // A display is set up
1635 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1636 display.inject();
1637
1638 // There is a change to the orientation state
1639 display.mutableDrawingDisplayState().orientation = oldTransform;
1640 display.mutableCurrentDisplayState().orientation = newTransform;
1641
1642 // --------------------------------------------------------------------
1643 // Invocation
1644
1645 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1646
1647 // --------------------------------------------------------------------
1648 // Postconditions
1649
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001650 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001651}
1652
1653TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
1654 using Case = NonHwcVirtualDisplayCase;
1655
1656 const Rect oldViewport(0, 0, 0, 0);
1657 const Rect newViewport(0, 0, 123, 456);
1658
1659 // --------------------------------------------------------------------
1660 // Preconditions
1661
1662 // A display is set up
1663 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1664 display.inject();
1665
1666 // There is a change to the viewport state
1667 display.mutableDrawingDisplayState().viewport = oldViewport;
1668 display.mutableCurrentDisplayState().viewport = newViewport;
1669
1670 // --------------------------------------------------------------------
1671 // Invocation
1672
1673 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1674
1675 // --------------------------------------------------------------------
1676 // Postconditions
1677
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001678 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001679}
1680
1681TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
1682 using Case = NonHwcVirtualDisplayCase;
1683
1684 const Rect oldFrame(0, 0, 0, 0);
1685 const Rect newFrame(0, 0, 123, 456);
1686
1687 // --------------------------------------------------------------------
1688 // Preconditions
1689
1690 // A display is set up
1691 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1692 display.inject();
1693
1694 // There is a change to the viewport state
1695 display.mutableDrawingDisplayState().frame = oldFrame;
1696 display.mutableCurrentDisplayState().frame = newFrame;
1697
1698 // --------------------------------------------------------------------
1699 // Invocation
1700
1701 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1702
1703 // --------------------------------------------------------------------
1704 // Postconditions
1705
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001706 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001707}
1708
1709TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
1710 using Case = NonHwcVirtualDisplayCase;
1711
1712 constexpr int oldWidth = 0;
1713 constexpr int oldHeight = 10;
1714 constexpr int newWidth = 123;
1715
1716 // --------------------------------------------------------------------
1717 // Preconditions
1718
1719 // A display is set up
1720 auto nativeWindow = new mock::NativeWindow();
1721 auto displaySurface = new mock::DisplaySurface();
1722 auto renderSurface = new RE::mock::Surface();
1723 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1724 display.setNativeWindow(nativeWindow);
1725 display.setDisplaySurface(displaySurface);
1726 display.setRenderSurface(std::unique_ptr<RE::Surface>(renderSurface));
1727 display.inject();
1728
1729 // There is a change to the viewport state
1730 display.mutableDrawingDisplayState().width = oldWidth;
1731 display.mutableDrawingDisplayState().height = oldHeight;
1732 display.mutableCurrentDisplayState().width = newWidth;
1733 display.mutableCurrentDisplayState().height = oldHeight;
1734
1735 // --------------------------------------------------------------------
1736 // Call Expectations
1737
1738 EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
1739 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
1740 EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
1741 EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(newWidth));
1742 EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(oldHeight));
1743
1744 // --------------------------------------------------------------------
1745 // Invocation
1746
1747 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1748}
1749
1750TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
1751 using Case = NonHwcVirtualDisplayCase;
1752
1753 constexpr int oldWidth = 0;
1754 constexpr int oldHeight = 10;
1755 constexpr int newHeight = 123;
1756
1757 // --------------------------------------------------------------------
1758 // Preconditions
1759
1760 // A display is set up
1761 auto nativeWindow = new mock::NativeWindow();
1762 auto displaySurface = new mock::DisplaySurface();
1763 auto renderSurface = new RE::mock::Surface();
1764 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1765 display.setNativeWindow(nativeWindow);
1766 display.setDisplaySurface(displaySurface);
1767 display.setRenderSurface(std::unique_ptr<RE::Surface>(renderSurface));
1768 display.inject();
1769
1770 // There is a change to the viewport state
1771 display.mutableDrawingDisplayState().width = oldWidth;
1772 display.mutableDrawingDisplayState().height = oldHeight;
1773 display.mutableCurrentDisplayState().width = oldWidth;
1774 display.mutableCurrentDisplayState().height = newHeight;
1775
1776 // --------------------------------------------------------------------
1777 // Call Expectations
1778
1779 EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
1780 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
1781 EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
1782 EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(oldWidth));
1783 EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(newHeight));
1784
1785 // --------------------------------------------------------------------
1786 // Invocation
1787
1788 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1789}
1790
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001791/* ------------------------------------------------------------------------
1792 * SurfaceFlinger::setDisplayStateLocked
1793 */
1794
1795TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
1796 // --------------------------------------------------------------------
1797 // Preconditions
1798
1799 // We have an unknown display token not associated with a known display
1800 sp<BBinder> displayToken = new BBinder();
1801
1802 // The requested display state references the unknown display.
1803 DisplayState state;
1804 state.what = DisplayState::eLayerStackChanged;
1805 state.token = displayToken;
1806 state.layerStack = 456;
1807
1808 // --------------------------------------------------------------------
1809 // Invocation
1810
1811 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1812
1813 // --------------------------------------------------------------------
1814 // Postconditions
1815
1816 // The returned flags are empty
1817 EXPECT_EQ(0u, flags);
1818
1819 // The display token still doesn't match anything known.
1820 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
1821}
1822
1823TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithInvalidDisplay) {
1824 using Case = InvalidDisplayCase;
1825
1826 // --------------------------------------------------------------------
1827 // Preconditions
1828
1829 // An invalid display is set up
1830 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1831 display.inject();
1832
1833 // The invalid display has some state
1834 display.mutableCurrentDisplayState().layerStack = 654u;
1835
1836 // The requested display state tries to change the display state.
1837 DisplayState state;
1838 state.what = DisplayState::eLayerStackChanged;
1839 state.token = display.token();
1840 state.layerStack = 456;
1841
1842 // --------------------------------------------------------------------
1843 // Invocation
1844
1845 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1846
1847 // --------------------------------------------------------------------
1848 // Postconditions
1849
1850 // The returned flags are empty
1851 EXPECT_EQ(0u, flags);
1852
1853 // The current display layer stack value is unchanged.
1854 EXPECT_EQ(654u, getCurrentDisplayState(display.token()).layerStack);
1855}
1856
1857TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
1858 using Case = SimplePrimaryDisplayCase;
1859
1860 // --------------------------------------------------------------------
1861 // Preconditions
1862
1863 // A display is already set up
1864 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1865 display.inject();
1866
1867 // No changes are made to the display
1868 DisplayState state;
1869 state.what = 0;
1870 state.token = display.token();
1871
1872 // --------------------------------------------------------------------
1873 // Invocation
1874
1875 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1876
1877 // --------------------------------------------------------------------
1878 // Postconditions
1879
1880 // The returned flags are empty
1881 EXPECT_EQ(0u, flags);
1882}
1883
1884TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
1885 using Case = SimplePrimaryDisplayCase;
1886
1887 // --------------------------------------------------------------------
1888 // Preconditions
1889
1890 // A display is already set up
1891 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1892 display.inject();
1893
1894 // There is a surface that can be set.
1895 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
1896
1897 // The current display state has the surface set
1898 display.mutableCurrentDisplayState().surface = surface;
1899
1900 // The incoming request sets the same surface
1901 DisplayState state;
1902 state.what = DisplayState::eSurfaceChanged;
1903 state.token = display.token();
1904 state.surface = surface;
1905
1906 // --------------------------------------------------------------------
1907 // Invocation
1908
1909 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1910
1911 // --------------------------------------------------------------------
1912 // Postconditions
1913
1914 // The returned flags are empty
1915 EXPECT_EQ(0u, flags);
1916
1917 // The current display state is unchanged.
1918 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
1919}
1920
1921TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
1922 using Case = SimplePrimaryDisplayCase;
1923
1924 // --------------------------------------------------------------------
1925 // Preconditions
1926
1927 // A display is already set up
1928 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1929 display.inject();
1930
1931 // There is a surface that can be set.
1932 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
1933
1934 // The current display state does not have a surface
1935 display.mutableCurrentDisplayState().surface = nullptr;
1936
1937 // The incoming request sets a surface
1938 DisplayState state;
1939 state.what = DisplayState::eSurfaceChanged;
1940 state.token = display.token();
1941 state.surface = surface;
1942
1943 // --------------------------------------------------------------------
1944 // Invocation
1945
1946 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1947
1948 // --------------------------------------------------------------------
1949 // Postconditions
1950
1951 // The returned flags indicate a transaction is needed
1952 EXPECT_EQ(eDisplayTransactionNeeded, flags);
1953
1954 // The current display layer stack state is set to the new value
1955 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
1956}
1957
1958TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
1959 using Case = SimplePrimaryDisplayCase;
1960
1961 // --------------------------------------------------------------------
1962 // Preconditions
1963
1964 // A display is already set up
1965 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1966 display.inject();
1967
1968 // The display has a layer stack set
1969 display.mutableCurrentDisplayState().layerStack = 456u;
1970
1971 // The incoming request sets the same layer stack
1972 DisplayState state;
1973 state.what = DisplayState::eLayerStackChanged;
1974 state.token = display.token();
1975 state.layerStack = 456u;
1976
1977 // --------------------------------------------------------------------
1978 // Invocation
1979
1980 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1981
1982 // --------------------------------------------------------------------
1983 // Postconditions
1984
1985 // The returned flags are empty
1986 EXPECT_EQ(0u, flags);
1987
1988 // The current display state is unchanged
1989 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
1990}
1991
1992TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
1993 using Case = SimplePrimaryDisplayCase;
1994
1995 // --------------------------------------------------------------------
1996 // Preconditions
1997
1998 // A display is set up
1999 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2000 display.inject();
2001
2002 // The display has a layer stack set
2003 display.mutableCurrentDisplayState().layerStack = 654u;
2004
2005 // The incoming request sets a different layer stack
2006 DisplayState state;
2007 state.what = DisplayState::eLayerStackChanged;
2008 state.token = display.token();
2009 state.layerStack = 456u;
2010
2011 // --------------------------------------------------------------------
2012 // Invocation
2013
2014 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2015
2016 // --------------------------------------------------------------------
2017 // Postconditions
2018
2019 // The returned flags indicate a transaction is needed
2020 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2021
2022 // The desired display state has been set to the new value.
2023 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2024}
2025
2026TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
2027 using Case = SimplePrimaryDisplayCase;
2028 constexpr int initialOrientation = 180;
2029 const Rect initialFrame = {1, 2, 3, 4};
2030 const Rect initialViewport = {5, 6, 7, 8};
2031
2032 // --------------------------------------------------------------------
2033 // Preconditions
2034
2035 // A display is set up
2036 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2037 display.inject();
2038
2039 // The current display state projection state is all set
2040 display.mutableCurrentDisplayState().orientation = initialOrientation;
2041 display.mutableCurrentDisplayState().frame = initialFrame;
2042 display.mutableCurrentDisplayState().viewport = initialViewport;
2043
2044 // The incoming request sets the same projection state
2045 DisplayState state;
2046 state.what = DisplayState::eDisplayProjectionChanged;
2047 state.token = display.token();
2048 state.orientation = initialOrientation;
2049 state.frame = initialFrame;
2050 state.viewport = initialViewport;
2051
2052 // --------------------------------------------------------------------
2053 // Invocation
2054
2055 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2056
2057 // --------------------------------------------------------------------
2058 // Postconditions
2059
2060 // The returned flags are empty
2061 EXPECT_EQ(0u, flags);
2062
2063 // The current display state is unchanged
2064 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
2065
2066 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
2067 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
2068}
2069
2070TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
2071 using Case = SimplePrimaryDisplayCase;
2072 constexpr int initialOrientation = 90;
2073 constexpr int desiredOrientation = 180;
2074
2075 // --------------------------------------------------------------------
2076 // Preconditions
2077
2078 // A display is set up
2079 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2080 display.inject();
2081
2082 // The current display state has an orientation set
2083 display.mutableCurrentDisplayState().orientation = initialOrientation;
2084
2085 // The incoming request sets a different orientation
2086 DisplayState state;
2087 state.what = DisplayState::eDisplayProjectionChanged;
2088 state.token = display.token();
2089 state.orientation = desiredOrientation;
2090
2091 // --------------------------------------------------------------------
2092 // Invocation
2093
2094 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2095
2096 // --------------------------------------------------------------------
2097 // Postconditions
2098
2099 // The returned flags indicate a transaction is needed
2100 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2101
2102 // The current display state has the new value.
2103 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2104}
2105
2106TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2107 using Case = SimplePrimaryDisplayCase;
2108 const Rect initialFrame = {0, 0, 0, 0};
2109 const Rect desiredFrame = {5, 6, 7, 8};
2110
2111 // --------------------------------------------------------------------
2112 // Preconditions
2113
2114 // A display is set up
2115 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2116 display.inject();
2117
2118 // The current display state does not have a frame
2119 display.mutableCurrentDisplayState().frame = initialFrame;
2120
2121 // The incoming request sets a frame
2122 DisplayState state;
2123 state.what = DisplayState::eDisplayProjectionChanged;
2124 state.token = display.token();
2125 state.frame = desiredFrame;
2126
2127 // --------------------------------------------------------------------
2128 // Invocation
2129
2130 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2131
2132 // --------------------------------------------------------------------
2133 // Postconditions
2134
2135 // The returned flags indicate a transaction is needed
2136 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2137
2138 // The current display state has the new value.
2139 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2140}
2141
2142TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2143 using Case = SimplePrimaryDisplayCase;
2144 const Rect initialViewport = {0, 0, 0, 0};
2145 const Rect desiredViewport = {5, 6, 7, 8};
2146
2147 // --------------------------------------------------------------------
2148 // Preconditions
2149
2150 // A display is set up
2151 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2152 display.inject();
2153
2154 // The current display state does not have a viewport
2155 display.mutableCurrentDisplayState().viewport = initialViewport;
2156
2157 // The incoming request sets a viewport
2158 DisplayState state;
2159 state.what = DisplayState::eDisplayProjectionChanged;
2160 state.token = display.token();
2161 state.viewport = desiredViewport;
2162
2163 // --------------------------------------------------------------------
2164 // Invocation
2165
2166 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2167
2168 // --------------------------------------------------------------------
2169 // Postconditions
2170
2171 // The returned flags indicate a transaction is needed
2172 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2173
2174 // The current display state has the new value.
2175 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2176}
2177
2178TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2179 using Case = SimplePrimaryDisplayCase;
2180 constexpr uint32_t initialWidth = 1024;
2181 constexpr uint32_t initialHeight = 768;
2182
2183 // --------------------------------------------------------------------
2184 // Preconditions
2185
2186 // A display is set up
2187 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2188 display.inject();
2189
2190 // The current display state has a size set
2191 display.mutableCurrentDisplayState().width = initialWidth;
2192 display.mutableCurrentDisplayState().height = initialHeight;
2193
2194 // The incoming request sets the same display size
2195 DisplayState state;
2196 state.what = DisplayState::eDisplaySizeChanged;
2197 state.token = display.token();
2198 state.width = initialWidth;
2199 state.height = initialHeight;
2200
2201 // --------------------------------------------------------------------
2202 // Invocation
2203
2204 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2205
2206 // --------------------------------------------------------------------
2207 // Postconditions
2208
2209 // The returned flags are empty
2210 EXPECT_EQ(0u, flags);
2211
2212 // The current display state is unchanged
2213 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2214 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2215}
2216
2217TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
2218 using Case = SimplePrimaryDisplayCase;
2219 constexpr uint32_t initialWidth = 0;
2220 constexpr uint32_t desiredWidth = 1024;
2221
2222 // --------------------------------------------------------------------
2223 // Preconditions
2224
2225 // A display is set up
2226 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2227 display.inject();
2228
2229 // The display does not yet have a width
2230 display.mutableCurrentDisplayState().width = initialWidth;
2231
2232 // The incoming request sets a display width
2233 DisplayState state;
2234 state.what = DisplayState::eDisplaySizeChanged;
2235 state.token = display.token();
2236 state.width = desiredWidth;
2237
2238 // --------------------------------------------------------------------
2239 // Invocation
2240
2241 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2242
2243 // --------------------------------------------------------------------
2244 // Postconditions
2245
2246 // The returned flags indicate a transaction is needed
2247 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2248
2249 // The current display state has the new value.
2250 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
2251}
2252
2253TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
2254 using Case = SimplePrimaryDisplayCase;
2255 constexpr uint32_t initialHeight = 0;
2256 constexpr uint32_t desiredHeight = 768;
2257
2258 // --------------------------------------------------------------------
2259 // Preconditions
2260
2261 // A display is set up
2262 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2263 display.inject();
2264
2265 // The display does not yet have a height
2266 display.mutableCurrentDisplayState().height = initialHeight;
2267
2268 // The incoming request sets a display height
2269 DisplayState state;
2270 state.what = DisplayState::eDisplaySizeChanged;
2271 state.token = display.token();
2272 state.height = desiredHeight;
2273
2274 // --------------------------------------------------------------------
2275 // Invocation
2276
2277 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2278
2279 // --------------------------------------------------------------------
2280 // Postconditions
2281
2282 // The returned flags indicate a transaction is needed
2283 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2284
2285 // The current display state has the new value.
2286 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
2287}
2288
Lloyd Pique86016da2018-03-01 16:09:38 -08002289/* ------------------------------------------------------------------------
2290 * SurfaceFlinger::onInitializeDisplays
2291 */
2292
2293TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
2294 using Case = SimplePrimaryDisplayCase;
2295
2296 // --------------------------------------------------------------------
2297 // Preconditions
2298
2299 // A primary display is set up
2300 Case::Display::injectHwcDisplay(this);
2301 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
2302 primaryDisplay.inject();
2303
2304 // --------------------------------------------------------------------
2305 // Call Expectations
2306
2307 // We expect the surface interceptor to possibly be used, but we treat it as
2308 // disabled since it is called as a side effect rather than directly by this
2309 // function.
2310 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
2311
2312 // We expect a call to get the active display config.
2313 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
2314
2315 // We expect invalidate() to be invoked once to trigger display transaction
2316 // processing.
2317 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
2318
2319 // --------------------------------------------------------------------
2320 // Invocation
2321
2322 mFlinger.onInitializeDisplays();
2323
2324 // --------------------------------------------------------------------
2325 // Postconditions
2326
2327 // The primary display should have a current state
2328 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
2329 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
2330 // The layer stack state should be set to zero
2331 EXPECT_EQ(0u, primaryDisplayState.layerStack);
2332 // The orientation state should be set to zero
2333 EXPECT_EQ(0, primaryDisplayState.orientation);
2334
2335 // The frame state should be set to INVALID
2336 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
2337
2338 // The viewport state should be set to INVALID
2339 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
2340
2341 // The width and height should both be zero
2342 EXPECT_EQ(0u, primaryDisplayState.width);
2343 EXPECT_EQ(0u, primaryDisplayState.height);
2344
2345 // The display should be set to HWC_POWER_MODE_NORMAL
2346 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
2347 auto displayDevice = primaryDisplay.mutableDisplayDevice();
2348 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
2349
2350 // The display refresh period should be set in the frame tracker.
2351 FrameStats stats;
2352 mFlinger.getAnimFrameTracker().getStats(&stats);
2353 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
2354
2355 // The display transaction needed flag should be set.
2356 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
2357
2358 // The compositor timing should be set to default values
2359 const auto& compositorTiming = mFlinger.getCompositorTiming();
2360 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
2361 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
2362 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
2363}
2364
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002365/* ------------------------------------------------------------------------
2366 * SurfaceFlinger::setPowerModeInternal
2367 */
2368
2369// Used when we simulate a display that supports doze.
2370struct DozeIsSupportedVariant {
2371 static constexpr bool DOZE_SUPPORTED = true;
2372 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
2373 IComposerClient::PowerMode::DOZE;
2374 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
2375 IComposerClient::PowerMode::DOZE_SUSPEND;
2376};
2377
2378// Used when we simulate a display that does not support doze.
2379struct DozeNotSupportedVariant {
2380 static constexpr bool DOZE_SUPPORTED = false;
2381 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
2382 IComposerClient::PowerMode::ON;
2383 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
2384 IComposerClient::PowerMode::ON;
2385};
2386
2387struct EventThreadBaseSupportedVariant {
2388 static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
2389 // The event control thread should not be notified.
2390 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
2391
2392 // The event thread should not be notified.
2393 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
2394 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(0);
2395 }
2396};
2397
2398struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
2399 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
2400 // These calls are only expected for the primary display.
2401
2402 // Instead expect no calls.
2403 setupEventAndEventControlThreadNoCallExpectations(test);
2404 }
2405
2406 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
2407 // These calls are only expected for the primary display.
2408
2409 // Instead expect no calls.
2410 setupEventAndEventControlThreadNoCallExpectations(test);
2411 }
2412};
2413
2414struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
2415 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
2416 // The event control thread should be notified to enable vsyncs
2417 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
2418
2419 // The event thread should be notified that the screen was acquired.
2420 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
2421 }
2422
2423 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
2424 // There should be a call to setVsyncEnabled(false)
2425 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
2426
2427 // The event thread should not be notified that the screen was released.
2428 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
2429 }
2430};
2431
2432// --------------------------------------------------------------------
2433// Note:
2434//
2435// There are a large number of transitions we could test, however we only test a
2436// selected subset which provides complete test coverage of the implementation.
2437// --------------------------------------------------------------------
2438
2439template <int initialPowerMode, int targetPowerMode>
2440struct TransitionVariantCommon {
2441 static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
2442 static constexpr auto TARGET_POWER_MODE = targetPowerMode;
2443
2444 static void verifyPostconditions(DisplayTransactionTest*) {}
2445};
2446
2447struct TransitionOffToOnVariant
2448 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
2449 template <typename Case>
2450 static void setupCallExpectations(DisplayTransactionTest* test) {
2451 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2452 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
2453 Case::setupRepaintEverythingCallExpectations(test);
2454 }
2455
2456 static void verifyPostconditions(DisplayTransactionTest* test) {
2457 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2458 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
2459 }
2460};
2461
2462struct TransitionOffToDozeSuspendVariant
2463 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
2464 template <typename Case>
2465 static void setupCallExpectations(DisplayTransactionTest* test) {
2466 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
2467 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2468 Case::setupRepaintEverythingCallExpectations(test);
2469 }
2470
2471 static void verifyPostconditions(DisplayTransactionTest* test) {
2472 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2473 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
2474 }
2475};
2476
2477struct TransitionOnToOffVariant
2478 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
2479 template <typename Case>
2480 static void setupCallExpectations(DisplayTransactionTest* test) {
2481 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
2482 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
2483 }
2484
2485 static void verifyPostconditions(DisplayTransactionTest* test) {
2486 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2487 }
2488};
2489
2490struct TransitionDozeSuspendToOffVariant
2491 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
2492 template <typename Case>
2493 static void setupCallExpectations(DisplayTransactionTest* test) {
2494 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2495 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
2496 }
2497
2498 static void verifyPostconditions(DisplayTransactionTest* test) {
2499 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2500 }
2501};
2502
2503struct TransitionOnToDozeVariant
2504 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
2505 template <typename Case>
2506 static void setupCallExpectations(DisplayTransactionTest* test) {
2507 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2508 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
2509 }
2510};
2511
2512struct TransitionDozeSuspendToDozeVariant
2513 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
2514 template <typename Case>
2515 static void setupCallExpectations(DisplayTransactionTest* test) {
2516 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
2517 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
2518 }
2519};
2520
2521struct TransitionDozeToOnVariant
2522 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
2523 template <typename Case>
2524 static void setupCallExpectations(DisplayTransactionTest* test) {
2525 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2526 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2527 }
2528};
2529
2530struct TransitionDozeSuspendToOnVariant
2531 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
2532 template <typename Case>
2533 static void setupCallExpectations(DisplayTransactionTest* test) {
2534 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
2535 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2536 }
2537};
2538
2539struct TransitionOnToDozeSuspendVariant
2540 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
2541 template <typename Case>
2542 static void setupCallExpectations(DisplayTransactionTest* test) {
2543 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
2544 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
2545 }
2546};
2547
2548struct TransitionOnToUnknownVariant
2549 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
2550 template <typename Case>
2551 static void setupCallExpectations(DisplayTransactionTest* test) {
2552 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2553 Case::setupNoComposerPowerModeCallExpectations(test);
2554 }
2555};
2556
2557// --------------------------------------------------------------------
2558// Note:
2559//
2560// Rather than testing the cartesian product of of
2561// DozeIsSupported/DozeNotSupported with all other options, we use one for one
2562// display type, and the other for another display type.
2563// --------------------------------------------------------------------
2564
2565template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
2566 typename TransitionVariant>
2567struct DisplayPowerCase {
2568 using Display = DisplayVariant;
2569 using Doze = DozeVariant;
2570 using EventThread = EventThreadVariant;
2571 using Transition = TransitionVariant;
2572
2573 static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
2574 Display::injectHwcDisplay(test);
2575 auto display = Display::makeFakeExistingDisplayInjector(test);
2576 display.inject();
2577 display.mutableDisplayDevice()->setPowerMode(mode);
2578 return display;
2579 }
2580
2581 static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
2582 test->mFlinger.mutablePrimaryHWVsyncEnabled() = enabled;
2583 }
2584
2585 static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
2586 EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
2587 }
2588
2589 static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
2590 EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
2591 EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
2592 }
2593
2594 static void setupComposerCallExpectations(DisplayTransactionTest* test,
2595 IComposerClient::PowerMode mode) {
2596 // Any calls to get the active config will return a default value.
2597 EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
2598 .WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
2599 Return(Error::NONE)));
2600
2601 // Any calls to get whether the display supports dozing will return the value set by the
2602 // policy variant.
2603 EXPECT_CALL(*test->mComposer, getDozeSupport(Display::HWC_DISPLAY_ID, _))
2604 .WillRepeatedly(DoAll(SetArgPointee<1>(Doze::DOZE_SUPPORTED), Return(Error::NONE)));
2605
2606 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, mode)).Times(1);
2607 }
2608
2609 static void setupNoComposerPowerModeCallExpectations(DisplayTransactionTest* test) {
2610 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, _)).Times(0);
2611 }
2612};
2613
2614// A sample configuration for the primary display.
2615// In addition to having event thread support, we emulate doze support.
2616template <typename TransitionVariant>
2617using PrimaryDisplayPowerCase = DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant,
2618 EventThreadIsSupportedVariant, TransitionVariant>;
2619
2620// A sample configuration for the external display.
2621// In addition to not having event thread support, we emulate not having doze
2622// support.
2623template <typename TransitionVariant>
2624using ExternalDisplayPowerCase =
2625 DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant,
2626 EventThreadNotSupportedVariant, TransitionVariant>;
2627
2628class SetPowerModeInternalTest : public DisplayTransactionTest {
2629public:
2630 template <typename Case>
2631 void transitionDisplayCommon();
2632};
2633
2634template <int PowerMode>
2635struct PowerModeInitialVSyncEnabled : public std::false_type {};
2636
2637template <>
2638struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
2639
2640template <>
2641struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
2642
2643template <typename Case>
2644void SetPowerModeInternalTest::transitionDisplayCommon() {
2645 // --------------------------------------------------------------------
2646 // Preconditions
2647
2648 auto display =
2649 Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
2650 Case::setInitialPrimaryHWVsyncEnabled(this,
2651 PowerModeInitialVSyncEnabled<
2652 Case::Transition::INITIAL_POWER_MODE>::value);
2653
2654 // --------------------------------------------------------------------
2655 // Call Expectations
2656
2657 Case::setupSurfaceInterceptorCallExpectations(this, Case::Transition::TARGET_POWER_MODE);
2658 Case::Transition::template setupCallExpectations<Case>(this);
2659
2660 // --------------------------------------------------------------------
2661 // Invocation
2662
2663 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
2664 Case::Transition::TARGET_POWER_MODE);
2665
2666 // --------------------------------------------------------------------
2667 // Postconditions
2668
2669 Case::Transition::verifyPostconditions(this);
2670}
2671
2672TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) {
2673 using Case = SimplePrimaryDisplayCase;
2674
2675 // --------------------------------------------------------------------
2676 // Preconditions
2677
2678 // A primary display device is set up
2679 Case::Display::injectHwcDisplay(this);
2680 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2681 display.inject();
2682
2683 // The diplay is already set to HWC_POWER_MODE_NORMAL
2684 display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
2685
2686 // --------------------------------------------------------------------
2687 // Invocation
2688
2689 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
2690
2691 // --------------------------------------------------------------------
2692 // Postconditions
2693
2694 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
2695}
2696
2697TEST_F(SetPowerModeInternalTest, setPowerModeInternalJustSetsInternalStateIfVirtualDisplay) {
2698 using Case = HwcVirtualDisplayCase;
2699
2700 // --------------------------------------------------------------------
2701 // Preconditions
2702
2703 // We need to resize this so that the HWC thinks the virtual display
2704 // is something it created.
2705 mFlinger.mutableHwcDisplayData().resize(3);
2706
2707 // A virtual display device is set up
2708 Case::Display::injectHwcDisplay(this);
2709 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2710 display.inject();
2711
2712 // The display is set to HWC_POWER_MODE_OFF
2713 getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_OFF);
2714
2715 // --------------------------------------------------------------------
2716 // Invocation
2717
2718 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
2719
2720 // --------------------------------------------------------------------
2721 // Postconditions
2722
2723 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
2724}
2725
2726TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
2727 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>();
2728}
2729
2730TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) {
2731 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
2732}
2733
2734TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) {
2735 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>();
2736}
2737
2738TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) {
2739 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
2740}
2741
2742TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) {
2743 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>();
2744}
2745
2746TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) {
2747 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
2748}
2749
2750TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) {
2751 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>();
2752}
2753
2754TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) {
2755 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
2756}
2757
2758TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) {
2759 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
2760}
2761
2762TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) {
2763 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>();
2764}
2765
2766TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) {
2767 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
2768}
2769
2770TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) {
2771 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
2772}
2773
2774TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) {
2775 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
2776}
2777
2778TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) {
2779 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
2780}
2781
2782TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) {
2783 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>();
2784}
2785
2786TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
2787 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
2788}
2789
2790TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) {
2791 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>();
2792}
2793
2794TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
2795 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
2796}
2797
2798TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
2799 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
2800}
2801
2802TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) {
2803 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
2804}
2805
Lloyd Piquef58625d2017-12-19 13:22:33 -08002806} // namespace
2807} // namespace android