blob: 08da1a2c17398f7e27cb5e82b262490bd6fe7de0 [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
48using android::hardware::graphics::common::V1_0::Hdr;
Peiyong Lin0e7a7912018-04-05 14:36:36 -070049using android::hardware::graphics::common::V1_1::ColorMode;
Peiyong Lind6fa4a72018-04-17 15:09:44 -070050using android::hardware::graphics::common::V1_1::RenderIntent;
Lloyd Piquee39cad22017-12-20 17:01:29 -080051using android::Hwc2::Error;
52using android::Hwc2::IComposer;
53using android::Hwc2::IComposerClient;
54
Lloyd Piquefc12f562018-01-22 18:44:59 -080055using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
56using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
Lloyd Pique1fa4d462018-01-22 18:03:16 -080057using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
Lloyd Piquefc12f562018-01-22 18:44:59 -080058using HWC2Display = TestableSurfaceFlinger::HWC2Display;
Lloyd Piquebc792092018-01-17 11:52:30 -080059
Lloyd Piquefc12f562018-01-22 18:44:59 -080060constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
Lloyd Piquee39cad22017-12-20 17:01:29 -080061constexpr int32_t DEFAULT_DPI = 320;
Lloyd Piquefc12f562018-01-22 18:44:59 -080062constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
Lloyd Piquee39cad22017-12-20 17:01:29 -080063
Lloyd Piquefc12f562018-01-22 18:44:59 -080064/* ------------------------------------------------------------------------
65 * Boolean avoidance
66 *
67 * To make calls and template instantiations more readable, we define some
68 * local enums along with an implicit bool conversion.
69 */
70
71#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
72
73BOOL_SUBSTITUTE(Critical);
74BOOL_SUBSTITUTE(Async);
75BOOL_SUBSTITUTE(Secure);
76
77/* ------------------------------------------------------------------------
78 *
79 */
Lloyd Pique1fa4d462018-01-22 18:03:16 -080080
Lloyd Piquef58625d2017-12-19 13:22:33 -080081class DisplayTransactionTest : public testing::Test {
Lloyd Piquefc12f562018-01-22 18:44:59 -080082public:
Lloyd Piquef58625d2017-12-19 13:22:33 -080083 DisplayTransactionTest();
84 ~DisplayTransactionTest() override;
85
Lloyd Pique1fa4d462018-01-22 18:03:16 -080086 // --------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -080087 // Mock/Fake injection
Lloyd Piquef58625d2017-12-19 13:22:33 -080088
Lloyd Piquefc12f562018-01-22 18:44:59 -080089 void injectMockComposer(int virtualDisplayCount);
90 void injectFakeBufferQueueFactory();
91 void injectFakeNativeWindowSurfaceFactory();
Lloyd Pique1fa4d462018-01-22 18:03:16 -080092
93 // --------------------------------------------------------------------
94 // Postcondition helpers
95
Lloyd Piquefc12f562018-01-22 18:44:59 -080096 bool hasHwcDisplay(hwc2_display_t displayId);
Lloyd Pique1fa4d462018-01-22 18:03:16 -080097 bool hasTransactionFlagSet(int flag);
98 bool hasDisplayDevice(sp<IBinder> displayToken);
99 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
100 bool hasCurrentDisplayState(sp<IBinder> displayToken);
101 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
102 bool hasDrawingDisplayState(sp<IBinder> displayToken);
103 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
104
105 // --------------------------------------------------------------------
106 // Test instances
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800107
Lloyd Piquef58625d2017-12-19 13:22:33 -0800108 TestableSurfaceFlinger mFlinger;
Lloyd Piquee39cad22017-12-20 17:01:29 -0800109 mock::EventThread* mEventThread = new mock::EventThread();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800110 mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800111
112 // These mocks are created by the test, but are destroyed by SurfaceFlinger
113 // by virtue of being stored into a std::unique_ptr. However we still need
114 // to keep a reference to them for use in setting up call expectations.
115 RE::mock::RenderEngine* mRenderEngine = new RE::mock::RenderEngine();
Lloyd Piquefc12f562018-01-22 18:44:59 -0800116 Hwc2::mock::Composer* mComposer = nullptr;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800117 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
118 mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800119
120 // These mocks are created only when expected to be created via a factory.
121 sp<mock::GraphicBufferConsumer> mConsumer;
122 sp<mock::GraphicBufferProducer> mProducer;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800123 mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
124 sp<mock::NativeWindow> mNativeWindow;
125 RE::mock::Surface* mRenderSurface = nullptr;
Lloyd Piquef58625d2017-12-19 13:22:33 -0800126};
127
128DisplayTransactionTest::DisplayTransactionTest() {
129 const ::testing::TestInfo* const test_info =
130 ::testing::UnitTest::GetInstance()->current_test_info();
131 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Lloyd Piquee39cad22017-12-20 17:01:29 -0800132
Lloyd Piquefc12f562018-01-22 18:44:59 -0800133 // Default to no wide color display support configured
134 mFlinger.mutableHasWideColorDisplay() = false;
135 mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
136
137 // Default to using HWC virtual displays
138 mFlinger.mutableUseHwcVirtualDisplays() = true;
139
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800140 mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
141 ADD_FAILURE() << "Unexpected request to create a buffer queue.";
142 });
143
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800144 mFlinger.setCreateNativeWindowSurface([](auto) {
145 ADD_FAILURE() << "Unexpected request to create a native window surface.";
146 return nullptr;
147 });
148
149 mFlinger.mutableEventControlThread().reset(mEventControlThread);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800150 mFlinger.mutableEventThread().reset(mEventThread);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800151 mFlinger.mutableEventQueue().reset(mMessageQueue);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800152 mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800153 mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800154
Lloyd Piquefc12f562018-01-22 18:44:59 -0800155 injectMockComposer(0);
Lloyd Piquef58625d2017-12-19 13:22:33 -0800156}
157
158DisplayTransactionTest::~DisplayTransactionTest() {
159 const ::testing::TestInfo* const test_info =
160 ::testing::UnitTest::GetInstance()->current_test_info();
161 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
162}
163
Lloyd Piquefc12f562018-01-22 18:44:59 -0800164void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
165 mComposer = new Hwc2::mock::Composer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800166 EXPECT_CALL(*mComposer, getCapabilities())
167 .WillOnce(Return(std::vector<IComposer::Capability>()));
168 EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
169 mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
Lloyd Piquef58625d2017-12-19 13:22:33 -0800170
Lloyd Piquee39cad22017-12-20 17:01:29 -0800171 Mock::VerifyAndClear(mComposer);
172}
173
Lloyd Piquefc12f562018-01-22 18:44:59 -0800174void DisplayTransactionTest::injectFakeBufferQueueFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800175 // This setup is only expected once per test.
176 ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
177
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800178 mConsumer = new mock::GraphicBufferConsumer();
179 mProducer = new mock::GraphicBufferProducer();
180
181 mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
182 *outProducer = mProducer;
183 *outConsumer = mConsumer;
184 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800185}
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800186
Lloyd Piquefc12f562018-01-22 18:44:59 -0800187void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800188 // This setup is only expected once per test.
189 ASSERT_TRUE(mNativeWindowSurface == nullptr);
190
191 mNativeWindowSurface = new mock::NativeWindowSurface();
192 mNativeWindow = new mock::NativeWindow();
193
194 mFlinger.setCreateNativeWindowSurface(
195 [this](auto) { return std::unique_ptr<NativeWindowSurface>(mNativeWindowSurface); });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800196}
197
Lloyd Piquefc12f562018-01-22 18:44:59 -0800198bool DisplayTransactionTest::hasHwcDisplay(hwc2_display_t displayId) {
199 return mFlinger.mutableHwcDisplaySlots().count(displayId) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800200}
201
202bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
203 return mFlinger.mutableTransactionFlags() & flag;
204}
205
206bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
207 return mFlinger.mutableDisplays().indexOfKey(displayToken) >= 0;
208}
209
210sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
211 return mFlinger.mutableDisplays().valueFor(displayToken);
212}
213
214bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
215 return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
216}
217
218const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
219 return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
220}
221
222bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
223 return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
224}
225
226const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
227 return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
228}
229
230/* ------------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -0800231 *
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800232 */
233
Lloyd Piquefc12f562018-01-22 18:44:59 -0800234template <DisplayDevice::DisplayType type, DisplayDevice::DisplayType hwcId, int width, int height,
235 Critical critical, Async async, Secure secure, int grallocUsage>
236struct DisplayVariant {
237 // The display width and height
238 static constexpr int WIDTH = width;
239 static constexpr int HEIGHT = height;
240
241 static constexpr int GRALLOC_USAGE = grallocUsage;
242
243 // The type for this display
244 static constexpr DisplayDevice::DisplayType TYPE = type;
245 static constexpr DisplayDevice::DisplayType HWCOMPOSER_ID = hwcId;
246
247 // When creating native window surfaces for the framebuffer, whether those should be critical
248 static constexpr Critical CRITICAL = critical;
249
250 // When creating native window surfaces for the framebuffer, whether those should be async
251 static constexpr Async ASYNC = async;
252
253 // Whether the display should be treated as secure
254 static constexpr Secure SECURE = secure;
255
256 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
257 auto injector = FakeDisplayDeviceInjector(test->mFlinger, TYPE, HWCOMPOSER_ID);
258 injector.setSecure(static_cast<bool>(SECURE));
259 return injector;
260 }
261
262 // Called by tests to set up any native window creation call expectations.
263 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
264 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
265 .WillOnce(Return(test->mNativeWindow));
266 EXPECT_CALL(*test->mNativeWindow, perform(19)).WillRepeatedly(Return(NO_ERROR));
267
268 // For simplicity, we only expect to create a single render surface for
269 // each test.
270 ASSERT_TRUE(test->mRenderSurface == nullptr);
271 test->mRenderSurface = new RE::mock::Surface();
272 EXPECT_CALL(*test->mRenderEngine, createSurface())
273 .WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(test->mRenderSurface))));
274 EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
275 EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
276 EXPECT_CALL(*test->mRenderSurface, setNativeWindow(test->mNativeWindow.get())).Times(1);
277 EXPECT_CALL(*test->mRenderSurface, queryWidth()).WillOnce(Return(WIDTH));
278 EXPECT_CALL(*test->mRenderSurface, queryHeight()).WillOnce(Return(HEIGHT));
279 }
280
281 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
282 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
283 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
284 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
285 .WillRepeatedly(Return(NO_ERROR));
286 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
287 .WillRepeatedly(Return(NO_ERROR));
288 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
289 .WillRepeatedly(Return(NO_ERROR));
290 }
291
292 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
293 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
294 }
295};
296
297template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant>
298struct HwcDisplayVariant {
299 // The display id supplied by the HWC
300 static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
301
302 // The HWC display type
303 static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
304
305 // The HWC active configuration id
306 // TODO(b/69807179): SurfaceFlinger does not correctly get the active
307 // config. Once it does, change this to non-zero so that it is properly
308 // covered.
309 // static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
310 static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
311
312 static void injectPendingHotplugEvent(DisplayTransactionTest* test,
313 HWC2::Connection connection) {
314 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
315 HotplugEvent{HWC_DISPLAY_ID, connection});
316 }
317
318 // Called by tests to inject a HWC display setup
319 static void injectHwcDisplay(DisplayTransactionTest* test) {
320 FakeHwcDisplayInjector(DisplayVariant::TYPE, HWC_DISPLAY_TYPE)
321 .setHwcDisplayId(HWC_DISPLAY_ID)
322 .setWidth(DisplayVariant::WIDTH)
323 .setHeight(DisplayVariant::HEIGHT)
324 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
325 .inject(&test->mFlinger, test->mComposer);
326 }
327
328 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
329 EXPECT_CALL(*test->mComposer, getDisplayType(HWC_DISPLAY_ID, _))
330 .WillOnce(DoAll(SetArgPointee<1>(static_cast<IComposerClient::DisplayType>(
331 HWC_DISPLAY_TYPE)),
332 Return(Error::NONE)));
333 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
334 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
335 .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
336 Return(Error::NONE)));
337 EXPECT_CALL(*test->mComposer,
338 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
339 IComposerClient::Attribute::WIDTH, _))
340 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
341 EXPECT_CALL(*test->mComposer,
342 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
343 IComposerClient::Attribute::HEIGHT, _))
344 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
345 EXPECT_CALL(*test->mComposer,
346 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
347 IComposerClient::Attribute::VSYNC_PERIOD, _))
348 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
349 EXPECT_CALL(*test->mComposer,
350 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
351 IComposerClient::Attribute::DPI_X, _))
352 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
353 EXPECT_CALL(*test->mComposer,
354 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
355 IComposerClient::Attribute::DPI_Y, _))
356 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
357 }
358
359 // Called by tests to set up HWC call expectations
360 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
361 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
362 .WillOnce(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
363 }
364};
365
366struct NonHwcDisplayVariant {
367 static constexpr int HWC_ACTIVE_CONFIG_ID = 0;
368
369 static void injectHwcDisplay(DisplayTransactionTest*) {}
370
371 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
372 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
373 }
374};
375
376// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
377constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
378 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
379
380template <hwc2_display_t hwcDisplayId, DisplayDevice::DisplayType type, int width, int height,
381 Critical critical>
382struct PhysicalDisplayVariant
383 : public DisplayVariant<type, type, width, height, critical, Async::FALSE, Secure::TRUE,
384 GRALLOC_USAGE_PHYSICAL_DISPLAY>,
385 public HwcDisplayVariant<hwcDisplayId, HWC2::DisplayType::Physical,
386 DisplayVariant<type, type, width, height, critical, Async::FALSE,
387 Secure::TRUE, GRALLOC_USAGE_PHYSICAL_DISPLAY>> {};
388
Lloyd Pique9d9cf402018-02-16 17:47:13 -0800389// An invalid display
390using InvalidDisplayVariant =
391 DisplayVariant<DisplayDevice::DISPLAY_ID_INVALID, DisplayDevice::DISPLAY_ID_INVALID, 0, 0,
392 Critical::FALSE, Async::FALSE, Secure::FALSE, 0>;
393
Lloyd Piquefc12f562018-01-22 18:44:59 -0800394// A primary display is a physical display that is critical
395using PrimaryDisplayVariant =
396 PhysicalDisplayVariant<1001, DisplayDevice::DISPLAY_PRIMARY, 3840, 2160, Critical::TRUE>;
397
398// An external display is physical display that is not critical.
399using ExternalDisplayVariant =
400 PhysicalDisplayVariant<1002, DisplayDevice::DISPLAY_EXTERNAL, 1920, 1280, Critical::FALSE>;
401
402using TertiaryDisplayVariant =
403 PhysicalDisplayVariant<1003, DisplayDevice::DISPLAY_EXTERNAL, 1600, 1200, Critical::FALSE>;
404
405// A virtual display not supported by the HWC.
406constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
407
408template <int width, int height, Secure secure>
409struct NonHwcVirtualDisplayVariant
410 : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
411 width, height, Critical::FALSE, Async::TRUE, secure,
412 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>,
413 public NonHwcDisplayVariant {
414 using Base = DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_ID_INVALID,
415 width, height, Critical::FALSE, Async::TRUE, secure,
416 GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
417
418 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
419 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
420 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
421 }
422};
423
424// A virtual display supported by the HWC.
425constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
426
427template <int width, int height, Secure secure>
428struct HwcVirtualDisplayVariant
429 : public DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
430 height, Critical::FALSE, Async::TRUE, secure,
431 GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
432 public HwcDisplayVariant<1010, HWC2::DisplayType::Virtual,
433 NonHwcVirtualDisplayVariant<width, height, secure>> {
434 using Base =
435 DisplayVariant<DisplayDevice::DISPLAY_VIRTUAL, DisplayDevice::DISPLAY_VIRTUAL, width,
436 height, Critical::FALSE, Async::TRUE, secure, GRALLOC_USAGE_HW_COMPOSER>;
437 using Self = HwcVirtualDisplayVariant<width, height, secure>;
438
439 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
440 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
441 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
442 }
443
444 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
445 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
446 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
447 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
448 }
449};
450
451// For this variant, SurfaceFlinger should not configure itself with wide
452// display support, so the display should not be configured for wide-color
453// support.
454struct WideColorSupportNotConfiguredVariant {
455 static constexpr bool WIDE_COLOR_SUPPORTED = false;
456
457 static void injectConfigChange(DisplayTransactionTest* test) {
458 test->mFlinger.mutableHasWideColorDisplay() = false;
459 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
460 }
461
462 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
463 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
464 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
465 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
466 }
467};
468
469// For this variant, SurfaceFlinger should configure itself with wide display
470// support, and the display should respond with an non-empty list of supported
471// color modes. Wide-color support should be configured.
472template <typename Display>
473struct WideColorP3ColorimetricSupportedVariant {
474 static constexpr bool WIDE_COLOR_SUPPORTED = true;
475
476 static void injectConfigChange(DisplayTransactionTest* test) {
477 test->mFlinger.mutableHasWideColorDisplay() = true;
478 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
479 }
480
481 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
482 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
483 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
484 Return(Error::NONE)));
485 EXPECT_CALL(*test->mComposer,
486 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
487 .WillOnce(DoAll(SetArgPointee<2>(
488 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
489 Return(Error::NONE)));
490 EXPECT_CALL(*test->mComposer,
491 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
492 RenderIntent::COLORIMETRIC))
493 .WillOnce(Return(Error::NONE));
494 }
495};
496
Lloyd Piquefc12f562018-01-22 18:44:59 -0800497// For this variant, SurfaceFlinger should configure itself with wide display
498// support, but the display should respond with an empty list of supported color
499// modes. Wide-color support for the display should not be configured.
500template <typename Display>
501struct WideColorNotSupportedVariant {
502 static constexpr bool WIDE_COLOR_SUPPORTED = false;
503
504 static void injectConfigChange(DisplayTransactionTest* test) {
505 test->mFlinger.mutableHasWideColorDisplay() = true;
506 }
507
508 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
509 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
510 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
511 EXPECT_CALL(*test->mComposer,
512 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::NATIVE,
513 RenderIntent::COLORIMETRIC))
514 .WillOnce(Return(Error::NONE));
515 }
516};
517
518// For this variant, the display is not a HWC display, so no HDR support should
519// be configured.
520struct NonHwcDisplayHdrSupportVariant {
521 static constexpr bool HDR10_SUPPORTED = false;
522 static constexpr bool HDR_HLG_SUPPORTED = false;
523 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
524 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
525 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
526 }
527};
528
529// For this variant, the composer should respond with a non-empty list of HDR
530// modes containing HDR10, so HDR10 support should be configured.
531template <typename Display>
532struct Hdr10SupportedVariant {
533 static constexpr bool HDR10_SUPPORTED = true;
534 static constexpr bool HDR_HLG_SUPPORTED = false;
535 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
536 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
537 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
538 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
539 Return(Error::NONE)));
540 }
541};
542
543// For this variant, the composer should respond with a non-empty list of HDR
544// modes containing HLG, so HLG support should be configured.
545template <typename Display>
546struct HdrHlgSupportedVariant {
547 static constexpr bool HDR10_SUPPORTED = false;
548 static constexpr bool HDR_HLG_SUPPORTED = true;
549 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
550 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
551 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
552 .WillOnce(
553 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
554 }
555};
556
557// For this variant, the composer should respond with a non-empty list of HDR
558// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
559template <typename Display>
560struct HdrDolbyVisionSupportedVariant {
561 static constexpr bool HDR10_SUPPORTED = false;
562 static constexpr bool HDR_HLG_SUPPORTED = false;
563 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
564 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
565 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
566 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
567 Return(Error::NONE)));
568 }
569};
570
571// For this variant, the composer should respond with am empty list of HDR
572// modes, so no HDR support should be configured.
573template <typename Display>
574struct HdrNotSupportedVariant {
575 static constexpr bool HDR10_SUPPORTED = false;
576 static constexpr bool HDR_HLG_SUPPORTED = false;
577 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
578 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
579 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
580 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
581 }
582};
583
584/* ------------------------------------------------------------------------
585 * Typical display configurations to test
586 */
587
588template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy>
589struct Case {
590 using Display = DisplayPolicy;
591 using WideColorSupport = WideColorSupportPolicy;
592 using HdrSupport = HdrSupportPolicy;
593};
594
595using SimplePrimaryDisplayCase =
596 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
597 HdrNotSupportedVariant<PrimaryDisplayVariant>>;
598using SimpleExternalDisplayCase =
599 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
600 HdrNotSupportedVariant<ExternalDisplayVariant>>;
601using SimpleTertiaryDisplayCase =
602 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
603 HdrNotSupportedVariant<TertiaryDisplayVariant>>;
604using NonHwcVirtualDisplayCase =
605 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
606 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant>;
607using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
608using HwcVirtualDisplayCase =
609 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
610 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>>;
611using WideColorP3ColorimetricDisplayCase =
612 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
613 HdrNotSupportedVariant<PrimaryDisplayVariant>>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800614using Hdr10DisplayCase =
615 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
616 Hdr10SupportedVariant<PrimaryDisplayVariant>>;
617using HdrHlgDisplayCase =
618 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
619 HdrHlgSupportedVariant<PrimaryDisplayVariant>>;
620using HdrDolbyVisionDisplayCase =
621 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
622 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>>;
Lloyd Pique9d9cf402018-02-16 17:47:13 -0800623using InvalidDisplayCase = Case<InvalidDisplayVariant, WideColorSupportNotConfiguredVariant,
624 NonHwcDisplayHdrSupportVariant>;
Lloyd Piquefc12f562018-01-22 18:44:59 -0800625
626/* ------------------------------------------------------------------------
Lloyd Pique6cf11032018-01-22 18:57:44 -0800627 *
628 * SurfaceFlinger::onHotplugReceived
629 */
630
631TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
632 constexpr int currentSequenceId = 123;
633 constexpr hwc2_display_t displayId1 = 456;
634 constexpr hwc2_display_t displayId2 = 654;
635
636 // --------------------------------------------------------------------
637 // Preconditions
638
639 // Set the current sequence id for accepted events
640 mFlinger.mutableComposerSequenceId() = currentSequenceId;
641
642 // Set the main thread id so that the current thread does not appear to be
643 // the main thread.
644 mFlinger.mutableMainThreadId() = std::thread::id();
645
646 // --------------------------------------------------------------------
647 // Call Expectations
648
649 // We expect invalidate() to be invoked once to trigger display transaction
650 // processing.
651 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
652
653 // --------------------------------------------------------------------
654 // Invocation
655
656 // Simulate two hotplug events (a connect and a disconnect)
657 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Connected);
658 mFlinger.onHotplugReceived(currentSequenceId, displayId2, HWC2::Connection::Disconnected);
659
660 // --------------------------------------------------------------------
661 // Postconditions
662
663 // The display transaction needed flag should be set.
664 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
665
666 // All events should be in the pending event queue.
667 const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
668 ASSERT_EQ(2u, pendingEvents.size());
669 EXPECT_EQ(displayId1, pendingEvents[0].display);
670 EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
671 EXPECT_EQ(displayId2, pendingEvents[1].display);
672 EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
673}
674
675TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
676 constexpr int currentSequenceId = 123;
677 constexpr int otherSequenceId = 321;
678 constexpr hwc2_display_t displayId = 456;
679
680 // --------------------------------------------------------------------
681 // Preconditions
682
683 // Set the current sequence id for accepted events
684 mFlinger.mutableComposerSequenceId() = currentSequenceId;
685
686 // Set the main thread id so that the current thread does not appear to be
687 // the main thread.
688 mFlinger.mutableMainThreadId() = std::thread::id();
689
690 // --------------------------------------------------------------------
691 // Call Expectations
692
693 // We do not expect any calls to invalidate().
694 EXPECT_CALL(*mMessageQueue, invalidate()).Times(0);
695
696 // --------------------------------------------------------------------
697 // Invocation
698
699 // Call with an unexpected sequence id
700 mFlinger.onHotplugReceived(otherSequenceId, displayId, HWC2::Connection::Invalid);
701
702 // --------------------------------------------------------------------
703 // Postconditions
704
705 // The display transaction needed flag should not be set
706 EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded));
707
708 // There should be no pending events
709 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
710}
711
712TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
713 constexpr int currentSequenceId = 123;
714 constexpr hwc2_display_t displayId1 = 456;
715
716 // --------------------------------------------------------------------
717 // Note:
718 // --------------------------------------------------------------------
719 // This test case is a bit tricky. We want to verify that
720 // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we
721 // don't really want to provide coverage for everything the later function
722 // does as there are specific tests for it.
723 // --------------------------------------------------------------------
724
725 // --------------------------------------------------------------------
726 // Preconditions
727
728 // Set the current sequence id for accepted events
729 mFlinger.mutableComposerSequenceId() = currentSequenceId;
730
731 // Set the main thread id so that the current thread does appear to be the
732 // main thread.
733 mFlinger.mutableMainThreadId() = std::this_thread::get_id();
734
735 // --------------------------------------------------------------------
736 // Call Expectations
737
738 // We expect invalidate() to be invoked once to trigger display transaction
739 // processing.
740 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
741
742 // --------------------------------------------------------------------
743 // Invocation
744
745 // Simulate a disconnect on a display id that is not connected. This should
746 // be enqueued by onHotplugReceived(), and dequeued by
747 // processDisplayHotplugEventsLocked(), but then ignored as invalid.
748 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Disconnected);
749
750 // --------------------------------------------------------------------
751 // Postconditions
752
753 // The display transaction needed flag should be set.
754 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
755
756 // There should be no event queued on return, as it should have been
757 // processed.
758 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
759}
760
761/* ------------------------------------------------------------------------
Lloyd Piquea482f992018-01-22 19:00:34 -0800762 * SurfaceFlinger::createDisplay
763 */
764
765TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
766 const String8 name("virtual.test");
767
768 // --------------------------------------------------------------------
769 // Call Expectations
770
771 // The call should notify the interceptor that a display was created.
772 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
773
774 // --------------------------------------------------------------------
775 // Invocation
776
777 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
778
779 // --------------------------------------------------------------------
780 // Postconditions
781
782 // The display should have been added to the current state
783 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
784 const auto& display = getCurrentDisplayState(displayToken);
785 EXPECT_EQ(DisplayDevice::DISPLAY_VIRTUAL, display.type);
786 EXPECT_EQ(false, display.isSecure);
787 EXPECT_EQ(name.string(), display.displayName);
788
789 // --------------------------------------------------------------------
790 // Cleanup conditions
791
792 // Destroying the display invalidates the display state.
793 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
794}
795
796TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForSecureDisplay) {
797 const String8 name("virtual.test");
798
799 // --------------------------------------------------------------------
800 // Call Expectations
801
802 // The call should notify the interceptor that a display was created.
803 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
804
805 // --------------------------------------------------------------------
806 // Invocation
807
808 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
809
810 // --------------------------------------------------------------------
811 // Postconditions
812
813 // The display should have been added to the current state
814 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
815 const auto& display = getCurrentDisplayState(displayToken);
816 EXPECT_EQ(DisplayDevice::DISPLAY_VIRTUAL, display.type);
817 EXPECT_EQ(true, display.isSecure);
818 EXPECT_EQ(name.string(), display.displayName);
819
820 // --------------------------------------------------------------------
821 // Cleanup conditions
822
823 // Destroying the display invalidates the display state.
824 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
825}
826
827/* ------------------------------------------------------------------------
828 * SurfaceFlinger::destroyDisplay
829 */
830
831TEST_F(DisplayTransactionTest, destroyDisplayClearsCurrentStateForDisplay) {
832 using Case = NonHwcVirtualDisplayCase;
833
834 // --------------------------------------------------------------------
835 // Preconditions
836
837 // A virtual display exists
838 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
839 existing.inject();
840
841 // --------------------------------------------------------------------
842 // Call Expectations
843
844 // The call should notify the interceptor that a display was created.
845 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
846
847 // Destroying the display invalidates the display state.
848 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
849
850 // --------------------------------------------------------------------
851 // Invocation
852
853 mFlinger.destroyDisplay(existing.token());
854
855 // --------------------------------------------------------------------
856 // Postconditions
857
858 // The display should have been removed from the current state
859 EXPECT_FALSE(hasCurrentDisplayState(existing.token()));
860
861 // Ths display should still exist in the drawing state
862 EXPECT_TRUE(hasDrawingDisplayState(existing.token()));
863
864 // The display transaction needed flasg should be set
865 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
866}
867
868TEST_F(DisplayTransactionTest, destroyDisplayHandlesUnknownDisplay) {
869 // --------------------------------------------------------------------
870 // Preconditions
871
872 sp<BBinder> displayToken = new BBinder();
873
874 // --------------------------------------------------------------------
875 // Invocation
876
877 mFlinger.destroyDisplay(displayToken);
878}
879
880/* ------------------------------------------------------------------------
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -0800881 * SurfaceFlinger::resetDisplayState
882 */
883
884TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
885 using Case = NonHwcVirtualDisplayCase;
886
887 // --------------------------------------------------------------------
888 // Preconditions
889
890 // vsync is enabled and available
891 mFlinger.mutablePrimaryHWVsyncEnabled() = true;
892 mFlinger.mutableHWVsyncAvailable() = true;
893
894 // A display exists
895 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
896 existing.inject();
897
898 // --------------------------------------------------------------------
899 // Call Expectations
900
901 // The call disable vsyncs
902 EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
903
904 // The call clears the current render engine surface
905 EXPECT_CALL(*mRenderEngine, resetCurrentSurface());
906
907 // --------------------------------------------------------------------
908 // Invocation
909
910 mFlinger.resetDisplayState();
911
912 // --------------------------------------------------------------------
913 // Postconditions
914
915 // vsyncs should be off and not available.
916 EXPECT_FALSE(mFlinger.mutablePrimaryHWVsyncEnabled());
917 EXPECT_FALSE(mFlinger.mutableHWVsyncAvailable());
918
919 // The display should have been removed from the display map.
920 EXPECT_FALSE(hasDisplayDevice(existing.token()));
921
922 // The display should still exist in the current state
923 EXPECT_TRUE(hasCurrentDisplayState(existing.token()));
924
925 // The display should have been removed from the drawing state
926 EXPECT_FALSE(hasDrawingDisplayState(existing.token()));
927}
928
929/* ------------------------------------------------------------------------
Lloyd Piquefc12f562018-01-22 18:44:59 -0800930 * SurfaceFlinger::setupNewDisplayDeviceInternal
931 */
932
933class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
934public:
935 template <typename T>
936 void setupNewDisplayDeviceInternalTest();
937};
938
939template <typename Case>
940void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
941 const sp<BBinder> displayToken = new BBinder();
942 const sp<mock::DisplaySurface> displaySurface = new mock::DisplaySurface();
943 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800944
945 // --------------------------------------------------------------------
946 // Preconditions
947
Lloyd Piquefc12f562018-01-22 18:44:59 -0800948 // Wide color displays support is configured appropriately
949 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800950
Lloyd Piquefc12f562018-01-22 18:44:59 -0800951 // The display is setup with the HWC.
952 Case::Display::injectHwcDisplay(this);
953
954 // SurfaceFlinger will use a test-controlled factory for native window
955 // surfaces.
956 injectFakeNativeWindowSurfaceFactory();
957
958 // --------------------------------------------------------------------
959 // Call Expectations
960
961 // Various native window calls will be made.
962 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
963
964 // TODO(b/69807179): SurfaceFlinger does not correctly get the active config.
965 // Case::Display::setupHwcGetActiveConfigCallExpectations(this)
966
967 Case::WideColorSupport::setupComposerCallExpectations(this);
968 Case::HdrSupport::setupComposerCallExpectations(this);
969
970 // --------------------------------------------------------------------
971 // Invocation
972
973 auto state = DisplayDeviceState(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
974 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, Case::Display::TYPE, state,
975 displaySurface, producer);
976
977 // --------------------------------------------------------------------
978 // Postconditions
979
980 ASSERT_TRUE(device != nullptr);
981 EXPECT_EQ(Case::Display::TYPE, device->getDisplayType());
982 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
983 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
984 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
985 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
986 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
987 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
988 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
989 EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveConfig());
990}
991
992TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
993 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
994}
995
996TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
997 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
998}
999
1000TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1001 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1002}
1003
1004TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
1005 // We need to resize this so that the HWC thinks the virtual display
1006 // is something it created.
1007 mFlinger.mutableHwcDisplayData().resize(3);
1008
1009 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
1010}
1011
1012TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1013 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1014}
1015
Lloyd Piquefc12f562018-01-22 18:44:59 -08001016TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1017 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1018}
1019
1020TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1021 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1022}
1023
1024TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1025 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1026}
1027
1028/* ------------------------------------------------------------------------
1029 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1030 */
1031
1032class HandleTransactionLockedTest : public DisplayTransactionTest {
1033public:
1034 template <typename Case>
1035 void setupCommonPreconditions();
1036
1037 template <typename Case>
1038 void setupCommonCallExpectationsForConnectProcessing();
1039
1040 template <typename Case>
1041 void setupCommonCallExpectationsForDisconnectProcessing();
1042
1043 template <typename Case>
1044 void processesHotplugConnectCommon();
1045
1046 template <typename Case>
1047 void ignoresHotplugConnectCommon();
1048
1049 template <typename Case>
1050 void processesHotplugDisconnectCommon();
1051
1052 template <typename Case>
1053 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1054
1055 template <typename Case>
1056 void verifyPhysicalDisplayIsConnected();
1057
1058 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1059};
1060
1061template <typename Case>
1062void HandleTransactionLockedTest::setupCommonPreconditions() {
1063 // Wide color displays support is configured appropriately
1064 Case::WideColorSupport::injectConfigChange(this);
1065
1066 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1067 injectFakeBufferQueueFactory();
1068
1069 // SurfaceFlinger will use a test-controlled factory for native window
1070 // surfaces.
1071 injectFakeNativeWindowSurfaceFactory();
1072}
1073
1074template <typename Case>
1075void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1076 Case::Display::setupHwcHotplugCallExpectations(this);
1077
1078 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1079 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1080 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1081 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1082
1083 Case::WideColorSupport::setupComposerCallExpectations(this);
1084 Case::HdrSupport::setupComposerCallExpectations(this);
1085
1086 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1087 EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, true)).Times(1);
1088}
1089
1090template <typename Case>
1091void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1092 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
1093 EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::TYPE, false)).Times(1);
1094}
1095
1096template <typename Case>
1097void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1098 // The display device should have been set up in the list of displays.
1099 ASSERT_TRUE(hasDisplayDevice(displayToken));
1100 const auto& device = getDisplayDevice(displayToken);
1101 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
1102 EXPECT_EQ(Case::Display::TYPE == DisplayDevice::DISPLAY_PRIMARY, device->isPrimary());
1103
1104 // The display should have been set up in the current display state
1105 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1106 const auto& current = getCurrentDisplayState(displayToken);
1107 EXPECT_EQ(Case::Display::TYPE, current.type);
1108
1109 // The display should have been set up in the drawing display state
1110 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1111 const auto& draw = getDrawingDisplayState(displayToken);
1112 EXPECT_EQ(Case::Display::TYPE, draw.type);
1113}
1114
1115template <typename Case>
1116void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1117 // HWComposer should have an entry for the display
1118 EXPECT_TRUE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1119
1120 // The display should be set up as a built-in display.
1121 static_assert(0 <= Case::Display::TYPE &&
1122 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
1123 "Must use a valid physical display type index for the fixed-size array");
1124 auto& displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1125 ASSERT_TRUE(displayToken != nullptr);
1126
1127 verifyDisplayIsConnected<Case>(displayToken);
1128}
1129
1130void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
1131 EXPECT_FALSE(hasDisplayDevice(displayToken));
1132 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
1133 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
1134}
1135
1136template <typename Case>
1137void HandleTransactionLockedTest::processesHotplugConnectCommon() {
1138 // --------------------------------------------------------------------
1139 // Preconditions
1140
1141 setupCommonPreconditions<Case>();
1142
1143 // A hotplug connect event is enqueued for a display
1144 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001145
1146 // --------------------------------------------------------------------
1147 // Call Expectations
1148
1149 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001150
Lloyd Piquefc12f562018-01-22 18:44:59 -08001151 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001152
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001153 // --------------------------------------------------------------------
1154 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08001155
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001156 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08001157
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001158 // --------------------------------------------------------------------
1159 // Postconditions
1160
Lloyd Piquefc12f562018-01-22 18:44:59 -08001161 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001162
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001163 // --------------------------------------------------------------------
1164 // Cleanup conditions
1165
Lloyd Piquefc12f562018-01-22 18:44:59 -08001166 EXPECT_CALL(*mComposer,
1167 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001168 .WillOnce(Return(Error::NONE));
1169 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08001170}
1171
Lloyd Piquefc12f562018-01-22 18:44:59 -08001172template <typename Case>
1173void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
1174 // --------------------------------------------------------------------
1175 // Preconditions
1176
1177 setupCommonPreconditions<Case>();
1178
1179 // A hotplug connect event is enqueued for a display
1180 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1181
1182 // --------------------------------------------------------------------
1183 // Invocation
1184
1185 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1186
1187 // --------------------------------------------------------------------
1188 // Postconditions
1189
1190 // HWComposer should not have an entry for the display
1191 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1192}
1193
1194template <typename Case>
1195void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
1196 // --------------------------------------------------------------------
1197 // Preconditions
1198
1199 setupCommonPreconditions<Case>();
1200
1201 // A hotplug disconnect event is enqueued for a display
1202 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1203
1204 // The display is already completely set up.
1205 Case::Display::injectHwcDisplay(this);
1206 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1207 existing.inject();
1208
1209 // --------------------------------------------------------------------
1210 // Call Expectations
1211
1212 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1213
1214 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1215
1216 // --------------------------------------------------------------------
1217 // Invocation
1218
1219 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1220
1221 // --------------------------------------------------------------------
1222 // Postconditions
1223
1224 // HWComposer should not have an entry for the display
1225 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1226
1227 // The display should not be set up as a built-in display.
1228 ASSERT_TRUE(0 <= Case::Display::TYPE &&
1229 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
1230 auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1231 EXPECT_TRUE(displayToken == nullptr);
1232
1233 // The existing token should have been removed
1234 verifyDisplayIsNotConnected(existing.token());
1235}
1236
1237TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
1238 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1239}
1240
1241TEST_F(HandleTransactionLockedTest,
1242 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
1243 // Inject an external display.
1244 ExternalDisplayVariant::injectHwcDisplay(this);
1245
1246 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1247}
1248
1249TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
1250 // Inject a primary display.
1251 PrimaryDisplayVariant::injectHwcDisplay(this);
1252
1253 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
1254}
1255
1256TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
1257 // Inject both a primary and external display.
1258 PrimaryDisplayVariant::injectHwcDisplay(this);
1259 ExternalDisplayVariant::injectHwcDisplay(this);
1260
1261 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1262
1263 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
1264}
1265
1266TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
1267 // Inject a primary display.
1268 PrimaryDisplayVariant::injectHwcDisplay(this);
1269
1270 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
1271
1272 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
1273}
1274
1275TEST_F(HandleTransactionLockedTest, processHotplugDisconnectPrimaryDisplay) {
1276 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
1277}
1278
1279TEST_F(HandleTransactionLockedTest, processHotplugDisconnectExternalDisplay) {
1280 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
1281}
1282
1283TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
1284 using Case = SimplePrimaryDisplayCase;
1285
1286 // --------------------------------------------------------------------
1287 // Preconditions
1288
1289 setupCommonPreconditions<Case>();
1290
1291 // A hotplug connect event is enqueued for a display
1292 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1293 // A hotplug disconnect event is also enqueued for the same display
1294 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1295
1296 // --------------------------------------------------------------------
1297 // Call Expectations
1298
1299 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1300
1301 setupCommonCallExpectationsForConnectProcessing<Case>();
1302 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1303
1304 EXPECT_CALL(*mComposer,
1305 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1306 .WillOnce(Return(Error::NONE));
1307 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1308
1309 // --------------------------------------------------------------------
1310 // Invocation
1311
1312 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1313
1314 // --------------------------------------------------------------------
1315 // Postconditions
1316
1317 // HWComposer should not have an entry for the display
1318 EXPECT_FALSE(hasHwcDisplay(Case::Display::HWC_DISPLAY_ID));
1319
1320 // The display should not be set up as a primary built-in display.
1321 ASSERT_TRUE(0 <= Case::Display::TYPE &&
1322 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES);
1323 auto displayToken = mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE];
1324 EXPECT_TRUE(displayToken == nullptr);
1325}
1326
1327TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
1328 using Case = SimplePrimaryDisplayCase;
1329
1330 // --------------------------------------------------------------------
1331 // Preconditions
1332
1333 setupCommonPreconditions<Case>();
1334
1335 // The display is already completely set up.
1336 Case::Display::injectHwcDisplay(this);
1337 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1338 existing.inject();
1339
1340 // A hotplug disconnect event is enqueued for a display
1341 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1342 // A hotplug connect event is also enqueued for the same display
1343 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1344
1345 // --------------------------------------------------------------------
1346 // Call Expectations
1347
1348 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1349
1350 setupCommonCallExpectationsForConnectProcessing<Case>();
1351 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1352
1353 // --------------------------------------------------------------------
1354 // Invocation
1355
1356 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1357
1358 // --------------------------------------------------------------------
1359 // Postconditions
1360
1361 // The existing token should have been removed
1362 verifyDisplayIsNotConnected(existing.token());
1363 static_assert(0 <= Case::Display::TYPE &&
1364 Case::Display::TYPE < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES,
1365 "Display type must be a built-in display");
1366 EXPECT_NE(existing.token(), mFlinger.mutableBuiltinDisplays()[Case::Display::TYPE]);
1367
1368 // A new display should be connected in its place
1369
1370 verifyPhysicalDisplayIsConnected<Case>();
1371
1372 // --------------------------------------------------------------------
1373 // Cleanup conditions
1374
1375 EXPECT_CALL(*mComposer,
1376 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1377 .WillOnce(Return(Error::NONE));
1378 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1379}
1380
1381TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
1382 using Case = HwcVirtualDisplayCase;
1383
1384 // --------------------------------------------------------------------
1385 // Preconditions
1386
1387 // The HWC supports at least one virtual display
1388 injectMockComposer(1);
1389
1390 setupCommonPreconditions<Case>();
1391
1392 // A virtual display was added to the current state, and it has a
1393 // surface(producer)
1394 sp<BBinder> displayToken = new BBinder();
1395 DisplayDeviceState info(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
1396 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
1397 info.surface = surface;
1398 mFlinger.mutableCurrentState().displays.add(displayToken, info);
1399
1400 // --------------------------------------------------------------------
1401 // Call Expectations
1402
1403 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1404 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1405
1406 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
1407 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
1408 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
1409 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
1410 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
1411 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
1412 Return(NO_ERROR)));
1413 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
1414 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
1415
1416 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
1417
1418 EXPECT_CALL(*mProducer, connect(_, _, _, _)).Times(1);
1419 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
1420
1421 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
1422 Case::WideColorSupport::setupComposerCallExpectations(this);
1423 Case::HdrSupport::setupComposerCallExpectations(this);
1424
1425 // --------------------------------------------------------------------
1426 // Invocation
1427
1428 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1429
1430 // --------------------------------------------------------------------
1431 // Postconditions
1432
1433 // The display device should have been set up in the list of displays.
1434 verifyDisplayIsConnected<Case>(displayToken);
1435
1436 // --------------------------------------------------------------------
1437 // Cleanup conditions
1438
1439 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
1440 .WillOnce(Return(Error::NONE));
1441 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1442}
1443
1444TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
1445 using Case = HwcVirtualDisplayCase;
1446
1447 // --------------------------------------------------------------------
1448 // Preconditions
1449
1450 // The HWC supports at least one virtual display
1451 injectMockComposer(1);
1452
1453 setupCommonPreconditions<Case>();
1454
1455 // A virtual display was added to the current state, but it does not have a
1456 // surface.
1457 sp<BBinder> displayToken = new BBinder();
1458 DisplayDeviceState info(Case::Display::TYPE, static_cast<bool>(Case::Display::SECURE));
1459 mFlinger.mutableCurrentState().displays.add(displayToken, info);
1460
1461 // --------------------------------------------------------------------
1462 // Call Expectations
1463
1464 // --------------------------------------------------------------------
1465 // Invocation
1466
1467 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1468
1469 // --------------------------------------------------------------------
1470 // Postconditions
1471
1472 // There will not be a display device set up.
1473 EXPECT_FALSE(hasDisplayDevice(displayToken));
1474
1475 // The drawing display state will be set from the current display state.
1476 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1477 const auto& draw = getDrawingDisplayState(displayToken);
1478 EXPECT_EQ(Case::Display::TYPE, draw.type);
1479}
1480
1481TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
1482 using Case = HwcVirtualDisplayCase;
1483
1484 // --------------------------------------------------------------------
1485 // Preconditions
1486
1487 // A virtual display is set up but is removed from the current state.
1488 mFlinger.mutableHwcDisplayData().resize(3);
1489 Case::Display::injectHwcDisplay(this);
1490 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1491 existing.inject();
1492 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
1493
1494 // --------------------------------------------------------------------
1495 // Call Expectations
1496
1497 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1498
1499 // --------------------------------------------------------------------
1500 // Invocation
1501
1502 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1503
1504 // --------------------------------------------------------------------
1505 // Postconditions
1506
1507 // The existing token should have been removed
1508 verifyDisplayIsNotConnected(existing.token());
1509}
1510
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001511TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
1512 using Case = NonHwcVirtualDisplayCase;
1513
1514 constexpr uint32_t oldLayerStack = 0u;
1515 constexpr uint32_t newLayerStack = 123u;
1516
1517 // --------------------------------------------------------------------
1518 // Preconditions
1519
1520 // A display is set up
1521 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1522 display.inject();
1523
1524 // There is a change to the layerStack state
1525 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
1526 display.mutableCurrentDisplayState().layerStack = newLayerStack;
1527
1528 // --------------------------------------------------------------------
1529 // Invocation
1530
1531 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1532
1533 // --------------------------------------------------------------------
1534 // Postconditions
1535
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001536 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001537}
1538
1539TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
1540 using Case = NonHwcVirtualDisplayCase;
1541
1542 constexpr int oldTransform = 0;
1543 constexpr int newTransform = 2;
1544
1545 // --------------------------------------------------------------------
1546 // Preconditions
1547
1548 // A display is set up
1549 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1550 display.inject();
1551
1552 // There is a change to the orientation state
1553 display.mutableDrawingDisplayState().orientation = oldTransform;
1554 display.mutableCurrentDisplayState().orientation = newTransform;
1555
1556 // --------------------------------------------------------------------
1557 // Invocation
1558
1559 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1560
1561 // --------------------------------------------------------------------
1562 // Postconditions
1563
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001564 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001565}
1566
1567TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
1568 using Case = NonHwcVirtualDisplayCase;
1569
1570 const Rect oldViewport(0, 0, 0, 0);
1571 const Rect newViewport(0, 0, 123, 456);
1572
1573 // --------------------------------------------------------------------
1574 // Preconditions
1575
1576 // A display is set up
1577 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1578 display.inject();
1579
1580 // There is a change to the viewport state
1581 display.mutableDrawingDisplayState().viewport = oldViewport;
1582 display.mutableCurrentDisplayState().viewport = newViewport;
1583
1584 // --------------------------------------------------------------------
1585 // Invocation
1586
1587 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1588
1589 // --------------------------------------------------------------------
1590 // Postconditions
1591
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001592 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001593}
1594
1595TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
1596 using Case = NonHwcVirtualDisplayCase;
1597
1598 const Rect oldFrame(0, 0, 0, 0);
1599 const Rect newFrame(0, 0, 123, 456);
1600
1601 // --------------------------------------------------------------------
1602 // Preconditions
1603
1604 // A display is set up
1605 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1606 display.inject();
1607
1608 // There is a change to the viewport state
1609 display.mutableDrawingDisplayState().frame = oldFrame;
1610 display.mutableCurrentDisplayState().frame = newFrame;
1611
1612 // --------------------------------------------------------------------
1613 // Invocation
1614
1615 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1616
1617 // --------------------------------------------------------------------
1618 // Postconditions
1619
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001620 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08001621}
1622
1623TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
1624 using Case = NonHwcVirtualDisplayCase;
1625
1626 constexpr int oldWidth = 0;
1627 constexpr int oldHeight = 10;
1628 constexpr int newWidth = 123;
1629
1630 // --------------------------------------------------------------------
1631 // Preconditions
1632
1633 // A display is set up
1634 auto nativeWindow = new mock::NativeWindow();
1635 auto displaySurface = new mock::DisplaySurface();
1636 auto renderSurface = new RE::mock::Surface();
1637 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1638 display.setNativeWindow(nativeWindow);
1639 display.setDisplaySurface(displaySurface);
1640 display.setRenderSurface(std::unique_ptr<RE::Surface>(renderSurface));
1641 display.inject();
1642
1643 // There is a change to the viewport state
1644 display.mutableDrawingDisplayState().width = oldWidth;
1645 display.mutableDrawingDisplayState().height = oldHeight;
1646 display.mutableCurrentDisplayState().width = newWidth;
1647 display.mutableCurrentDisplayState().height = oldHeight;
1648
1649 // --------------------------------------------------------------------
1650 // Call Expectations
1651
1652 EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
1653 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
1654 EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
1655 EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(newWidth));
1656 EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(oldHeight));
1657
1658 // --------------------------------------------------------------------
1659 // Invocation
1660
1661 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1662}
1663
1664TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
1665 using Case = NonHwcVirtualDisplayCase;
1666
1667 constexpr int oldWidth = 0;
1668 constexpr int oldHeight = 10;
1669 constexpr int newHeight = 123;
1670
1671 // --------------------------------------------------------------------
1672 // Preconditions
1673
1674 // A display is set up
1675 auto nativeWindow = new mock::NativeWindow();
1676 auto displaySurface = new mock::DisplaySurface();
1677 auto renderSurface = new RE::mock::Surface();
1678 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1679 display.setNativeWindow(nativeWindow);
1680 display.setDisplaySurface(displaySurface);
1681 display.setRenderSurface(std::unique_ptr<RE::Surface>(renderSurface));
1682 display.inject();
1683
1684 // There is a change to the viewport state
1685 display.mutableDrawingDisplayState().width = oldWidth;
1686 display.mutableDrawingDisplayState().height = oldHeight;
1687 display.mutableCurrentDisplayState().width = oldWidth;
1688 display.mutableCurrentDisplayState().height = newHeight;
1689
1690 // --------------------------------------------------------------------
1691 // Call Expectations
1692
1693 EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
1694 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
1695 EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
1696 EXPECT_CALL(*renderSurface, queryWidth()).WillOnce(Return(oldWidth));
1697 EXPECT_CALL(*renderSurface, queryHeight()).WillOnce(Return(newHeight));
1698
1699 // --------------------------------------------------------------------
1700 // Invocation
1701
1702 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1703}
1704
Lloyd Pique9d9cf402018-02-16 17:47:13 -08001705/* ------------------------------------------------------------------------
1706 * SurfaceFlinger::setDisplayStateLocked
1707 */
1708
1709TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
1710 // --------------------------------------------------------------------
1711 // Preconditions
1712
1713 // We have an unknown display token not associated with a known display
1714 sp<BBinder> displayToken = new BBinder();
1715
1716 // The requested display state references the unknown display.
1717 DisplayState state;
1718 state.what = DisplayState::eLayerStackChanged;
1719 state.token = displayToken;
1720 state.layerStack = 456;
1721
1722 // --------------------------------------------------------------------
1723 // Invocation
1724
1725 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1726
1727 // --------------------------------------------------------------------
1728 // Postconditions
1729
1730 // The returned flags are empty
1731 EXPECT_EQ(0u, flags);
1732
1733 // The display token still doesn't match anything known.
1734 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
1735}
1736
1737TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithInvalidDisplay) {
1738 using Case = InvalidDisplayCase;
1739
1740 // --------------------------------------------------------------------
1741 // Preconditions
1742
1743 // An invalid display is set up
1744 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1745 display.inject();
1746
1747 // The invalid display has some state
1748 display.mutableCurrentDisplayState().layerStack = 654u;
1749
1750 // The requested display state tries to change the display state.
1751 DisplayState state;
1752 state.what = DisplayState::eLayerStackChanged;
1753 state.token = display.token();
1754 state.layerStack = 456;
1755
1756 // --------------------------------------------------------------------
1757 // Invocation
1758
1759 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1760
1761 // --------------------------------------------------------------------
1762 // Postconditions
1763
1764 // The returned flags are empty
1765 EXPECT_EQ(0u, flags);
1766
1767 // The current display layer stack value is unchanged.
1768 EXPECT_EQ(654u, getCurrentDisplayState(display.token()).layerStack);
1769}
1770
1771TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
1772 using Case = SimplePrimaryDisplayCase;
1773
1774 // --------------------------------------------------------------------
1775 // Preconditions
1776
1777 // A display is already set up
1778 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1779 display.inject();
1780
1781 // No changes are made to the display
1782 DisplayState state;
1783 state.what = 0;
1784 state.token = display.token();
1785
1786 // --------------------------------------------------------------------
1787 // Invocation
1788
1789 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1790
1791 // --------------------------------------------------------------------
1792 // Postconditions
1793
1794 // The returned flags are empty
1795 EXPECT_EQ(0u, flags);
1796}
1797
1798TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
1799 using Case = SimplePrimaryDisplayCase;
1800
1801 // --------------------------------------------------------------------
1802 // Preconditions
1803
1804 // A display is already set up
1805 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1806 display.inject();
1807
1808 // There is a surface that can be set.
1809 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
1810
1811 // The current display state has the surface set
1812 display.mutableCurrentDisplayState().surface = surface;
1813
1814 // The incoming request sets the same surface
1815 DisplayState state;
1816 state.what = DisplayState::eSurfaceChanged;
1817 state.token = display.token();
1818 state.surface = surface;
1819
1820 // --------------------------------------------------------------------
1821 // Invocation
1822
1823 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1824
1825 // --------------------------------------------------------------------
1826 // Postconditions
1827
1828 // The returned flags are empty
1829 EXPECT_EQ(0u, flags);
1830
1831 // The current display state is unchanged.
1832 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
1833}
1834
1835TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
1836 using Case = SimplePrimaryDisplayCase;
1837
1838 // --------------------------------------------------------------------
1839 // Preconditions
1840
1841 // A display is already set up
1842 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1843 display.inject();
1844
1845 // There is a surface that can be set.
1846 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
1847
1848 // The current display state does not have a surface
1849 display.mutableCurrentDisplayState().surface = nullptr;
1850
1851 // The incoming request sets a surface
1852 DisplayState state;
1853 state.what = DisplayState::eSurfaceChanged;
1854 state.token = display.token();
1855 state.surface = surface;
1856
1857 // --------------------------------------------------------------------
1858 // Invocation
1859
1860 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1861
1862 // --------------------------------------------------------------------
1863 // Postconditions
1864
1865 // The returned flags indicate a transaction is needed
1866 EXPECT_EQ(eDisplayTransactionNeeded, flags);
1867
1868 // The current display layer stack state is set to the new value
1869 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
1870}
1871
1872TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
1873 using Case = SimplePrimaryDisplayCase;
1874
1875 // --------------------------------------------------------------------
1876 // Preconditions
1877
1878 // A display is already set up
1879 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1880 display.inject();
1881
1882 // The display has a layer stack set
1883 display.mutableCurrentDisplayState().layerStack = 456u;
1884
1885 // The incoming request sets the same layer stack
1886 DisplayState state;
1887 state.what = DisplayState::eLayerStackChanged;
1888 state.token = display.token();
1889 state.layerStack = 456u;
1890
1891 // --------------------------------------------------------------------
1892 // Invocation
1893
1894 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1895
1896 // --------------------------------------------------------------------
1897 // Postconditions
1898
1899 // The returned flags are empty
1900 EXPECT_EQ(0u, flags);
1901
1902 // The current display state is unchanged
1903 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
1904}
1905
1906TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
1907 using Case = SimplePrimaryDisplayCase;
1908
1909 // --------------------------------------------------------------------
1910 // Preconditions
1911
1912 // A display is set up
1913 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1914 display.inject();
1915
1916 // The display has a layer stack set
1917 display.mutableCurrentDisplayState().layerStack = 654u;
1918
1919 // The incoming request sets a different layer stack
1920 DisplayState state;
1921 state.what = DisplayState::eLayerStackChanged;
1922 state.token = display.token();
1923 state.layerStack = 456u;
1924
1925 // --------------------------------------------------------------------
1926 // Invocation
1927
1928 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1929
1930 // --------------------------------------------------------------------
1931 // Postconditions
1932
1933 // The returned flags indicate a transaction is needed
1934 EXPECT_EQ(eDisplayTransactionNeeded, flags);
1935
1936 // The desired display state has been set to the new value.
1937 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
1938}
1939
1940TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
1941 using Case = SimplePrimaryDisplayCase;
1942 constexpr int initialOrientation = 180;
1943 const Rect initialFrame = {1, 2, 3, 4};
1944 const Rect initialViewport = {5, 6, 7, 8};
1945
1946 // --------------------------------------------------------------------
1947 // Preconditions
1948
1949 // A display is set up
1950 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1951 display.inject();
1952
1953 // The current display state projection state is all set
1954 display.mutableCurrentDisplayState().orientation = initialOrientation;
1955 display.mutableCurrentDisplayState().frame = initialFrame;
1956 display.mutableCurrentDisplayState().viewport = initialViewport;
1957
1958 // The incoming request sets the same projection state
1959 DisplayState state;
1960 state.what = DisplayState::eDisplayProjectionChanged;
1961 state.token = display.token();
1962 state.orientation = initialOrientation;
1963 state.frame = initialFrame;
1964 state.viewport = initialViewport;
1965
1966 // --------------------------------------------------------------------
1967 // Invocation
1968
1969 uint32_t flags = mFlinger.setDisplayStateLocked(state);
1970
1971 // --------------------------------------------------------------------
1972 // Postconditions
1973
1974 // The returned flags are empty
1975 EXPECT_EQ(0u, flags);
1976
1977 // The current display state is unchanged
1978 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
1979
1980 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
1981 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
1982}
1983
1984TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
1985 using Case = SimplePrimaryDisplayCase;
1986 constexpr int initialOrientation = 90;
1987 constexpr int desiredOrientation = 180;
1988
1989 // --------------------------------------------------------------------
1990 // Preconditions
1991
1992 // A display is set up
1993 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
1994 display.inject();
1995
1996 // The current display state has an orientation set
1997 display.mutableCurrentDisplayState().orientation = initialOrientation;
1998
1999 // The incoming request sets a different orientation
2000 DisplayState state;
2001 state.what = DisplayState::eDisplayProjectionChanged;
2002 state.token = display.token();
2003 state.orientation = desiredOrientation;
2004
2005 // --------------------------------------------------------------------
2006 // Invocation
2007
2008 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2009
2010 // --------------------------------------------------------------------
2011 // Postconditions
2012
2013 // The returned flags indicate a transaction is needed
2014 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2015
2016 // The current display state has the new value.
2017 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2018}
2019
2020TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2021 using Case = SimplePrimaryDisplayCase;
2022 const Rect initialFrame = {0, 0, 0, 0};
2023 const Rect desiredFrame = {5, 6, 7, 8};
2024
2025 // --------------------------------------------------------------------
2026 // Preconditions
2027
2028 // A display is set up
2029 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2030 display.inject();
2031
2032 // The current display state does not have a frame
2033 display.mutableCurrentDisplayState().frame = initialFrame;
2034
2035 // The incoming request sets a frame
2036 DisplayState state;
2037 state.what = DisplayState::eDisplayProjectionChanged;
2038 state.token = display.token();
2039 state.frame = desiredFrame;
2040
2041 // --------------------------------------------------------------------
2042 // Invocation
2043
2044 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2045
2046 // --------------------------------------------------------------------
2047 // Postconditions
2048
2049 // The returned flags indicate a transaction is needed
2050 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2051
2052 // The current display state has the new value.
2053 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2054}
2055
2056TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2057 using Case = SimplePrimaryDisplayCase;
2058 const Rect initialViewport = {0, 0, 0, 0};
2059 const Rect desiredViewport = {5, 6, 7, 8};
2060
2061 // --------------------------------------------------------------------
2062 // Preconditions
2063
2064 // A display is set up
2065 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2066 display.inject();
2067
2068 // The current display state does not have a viewport
2069 display.mutableCurrentDisplayState().viewport = initialViewport;
2070
2071 // The incoming request sets a viewport
2072 DisplayState state;
2073 state.what = DisplayState::eDisplayProjectionChanged;
2074 state.token = display.token();
2075 state.viewport = desiredViewport;
2076
2077 // --------------------------------------------------------------------
2078 // Invocation
2079
2080 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2081
2082 // --------------------------------------------------------------------
2083 // Postconditions
2084
2085 // The returned flags indicate a transaction is needed
2086 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2087
2088 // The current display state has the new value.
2089 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2090}
2091
2092TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2093 using Case = SimplePrimaryDisplayCase;
2094 constexpr uint32_t initialWidth = 1024;
2095 constexpr uint32_t initialHeight = 768;
2096
2097 // --------------------------------------------------------------------
2098 // Preconditions
2099
2100 // A display is set up
2101 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2102 display.inject();
2103
2104 // The current display state has a size set
2105 display.mutableCurrentDisplayState().width = initialWidth;
2106 display.mutableCurrentDisplayState().height = initialHeight;
2107
2108 // The incoming request sets the same display size
2109 DisplayState state;
2110 state.what = DisplayState::eDisplaySizeChanged;
2111 state.token = display.token();
2112 state.width = initialWidth;
2113 state.height = initialHeight;
2114
2115 // --------------------------------------------------------------------
2116 // Invocation
2117
2118 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2119
2120 // --------------------------------------------------------------------
2121 // Postconditions
2122
2123 // The returned flags are empty
2124 EXPECT_EQ(0u, flags);
2125
2126 // The current display state is unchanged
2127 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2128 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2129}
2130
2131TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
2132 using Case = SimplePrimaryDisplayCase;
2133 constexpr uint32_t initialWidth = 0;
2134 constexpr uint32_t desiredWidth = 1024;
2135
2136 // --------------------------------------------------------------------
2137 // Preconditions
2138
2139 // A display is set up
2140 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2141 display.inject();
2142
2143 // The display does not yet have a width
2144 display.mutableCurrentDisplayState().width = initialWidth;
2145
2146 // The incoming request sets a display width
2147 DisplayState state;
2148 state.what = DisplayState::eDisplaySizeChanged;
2149 state.token = display.token();
2150 state.width = desiredWidth;
2151
2152 // --------------------------------------------------------------------
2153 // Invocation
2154
2155 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2156
2157 // --------------------------------------------------------------------
2158 // Postconditions
2159
2160 // The returned flags indicate a transaction is needed
2161 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2162
2163 // The current display state has the new value.
2164 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
2165}
2166
2167TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
2168 using Case = SimplePrimaryDisplayCase;
2169 constexpr uint32_t initialHeight = 0;
2170 constexpr uint32_t desiredHeight = 768;
2171
2172 // --------------------------------------------------------------------
2173 // Preconditions
2174
2175 // A display is set up
2176 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2177 display.inject();
2178
2179 // The display does not yet have a height
2180 display.mutableCurrentDisplayState().height = initialHeight;
2181
2182 // The incoming request sets a display height
2183 DisplayState state;
2184 state.what = DisplayState::eDisplaySizeChanged;
2185 state.token = display.token();
2186 state.height = desiredHeight;
2187
2188 // --------------------------------------------------------------------
2189 // Invocation
2190
2191 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2192
2193 // --------------------------------------------------------------------
2194 // Postconditions
2195
2196 // The returned flags indicate a transaction is needed
2197 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2198
2199 // The current display state has the new value.
2200 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
2201}
2202
Lloyd Pique86016da2018-03-01 16:09:38 -08002203/* ------------------------------------------------------------------------
2204 * SurfaceFlinger::onInitializeDisplays
2205 */
2206
2207TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
2208 using Case = SimplePrimaryDisplayCase;
2209
2210 // --------------------------------------------------------------------
2211 // Preconditions
2212
2213 // A primary display is set up
2214 Case::Display::injectHwcDisplay(this);
2215 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
2216 primaryDisplay.inject();
2217
2218 // --------------------------------------------------------------------
2219 // Call Expectations
2220
2221 // We expect the surface interceptor to possibly be used, but we treat it as
2222 // disabled since it is called as a side effect rather than directly by this
2223 // function.
2224 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
2225
2226 // We expect a call to get the active display config.
2227 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
2228
2229 // We expect invalidate() to be invoked once to trigger display transaction
2230 // processing.
2231 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
2232
2233 // --------------------------------------------------------------------
2234 // Invocation
2235
2236 mFlinger.onInitializeDisplays();
2237
2238 // --------------------------------------------------------------------
2239 // Postconditions
2240
2241 // The primary display should have a current state
2242 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
2243 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
2244 // The layer stack state should be set to zero
2245 EXPECT_EQ(0u, primaryDisplayState.layerStack);
2246 // The orientation state should be set to zero
2247 EXPECT_EQ(0, primaryDisplayState.orientation);
2248
2249 // The frame state should be set to INVALID
2250 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
2251
2252 // The viewport state should be set to INVALID
2253 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
2254
2255 // The width and height should both be zero
2256 EXPECT_EQ(0u, primaryDisplayState.width);
2257 EXPECT_EQ(0u, primaryDisplayState.height);
2258
2259 // The display should be set to HWC_POWER_MODE_NORMAL
2260 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
2261 auto displayDevice = primaryDisplay.mutableDisplayDevice();
2262 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
2263
2264 // The display refresh period should be set in the frame tracker.
2265 FrameStats stats;
2266 mFlinger.getAnimFrameTracker().getStats(&stats);
2267 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
2268
2269 // The display transaction needed flag should be set.
2270 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
2271
2272 // The compositor timing should be set to default values
2273 const auto& compositorTiming = mFlinger.getCompositorTiming();
2274 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
2275 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
2276 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
2277}
2278
Lloyd Piquef58625d2017-12-19 13:22:33 -08002279} // namespace
2280} // namespace android