blob: b1a49514518b8bc3a4962dbaec74082e93932a02 [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
Dominik Laskowski075d3172018-05-24 15:50:06 -070020#include <type_traits>
21
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070022#include <compositionengine/Display.h>
23#include <compositionengine/DisplayColorProfile.h>
Lloyd Pique542307f2018-10-19 13:24:08 -070024#include <compositionengine/mock/DisplaySurface.h>
Lloyd Piquef58625d2017-12-19 13:22:33 -080025#include <gmock/gmock.h>
26#include <gtest/gtest.h>
Lloyd Pique1ebe0902019-10-04 14:47:13 -070027#include <gui/mock/GraphicBufferConsumer.h>
28#include <gui/mock/GraphicBufferProducer.h>
Lloyd Piquef58625d2017-12-19 13:22:33 -080029#include <log/log.h>
Lloyd Pique3823e7b2018-10-18 16:58:10 -070030#include <renderengine/mock/RenderEngine.h>
Valerie Hau9758ae02018-10-09 16:05:09 -070031#include <ui/DebugUtils.h>
Dominik Laskowski075d3172018-05-24 15:50:06 -070032
33#include "DisplayIdentificationTest.h"
Ana Krulecafb45842019-02-13 13:33:03 -080034#include "TestableScheduler.h"
Lloyd Piquef58625d2017-12-19 13:22:33 -080035#include "TestableSurfaceFlinger.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080036#include "mock/DisplayHardware/MockComposer.h"
Lloyd Pique41be5d22018-06-21 13:11:48 -070037#include "mock/MockDispSync.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080038#include "mock/MockEventControlThread.h"
39#include "mock/MockEventThread.h"
40#include "mock/MockMessageQueue.h"
41#include "mock/MockNativeWindowSurface.h"
42#include "mock/MockSurfaceInterceptor.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080043#include "mock/system/window/MockNativeWindow.h"
Lloyd Piquef58625d2017-12-19 13:22:33 -080044
45namespace android {
46namespace {
47
Lloyd Piquee39cad22017-12-20 17:01:29 -080048using testing::_;
Lloyd Piquee39cad22017-12-20 17:01:29 -080049using testing::DoAll;
50using testing::Mock;
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080051using testing::ResultOf;
Lloyd Piquee39cad22017-12-20 17:01:29 -080052using testing::Return;
53using testing::SetArgPointee;
54
Lloyd Piqued883d5a2018-04-27 19:32:30 -070055using android::Hwc2::ColorMode;
Lloyd Piquee39cad22017-12-20 17:01:29 -080056using android::Hwc2::Error;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070057using android::Hwc2::Hdr;
Lloyd Piquee39cad22017-12-20 17:01:29 -080058using android::Hwc2::IComposer;
59using android::Hwc2::IComposerClient;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070060using android::Hwc2::PerFrameMetadataKey;
61using android::Hwc2::RenderIntent;
Lloyd Piquee39cad22017-12-20 17:01:29 -080062
Lloyd Piquec11e0d32018-01-22 18:44:59 -080063using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
64using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
Lloyd Pique1fa4d462018-01-22 18:03:16 -080065using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080066using HWC2Display = TestableSurfaceFlinger::HWC2Display;
Lloyd Piquebc792092018-01-17 11:52:30 -080067
Lloyd Piquec11e0d32018-01-22 18:44:59 -080068constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
Lloyd Piquee39cad22017-12-20 17:01:29 -080069constexpr int32_t DEFAULT_DPI = 320;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080070constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
Lloyd Piquee39cad22017-12-20 17:01:29 -080071
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -080072constexpr int HWC_POWER_MODE_LEET = 1337; // An out of range power mode value
73
Lloyd Piquec11e0d32018-01-22 18:44:59 -080074/* ------------------------------------------------------------------------
75 * Boolean avoidance
76 *
77 * To make calls and template instantiations more readable, we define some
78 * local enums along with an implicit bool conversion.
79 */
80
81#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
82
Lloyd Piquec11e0d32018-01-22 18:44:59 -080083BOOL_SUBSTITUTE(Async);
Dominik Laskowski075d3172018-05-24 15:50:06 -070084BOOL_SUBSTITUTE(Critical);
85BOOL_SUBSTITUTE(Primary);
Lloyd Piquec11e0d32018-01-22 18:44:59 -080086BOOL_SUBSTITUTE(Secure);
Dominik Laskowski075d3172018-05-24 15:50:06 -070087BOOL_SUBSTITUTE(Virtual);
Lloyd Piquec11e0d32018-01-22 18:44:59 -080088
89/* ------------------------------------------------------------------------
90 *
91 */
Lloyd Pique1fa4d462018-01-22 18:03:16 -080092
Lloyd Piquef58625d2017-12-19 13:22:33 -080093class DisplayTransactionTest : public testing::Test {
Lloyd Piquec11e0d32018-01-22 18:44:59 -080094public:
Lloyd Piquef58625d2017-12-19 13:22:33 -080095 DisplayTransactionTest();
96 ~DisplayTransactionTest() override;
97
Lloyd Pique1fa4d462018-01-22 18:03:16 -080098 // --------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -080099 // Mock/Fake injection
Lloyd Piquef58625d2017-12-19 13:22:33 -0800100
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700101 void injectMockScheduler();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800102 void injectMockComposer(int virtualDisplayCount);
103 void injectFakeBufferQueueFactory();
104 void injectFakeNativeWindowSurfaceFactory();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800105
106 // --------------------------------------------------------------------
107 // Postcondition helpers
108
Dominik Laskowski075d3172018-05-24 15:50:06 -0700109 bool hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800110 bool hasTransactionFlagSet(int flag);
111 bool hasDisplayDevice(sp<IBinder> displayToken);
112 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
113 bool hasCurrentDisplayState(sp<IBinder> displayToken);
114 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
115 bool hasDrawingDisplayState(sp<IBinder> displayToken);
116 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
117
118 // --------------------------------------------------------------------
119 // Test instances
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800120
Lloyd Piquef58625d2017-12-19 13:22:33 -0800121 TestableSurfaceFlinger mFlinger;
Alec Mouriba013fa2018-10-16 12:43:11 -0700122 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800123 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800124
125 // These mocks are created by the test, but are destroyed by SurfaceFlinger
126 // by virtue of being stored into a std::unique_ptr. However we still need
127 // to keep a reference to them for use in setting up call expectations.
Peiyong Lin833074a2018-08-28 11:53:54 -0700128 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800129 Hwc2::mock::Composer* mComposer = nullptr;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800130 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
131 mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700132
133 mock::DispSync* mPrimaryDispSync = new mock::DispSync;
134 mock::EventControlThread* mEventControlThread = new mock::EventControlThread;
135 mock::EventThread* mEventThread = new mock::EventThread;
136 mock::EventThread* mSFEventThread = new mock::EventThread;
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800137
138 // These mocks are created only when expected to be created via a factory.
139 sp<mock::GraphicBufferConsumer> mConsumer;
140 sp<mock::GraphicBufferProducer> mProducer;
Lloyd Pique22098362018-09-13 11:46:49 -0700141 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
Lloyd Piquef58625d2017-12-19 13:22:33 -0800142};
143
144DisplayTransactionTest::DisplayTransactionTest() {
145 const ::testing::TestInfo* const test_info =
146 ::testing::UnitTest::GetInstance()->current_test_info();
147 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Lloyd Piquee39cad22017-12-20 17:01:29 -0800148
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800149 // Default to no wide color display support configured
150 mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700151 mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800152 mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800153
154 // Default to using HWC virtual displays
155 mFlinger.mutableUseHwcVirtualDisplays() = true;
156
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800157 mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
158 ADD_FAILURE() << "Unexpected request to create a buffer queue.";
159 });
160
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800161 mFlinger.setCreateNativeWindowSurface([](auto) {
162 ADD_FAILURE() << "Unexpected request to create a native window surface.";
163 return nullptr;
164 });
165
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700166 injectMockScheduler();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800167 mFlinger.mutableEventQueue().reset(mMessageQueue);
Peiyong Lin833074a2018-08-28 11:53:54 -0700168 mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800169 mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800170
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800171 injectMockComposer(0);
Lloyd Piquef58625d2017-12-19 13:22:33 -0800172}
173
174DisplayTransactionTest::~DisplayTransactionTest() {
175 const ::testing::TestInfo* const test_info =
176 ::testing::UnitTest::GetInstance()->current_test_info();
177 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
178}
179
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700180void DisplayTransactionTest::injectMockScheduler() {
Ana Krulecafb45842019-02-13 13:33:03 -0800181 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700182 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
183 .WillOnce(Return(new EventThreadConnection(mEventThread, ResyncCallback(),
184 ISurfaceComposer::eConfigChangedSuppress)));
185
Ana Krulecafb45842019-02-13 13:33:03 -0800186 EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700187 EXPECT_CALL(*mSFEventThread, createEventConnection(_, _))
188 .WillOnce(Return(new EventThreadConnection(mSFEventThread, ResyncCallback(),
189 ISurfaceComposer::eConfigChangedSuppress)));
Ana Krulecafb45842019-02-13 13:33:03 -0800190
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700191 mFlinger.setupScheduler(std::unique_ptr<DispSync>(mPrimaryDispSync),
192 std::unique_ptr<EventControlThread>(mEventControlThread),
193 std::unique_ptr<EventThread>(mEventThread),
194 std::unique_ptr<EventThread>(mSFEventThread));
Ana Krulecafb45842019-02-13 13:33:03 -0800195}
196
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800197void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
198 mComposer = new Hwc2::mock::Composer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800199 EXPECT_CALL(*mComposer, getCapabilities())
200 .WillOnce(Return(std::vector<IComposer::Capability>()));
201 EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
202 mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
Lloyd Piquef58625d2017-12-19 13:22:33 -0800203
Lloyd Piquee39cad22017-12-20 17:01:29 -0800204 Mock::VerifyAndClear(mComposer);
205}
206
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800207void DisplayTransactionTest::injectFakeBufferQueueFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800208 // This setup is only expected once per test.
209 ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
210
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800211 mConsumer = new mock::GraphicBufferConsumer();
212 mProducer = new mock::GraphicBufferProducer();
213
214 mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
215 *outProducer = mProducer;
216 *outConsumer = mConsumer;
217 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800218}
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800219
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800220void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800221 // This setup is only expected once per test.
222 ASSERT_TRUE(mNativeWindowSurface == nullptr);
223
Lloyd Pique22098362018-09-13 11:46:49 -0700224 mNativeWindowSurface = new surfaceflinger::mock::NativeWindowSurface();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800225
Lloyd Pique22098362018-09-13 11:46:49 -0700226 mFlinger.setCreateNativeWindowSurface([this](auto) {
227 return std::unique_ptr<surfaceflinger::NativeWindowSurface>(mNativeWindowSurface);
228 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800229}
230
Dominik Laskowski075d3172018-05-24 15:50:06 -0700231bool DisplayTransactionTest::hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId) {
232 return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800233}
234
235bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
236 return mFlinger.mutableTransactionFlags() & flag;
237}
238
239bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700240 return mFlinger.mutableDisplays().count(displayToken) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800241}
242
243sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700244 return mFlinger.mutableDisplays()[displayToken];
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800245}
246
247bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
248 return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
249}
250
251const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
252 return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
253}
254
255bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
256 return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
257}
258
259const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
260 return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
261}
262
263/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800264 *
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800265 */
266
Dominik Laskowski075d3172018-05-24 15:50:06 -0700267template <typename PhysicalDisplay>
268struct PhysicalDisplayId {};
269
Dominik Laskowski34157762018-10-31 13:07:19 -0700270template <DisplayId::Type displayId>
271using VirtualDisplayId = std::integral_constant<DisplayId::Type, displayId>;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700272
273struct NoDisplayId {};
274
275template <typename>
276struct IsPhysicalDisplayId : std::bool_constant<false> {};
277
278template <typename PhysicalDisplay>
279struct IsPhysicalDisplayId<PhysicalDisplayId<PhysicalDisplay>> : std::bool_constant<true> {};
280
281template <typename>
282struct DisplayIdGetter;
283
284template <typename PhysicalDisplay>
285struct DisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
286 static std::optional<DisplayId> get() {
287 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
288 return getFallbackDisplayId(static_cast<bool>(PhysicalDisplay::PRIMARY)
289 ? HWC_DISPLAY_PRIMARY
290 : HWC_DISPLAY_EXTERNAL);
291 }
292
293 const auto info =
294 parseDisplayIdentificationData(PhysicalDisplay::PORT,
295 PhysicalDisplay::GET_IDENTIFICATION_DATA());
296 return info ? std::make_optional(info->id) : std::nullopt;
297 }
298};
299
Dominik Laskowski34157762018-10-31 13:07:19 -0700300template <DisplayId::Type displayId>
Dominik Laskowski075d3172018-05-24 15:50:06 -0700301struct DisplayIdGetter<VirtualDisplayId<displayId>> {
Dominik Laskowski34157762018-10-31 13:07:19 -0700302 static std::optional<DisplayId> get() { return DisplayId{displayId}; }
Dominik Laskowski075d3172018-05-24 15:50:06 -0700303};
304
305template <>
306struct DisplayIdGetter<NoDisplayId> {
307 static std::optional<DisplayId> get() { return {}; }
308};
309
310// DisplayIdType can be:
311// 1) PhysicalDisplayId<...> for generated ID of physical display backed by HWC.
312// 2) VirtualDisplayId<...> for hard-coded ID of virtual display backed by HWC.
313// 3) NoDisplayId for virtual display without HWC backing.
314template <typename DisplayIdType, int width, int height, Critical critical, Async async,
315 Secure secure, Primary primary, int grallocUsage>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800316struct DisplayVariant {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700317 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
318
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800319 // The display width and height
320 static constexpr int WIDTH = width;
321 static constexpr int HEIGHT = height;
322
323 static constexpr int GRALLOC_USAGE = grallocUsage;
324
Dominik Laskowski075d3172018-05-24 15:50:06 -0700325 // Whether the display is virtual or physical
326 static constexpr Virtual VIRTUAL =
327 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800328
329 // When creating native window surfaces for the framebuffer, whether those should be critical
330 static constexpr Critical CRITICAL = critical;
331
332 // When creating native window surfaces for the framebuffer, whether those should be async
333 static constexpr Async ASYNC = async;
334
335 // Whether the display should be treated as secure
336 static constexpr Secure SECURE = secure;
337
Dominik Laskowski075d3172018-05-24 15:50:06 -0700338 // Whether the display is primary
339 static constexpr Primary PRIMARY = primary;
340
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800341 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700342 auto injector =
343 FakeDisplayDeviceInjector(test->mFlinger, DISPLAY_ID::get(),
344 static_cast<bool>(VIRTUAL), static_cast<bool>(PRIMARY));
345
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800346 injector.setSecure(static_cast<bool>(SECURE));
Alec Mouriba013fa2018-10-16 12:43:11 -0700347 injector.setNativeWindow(test->mNativeWindow);
348
349 // Creating a DisplayDevice requires getting default dimensions from the
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800350 // native window along with some other initial setup.
Alec Mouriba013fa2018-10-16 12:43:11 -0700351 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
352 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
353 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
354 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800355 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
356 .WillRepeatedly(Return(0));
357 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
358 .WillRepeatedly(Return(0));
359 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
360 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700361 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
362 .WillRepeatedly(Return(0));
363
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800364 return injector;
365 }
366
367 // Called by tests to set up any native window creation call expectations.
368 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
369 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
370 .WillOnce(Return(test->mNativeWindow));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800371
Alec Mouriba013fa2018-10-16 12:43:11 -0700372 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
373 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
374 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
375 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800376 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
377 .WillRepeatedly(Return(0));
378 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
379 .WillRepeatedly(Return(0));
380 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
381 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700382 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
383 .WillRepeatedly(Return(0));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800384 }
385
386 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
387 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
388 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
389 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
390 .WillRepeatedly(Return(NO_ERROR));
391 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
392 .WillRepeatedly(Return(NO_ERROR));
393 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
394 .WillRepeatedly(Return(NO_ERROR));
395 }
396
397 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
398 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
399 }
400};
401
Dominik Laskowski075d3172018-05-24 15:50:06 -0700402template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant,
403 typename PhysicalDisplay = void>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800404struct HwcDisplayVariant {
405 // The display id supplied by the HWC
406 static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
407
408 // The HWC display type
409 static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
410
411 // The HWC active configuration id
Lloyd Pique3c085a02018-05-09 19:38:32 -0700412 static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700413 static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800414
415 static void injectPendingHotplugEvent(DisplayTransactionTest* test,
416 HWC2::Connection connection) {
417 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
418 HotplugEvent{HWC_DISPLAY_ID, connection});
419 }
420
421 // Called by tests to inject a HWC display setup
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800422 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700423 const auto displayId = DisplayVariant::DISPLAY_ID::get();
424 ASSERT_TRUE(displayId);
425 FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
426 static_cast<bool>(DisplayVariant::PRIMARY))
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800427 .setHwcDisplayId(HWC_DISPLAY_ID)
428 .setWidth(DisplayVariant::WIDTH)
429 .setHeight(DisplayVariant::HEIGHT)
430 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700431 .setPowerMode(INIT_POWER_MODE)
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800432 .inject(&test->mFlinger, test->mComposer);
433 }
434
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800435 // Called by tests to inject a HWC display setup
436 static void injectHwcDisplay(DisplayTransactionTest* test) {
437 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
438 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
439 Return(Error::NONE)));
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700440 EXPECT_CALL(*test->mComposer,
441 setPowerMode(HWC_DISPLAY_ID,
442 static_cast<Hwc2::IComposerClient::PowerMode>(INIT_POWER_MODE)))
443 .WillOnce(Return(Error::NONE));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800444 injectHwcDisplayWithNoDefaultCapabilities(test);
445 }
446
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800447 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800448 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
449 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
450 .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
451 Return(Error::NONE)));
452 EXPECT_CALL(*test->mComposer,
453 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
454 IComposerClient::Attribute::WIDTH, _))
455 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
456 EXPECT_CALL(*test->mComposer,
457 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
458 IComposerClient::Attribute::HEIGHT, _))
459 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
460 EXPECT_CALL(*test->mComposer,
461 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
462 IComposerClient::Attribute::VSYNC_PERIOD, _))
463 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
464 EXPECT_CALL(*test->mComposer,
465 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
466 IComposerClient::Attribute::DPI_X, _))
467 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
468 EXPECT_CALL(*test->mComposer,
469 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
470 IComposerClient::Attribute::DPI_Y, _))
471 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
Dominik Laskowski075d3172018-05-24 15:50:06 -0700472
473 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
474 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
475 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
476 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
477 Return(Error::NONE)));
478 } else {
479 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
480 .WillOnce(Return(Error::UNSUPPORTED));
481 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800482 }
483
484 // Called by tests to set up HWC call expectations
485 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
486 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
Lloyd Pique3c085a02018-05-09 19:38:32 -0700487 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800488 }
489};
490
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800491// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
492constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
493 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
494
Dominik Laskowski075d3172018-05-24 15:50:06 -0700495template <hwc2_display_t hwcDisplayId, typename PhysicalDisplay, int width, int height,
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800496 Critical critical>
497struct PhysicalDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700498 : DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height, critical, Async::FALSE,
499 Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
500 HwcDisplayVariant<hwcDisplayId, HWC2::DisplayType::Physical,
501 DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height,
502 critical, Async::FALSE, Secure::TRUE,
503 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
504 PhysicalDisplay> {};
505
506template <bool hasIdentificationData>
507struct PrimaryDisplay {
508 static constexpr Primary PRIMARY = Primary::TRUE;
509 static constexpr uint8_t PORT = 255;
510 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
511 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
512};
513
514template <bool hasIdentificationData>
515struct ExternalDisplay {
516 static constexpr Primary PRIMARY = Primary::FALSE;
517 static constexpr uint8_t PORT = 254;
518 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
519 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
520};
521
522struct TertiaryDisplay {
523 static constexpr Primary PRIMARY = Primary::FALSE;
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800524 static constexpr uint8_t PORT = 253;
525 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700526};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800527
528// A primary display is a physical display that is critical
529using PrimaryDisplayVariant =
Dominik Laskowski075d3172018-05-24 15:50:06 -0700530 PhysicalDisplayVariant<1001, PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800531
532// An external display is physical display that is not critical.
533using ExternalDisplayVariant =
Dominik Laskowski075d3172018-05-24 15:50:06 -0700534 PhysicalDisplayVariant<1002, ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800535
536using TertiaryDisplayVariant =
Dominik Laskowski075d3172018-05-24 15:50:06 -0700537 PhysicalDisplayVariant<1003, TertiaryDisplay, 1600, 1200, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800538
539// A virtual display not supported by the HWC.
540constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
541
542template <int width, int height, Secure secure>
543struct NonHwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700544 : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
545 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
546 using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
547 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
548
549 static void injectHwcDisplay(DisplayTransactionTest*) {}
550
551 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
552 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
553 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800554
555 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
556 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
557 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
558 }
559};
560
561// A virtual display supported by the HWC.
562constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
563
564template <int width, int height, Secure secure>
565struct HwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700566 : DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE, secure,
567 Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
568 HwcDisplayVariant<
569 1010, HWC2::DisplayType::Virtual,
570 DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
571 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
572 using Base = DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
573 secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800574 using Self = HwcVirtualDisplayVariant<width, height, secure>;
575
576 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
577 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
578 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
579 }
580
581 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
582 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
583 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
584 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
585 }
586};
587
588// For this variant, SurfaceFlinger should not configure itself with wide
589// display support, so the display should not be configured for wide-color
590// support.
591struct WideColorSupportNotConfiguredVariant {
592 static constexpr bool WIDE_COLOR_SUPPORTED = false;
593
594 static void injectConfigChange(DisplayTransactionTest* test) {
595 test->mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700596 test->mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800597 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800598 }
599
600 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
601 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
602 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
603 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
604 }
605};
606
607// For this variant, SurfaceFlinger should configure itself with wide display
608// support, and the display should respond with an non-empty list of supported
609// color modes. Wide-color support should be configured.
610template <typename Display>
611struct WideColorP3ColorimetricSupportedVariant {
612 static constexpr bool WIDE_COLOR_SUPPORTED = true;
613
614 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700615 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800616 test->mFlinger.mutableHasWideColorDisplay() = true;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800617 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800618 }
619
620 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800621 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_DATASPACE)).Times(1);
622
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800623 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
624 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
625 Return(Error::NONE)));
626 EXPECT_CALL(*test->mComposer,
627 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
628 .WillOnce(DoAll(SetArgPointee<2>(
629 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
630 Return(Error::NONE)));
631 EXPECT_CALL(*test->mComposer,
632 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
633 RenderIntent::COLORIMETRIC))
634 .WillOnce(Return(Error::NONE));
635 }
636};
637
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800638// For this variant, SurfaceFlinger should configure itself with wide display
639// support, but the display should respond with an empty list of supported color
640// modes. Wide-color support for the display should not be configured.
641template <typename Display>
642struct WideColorNotSupportedVariant {
643 static constexpr bool WIDE_COLOR_SUPPORTED = false;
644
645 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700646 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800647 test->mFlinger.mutableHasWideColorDisplay() = true;
648 }
649
650 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
651 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
652 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
Chia-I Wu614e1422018-05-23 02:17:03 -0700653 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800654 }
655};
656
657// For this variant, the display is not a HWC display, so no HDR support should
658// be configured.
659struct NonHwcDisplayHdrSupportVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800660 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800661 static constexpr bool HDR10_SUPPORTED = false;
662 static constexpr bool HDR_HLG_SUPPORTED = false;
663 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
664 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
665 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
666 }
667};
668
Valerie Haue9e843a2018-12-18 13:39:23 -0800669template <typename Display>
670struct Hdr10PlusSupportedVariant {
671 static constexpr bool HDR10_PLUS_SUPPORTED = true;
672 static constexpr bool HDR10_SUPPORTED = true;
673 static constexpr bool HDR_HLG_SUPPORTED = false;
674 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
675 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
676 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _))
677 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({
678 Hdr::HDR10_PLUS,
679 Hdr::HDR10,
680 })),
681 Return(Error::NONE)));
682 }
683};
684
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800685// For this variant, the composer should respond with a non-empty list of HDR
686// modes containing HDR10, so HDR10 support should be configured.
687template <typename Display>
688struct Hdr10SupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800689 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800690 static constexpr bool HDR10_SUPPORTED = true;
691 static constexpr bool HDR_HLG_SUPPORTED = false;
692 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
693 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
694 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
695 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
696 Return(Error::NONE)));
697 }
698};
699
700// For this variant, the composer should respond with a non-empty list of HDR
701// modes containing HLG, so HLG support should be configured.
702template <typename Display>
703struct HdrHlgSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800704 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800705 static constexpr bool HDR10_SUPPORTED = false;
706 static constexpr bool HDR_HLG_SUPPORTED = true;
707 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
708 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
709 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
710 .WillOnce(
711 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
712 }
713};
714
715// For this variant, the composer should respond with a non-empty list of HDR
716// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
717template <typename Display>
718struct HdrDolbyVisionSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800719 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800720 static constexpr bool HDR10_SUPPORTED = false;
721 static constexpr bool HDR_HLG_SUPPORTED = false;
722 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
723 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
724 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
725 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
726 Return(Error::NONE)));
727 }
728};
729
730// For this variant, the composer should respond with am empty list of HDR
731// modes, so no HDR support should be configured.
732template <typename Display>
733struct HdrNotSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800734 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800735 static constexpr bool HDR10_SUPPORTED = false;
736 static constexpr bool HDR_HLG_SUPPORTED = false;
737 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
738 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
739 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
740 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
741 }
742};
743
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700744struct NonHwcPerFrameMetadataSupportVariant {
745 static constexpr int PER_FRAME_METADATA_KEYS = 0;
746 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800747 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700748 }
749};
750
751template <typename Display>
752struct NoPerFrameMetadataSupportVariant {
753 static constexpr int PER_FRAME_METADATA_KEYS = 0;
754 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800755 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
756 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700757 }
758};
759
760template <typename Display>
761struct Smpte2086PerFrameMetadataSupportVariant {
762 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::SMPTE2086;
763 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800764 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
765 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800766 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
767 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
768 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
769 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
770 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
771 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
772 PerFrameMetadataKey::WHITE_POINT_X,
773 PerFrameMetadataKey::WHITE_POINT_Y,
774 PerFrameMetadataKey::MAX_LUMINANCE,
775 PerFrameMetadataKey::MIN_LUMINANCE,
776 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700777 }
778};
779
780template <typename Display>
781struct Cta861_3_PerFrameMetadataSupportVariant {
782 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::CTA861_3;
783 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800784 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
785 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800786 PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
787 PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
788 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700789 }
790};
791
Valerie Haue9e843a2018-12-18 13:39:23 -0800792template <typename Display>
793struct Hdr10_Plus_PerFrameMetadataSupportVariant {
794 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::HDR10PLUS;
795 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
796 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
797 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
798 PerFrameMetadataKey::HDR10_PLUS_SEI,
799 })));
800 }
801};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800802/* ------------------------------------------------------------------------
803 * Typical display configurations to test
804 */
805
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700806template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
807 typename PerFrameMetadataSupportPolicy>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800808struct Case {
809 using Display = DisplayPolicy;
810 using WideColorSupport = WideColorSupportPolicy;
811 using HdrSupport = HdrSupportPolicy;
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700812 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800813};
814
815using SimplePrimaryDisplayCase =
816 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700817 HdrNotSupportedVariant<PrimaryDisplayVariant>,
818 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800819using SimpleExternalDisplayCase =
820 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700821 HdrNotSupportedVariant<ExternalDisplayVariant>,
822 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800823using SimpleTertiaryDisplayCase =
824 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700825 HdrNotSupportedVariant<TertiaryDisplayVariant>,
826 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800827using NonHwcVirtualDisplayCase =
828 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700829 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
830 NonHwcPerFrameMetadataSupportVariant>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800831using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
832using HwcVirtualDisplayCase =
833 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
Lloyd Pique438e9e72018-09-04 18:06:08 -0700834 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
tangrobin6753a022018-08-10 10:58:54 +0800835 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800836using WideColorP3ColorimetricDisplayCase =
837 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700838 HdrNotSupportedVariant<PrimaryDisplayVariant>,
839 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Valerie Haue9e843a2018-12-18 13:39:23 -0800840using Hdr10PlusDisplayCase =
841 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
842 Hdr10SupportedVariant<PrimaryDisplayVariant>,
843 Hdr10_Plus_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800844using Hdr10DisplayCase =
845 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700846 Hdr10SupportedVariant<PrimaryDisplayVariant>,
847 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800848using HdrHlgDisplayCase =
849 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700850 HdrHlgSupportedVariant<PrimaryDisplayVariant>,
851 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800852using HdrDolbyVisionDisplayCase =
853 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700854 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>,
855 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
856using HdrSmpte2086DisplayCase =
857 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
858 HdrNotSupportedVariant<PrimaryDisplayVariant>,
859 Smpte2086PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
860using HdrCta861_3_DisplayCase =
861 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
862 HdrNotSupportedVariant<PrimaryDisplayVariant>,
863 Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Dominik Laskowskif07b85b2018-06-11 12:49:15 -0700864
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800865/* ------------------------------------------------------------------------
Lloyd Pique6cf11032018-01-22 18:57:44 -0800866 *
867 * SurfaceFlinger::onHotplugReceived
868 */
869
870TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
871 constexpr int currentSequenceId = 123;
Dominik Laskowskia2edf612018-06-01 13:15:16 -0700872 constexpr hwc2_display_t hwcDisplayId1 = 456;
873 constexpr hwc2_display_t hwcDisplayId2 = 654;
Lloyd Pique6cf11032018-01-22 18:57:44 -0800874
875 // --------------------------------------------------------------------
876 // Preconditions
877
878 // Set the current sequence id for accepted events
879 mFlinger.mutableComposerSequenceId() = currentSequenceId;
880
881 // Set the main thread id so that the current thread does not appear to be
882 // the main thread.
883 mFlinger.mutableMainThreadId() = std::thread::id();
884
885 // --------------------------------------------------------------------
886 // Call Expectations
887
888 // We expect invalidate() to be invoked once to trigger display transaction
889 // processing.
890 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
891
892 // --------------------------------------------------------------------
893 // Invocation
894
895 // Simulate two hotplug events (a connect and a disconnect)
Dominik Laskowskia2edf612018-06-01 13:15:16 -0700896 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, HWC2::Connection::Connected);
897 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, HWC2::Connection::Disconnected);
Lloyd Pique6cf11032018-01-22 18:57:44 -0800898
899 // --------------------------------------------------------------------
900 // Postconditions
901
902 // The display transaction needed flag should be set.
903 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
904
905 // All events should be in the pending event queue.
906 const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
907 ASSERT_EQ(2u, pendingEvents.size());
Dominik Laskowskia2edf612018-06-01 13:15:16 -0700908 EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
Lloyd Pique6cf11032018-01-22 18:57:44 -0800909 EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
Dominik Laskowskia2edf612018-06-01 13:15:16 -0700910 EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
Lloyd Pique6cf11032018-01-22 18:57:44 -0800911 EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
912}
913
914TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
915 constexpr int currentSequenceId = 123;
916 constexpr int otherSequenceId = 321;
917 constexpr hwc2_display_t displayId = 456;
918
919 // --------------------------------------------------------------------
920 // Preconditions
921
922 // Set the current sequence id for accepted events
923 mFlinger.mutableComposerSequenceId() = currentSequenceId;
924
925 // Set the main thread id so that the current thread does not appear to be
926 // the main thread.
927 mFlinger.mutableMainThreadId() = std::thread::id();
928
929 // --------------------------------------------------------------------
930 // Call Expectations
931
932 // We do not expect any calls to invalidate().
933 EXPECT_CALL(*mMessageQueue, invalidate()).Times(0);
934
935 // --------------------------------------------------------------------
936 // Invocation
937
938 // Call with an unexpected sequence id
939 mFlinger.onHotplugReceived(otherSequenceId, displayId, HWC2::Connection::Invalid);
940
941 // --------------------------------------------------------------------
942 // Postconditions
943
944 // The display transaction needed flag should not be set
945 EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded));
946
947 // There should be no pending events
948 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
949}
950
951TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
952 constexpr int currentSequenceId = 123;
953 constexpr hwc2_display_t displayId1 = 456;
954
955 // --------------------------------------------------------------------
956 // Note:
957 // --------------------------------------------------------------------
958 // This test case is a bit tricky. We want to verify that
959 // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we
960 // don't really want to provide coverage for everything the later function
961 // does as there are specific tests for it.
962 // --------------------------------------------------------------------
963
964 // --------------------------------------------------------------------
965 // Preconditions
966
967 // Set the current sequence id for accepted events
968 mFlinger.mutableComposerSequenceId() = currentSequenceId;
969
970 // Set the main thread id so that the current thread does appear to be the
971 // main thread.
972 mFlinger.mutableMainThreadId() = std::this_thread::get_id();
973
974 // --------------------------------------------------------------------
975 // Call Expectations
976
977 // We expect invalidate() to be invoked once to trigger display transaction
978 // processing.
979 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
980
981 // --------------------------------------------------------------------
982 // Invocation
983
984 // Simulate a disconnect on a display id that is not connected. This should
985 // be enqueued by onHotplugReceived(), and dequeued by
986 // processDisplayHotplugEventsLocked(), but then ignored as invalid.
987 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Disconnected);
988
989 // --------------------------------------------------------------------
990 // Postconditions
991
992 // The display transaction needed flag should be set.
993 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
994
995 // There should be no event queued on return, as it should have been
996 // processed.
997 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
998}
999
1000/* ------------------------------------------------------------------------
Lloyd Piquea482f992018-01-22 19:00:34 -08001001 * SurfaceFlinger::createDisplay
1002 */
1003
1004TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
1005 const String8 name("virtual.test");
1006
1007 // --------------------------------------------------------------------
1008 // Call Expectations
1009
1010 // The call should notify the interceptor that a display was created.
1011 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1012
1013 // --------------------------------------------------------------------
1014 // Invocation
1015
1016 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
1017
1018 // --------------------------------------------------------------------
1019 // Postconditions
1020
1021 // The display should have been added to the current state
1022 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1023 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001024 EXPECT_TRUE(display.isVirtual());
1025 EXPECT_FALSE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001026 EXPECT_EQ(name.string(), display.displayName);
1027
1028 // --------------------------------------------------------------------
1029 // Cleanup conditions
1030
1031 // Destroying the display invalidates the display state.
1032 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1033}
1034
1035TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForSecureDisplay) {
1036 const String8 name("virtual.test");
1037
1038 // --------------------------------------------------------------------
1039 // Call Expectations
1040
1041 // The call should notify the interceptor that a display was created.
1042 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1043
1044 // --------------------------------------------------------------------
1045 // Invocation
1046
1047 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
1048
1049 // --------------------------------------------------------------------
1050 // Postconditions
1051
1052 // The display should have been added to the current state
1053 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1054 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001055 EXPECT_TRUE(display.isVirtual());
1056 EXPECT_TRUE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001057 EXPECT_EQ(name.string(), display.displayName);
1058
1059 // --------------------------------------------------------------------
1060 // Cleanup conditions
1061
1062 // Destroying the display invalidates the display state.
1063 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1064}
1065
1066/* ------------------------------------------------------------------------
1067 * SurfaceFlinger::destroyDisplay
1068 */
1069
1070TEST_F(DisplayTransactionTest, destroyDisplayClearsCurrentStateForDisplay) {
1071 using Case = NonHwcVirtualDisplayCase;
1072
1073 // --------------------------------------------------------------------
1074 // Preconditions
1075
1076 // A virtual display exists
1077 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1078 existing.inject();
1079
1080 // --------------------------------------------------------------------
1081 // Call Expectations
1082
1083 // The call should notify the interceptor that a display was created.
1084 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
1085
1086 // Destroying the display invalidates the display state.
1087 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1088
1089 // --------------------------------------------------------------------
1090 // Invocation
1091
1092 mFlinger.destroyDisplay(existing.token());
1093
1094 // --------------------------------------------------------------------
1095 // Postconditions
1096
1097 // The display should have been removed from the current state
1098 EXPECT_FALSE(hasCurrentDisplayState(existing.token()));
1099
1100 // Ths display should still exist in the drawing state
1101 EXPECT_TRUE(hasDrawingDisplayState(existing.token()));
1102
1103 // The display transaction needed flasg should be set
1104 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1105}
1106
1107TEST_F(DisplayTransactionTest, destroyDisplayHandlesUnknownDisplay) {
1108 // --------------------------------------------------------------------
1109 // Preconditions
1110
1111 sp<BBinder> displayToken = new BBinder();
1112
1113 // --------------------------------------------------------------------
1114 // Invocation
1115
1116 mFlinger.destroyDisplay(displayToken);
1117}
1118
1119/* ------------------------------------------------------------------------
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001120 * SurfaceFlinger::resetDisplayState
1121 */
1122
1123TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
1124 using Case = NonHwcVirtualDisplayCase;
1125
1126 // --------------------------------------------------------------------
1127 // Preconditions
1128
1129 // vsync is enabled and available
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001130 mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = true;
1131 mFlinger.scheduler()->mutableHWVsyncAvailable() = true;
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001132
1133 // A display exists
1134 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1135 existing.inject();
1136
1137 // --------------------------------------------------------------------
1138 // Call Expectations
1139
1140 // The call disable vsyncs
1141 EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
1142
Lloyd Pique41be5d22018-06-21 13:11:48 -07001143 // The call ends any display resyncs
1144 EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
1145
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001146 // --------------------------------------------------------------------
1147 // Invocation
1148
1149 mFlinger.resetDisplayState();
1150
1151 // --------------------------------------------------------------------
1152 // Postconditions
1153
1154 // vsyncs should be off and not available.
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001155 EXPECT_FALSE(mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled());
1156 EXPECT_FALSE(mFlinger.scheduler()->mutableHWVsyncAvailable());
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001157
1158 // The display should have been removed from the display map.
1159 EXPECT_FALSE(hasDisplayDevice(existing.token()));
1160
1161 // The display should still exist in the current state
1162 EXPECT_TRUE(hasCurrentDisplayState(existing.token()));
1163
1164 // The display should have been removed from the drawing state
1165 EXPECT_FALSE(hasDrawingDisplayState(existing.token()));
1166}
1167
1168/* ------------------------------------------------------------------------
Valerie Hau9758ae02018-10-09 16:05:09 -07001169 * DisplayDevice::GetBestColorMode
1170 */
1171class GetBestColorModeTest : public DisplayTransactionTest {
1172public:
Dominik Laskowski34157762018-10-31 13:07:19 -07001173 static constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
Dominik Laskowski075d3172018-05-24 15:50:06 -07001174
Valerie Hau9758ae02018-10-09 16:05:09 -07001175 GetBestColorModeTest()
1176 : DisplayTransactionTest(),
Dominik Laskowski075d3172018-05-24 15:50:06 -07001177 mInjector(FakeDisplayDeviceInjector(mFlinger, DEFAULT_DISPLAY_ID, false /* isVirtual */,
1178 true /* isPrimary */)) {}
Valerie Hau9758ae02018-10-09 16:05:09 -07001179
1180 void setHasWideColorGamut(bool hasWideColorGamut) { mHasWideColorGamut = hasWideColorGamut; }
1181
1182 void addHwcColorModesMapping(ui::ColorMode colorMode,
1183 std::vector<ui::RenderIntent> renderIntents) {
1184 mHwcColorModes[colorMode] = renderIntents;
1185 }
1186
1187 void setInputDataspace(ui::Dataspace dataspace) { mInputDataspace = dataspace; }
1188
1189 void setInputRenderIntent(ui::RenderIntent renderIntent) { mInputRenderIntent = renderIntent; }
1190
1191 void getBestColorMode() {
1192 mInjector.setHwcColorModes(mHwcColorModes);
1193 mInjector.setHasWideColorGamut(mHasWideColorGamut);
Alec Mouriba013fa2018-10-16 12:43:11 -07001194 mInjector.setNativeWindow(mNativeWindow);
1195
1196 // Creating a DisplayDevice requires getting default dimensions from the
1197 // native window.
1198 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
1199 .WillRepeatedly(DoAll(SetArgPointee<1>(1080 /* arbitrary */), Return(0)));
1200 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
1201 .WillRepeatedly(DoAll(SetArgPointee<1>(1920 /* arbitrary */), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08001202 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
1203 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
1204 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07001205 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Valerie Hau9758ae02018-10-09 16:05:09 -07001206 auto displayDevice = mInjector.inject();
1207
Lloyd Pique3d0c02e2018-10-19 18:38:12 -07001208 displayDevice->getCompositionDisplay()
1209 ->getDisplayColorProfile()
1210 ->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace,
1211 &mOutColorMode, &mOutRenderIntent);
Valerie Hau9758ae02018-10-09 16:05:09 -07001212 }
1213
1214 ui::Dataspace mOutDataspace;
1215 ui::ColorMode mOutColorMode;
1216 ui::RenderIntent mOutRenderIntent;
1217
1218private:
1219 ui::Dataspace mInputDataspace;
1220 ui::RenderIntent mInputRenderIntent;
1221 bool mHasWideColorGamut = false;
1222 std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> mHwcColorModes;
1223 FakeDisplayDeviceInjector mInjector;
1224};
1225
1226TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeSRGB) {
1227 addHwcColorModesMapping(ui::ColorMode::SRGB,
1228 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1229 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1230 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1231 setHasWideColorGamut(true);
1232
1233 getBestColorMode();
1234
Peiyong Lin14724e62018-12-05 07:27:30 -08001235 ASSERT_EQ(ui::Dataspace::V0_SRGB, mOutDataspace);
Valerie Hau9758ae02018-10-09 16:05:09 -07001236 ASSERT_EQ(ui::ColorMode::SRGB, mOutColorMode);
1237 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1238}
1239
1240TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDisplayP3) {
1241 addHwcColorModesMapping(ui::ColorMode::DISPLAY_P3,
1242 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1243 addHwcColorModesMapping(ui::ColorMode::SRGB,
1244 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1245 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1246 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1247 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1248 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1249 setHasWideColorGamut(true);
1250
1251 getBestColorMode();
1252
1253 ASSERT_EQ(ui::Dataspace::DISPLAY_P3, mOutDataspace);
1254 ASSERT_EQ(ui::ColorMode::DISPLAY_P3, mOutColorMode);
1255 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1256}
1257
1258TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDISPLAY_BT2020) {
1259 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1260 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1261 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1262 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1263 setHasWideColorGamut(true);
1264
1265 getBestColorMode();
1266
1267 ASSERT_EQ(ui::Dataspace::DISPLAY_BT2020, mOutDataspace);
1268 ASSERT_EQ(ui::ColorMode::DISPLAY_BT2020, mOutColorMode);
1269 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1270}
1271
1272/* ------------------------------------------------------------------------
Daniel Solomon42d04562019-01-20 21:03:19 -08001273 * SurfaceFlinger::getDisplayNativePrimaries
1274 */
1275
1276class GetDisplayNativePrimaries : public DisplayTransactionTest {
1277public:
1278 GetDisplayNativePrimaries();
1279 void populateDummyDisplayNativePrimaries(ui::DisplayPrimaries& primaries);
1280 void checkDummyDisplayNativePrimaries(const ui::DisplayPrimaries& primaries);
1281
1282private:
1283 static constexpr float mStartingTestValue = 1.0f;
1284};
1285
1286GetDisplayNativePrimaries::GetDisplayNativePrimaries() {
1287 SimplePrimaryDisplayCase::Display::injectHwcDisplay(this);
1288 injectFakeNativeWindowSurfaceFactory();
1289}
1290
1291void GetDisplayNativePrimaries::populateDummyDisplayNativePrimaries(
1292 ui::DisplayPrimaries& primaries) {
1293 float startingVal = mStartingTestValue;
1294 primaries.red.X = startingVal++;
1295 primaries.red.Y = startingVal++;
1296 primaries.red.Z = startingVal++;
1297 primaries.green.X = startingVal++;
1298 primaries.green.Y = startingVal++;
1299 primaries.green.Z = startingVal++;
1300 primaries.blue.X = startingVal++;
1301 primaries.blue.Y = startingVal++;
1302 primaries.blue.Z = startingVal++;
1303 primaries.white.X = startingVal++;
1304 primaries.white.Y = startingVal++;
1305 primaries.white.Z = startingVal++;
1306}
1307
1308void GetDisplayNativePrimaries::checkDummyDisplayNativePrimaries(
1309 const ui::DisplayPrimaries& primaries) {
1310 float startingVal = mStartingTestValue;
1311 EXPECT_EQ(primaries.red.X, startingVal++);
1312 EXPECT_EQ(primaries.red.Y, startingVal++);
1313 EXPECT_EQ(primaries.red.Z, startingVal++);
1314 EXPECT_EQ(primaries.green.X, startingVal++);
1315 EXPECT_EQ(primaries.green.Y, startingVal++);
1316 EXPECT_EQ(primaries.green.Z, startingVal++);
1317 EXPECT_EQ(primaries.blue.X, startingVal++);
1318 EXPECT_EQ(primaries.blue.Y, startingVal++);
1319 EXPECT_EQ(primaries.blue.Z, startingVal++);
1320 EXPECT_EQ(primaries.white.X, startingVal++);
1321 EXPECT_EQ(primaries.white.Y, startingVal++);
1322 EXPECT_EQ(primaries.white.Z, startingVal++);
1323}
1324
1325TEST_F(GetDisplayNativePrimaries, nullDisplayToken) {
1326 ui::DisplayPrimaries primaries;
1327 EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(nullptr, primaries));
1328}
1329
Daniel Solomon42d04562019-01-20 21:03:19 -08001330TEST_F(GetDisplayNativePrimaries, internalDisplayWithPrimariesData) {
1331 auto injector = SimplePrimaryDisplayCase::Display::makeFakeExistingDisplayInjector(this);
1332 injector.inject();
1333 auto internalDisplayToken = injector.token();
1334
1335 ui::DisplayPrimaries expectedPrimaries;
1336 populateDummyDisplayNativePrimaries(expectedPrimaries);
1337 mFlinger.setInternalDisplayPrimaries(expectedPrimaries);
1338
1339 ui::DisplayPrimaries primaries;
1340 EXPECT_EQ(NO_ERROR, mFlinger.getDisplayNativePrimaries(internalDisplayToken, primaries));
1341
1342 checkDummyDisplayNativePrimaries(primaries);
1343}
1344
1345TEST_F(GetDisplayNativePrimaries, notInternalDisplayToken) {
1346 sp<BBinder> notInternalDisplayToken = new BBinder();
1347
1348 ui::DisplayPrimaries primaries;
1349 populateDummyDisplayNativePrimaries(primaries);
1350 EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
1351
1352 // Check primaries argument wasn't modified in case of failure
1353 checkDummyDisplayNativePrimaries(primaries);
1354}
1355
1356/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001357 * SurfaceFlinger::setupNewDisplayDeviceInternal
1358 */
1359
1360class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
1361public:
1362 template <typename T>
1363 void setupNewDisplayDeviceInternalTest();
1364};
1365
1366template <typename Case>
1367void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
1368 const sp<BBinder> displayToken = new BBinder();
Lloyd Pique542307f2018-10-19 13:24:08 -07001369 const sp<compositionengine::mock::DisplaySurface> displaySurface =
1370 new compositionengine::mock::DisplaySurface();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001371 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001372
1373 // --------------------------------------------------------------------
1374 // Preconditions
1375
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001376 // Wide color displays support is configured appropriately
1377 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001378
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001379 // The display is setup with the HWC.
1380 Case::Display::injectHwcDisplay(this);
1381
1382 // SurfaceFlinger will use a test-controlled factory for native window
1383 // surfaces.
1384 injectFakeNativeWindowSurfaceFactory();
1385
1386 // --------------------------------------------------------------------
1387 // Call Expectations
1388
1389 // Various native window calls will be made.
1390 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
Lloyd Pique3c085a02018-05-09 19:38:32 -07001391 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001392 Case::WideColorSupport::setupComposerCallExpectations(this);
1393 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001394 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001395
1396 // --------------------------------------------------------------------
1397 // Invocation
1398
1399 DisplayDeviceState state;
Dominik Laskowski075d3172018-05-24 15:50:06 -07001400 state.displayId = static_cast<bool>(Case::Display::VIRTUAL) ? std::nullopt
1401 : Case::Display::DISPLAY_ID::get();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001402 state.isSecure = static_cast<bool>(Case::Display::SECURE);
1403
Dominik Laskowski075d3172018-05-24 15:50:06 -07001404 auto device =
1405 mFlinger.setupNewDisplayDeviceInternal(displayToken, Case::Display::DISPLAY_ID::get(),
1406 state, displaySurface, producer);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001407
1408 // --------------------------------------------------------------------
1409 // Postconditions
1410
1411 ASSERT_TRUE(device != nullptr);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001412 EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
1413 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001414 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001415 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001416 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
1417 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
1418 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
Valerie Haue9e843a2018-12-18 13:39:23 -08001419 EXPECT_EQ(Case::HdrSupport::HDR10_PLUS_SUPPORTED, device->hasHDR10PlusSupport());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001420 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
1421 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
1422 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
Lloyd Pique3c085a02018-05-09 19:38:32 -07001423 // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
1424 // remapped, and the test only ever sets up one config. If there were an error
1425 // looking up the remapped index, device->getActiveConfig() would be -1 instead.
1426 EXPECT_EQ(0, device->getActiveConfig());
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001427 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
1428 device->getSupportedPerFrameMetadata());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001429}
1430
1431TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
1432 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
1433}
1434
1435TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
1436 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
1437}
1438
1439TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1440 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1441}
1442
1443TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
Dominik Laskowski075d3172018-05-24 15:50:06 -07001444 using Case = HwcVirtualDisplayCase;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001445
Dominik Laskowski075d3172018-05-24 15:50:06 -07001446 // Insert display data so that the HWC thinks it created the virtual display.
1447 const auto displayId = Case::Display::DISPLAY_ID::get();
1448 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08001449 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001450
1451 setupNewDisplayDeviceInternalTest<Case>();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001452}
1453
1454TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1455 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1456}
1457
Valerie Haue9e843a2018-12-18 13:39:23 -08001458TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10PlusDisplay) {
1459 setupNewDisplayDeviceInternalTest<Hdr10PlusDisplayCase>();
1460}
1461
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001462TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1463 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1464}
1465
1466TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1467 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1468}
1469
1470TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1471 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1472}
1473
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001474TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
1475 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
1476}
1477
1478TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
1479 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
1480}
1481
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001482/* ------------------------------------------------------------------------
1483 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1484 */
1485
1486class HandleTransactionLockedTest : public DisplayTransactionTest {
1487public:
1488 template <typename Case>
1489 void setupCommonPreconditions();
1490
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001491 template <typename Case, bool connected>
1492 static void expectHotplugReceived(mock::EventThread*);
1493
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001494 template <typename Case>
1495 void setupCommonCallExpectationsForConnectProcessing();
1496
1497 template <typename Case>
1498 void setupCommonCallExpectationsForDisconnectProcessing();
1499
1500 template <typename Case>
1501 void processesHotplugConnectCommon();
1502
1503 template <typename Case>
1504 void ignoresHotplugConnectCommon();
1505
1506 template <typename Case>
1507 void processesHotplugDisconnectCommon();
1508
1509 template <typename Case>
1510 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1511
1512 template <typename Case>
1513 void verifyPhysicalDisplayIsConnected();
1514
1515 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1516};
1517
1518template <typename Case>
1519void HandleTransactionLockedTest::setupCommonPreconditions() {
1520 // Wide color displays support is configured appropriately
1521 Case::WideColorSupport::injectConfigChange(this);
1522
1523 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1524 injectFakeBufferQueueFactory();
1525
1526 // SurfaceFlinger will use a test-controlled factory for native window
1527 // surfaces.
1528 injectFakeNativeWindowSurfaceFactory();
1529}
1530
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001531template <typename Case, bool connected>
1532void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) {
1533 const auto convert = [](auto physicalDisplayId) {
1534 return std::make_optional(DisplayId{physicalDisplayId});
1535 };
1536
1537 EXPECT_CALL(*eventThread,
1538 onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
1539 .Times(1);
1540}
1541
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001542template <typename Case>
1543void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1544 Case::Display::setupHwcHotplugCallExpectations(this);
1545
1546 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1547 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1548 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1549 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1550
1551 Case::WideColorSupport::setupComposerCallExpectations(this);
1552 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001553 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001554
1555 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001556 expectHotplugReceived<Case, true>(mEventThread);
1557 expectHotplugReceived<Case, true>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001558}
1559
1560template <typename Case>
1561void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1562 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
Dominik Laskowski1eba0202019-01-24 09:14:40 -08001563
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001564 expectHotplugReceived<Case, false>(mEventThread);
1565 expectHotplugReceived<Case, false>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001566}
1567
1568template <typename Case>
1569void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1570 // The display device should have been set up in the list of displays.
1571 ASSERT_TRUE(hasDisplayDevice(displayToken));
1572 const auto& device = getDisplayDevice(displayToken);
1573 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001574 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001575
1576 // The display should have been set up in the current display state
1577 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1578 const auto& current = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001579 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), current.isVirtual());
1580 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL) ? std::nullopt
1581 : Case::Display::DISPLAY_ID::get(),
1582 current.displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001583
1584 // The display should have been set up in the drawing display state
1585 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1586 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001587 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
1588 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL) ? std::nullopt
1589 : Case::Display::DISPLAY_ID::get(),
1590 draw.displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001591}
1592
1593template <typename Case>
1594void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1595 // HWComposer should have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001596 EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001597
Dominik Laskowski075d3172018-05-24 15:50:06 -07001598 // SF should have a display token.
1599 const auto displayId = Case::Display::DISPLAY_ID::get();
1600 ASSERT_TRUE(displayId);
1601 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
1602 auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001603
1604 verifyDisplayIsConnected<Case>(displayToken);
1605}
1606
1607void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
1608 EXPECT_FALSE(hasDisplayDevice(displayToken));
1609 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
1610 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
1611}
1612
1613template <typename Case>
1614void HandleTransactionLockedTest::processesHotplugConnectCommon() {
1615 // --------------------------------------------------------------------
1616 // Preconditions
1617
1618 setupCommonPreconditions<Case>();
1619
1620 // A hotplug connect event is enqueued for a display
1621 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001622
1623 // --------------------------------------------------------------------
1624 // Call Expectations
1625
1626 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001627
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001628 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001629
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001630 // --------------------------------------------------------------------
1631 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08001632
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001633 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08001634
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001635 // --------------------------------------------------------------------
1636 // Postconditions
1637
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001638 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08001639
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001640 // --------------------------------------------------------------------
1641 // Cleanup conditions
1642
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001643 EXPECT_CALL(*mComposer,
1644 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001645 .WillOnce(Return(Error::NONE));
1646 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08001647}
1648
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001649template <typename Case>
1650void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
1651 // --------------------------------------------------------------------
1652 // Preconditions
1653
1654 setupCommonPreconditions<Case>();
1655
1656 // A hotplug connect event is enqueued for a display
1657 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1658
1659 // --------------------------------------------------------------------
1660 // Invocation
1661
1662 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1663
1664 // --------------------------------------------------------------------
1665 // Postconditions
1666
1667 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001668 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001669}
1670
1671template <typename Case>
1672void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
1673 // --------------------------------------------------------------------
1674 // Preconditions
1675
1676 setupCommonPreconditions<Case>();
1677
1678 // A hotplug disconnect event is enqueued for a display
1679 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1680
1681 // The display is already completely set up.
1682 Case::Display::injectHwcDisplay(this);
1683 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1684 existing.inject();
1685
1686 // --------------------------------------------------------------------
1687 // Call Expectations
1688
1689 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
Lloyd Pique438e9e72018-09-04 18:06:08 -07001690 EXPECT_CALL(*mComposer, getDisplayIdentificationData(Case::Display::HWC_DISPLAY_ID, _, _))
1691 .Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001692
1693 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1694
1695 // --------------------------------------------------------------------
1696 // Invocation
1697
1698 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1699
1700 // --------------------------------------------------------------------
1701 // Postconditions
1702
1703 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001704 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001705
Dominik Laskowski075d3172018-05-24 15:50:06 -07001706 // SF should not have a display token.
1707 const auto displayId = Case::Display::DISPLAY_ID::get();
1708 ASSERT_TRUE(displayId);
1709 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001710
1711 // The existing token should have been removed
1712 verifyDisplayIsNotConnected(existing.token());
1713}
1714
1715TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
1716 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1717}
1718
1719TEST_F(HandleTransactionLockedTest,
1720 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
1721 // Inject an external display.
1722 ExternalDisplayVariant::injectHwcDisplay(this);
1723
1724 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
1725}
1726
1727TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
1728 // Inject a primary display.
1729 PrimaryDisplayVariant::injectHwcDisplay(this);
1730
1731 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
1732}
1733
1734TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
1735 // Inject both a primary and external display.
1736 PrimaryDisplayVariant::injectHwcDisplay(this);
1737 ExternalDisplayVariant::injectHwcDisplay(this);
1738
Lloyd Pique86fa3db2019-02-04 18:46:01 -08001739 // TODO: This is an unnecessary call.
1740 EXPECT_CALL(*mComposer,
1741 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
1742 .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
1743 SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
1744 Return(Error::NONE)));
1745
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001746 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1747
1748 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
1749}
1750
1751TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
1752 // Inject a primary display.
1753 PrimaryDisplayVariant::injectHwcDisplay(this);
1754
1755 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
1756
1757 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
1758}
1759
1760TEST_F(HandleTransactionLockedTest, processHotplugDisconnectPrimaryDisplay) {
1761 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
1762}
1763
1764TEST_F(HandleTransactionLockedTest, processHotplugDisconnectExternalDisplay) {
1765 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
1766}
1767
1768TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
1769 using Case = SimplePrimaryDisplayCase;
1770
1771 // --------------------------------------------------------------------
1772 // Preconditions
1773
1774 setupCommonPreconditions<Case>();
1775
1776 // A hotplug connect event is enqueued for a display
1777 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1778 // A hotplug disconnect event is also enqueued for the same display
1779 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1780
1781 // --------------------------------------------------------------------
1782 // Call Expectations
1783
1784 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1785
1786 setupCommonCallExpectationsForConnectProcessing<Case>();
1787 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1788
1789 EXPECT_CALL(*mComposer,
1790 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1791 .WillOnce(Return(Error::NONE));
1792 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1793
1794 // --------------------------------------------------------------------
1795 // Invocation
1796
1797 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1798
1799 // --------------------------------------------------------------------
1800 // Postconditions
1801
1802 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001803 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001804
Dominik Laskowski075d3172018-05-24 15:50:06 -07001805 // SF should not have a display token.
1806 const auto displayId = Case::Display::DISPLAY_ID::get();
1807 ASSERT_TRUE(displayId);
1808 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001809}
1810
1811TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
1812 using Case = SimplePrimaryDisplayCase;
1813
1814 // --------------------------------------------------------------------
1815 // Preconditions
1816
1817 setupCommonPreconditions<Case>();
1818
1819 // The display is already completely set up.
1820 Case::Display::injectHwcDisplay(this);
1821 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1822 existing.inject();
1823
1824 // A hotplug disconnect event is enqueued for a display
1825 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
1826 // A hotplug connect event is also enqueued for the same display
1827 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
1828
1829 // --------------------------------------------------------------------
1830 // Call Expectations
1831
1832 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1833
1834 setupCommonCallExpectationsForConnectProcessing<Case>();
1835 setupCommonCallExpectationsForDisconnectProcessing<Case>();
1836
1837 // --------------------------------------------------------------------
1838 // Invocation
1839
1840 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1841
1842 // --------------------------------------------------------------------
1843 // Postconditions
1844
1845 // The existing token should have been removed
1846 verifyDisplayIsNotConnected(existing.token());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001847 const auto displayId = Case::Display::DISPLAY_ID::get();
1848 ASSERT_TRUE(displayId);
1849 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
1850 EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001851
1852 // A new display should be connected in its place
1853
1854 verifyPhysicalDisplayIsConnected<Case>();
1855
1856 // --------------------------------------------------------------------
1857 // Cleanup conditions
1858
1859 EXPECT_CALL(*mComposer,
1860 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
1861 .WillOnce(Return(Error::NONE));
1862 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
1863}
1864
1865TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
1866 using Case = HwcVirtualDisplayCase;
1867
1868 // --------------------------------------------------------------------
1869 // Preconditions
1870
1871 // The HWC supports at least one virtual display
1872 injectMockComposer(1);
1873
1874 setupCommonPreconditions<Case>();
1875
1876 // A virtual display was added to the current state, and it has a
1877 // surface(producer)
1878 sp<BBinder> displayToken = new BBinder();
Lloyd Pique4c2ac022018-04-27 12:08:03 -07001879
Dominik Laskowski075d3172018-05-24 15:50:06 -07001880 DisplayDeviceState state;
1881 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001882
1883 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
Dominik Laskowski075d3172018-05-24 15:50:06 -07001884 state.surface = surface;
1885 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001886
1887 // --------------------------------------------------------------------
1888 // Call Expectations
1889
1890 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1891 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1892
1893 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
1894 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
1895 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
1896 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
1897 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
1898 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
1899 Return(NO_ERROR)));
1900 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
1901 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
1902
1903 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
1904
Lloyd Pique86fa3db2019-02-04 18:46:01 -08001905 EXPECT_CALL(*mProducer, connect(_, NATIVE_WINDOW_API_EGL, false, _)).Times(1);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001906 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
1907
1908 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
1909 Case::WideColorSupport::setupComposerCallExpectations(this);
1910 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001911 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001912
1913 // --------------------------------------------------------------------
1914 // Invocation
1915
1916 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1917
1918 // --------------------------------------------------------------------
1919 // Postconditions
1920
1921 // The display device should have been set up in the list of displays.
1922 verifyDisplayIsConnected<Case>(displayToken);
1923
1924 // --------------------------------------------------------------------
1925 // Cleanup conditions
1926
1927 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
1928 .WillOnce(Return(Error::NONE));
1929 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Pique9e9800c2019-02-26 16:26:09 -08001930
1931 // Cleanup
1932 mFlinger.mutableCurrentState().displays.removeItem(displayToken);
1933 mFlinger.mutableDrawingState().displays.removeItem(displayToken);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001934}
1935
1936TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
1937 using Case = HwcVirtualDisplayCase;
1938
1939 // --------------------------------------------------------------------
1940 // Preconditions
1941
1942 // The HWC supports at least one virtual display
1943 injectMockComposer(1);
1944
1945 setupCommonPreconditions<Case>();
1946
1947 // A virtual display was added to the current state, but it does not have a
1948 // surface.
1949 sp<BBinder> displayToken = new BBinder();
1950
Dominik Laskowski075d3172018-05-24 15:50:06 -07001951 DisplayDeviceState state;
1952 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001953
Dominik Laskowski075d3172018-05-24 15:50:06 -07001954 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001955
1956 // --------------------------------------------------------------------
1957 // Call Expectations
1958
1959 // --------------------------------------------------------------------
1960 // Invocation
1961
1962 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
1963
1964 // --------------------------------------------------------------------
1965 // Postconditions
1966
1967 // There will not be a display device set up.
1968 EXPECT_FALSE(hasDisplayDevice(displayToken));
1969
1970 // The drawing display state will be set from the current display state.
1971 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1972 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001973 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001974}
1975
1976TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
1977 using Case = HwcVirtualDisplayCase;
1978
1979 // --------------------------------------------------------------------
1980 // Preconditions
1981
1982 // A virtual display is set up but is removed from the current state.
Dominik Laskowski075d3172018-05-24 15:50:06 -07001983 const auto displayId = Case::Display::DISPLAY_ID::get();
1984 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08001985 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001986 Case::Display::injectHwcDisplay(this);
1987 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1988 existing.inject();
1989 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
1990
1991 // --------------------------------------------------------------------
1992 // Call Expectations
1993
1994 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
1995
1996 // --------------------------------------------------------------------
1997 // Invocation
1998
1999 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2000
2001 // --------------------------------------------------------------------
2002 // Postconditions
2003
2004 // The existing token should have been removed
2005 verifyDisplayIsNotConnected(existing.token());
2006}
2007
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002008TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
2009 using Case = NonHwcVirtualDisplayCase;
2010
2011 constexpr uint32_t oldLayerStack = 0u;
2012 constexpr uint32_t newLayerStack = 123u;
2013
2014 // --------------------------------------------------------------------
2015 // Preconditions
2016
2017 // A display is set up
2018 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2019 display.inject();
2020
2021 // There is a change to the layerStack state
2022 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
2023 display.mutableCurrentDisplayState().layerStack = newLayerStack;
2024
2025 // --------------------------------------------------------------------
2026 // Invocation
2027
2028 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2029
2030 // --------------------------------------------------------------------
2031 // Postconditions
2032
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002033 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002034}
2035
2036TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
2037 using Case = NonHwcVirtualDisplayCase;
2038
2039 constexpr int oldTransform = 0;
2040 constexpr int newTransform = 2;
2041
2042 // --------------------------------------------------------------------
2043 // Preconditions
2044
2045 // A display is set up
2046 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2047 display.inject();
2048
2049 // There is a change to the orientation state
2050 display.mutableDrawingDisplayState().orientation = oldTransform;
2051 display.mutableCurrentDisplayState().orientation = newTransform;
2052
2053 // --------------------------------------------------------------------
2054 // Invocation
2055
2056 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2057
2058 // --------------------------------------------------------------------
2059 // Postconditions
2060
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002061 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002062}
2063
2064TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
2065 using Case = NonHwcVirtualDisplayCase;
2066
2067 const Rect oldViewport(0, 0, 0, 0);
2068 const Rect newViewport(0, 0, 123, 456);
2069
2070 // --------------------------------------------------------------------
2071 // Preconditions
2072
2073 // A display is set up
2074 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2075 display.inject();
2076
2077 // There is a change to the viewport state
2078 display.mutableDrawingDisplayState().viewport = oldViewport;
2079 display.mutableCurrentDisplayState().viewport = newViewport;
2080
2081 // --------------------------------------------------------------------
2082 // Invocation
2083
2084 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2085
2086 // --------------------------------------------------------------------
2087 // Postconditions
2088
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002089 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002090}
2091
2092TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
2093 using Case = NonHwcVirtualDisplayCase;
2094
2095 const Rect oldFrame(0, 0, 0, 0);
2096 const Rect newFrame(0, 0, 123, 456);
2097
2098 // --------------------------------------------------------------------
2099 // Preconditions
2100
2101 // A display is set up
2102 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2103 display.inject();
2104
2105 // There is a change to the viewport state
2106 display.mutableDrawingDisplayState().frame = oldFrame;
2107 display.mutableCurrentDisplayState().frame = newFrame;
2108
2109 // --------------------------------------------------------------------
2110 // Invocation
2111
2112 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2113
2114 // --------------------------------------------------------------------
2115 // Postconditions
2116
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002117 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002118}
2119
2120TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
2121 using Case = NonHwcVirtualDisplayCase;
2122
2123 constexpr int oldWidth = 0;
2124 constexpr int oldHeight = 10;
2125 constexpr int newWidth = 123;
2126
2127 // --------------------------------------------------------------------
2128 // Preconditions
2129
2130 // A display is set up
2131 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002132 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002133 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002134 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2135 display.setNativeWindow(nativeWindow);
2136 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002137 // Setup injection expections
2138 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2139 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2140 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2141 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002142 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2143 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2144 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002145 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002146 display.inject();
2147
2148 // There is a change to the viewport state
2149 display.mutableDrawingDisplayState().width = oldWidth;
2150 display.mutableDrawingDisplayState().height = oldHeight;
2151 display.mutableCurrentDisplayState().width = newWidth;
2152 display.mutableCurrentDisplayState().height = oldHeight;
2153
2154 // --------------------------------------------------------------------
2155 // Call Expectations
2156
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002157 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002158
2159 // --------------------------------------------------------------------
2160 // Invocation
2161
2162 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2163}
2164
2165TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
2166 using Case = NonHwcVirtualDisplayCase;
2167
2168 constexpr int oldWidth = 0;
2169 constexpr int oldHeight = 10;
2170 constexpr int newHeight = 123;
2171
2172 // --------------------------------------------------------------------
2173 // Preconditions
2174
2175 // A display is set up
2176 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002177 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002178 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002179 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2180 display.setNativeWindow(nativeWindow);
2181 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002182 // Setup injection expections
2183 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2184 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2185 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2186 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002187 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2188 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2189 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002190 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002191 display.inject();
2192
2193 // There is a change to the viewport state
2194 display.mutableDrawingDisplayState().width = oldWidth;
2195 display.mutableDrawingDisplayState().height = oldHeight;
2196 display.mutableCurrentDisplayState().width = oldWidth;
2197 display.mutableCurrentDisplayState().height = newHeight;
2198
2199 // --------------------------------------------------------------------
2200 // Call Expectations
2201
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002202 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002203
2204 // --------------------------------------------------------------------
2205 // Invocation
2206
2207 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2208}
2209
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002210/* ------------------------------------------------------------------------
2211 * SurfaceFlinger::setDisplayStateLocked
2212 */
2213
2214TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
2215 // --------------------------------------------------------------------
2216 // Preconditions
2217
2218 // We have an unknown display token not associated with a known display
2219 sp<BBinder> displayToken = new BBinder();
2220
2221 // The requested display state references the unknown display.
2222 DisplayState state;
2223 state.what = DisplayState::eLayerStackChanged;
2224 state.token = displayToken;
2225 state.layerStack = 456;
2226
2227 // --------------------------------------------------------------------
2228 // Invocation
2229
2230 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2231
2232 // --------------------------------------------------------------------
2233 // Postconditions
2234
2235 // The returned flags are empty
2236 EXPECT_EQ(0u, flags);
2237
2238 // The display token still doesn't match anything known.
2239 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2240}
2241
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002242TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
2243 using Case = SimplePrimaryDisplayCase;
2244
2245 // --------------------------------------------------------------------
2246 // Preconditions
2247
2248 // A display is already set up
2249 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2250 display.inject();
2251
2252 // No changes are made to the display
2253 DisplayState state;
2254 state.what = 0;
2255 state.token = display.token();
2256
2257 // --------------------------------------------------------------------
2258 // Invocation
2259
2260 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2261
2262 // --------------------------------------------------------------------
2263 // Postconditions
2264
2265 // The returned flags are empty
2266 EXPECT_EQ(0u, flags);
2267}
2268
2269TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
2270 using Case = SimplePrimaryDisplayCase;
2271
2272 // --------------------------------------------------------------------
2273 // Preconditions
2274
2275 // A display is already set up
2276 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2277 display.inject();
2278
2279 // There is a surface that can be set.
2280 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2281
2282 // The current display state has the surface set
2283 display.mutableCurrentDisplayState().surface = surface;
2284
2285 // The incoming request sets the same surface
2286 DisplayState state;
2287 state.what = DisplayState::eSurfaceChanged;
2288 state.token = display.token();
2289 state.surface = surface;
2290
2291 // --------------------------------------------------------------------
2292 // Invocation
2293
2294 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2295
2296 // --------------------------------------------------------------------
2297 // Postconditions
2298
2299 // The returned flags are empty
2300 EXPECT_EQ(0u, flags);
2301
2302 // The current display state is unchanged.
2303 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2304}
2305
2306TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
2307 using Case = SimplePrimaryDisplayCase;
2308
2309 // --------------------------------------------------------------------
2310 // Preconditions
2311
2312 // A display is already set up
2313 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2314 display.inject();
2315
2316 // There is a surface that can be set.
2317 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2318
2319 // The current display state does not have a surface
2320 display.mutableCurrentDisplayState().surface = nullptr;
2321
2322 // The incoming request sets a surface
2323 DisplayState state;
2324 state.what = DisplayState::eSurfaceChanged;
2325 state.token = display.token();
2326 state.surface = surface;
2327
2328 // --------------------------------------------------------------------
2329 // Invocation
2330
2331 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2332
2333 // --------------------------------------------------------------------
2334 // Postconditions
2335
2336 // The returned flags indicate a transaction is needed
2337 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2338
2339 // The current display layer stack state is set to the new value
2340 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2341}
2342
2343TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
2344 using Case = SimplePrimaryDisplayCase;
2345
2346 // --------------------------------------------------------------------
2347 // Preconditions
2348
2349 // A display is already set up
2350 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2351 display.inject();
2352
2353 // The display has a layer stack set
2354 display.mutableCurrentDisplayState().layerStack = 456u;
2355
2356 // The incoming request sets the same layer stack
2357 DisplayState state;
2358 state.what = DisplayState::eLayerStackChanged;
2359 state.token = display.token();
2360 state.layerStack = 456u;
2361
2362 // --------------------------------------------------------------------
2363 // Invocation
2364
2365 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2366
2367 // --------------------------------------------------------------------
2368 // Postconditions
2369
2370 // The returned flags are empty
2371 EXPECT_EQ(0u, flags);
2372
2373 // The current display state is unchanged
2374 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2375}
2376
2377TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
2378 using Case = SimplePrimaryDisplayCase;
2379
2380 // --------------------------------------------------------------------
2381 // Preconditions
2382
2383 // A display is set up
2384 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2385 display.inject();
2386
2387 // The display has a layer stack set
2388 display.mutableCurrentDisplayState().layerStack = 654u;
2389
2390 // The incoming request sets a different layer stack
2391 DisplayState state;
2392 state.what = DisplayState::eLayerStackChanged;
2393 state.token = display.token();
2394 state.layerStack = 456u;
2395
2396 // --------------------------------------------------------------------
2397 // Invocation
2398
2399 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2400
2401 // --------------------------------------------------------------------
2402 // Postconditions
2403
2404 // The returned flags indicate a transaction is needed
2405 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2406
2407 // The desired display state has been set to the new value.
2408 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2409}
2410
2411TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
2412 using Case = SimplePrimaryDisplayCase;
2413 constexpr int initialOrientation = 180;
2414 const Rect initialFrame = {1, 2, 3, 4};
2415 const Rect initialViewport = {5, 6, 7, 8};
2416
2417 // --------------------------------------------------------------------
2418 // Preconditions
2419
2420 // A display is set up
2421 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2422 display.inject();
2423
2424 // The current display state projection state is all set
2425 display.mutableCurrentDisplayState().orientation = initialOrientation;
2426 display.mutableCurrentDisplayState().frame = initialFrame;
2427 display.mutableCurrentDisplayState().viewport = initialViewport;
2428
2429 // The incoming request sets the same projection state
2430 DisplayState state;
2431 state.what = DisplayState::eDisplayProjectionChanged;
2432 state.token = display.token();
2433 state.orientation = initialOrientation;
2434 state.frame = initialFrame;
2435 state.viewport = initialViewport;
2436
2437 // --------------------------------------------------------------------
2438 // Invocation
2439
2440 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2441
2442 // --------------------------------------------------------------------
2443 // Postconditions
2444
2445 // The returned flags are empty
2446 EXPECT_EQ(0u, flags);
2447
2448 // The current display state is unchanged
2449 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
2450
2451 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
2452 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
2453}
2454
2455TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
2456 using Case = SimplePrimaryDisplayCase;
2457 constexpr int initialOrientation = 90;
2458 constexpr int desiredOrientation = 180;
2459
2460 // --------------------------------------------------------------------
2461 // Preconditions
2462
2463 // A display is set up
2464 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2465 display.inject();
2466
2467 // The current display state has an orientation set
2468 display.mutableCurrentDisplayState().orientation = initialOrientation;
2469
2470 // The incoming request sets a different orientation
2471 DisplayState state;
2472 state.what = DisplayState::eDisplayProjectionChanged;
2473 state.token = display.token();
2474 state.orientation = desiredOrientation;
2475
2476 // --------------------------------------------------------------------
2477 // Invocation
2478
2479 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2480
2481 // --------------------------------------------------------------------
2482 // Postconditions
2483
2484 // The returned flags indicate a transaction is needed
2485 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2486
2487 // The current display state has the new value.
2488 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2489}
2490
2491TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2492 using Case = SimplePrimaryDisplayCase;
2493 const Rect initialFrame = {0, 0, 0, 0};
2494 const Rect desiredFrame = {5, 6, 7, 8};
2495
2496 // --------------------------------------------------------------------
2497 // Preconditions
2498
2499 // A display is set up
2500 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2501 display.inject();
2502
2503 // The current display state does not have a frame
2504 display.mutableCurrentDisplayState().frame = initialFrame;
2505
2506 // The incoming request sets a frame
2507 DisplayState state;
2508 state.what = DisplayState::eDisplayProjectionChanged;
2509 state.token = display.token();
2510 state.frame = desiredFrame;
2511
2512 // --------------------------------------------------------------------
2513 // Invocation
2514
2515 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2516
2517 // --------------------------------------------------------------------
2518 // Postconditions
2519
2520 // The returned flags indicate a transaction is needed
2521 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2522
2523 // The current display state has the new value.
2524 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2525}
2526
2527TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2528 using Case = SimplePrimaryDisplayCase;
2529 const Rect initialViewport = {0, 0, 0, 0};
2530 const Rect desiredViewport = {5, 6, 7, 8};
2531
2532 // --------------------------------------------------------------------
2533 // Preconditions
2534
2535 // A display is set up
2536 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2537 display.inject();
2538
2539 // The current display state does not have a viewport
2540 display.mutableCurrentDisplayState().viewport = initialViewport;
2541
2542 // The incoming request sets a viewport
2543 DisplayState state;
2544 state.what = DisplayState::eDisplayProjectionChanged;
2545 state.token = display.token();
2546 state.viewport = desiredViewport;
2547
2548 // --------------------------------------------------------------------
2549 // Invocation
2550
2551 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2552
2553 // --------------------------------------------------------------------
2554 // Postconditions
2555
2556 // The returned flags indicate a transaction is needed
2557 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2558
2559 // The current display state has the new value.
2560 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2561}
2562
2563TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2564 using Case = SimplePrimaryDisplayCase;
2565 constexpr uint32_t initialWidth = 1024;
2566 constexpr uint32_t initialHeight = 768;
2567
2568 // --------------------------------------------------------------------
2569 // Preconditions
2570
2571 // A display is set up
2572 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2573 display.inject();
2574
2575 // The current display state has a size set
2576 display.mutableCurrentDisplayState().width = initialWidth;
2577 display.mutableCurrentDisplayState().height = initialHeight;
2578
2579 // The incoming request sets the same display size
2580 DisplayState state;
2581 state.what = DisplayState::eDisplaySizeChanged;
2582 state.token = display.token();
2583 state.width = initialWidth;
2584 state.height = initialHeight;
2585
2586 // --------------------------------------------------------------------
2587 // Invocation
2588
2589 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2590
2591 // --------------------------------------------------------------------
2592 // Postconditions
2593
2594 // The returned flags are empty
2595 EXPECT_EQ(0u, flags);
2596
2597 // The current display state is unchanged
2598 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2599 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2600}
2601
2602TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
2603 using Case = SimplePrimaryDisplayCase;
2604 constexpr uint32_t initialWidth = 0;
2605 constexpr uint32_t desiredWidth = 1024;
2606
2607 // --------------------------------------------------------------------
2608 // Preconditions
2609
2610 // A display is set up
2611 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2612 display.inject();
2613
2614 // The display does not yet have a width
2615 display.mutableCurrentDisplayState().width = initialWidth;
2616
2617 // The incoming request sets a display width
2618 DisplayState state;
2619 state.what = DisplayState::eDisplaySizeChanged;
2620 state.token = display.token();
2621 state.width = desiredWidth;
2622
2623 // --------------------------------------------------------------------
2624 // Invocation
2625
2626 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2627
2628 // --------------------------------------------------------------------
2629 // Postconditions
2630
2631 // The returned flags indicate a transaction is needed
2632 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2633
2634 // The current display state has the new value.
2635 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
2636}
2637
2638TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
2639 using Case = SimplePrimaryDisplayCase;
2640 constexpr uint32_t initialHeight = 0;
2641 constexpr uint32_t desiredHeight = 768;
2642
2643 // --------------------------------------------------------------------
2644 // Preconditions
2645
2646 // A display is set up
2647 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2648 display.inject();
2649
2650 // The display does not yet have a height
2651 display.mutableCurrentDisplayState().height = initialHeight;
2652
2653 // The incoming request sets a display height
2654 DisplayState state;
2655 state.what = DisplayState::eDisplaySizeChanged;
2656 state.token = display.token();
2657 state.height = desiredHeight;
2658
2659 // --------------------------------------------------------------------
2660 // Invocation
2661
2662 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2663
2664 // --------------------------------------------------------------------
2665 // Postconditions
2666
2667 // The returned flags indicate a transaction is needed
2668 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2669
2670 // The current display state has the new value.
2671 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
2672}
2673
Lloyd Pique86016da2018-03-01 16:09:38 -08002674/* ------------------------------------------------------------------------
2675 * SurfaceFlinger::onInitializeDisplays
2676 */
2677
2678TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
2679 using Case = SimplePrimaryDisplayCase;
2680
2681 // --------------------------------------------------------------------
2682 // Preconditions
2683
2684 // A primary display is set up
2685 Case::Display::injectHwcDisplay(this);
2686 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
2687 primaryDisplay.inject();
2688
2689 // --------------------------------------------------------------------
2690 // Call Expectations
2691
2692 // We expect the surface interceptor to possibly be used, but we treat it as
2693 // disabled since it is called as a side effect rather than directly by this
2694 // function.
2695 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
2696
2697 // We expect a call to get the active display config.
2698 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
2699
2700 // We expect invalidate() to be invoked once to trigger display transaction
2701 // processing.
2702 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
2703
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002704 EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
2705
Lloyd Pique86016da2018-03-01 16:09:38 -08002706 // --------------------------------------------------------------------
2707 // Invocation
2708
2709 mFlinger.onInitializeDisplays();
2710
2711 // --------------------------------------------------------------------
2712 // Postconditions
2713
2714 // The primary display should have a current state
2715 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
2716 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
2717 // The layer stack state should be set to zero
2718 EXPECT_EQ(0u, primaryDisplayState.layerStack);
2719 // The orientation state should be set to zero
2720 EXPECT_EQ(0, primaryDisplayState.orientation);
2721
2722 // The frame state should be set to INVALID
2723 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
2724
2725 // The viewport state should be set to INVALID
2726 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
2727
2728 // The width and height should both be zero
2729 EXPECT_EQ(0u, primaryDisplayState.width);
2730 EXPECT_EQ(0u, primaryDisplayState.height);
2731
2732 // The display should be set to HWC_POWER_MODE_NORMAL
2733 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
2734 auto displayDevice = primaryDisplay.mutableDisplayDevice();
2735 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
2736
2737 // The display refresh period should be set in the frame tracker.
2738 FrameStats stats;
2739 mFlinger.getAnimFrameTracker().getStats(&stats);
2740 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
2741
2742 // The display transaction needed flag should be set.
2743 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
2744
2745 // The compositor timing should be set to default values
2746 const auto& compositorTiming = mFlinger.getCompositorTiming();
2747 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
2748 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
2749 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
2750}
2751
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002752/* ------------------------------------------------------------------------
2753 * SurfaceFlinger::setPowerModeInternal
2754 */
2755
2756// Used when we simulate a display that supports doze.
Peiyong Lined531a32018-10-26 18:27:56 -07002757template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002758struct DozeIsSupportedVariant {
2759 static constexpr bool DOZE_SUPPORTED = true;
2760 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
2761 IComposerClient::PowerMode::DOZE;
2762 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
2763 IComposerClient::PowerMode::DOZE_SUSPEND;
Peiyong Lined531a32018-10-26 18:27:56 -07002764
2765 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
2766 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
2767 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>(
2768 {Hwc2::DisplayCapability::DOZE})),
2769 Return(Error::NONE)));
2770 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002771};
2772
Peiyong Lined531a32018-10-26 18:27:56 -07002773template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002774// Used when we simulate a display that does not support doze.
2775struct DozeNotSupportedVariant {
2776 static constexpr bool DOZE_SUPPORTED = false;
2777 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
2778 IComposerClient::PowerMode::ON;
2779 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
2780 IComposerClient::PowerMode::ON;
Peiyong Lined531a32018-10-26 18:27:56 -07002781
2782 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
2783 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
2784 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
2785 Return(Error::NONE)));
2786 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002787};
2788
2789struct EventThreadBaseSupportedVariant {
2790 static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
2791 // The event control thread should not be notified.
2792 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
2793
2794 // The event thread should not be notified.
2795 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
2796 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(0);
2797 }
2798};
2799
2800struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
2801 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
2802 // These calls are only expected for the primary display.
2803
2804 // Instead expect no calls.
2805 setupEventAndEventControlThreadNoCallExpectations(test);
2806 }
2807
2808 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
2809 // These calls are only expected for the primary display.
2810
2811 // Instead expect no calls.
2812 setupEventAndEventControlThreadNoCallExpectations(test);
2813 }
2814};
2815
2816struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
2817 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
2818 // The event control thread should be notified to enable vsyncs
2819 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
2820
2821 // The event thread should be notified that the screen was acquired.
2822 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
2823 }
2824
2825 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
2826 // There should be a call to setVsyncEnabled(false)
2827 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
2828
2829 // The event thread should not be notified that the screen was released.
2830 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
2831 }
2832};
2833
Lloyd Pique41be5d22018-06-21 13:11:48 -07002834struct DispSyncIsSupportedVariant {
2835 static void setupBeginResyncCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique41be5d22018-06-21 13:11:48 -07002836 EXPECT_CALL(*test->mPrimaryDispSync, setPeriod(DEFAULT_REFRESH_RATE)).Times(1);
2837 EXPECT_CALL(*test->mPrimaryDispSync, beginResync()).Times(1);
2838 }
2839
2840 static void setupEndResyncCallExpectations(DisplayTransactionTest* test) {
2841 EXPECT_CALL(*test->mPrimaryDispSync, endResync()).Times(1);
2842 }
2843};
2844
2845struct DispSyncNotSupportedVariant {
2846 static void setupBeginResyncCallExpectations(DisplayTransactionTest* /* test */) {}
2847
2848 static void setupEndResyncCallExpectations(DisplayTransactionTest* /* test */) {}
2849};
2850
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002851// --------------------------------------------------------------------
2852// Note:
2853//
2854// There are a large number of transitions we could test, however we only test a
2855// selected subset which provides complete test coverage of the implementation.
2856// --------------------------------------------------------------------
2857
2858template <int initialPowerMode, int targetPowerMode>
2859struct TransitionVariantCommon {
2860 static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
2861 static constexpr auto TARGET_POWER_MODE = targetPowerMode;
2862
2863 static void verifyPostconditions(DisplayTransactionTest*) {}
2864};
2865
2866struct TransitionOffToOnVariant
2867 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
2868 template <typename Case>
2869 static void setupCallExpectations(DisplayTransactionTest* test) {
2870 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2871 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07002872 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002873 Case::setupRepaintEverythingCallExpectations(test);
2874 }
2875
2876 static void verifyPostconditions(DisplayTransactionTest* test) {
2877 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2878 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
2879 }
2880};
2881
2882struct TransitionOffToDozeSuspendVariant
2883 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
2884 template <typename Case>
2885 static void setupCallExpectations(DisplayTransactionTest* test) {
2886 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
2887 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2888 Case::setupRepaintEverythingCallExpectations(test);
2889 }
2890
2891 static void verifyPostconditions(DisplayTransactionTest* test) {
2892 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2893 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
2894 }
2895};
2896
2897struct TransitionOnToOffVariant
2898 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
2899 template <typename Case>
2900 static void setupCallExpectations(DisplayTransactionTest* test) {
2901 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07002902 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002903 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
2904 }
2905
2906 static void verifyPostconditions(DisplayTransactionTest* test) {
2907 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2908 }
2909};
2910
2911struct TransitionDozeSuspendToOffVariant
2912 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
2913 template <typename Case>
2914 static void setupCallExpectations(DisplayTransactionTest* test) {
2915 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2916 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
2917 }
2918
2919 static void verifyPostconditions(DisplayTransactionTest* test) {
2920 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
2921 }
2922};
2923
2924struct TransitionOnToDozeVariant
2925 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
2926 template <typename Case>
2927 static void setupCallExpectations(DisplayTransactionTest* test) {
2928 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2929 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
2930 }
2931};
2932
2933struct TransitionDozeSuspendToDozeVariant
2934 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
2935 template <typename Case>
2936 static void setupCallExpectations(DisplayTransactionTest* test) {
2937 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07002938 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002939 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
2940 }
2941};
2942
2943struct TransitionDozeToOnVariant
2944 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
2945 template <typename Case>
2946 static void setupCallExpectations(DisplayTransactionTest* test) {
2947 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2948 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2949 }
2950};
2951
2952struct TransitionDozeSuspendToOnVariant
2953 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
2954 template <typename Case>
2955 static void setupCallExpectations(DisplayTransactionTest* test) {
2956 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07002957 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002958 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
2959 }
2960};
2961
2962struct TransitionOnToDozeSuspendVariant
2963 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
2964 template <typename Case>
2965 static void setupCallExpectations(DisplayTransactionTest* test) {
2966 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07002967 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002968 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
2969 }
2970};
2971
2972struct TransitionOnToUnknownVariant
2973 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
2974 template <typename Case>
2975 static void setupCallExpectations(DisplayTransactionTest* test) {
2976 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
2977 Case::setupNoComposerPowerModeCallExpectations(test);
2978 }
2979};
2980
2981// --------------------------------------------------------------------
2982// Note:
2983//
2984// Rather than testing the cartesian product of of
2985// DozeIsSupported/DozeNotSupported with all other options, we use one for one
2986// display type, and the other for another display type.
2987// --------------------------------------------------------------------
2988
2989template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
Lloyd Pique41be5d22018-06-21 13:11:48 -07002990 typename DispSyncVariant, typename TransitionVariant>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002991struct DisplayPowerCase {
2992 using Display = DisplayVariant;
2993 using Doze = DozeVariant;
2994 using EventThread = EventThreadVariant;
Lloyd Pique41be5d22018-06-21 13:11:48 -07002995 using DispSync = DispSyncVariant;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08002996 using Transition = TransitionVariant;
2997
2998 static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002999 Display::injectHwcDisplayWithNoDefaultCapabilities(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003000 auto display = Display::makeFakeExistingDisplayInjector(test);
3001 display.inject();
3002 display.mutableDisplayDevice()->setPowerMode(mode);
3003 return display;
3004 }
3005
3006 static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07003007 test->mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = enabled;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003008 }
3009
3010 static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
3011 EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
3012 }
3013
3014 static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
3015 EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
3016 EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
3017 }
3018
3019 static void setupComposerCallExpectations(DisplayTransactionTest* test,
3020 IComposerClient::PowerMode mode) {
3021 // Any calls to get the active config will return a default value.
3022 EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
3023 .WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
3024 Return(Error::NONE)));
3025
3026 // Any calls to get whether the display supports dozing will return the value set by the
3027 // policy variant.
3028 EXPECT_CALL(*test->mComposer, getDozeSupport(Display::HWC_DISPLAY_ID, _))
3029 .WillRepeatedly(DoAll(SetArgPointee<1>(Doze::DOZE_SUPPORTED), Return(Error::NONE)));
3030
3031 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, mode)).Times(1);
3032 }
3033
3034 static void setupNoComposerPowerModeCallExpectations(DisplayTransactionTest* test) {
3035 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, _)).Times(0);
3036 }
3037};
3038
3039// A sample configuration for the primary display.
3040// In addition to having event thread support, we emulate doze support.
3041template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003042using PrimaryDisplayPowerCase =
3043 DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant<PrimaryDisplayVariant>,
3044 EventThreadIsSupportedVariant, DispSyncIsSupportedVariant,
3045 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003046
3047// A sample configuration for the external display.
3048// In addition to not having event thread support, we emulate not having doze
3049// support.
3050template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003051using ExternalDisplayPowerCase =
3052 DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant<ExternalDisplayVariant>,
3053 EventThreadNotSupportedVariant, DispSyncNotSupportedVariant,
3054 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003055
3056class SetPowerModeInternalTest : public DisplayTransactionTest {
3057public:
3058 template <typename Case>
3059 void transitionDisplayCommon();
3060};
3061
3062template <int PowerMode>
3063struct PowerModeInitialVSyncEnabled : public std::false_type {};
3064
3065template <>
3066struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
3067
3068template <>
3069struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
3070
3071template <typename Case>
3072void SetPowerModeInternalTest::transitionDisplayCommon() {
3073 // --------------------------------------------------------------------
3074 // Preconditions
3075
Peiyong Lined531a32018-10-26 18:27:56 -07003076 Case::Doze::setupComposerCallExpectations(this);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003077 auto display =
3078 Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
3079 Case::setInitialPrimaryHWVsyncEnabled(this,
3080 PowerModeInitialVSyncEnabled<
3081 Case::Transition::INITIAL_POWER_MODE>::value);
3082
3083 // --------------------------------------------------------------------
3084 // Call Expectations
3085
3086 Case::setupSurfaceInterceptorCallExpectations(this, Case::Transition::TARGET_POWER_MODE);
3087 Case::Transition::template setupCallExpectations<Case>(this);
3088
3089 // --------------------------------------------------------------------
3090 // Invocation
3091
3092 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
3093 Case::Transition::TARGET_POWER_MODE);
3094
3095 // --------------------------------------------------------------------
3096 // Postconditions
3097
3098 Case::Transition::verifyPostconditions(this);
3099}
3100
3101TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) {
3102 using Case = SimplePrimaryDisplayCase;
3103
3104 // --------------------------------------------------------------------
3105 // Preconditions
3106
3107 // A primary display device is set up
3108 Case::Display::injectHwcDisplay(this);
3109 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3110 display.inject();
3111
Dominik Laskowskia2edf612018-06-01 13:15:16 -07003112 // The display is already set to HWC_POWER_MODE_NORMAL
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003113 display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
3114
3115 // --------------------------------------------------------------------
3116 // Invocation
3117
3118 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
3119
3120 // --------------------------------------------------------------------
3121 // Postconditions
3122
3123 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3124}
3125
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003126TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) {
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003127 using Case = HwcVirtualDisplayCase;
3128
3129 // --------------------------------------------------------------------
3130 // Preconditions
3131
Dominik Laskowski075d3172018-05-24 15:50:06 -07003132 // Insert display data so that the HWC thinks it created the virtual display.
3133 const auto displayId = Case::Display::DISPLAY_ID::get();
3134 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08003135 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003136
3137 // A virtual display device is set up
3138 Case::Display::injectHwcDisplay(this);
3139 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3140 display.inject();
3141
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003142 // The display is set to HWC_POWER_MODE_NORMAL
3143 getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_NORMAL);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003144
3145 // --------------------------------------------------------------------
3146 // Invocation
3147
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003148 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_OFF);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003149
3150 // --------------------------------------------------------------------
3151 // Postconditions
3152
3153 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3154}
3155
3156TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
3157 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>();
3158}
3159
3160TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) {
3161 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3162}
3163
3164TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) {
3165 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>();
3166}
3167
3168TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) {
3169 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3170}
3171
3172TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) {
3173 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>();
3174}
3175
3176TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) {
3177 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3178}
3179
3180TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) {
3181 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>();
3182}
3183
3184TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) {
3185 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3186}
3187
3188TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) {
3189 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3190}
3191
3192TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) {
3193 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>();
3194}
3195
3196TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) {
3197 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
3198}
3199
3200TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) {
3201 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3202}
3203
3204TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) {
3205 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
3206}
3207
3208TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) {
3209 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3210}
3211
3212TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) {
3213 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>();
3214}
3215
3216TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
3217 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3218}
3219
3220TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) {
3221 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>();
3222}
3223
3224TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
3225 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3226}
3227
3228TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
3229 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3230}
3231
3232TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) {
3233 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
3234}
3235
Lloyd Piquef58625d2017-12-19 13:22:33 -08003236} // namespace
3237} // namespace android