blob: abf846669ca68b7a5216be51a9e079f2bc2691f6 [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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Lloyd Piquef58625d2017-12-19 13:22:33 -080021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
Dominik Laskowski075d3172018-05-24 15:50:06 -070024#include <type_traits>
25
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070026#include <compositionengine/Display.h>
27#include <compositionengine/DisplayColorProfile.h>
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070028#include <compositionengine/impl/Display.h>
Lloyd Pique33050472019-12-19 17:12:44 -080029#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070030#include <compositionengine/mock/Display.h>
31#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Pique542307f2018-10-19 13:24:08 -070032#include <compositionengine/mock/DisplaySurface.h>
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070033#include <compositionengine/mock/RenderSurface.h>
Lloyd Piquef58625d2017-12-19 13:22:33 -080034#include <gmock/gmock.h>
35#include <gtest/gtest.h>
Lloyd Pique1ebe0902019-10-04 14:47:13 -070036#include <gui/mock/GraphicBufferConsumer.h>
37#include <gui/mock/GraphicBufferProducer.h>
Lloyd Piquef58625d2017-12-19 13:22:33 -080038#include <log/log.h>
Lloyd Pique3823e7b2018-10-18 16:58:10 -070039#include <renderengine/mock/RenderEngine.h>
Valerie Hau9758ae02018-10-09 16:05:09 -070040#include <ui/DebugUtils.h>
Dominik Laskowski075d3172018-05-24 15:50:06 -070041
42#include "DisplayIdentificationTest.h"
Ana Krulecafb45842019-02-13 13:33:03 -080043#include "TestableScheduler.h"
Lloyd Piquef58625d2017-12-19 13:22:33 -080044#include "TestableSurfaceFlinger.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080045#include "mock/DisplayHardware/MockComposer.h"
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070046#include "mock/DisplayHardware/MockPowerAdvisor.h"
Lloyd Pique41be5d22018-06-21 13:11:48 -070047#include "mock/MockDispSync.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080048#include "mock/MockEventControlThread.h"
49#include "mock/MockEventThread.h"
50#include "mock/MockMessageQueue.h"
51#include "mock/MockNativeWindowSurface.h"
52#include "mock/MockSurfaceInterceptor.h"
Lloyd Piquecbe00012018-02-02 15:40:42 -080053#include "mock/system/window/MockNativeWindow.h"
Lloyd Piquef58625d2017-12-19 13:22:33 -080054
55namespace android {
56namespace {
57
Peiyong Line9d809e2020-04-14 13:10:48 -070058namespace hal = android::hardware::graphics::composer::hal;
59
Lloyd Piquee39cad22017-12-20 17:01:29 -080060using testing::_;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070061using testing::AnyNumber;
Lloyd Piquee39cad22017-12-20 17:01:29 -080062using testing::DoAll;
63using testing::Mock;
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080064using testing::ResultOf;
Lloyd Piquee39cad22017-12-20 17:01:29 -080065using testing::Return;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070066using testing::ReturnRefOfCopy;
Lloyd Piquee39cad22017-12-20 17:01:29 -080067using testing::SetArgPointee;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070068using testing::StrictMock;
Lloyd Piquee39cad22017-12-20 17:01:29 -080069
Peiyong Line9d809e2020-04-14 13:10:48 -070070using hal::ColorMode;
71using hal::Connection;
72using hal::DisplayCapability;
73using hal::DisplayType;
74using hal::Error;
75using hal::Hdr;
76using hal::HWDisplayId;
77using hal::IComposer;
78using hal::IComposerClient;
79using hal::PerFrameMetadataKey;
80using hal::PowerMode;
81using hal::RenderIntent;
Lloyd Piquee39cad22017-12-20 17:01:29 -080082
Lloyd Piquec11e0d32018-01-22 18:44:59 -080083using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
84using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
Lloyd Pique1fa4d462018-01-22 18:03:16 -080085using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080086using HWC2Display = TestableSurfaceFlinger::HWC2Display;
Lloyd Piquebc792092018-01-17 11:52:30 -080087
Lloyd Piquec11e0d32018-01-22 18:44:59 -080088constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
Lloyd Piquee39cad22017-12-20 17:01:29 -080089constexpr int32_t DEFAULT_DPI = 320;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080090constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
Lloyd Piquee39cad22017-12-20 17:01:29 -080091
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -080092constexpr int HWC_POWER_MODE_LEET = 1337; // An out of range power mode value
93
Lloyd Piquec11e0d32018-01-22 18:44:59 -080094/* ------------------------------------------------------------------------
95 * Boolean avoidance
96 *
97 * To make calls and template instantiations more readable, we define some
98 * local enums along with an implicit bool conversion.
99 */
100
101#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
102
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800103BOOL_SUBSTITUTE(Async);
Dominik Laskowski075d3172018-05-24 15:50:06 -0700104BOOL_SUBSTITUTE(Critical);
105BOOL_SUBSTITUTE(Primary);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800106BOOL_SUBSTITUTE(Secure);
Dominik Laskowski075d3172018-05-24 15:50:06 -0700107BOOL_SUBSTITUTE(Virtual);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800108
109/* ------------------------------------------------------------------------
110 *
111 */
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800112
Lloyd Piquef58625d2017-12-19 13:22:33 -0800113class DisplayTransactionTest : public testing::Test {
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800114public:
Lloyd Piquef58625d2017-12-19 13:22:33 -0800115 DisplayTransactionTest();
116 ~DisplayTransactionTest() override;
117
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800118 // --------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800119 // Mock/Fake injection
Lloyd Piquef58625d2017-12-19 13:22:33 -0800120
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700121 void injectMockScheduler();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800122 void injectMockComposer(int virtualDisplayCount);
123 void injectFakeBufferQueueFactory();
124 void injectFakeNativeWindowSurfaceFactory();
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700125 sp<DisplayDevice> injectDefaultInternalDisplay(std::function<void(FakeDisplayDeviceInjector&)>);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800126
127 // --------------------------------------------------------------------
128 // Postcondition helpers
129
Peiyong Line9d809e2020-04-14 13:10:48 -0700130 bool hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800131 bool hasTransactionFlagSet(int flag);
132 bool hasDisplayDevice(sp<IBinder> displayToken);
133 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
134 bool hasCurrentDisplayState(sp<IBinder> displayToken);
135 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
136 bool hasDrawingDisplayState(sp<IBinder> displayToken);
137 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
138
139 // --------------------------------------------------------------------
140 // Test instances
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800141
Lloyd Piquef58625d2017-12-19 13:22:33 -0800142 TestableSurfaceFlinger mFlinger;
Alec Mouriba013fa2018-10-16 12:43:11 -0700143 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800144 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700145 Hwc2::mock::PowerAdvisor mPowerAdvisor;
Lloyd Piquee39cad22017-12-20 17:01:29 -0800146
147 // These mocks are created by the test, but are destroyed by SurfaceFlinger
148 // by virtue of being stored into a std::unique_ptr. However we still need
149 // to keep a reference to them for use in setting up call expectations.
Peiyong Lin833074a2018-08-28 11:53:54 -0700150 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800151 Hwc2::mock::Composer* mComposer = nullptr;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800152 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
153 mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700154
155 mock::DispSync* mPrimaryDispSync = new mock::DispSync;
156 mock::EventControlThread* mEventControlThread = new mock::EventControlThread;
157 mock::EventThread* mEventThread = new mock::EventThread;
158 mock::EventThread* mSFEventThread = new mock::EventThread;
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800159
160 // These mocks are created only when expected to be created via a factory.
161 sp<mock::GraphicBufferConsumer> mConsumer;
162 sp<mock::GraphicBufferProducer> mProducer;
Lloyd Pique22098362018-09-13 11:46:49 -0700163 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
Lloyd Piquef58625d2017-12-19 13:22:33 -0800164};
165
166DisplayTransactionTest::DisplayTransactionTest() {
167 const ::testing::TestInfo* const test_info =
168 ::testing::UnitTest::GetInstance()->current_test_info();
169 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Lloyd Piquee39cad22017-12-20 17:01:29 -0800170
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800171 // Default to no wide color display support configured
172 mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700173 mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800174 mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800175
176 // Default to using HWC virtual displays
177 mFlinger.mutableUseHwcVirtualDisplays() = true;
178
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800179 mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
180 ADD_FAILURE() << "Unexpected request to create a buffer queue.";
181 });
182
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800183 mFlinger.setCreateNativeWindowSurface([](auto) {
184 ADD_FAILURE() << "Unexpected request to create a native window surface.";
185 return nullptr;
186 });
187
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700188 injectMockScheduler();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800189 mFlinger.mutableEventQueue().reset(mMessageQueue);
Peiyong Lin833074a2018-08-28 11:53:54 -0700190 mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800191 mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800192
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800193 injectMockComposer(0);
Lloyd Piquef58625d2017-12-19 13:22:33 -0800194}
195
196DisplayTransactionTest::~DisplayTransactionTest() {
197 const ::testing::TestInfo* const test_info =
198 ::testing::UnitTest::GetInstance()->current_test_info();
199 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
200}
201
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700202void DisplayTransactionTest::injectMockScheduler() {
Ana Krulecafb45842019-02-13 13:33:03 -0800203 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700204 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
205 .WillOnce(Return(new EventThreadConnection(mEventThread, ResyncCallback(),
206 ISurfaceComposer::eConfigChangedSuppress)));
207
Ana Krulecafb45842019-02-13 13:33:03 -0800208 EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700209 EXPECT_CALL(*mSFEventThread, createEventConnection(_, _))
210 .WillOnce(Return(new EventThreadConnection(mSFEventThread, ResyncCallback(),
211 ISurfaceComposer::eConfigChangedSuppress)));
Ana Krulecafb45842019-02-13 13:33:03 -0800212
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700213 mFlinger.setupScheduler(std::unique_ptr<DispSync>(mPrimaryDispSync),
214 std::unique_ptr<EventControlThread>(mEventControlThread),
215 std::unique_ptr<EventThread>(mEventThread),
216 std::unique_ptr<EventThread>(mSFEventThread));
Ana Krulecafb45842019-02-13 13:33:03 -0800217}
218
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800219void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
220 mComposer = new Hwc2::mock::Composer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800221 EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
222 mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
Lloyd Piquef58625d2017-12-19 13:22:33 -0800223
Lloyd Piquee39cad22017-12-20 17:01:29 -0800224 Mock::VerifyAndClear(mComposer);
225}
226
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800227void DisplayTransactionTest::injectFakeBufferQueueFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800228 // This setup is only expected once per test.
229 ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
230
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800231 mConsumer = new mock::GraphicBufferConsumer();
232 mProducer = new mock::GraphicBufferProducer();
233
234 mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
235 *outProducer = mProducer;
236 *outConsumer = mConsumer;
237 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800238}
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800239
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800240void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800241 // This setup is only expected once per test.
242 ASSERT_TRUE(mNativeWindowSurface == nullptr);
243
Lloyd Pique22098362018-09-13 11:46:49 -0700244 mNativeWindowSurface = new surfaceflinger::mock::NativeWindowSurface();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800245
Lloyd Pique22098362018-09-13 11:46:49 -0700246 mFlinger.setCreateNativeWindowSurface([this](auto) {
247 return std::unique_ptr<surfaceflinger::NativeWindowSurface>(mNativeWindowSurface);
248 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800249}
250
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700251sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
252 std::function<void(FakeDisplayDeviceInjector&)> injectExtra) {
253 constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
254 constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
255 constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
Peiyong Line9d809e2020-04-14 13:10:48 -0700256 constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700257
258 // The DisplayDevice is required to have a framebuffer (behind the
259 // ANativeWindow interface) which uses the actual hardware display
260 // size.
261 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
262 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
263 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
264 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
265 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT));
266 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT));
267 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64));
268 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber());
269
270 auto compositionDisplay = compositionengine::impl::
271 createDisplay(mFlinger.getCompositionEngine(),
272 compositionengine::DisplayCreationArgsBuilder()
273 .setPhysical(
274 {DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal})
275 .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
276 .setPowerAdvisor(&mPowerAdvisor)
277 .build());
278
279 auto injector =
280 FakeDisplayDeviceInjector(mFlinger, compositionDisplay, DisplayConnectionType::Internal,
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100281 DEFAULT_DISPLAY_HWC_DISPLAY_ID, true /* isPrimary */);
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700282
283 injector.setNativeWindow(mNativeWindow);
284 if (injectExtra) {
285 injectExtra(injector);
286 }
287
288 auto displayDevice = injector.inject();
289
290 Mock::VerifyAndClear(mNativeWindow.get());
291
292 return displayDevice;
293}
294
Peiyong Line9d809e2020-04-14 13:10:48 -0700295bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700296 return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800297}
298
299bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
300 return mFlinger.mutableTransactionFlags() & flag;
301}
302
303bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700304 return mFlinger.mutableDisplays().count(displayToken) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800305}
306
307sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700308 return mFlinger.mutableDisplays()[displayToken];
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800309}
310
311bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
312 return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
313}
314
315const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
316 return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
317}
318
319bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
320 return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
321}
322
323const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
324 return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
325}
326
327/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800328 *
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800329 */
330
Dominik Laskowski075d3172018-05-24 15:50:06 -0700331template <typename PhysicalDisplay>
332struct PhysicalDisplayId {};
333
Dominik Laskowski34157762018-10-31 13:07:19 -0700334template <DisplayId::Type displayId>
335using VirtualDisplayId = std::integral_constant<DisplayId::Type, displayId>;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700336
337struct NoDisplayId {};
338
339template <typename>
340struct IsPhysicalDisplayId : std::bool_constant<false> {};
341
342template <typename PhysicalDisplay>
343struct IsPhysicalDisplayId<PhysicalDisplayId<PhysicalDisplay>> : std::bool_constant<true> {};
344
345template <typename>
346struct DisplayIdGetter;
347
348template <typename PhysicalDisplay>
349struct DisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
350 static std::optional<DisplayId> get() {
351 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
352 return getFallbackDisplayId(static_cast<bool>(PhysicalDisplay::PRIMARY)
353 ? HWC_DISPLAY_PRIMARY
354 : HWC_DISPLAY_EXTERNAL);
355 }
356
357 const auto info =
358 parseDisplayIdentificationData(PhysicalDisplay::PORT,
359 PhysicalDisplay::GET_IDENTIFICATION_DATA());
360 return info ? std::make_optional(info->id) : std::nullopt;
361 }
362};
363
Dominik Laskowski34157762018-10-31 13:07:19 -0700364template <DisplayId::Type displayId>
Dominik Laskowski075d3172018-05-24 15:50:06 -0700365struct DisplayIdGetter<VirtualDisplayId<displayId>> {
Dominik Laskowski34157762018-10-31 13:07:19 -0700366 static std::optional<DisplayId> get() { return DisplayId{displayId}; }
Dominik Laskowski075d3172018-05-24 15:50:06 -0700367};
368
369template <>
370struct DisplayIdGetter<NoDisplayId> {
371 static std::optional<DisplayId> get() { return {}; }
372};
373
Dominik Laskowski55c85402020-01-21 16:25:47 -0800374template <typename>
375struct DisplayConnectionTypeGetter {
376 static constexpr std::optional<DisplayConnectionType> value;
377};
378
379template <typename PhysicalDisplay>
380struct DisplayConnectionTypeGetter<PhysicalDisplayId<PhysicalDisplay>> {
381 static constexpr std::optional<DisplayConnectionType> value = PhysicalDisplay::CONNECTION_TYPE;
382};
383
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100384template <typename>
385struct HwcDisplayIdGetter {
Peiyong Line9d809e2020-04-14 13:10:48 -0700386 static constexpr std::optional<HWDisplayId> value;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100387};
388
Peiyong Line9d809e2020-04-14 13:10:48 -0700389constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100390
391template <DisplayId::Type displayId>
392struct HwcDisplayIdGetter<VirtualDisplayId<displayId>> {
Peiyong Line9d809e2020-04-14 13:10:48 -0700393 static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100394};
395
396template <typename PhysicalDisplay>
397struct HwcDisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
Peiyong Line9d809e2020-04-14 13:10:48 -0700398 static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100399};
400
Dominik Laskowski075d3172018-05-24 15:50:06 -0700401// DisplayIdType can be:
402// 1) PhysicalDisplayId<...> for generated ID of physical display backed by HWC.
403// 2) VirtualDisplayId<...> for hard-coded ID of virtual display backed by HWC.
404// 3) NoDisplayId for virtual display without HWC backing.
405template <typename DisplayIdType, int width, int height, Critical critical, Async async,
406 Secure secure, Primary primary, int grallocUsage>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800407struct DisplayVariant {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700408 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
Dominik Laskowski55c85402020-01-21 16:25:47 -0800409 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100410 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700411
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800412 // The display width and height
413 static constexpr int WIDTH = width;
414 static constexpr int HEIGHT = height;
415
416 static constexpr int GRALLOC_USAGE = grallocUsage;
417
Dominik Laskowski075d3172018-05-24 15:50:06 -0700418 // Whether the display is virtual or physical
419 static constexpr Virtual VIRTUAL =
420 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800421
422 // When creating native window surfaces for the framebuffer, whether those should be critical
423 static constexpr Critical CRITICAL = critical;
424
425 // When creating native window surfaces for the framebuffer, whether those should be async
426 static constexpr Async ASYNC = async;
427
428 // Whether the display should be treated as secure
429 static constexpr Secure SECURE = secure;
430
Dominik Laskowski075d3172018-05-24 15:50:06 -0700431 // Whether the display is primary
432 static constexpr Primary PRIMARY = primary;
433
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800434 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700435 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
436 if (auto displayId = DISPLAY_ID::get()) {
437 ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal});
438 } else {
439 ceDisplayArgs.setUseHwcVirtualDisplays(false);
440 }
441 ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build();
442
443 auto compositionDisplay =
444 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
445 ceDisplayArgs.build());
446
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100447 auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
448 CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
449 static_cast<bool>(PRIMARY));
Dominik Laskowski075d3172018-05-24 15:50:06 -0700450
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800451 injector.setSecure(static_cast<bool>(SECURE));
Alec Mouriba013fa2018-10-16 12:43:11 -0700452 injector.setNativeWindow(test->mNativeWindow);
453
454 // Creating a DisplayDevice requires getting default dimensions from the
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800455 // native window along with some other initial setup.
Alec Mouriba013fa2018-10-16 12:43:11 -0700456 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
457 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
458 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
459 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800460 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
461 .WillRepeatedly(Return(0));
462 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
463 .WillRepeatedly(Return(0));
464 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
465 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700466 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
467 .WillRepeatedly(Return(0));
468
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800469 return injector;
470 }
471
472 // Called by tests to set up any native window creation call expectations.
473 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
474 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
475 .WillOnce(Return(test->mNativeWindow));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800476
Alec Mouriba013fa2018-10-16 12:43:11 -0700477 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
478 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
479 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
480 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800481 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
482 .WillRepeatedly(Return(0));
483 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
484 .WillRepeatedly(Return(0));
485 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
486 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700487 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
488 .WillRepeatedly(Return(0));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800489 }
490
491 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
492 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
493 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
494 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
495 .WillRepeatedly(Return(NO_ERROR));
496 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
497 .WillRepeatedly(Return(NO_ERROR));
498 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
499 .WillRepeatedly(Return(NO_ERROR));
500 }
501
502 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
503 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
504 }
505};
506
Peiyong Line9d809e2020-04-14 13:10:48 -0700507template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700508 typename PhysicalDisplay = void>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800509struct HwcDisplayVariant {
510 // The display id supplied by the HWC
Peiyong Line9d809e2020-04-14 13:10:48 -0700511 static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800512
513 // The HWC display type
Peiyong Line9d809e2020-04-14 13:10:48 -0700514 static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800515
516 // The HWC active configuration id
Lloyd Pique3c085a02018-05-09 19:38:32 -0700517 static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700518 static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800519
Peiyong Line9d809e2020-04-14 13:10:48 -0700520 static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800521 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
522 HotplugEvent{HWC_DISPLAY_ID, connection});
523 }
524
525 // Called by tests to inject a HWC display setup
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800526 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700527 const auto displayId = DisplayVariant::DISPLAY_ID::get();
528 ASSERT_TRUE(displayId);
529 FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
530 static_cast<bool>(DisplayVariant::PRIMARY))
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800531 .setHwcDisplayId(HWC_DISPLAY_ID)
532 .setWidth(DisplayVariant::WIDTH)
533 .setHeight(DisplayVariant::HEIGHT)
534 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700535 .setPowerMode(INIT_POWER_MODE)
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800536 .inject(&test->mFlinger, test->mComposer);
537 }
538
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800539 // Called by tests to inject a HWC display setup
540 static void injectHwcDisplay(DisplayTransactionTest* test) {
541 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
Peiyong Line9d809e2020-04-14 13:10:48 -0700542 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800543 Return(Error::NONE)));
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700544 EXPECT_CALL(*test->mComposer,
Peiyong Line9d809e2020-04-14 13:10:48 -0700545 setPowerMode(HWC_DISPLAY_ID, static_cast<PowerMode>(INIT_POWER_MODE)))
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700546 .WillOnce(Return(Error::NONE));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800547 injectHwcDisplayWithNoDefaultCapabilities(test);
548 }
549
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700550 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
551 DisplayTransactionTest* test) {
552 const ::testing::TestInfo* const test_info =
553 ::testing::UnitTest::GetInstance()->current_test_info();
554
555 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
556 .setPhysical({*DisplayVariant::DISPLAY_ID::get(),
557 PhysicalDisplay::CONNECTION_TYPE})
558 .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
559 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
560 .setPowerAdvisor(&test->mPowerAdvisor)
561 .setName(std::string("Injected display for ") +
562 test_info->test_case_name() + "." + test_info->name())
563 .build();
564
565 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
566 ceDisplayArgs);
567 }
568
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800569 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800570 constexpr auto CONNECTION_TYPE =
571 PhysicalDisplay::CONNECTION_TYPE == DisplayConnectionType::Internal
572 ? IComposerClient::DisplayConnectionType::INTERNAL
573 : IComposerClient::DisplayConnectionType::EXTERNAL;
574
575 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
Peiyong Line9d809e2020-04-14 13:10:48 -0700576 .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
Dominik Laskowski55c85402020-01-21 16:25:47 -0800577
Peiyong Line9d809e2020-04-14 13:10:48 -0700578 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
579 .WillOnce(Return(hal::Error::NONE));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800580 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
581 .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
582 Return(Error::NONE)));
583 EXPECT_CALL(*test->mComposer,
584 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
585 IComposerClient::Attribute::WIDTH, _))
586 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
587 EXPECT_CALL(*test->mComposer,
588 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
589 IComposerClient::Attribute::HEIGHT, _))
590 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
591 EXPECT_CALL(*test->mComposer,
592 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
593 IComposerClient::Attribute::VSYNC_PERIOD, _))
594 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
595 EXPECT_CALL(*test->mComposer,
596 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
597 IComposerClient::Attribute::DPI_X, _))
598 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
599 EXPECT_CALL(*test->mComposer,
600 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
601 IComposerClient::Attribute::DPI_Y, _))
602 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
Ady Abraham7159f572019-10-11 11:10:18 -0700603 EXPECT_CALL(*test->mComposer,
604 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
605 IComposerClient::Attribute::CONFIG_GROUP, _))
606 .WillOnce(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
Dominik Laskowski075d3172018-05-24 15:50:06 -0700607
608 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
609 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
610 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
611 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
612 Return(Error::NONE)));
613 } else {
614 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
615 .WillOnce(Return(Error::UNSUPPORTED));
616 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800617 }
618
619 // Called by tests to set up HWC call expectations
620 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
621 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
Lloyd Pique3c085a02018-05-09 19:38:32 -0700622 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800623 }
624};
625
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800626// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
627constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
628 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
629
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100630template <typename PhysicalDisplay, int width, int height, Critical critical>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800631struct PhysicalDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700632 : DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height, critical, Async::FALSE,
633 Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
Peiyong Line9d809e2020-04-14 13:10:48 -0700634 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700635 DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height,
636 critical, Async::FALSE, Secure::TRUE,
637 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
638 PhysicalDisplay> {};
639
640template <bool hasIdentificationData>
641struct PrimaryDisplay {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800642 static constexpr auto CONNECTION_TYPE = DisplayConnectionType::Internal;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700643 static constexpr Primary PRIMARY = Primary::TRUE;
644 static constexpr uint8_t PORT = 255;
Peiyong Line9d809e2020-04-14 13:10:48 -0700645 static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700646 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
647 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
648};
649
650template <bool hasIdentificationData>
651struct ExternalDisplay {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800652 static constexpr auto CONNECTION_TYPE = DisplayConnectionType::External;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700653 static constexpr Primary PRIMARY = Primary::FALSE;
654 static constexpr uint8_t PORT = 254;
Peiyong Line9d809e2020-04-14 13:10:48 -0700655 static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700656 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
657 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
658};
659
660struct TertiaryDisplay {
661 static constexpr Primary PRIMARY = Primary::FALSE;
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800662 static constexpr uint8_t PORT = 253;
Peiyong Line9d809e2020-04-14 13:10:48 -0700663 static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800664 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700665};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800666
667// A primary display is a physical display that is critical
668using PrimaryDisplayVariant =
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100669 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800670
671// An external display is physical display that is not critical.
672using ExternalDisplayVariant =
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100673 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800674
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100675using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800676
677// A virtual display not supported by the HWC.
678constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
679
680template <int width, int height, Secure secure>
681struct NonHwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700682 : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
683 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
684 using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
685 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
686
687 static void injectHwcDisplay(DisplayTransactionTest*) {}
688
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700689 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
690 DisplayTransactionTest* test) {
691 const ::testing::TestInfo* const test_info =
692 ::testing::UnitTest::GetInstance()->current_test_info();
693
694 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
695 .setPixels({Base::WIDTH, Base::HEIGHT})
696 .setIsSecure(static_cast<bool>(Base::SECURE))
697 .setPowerAdvisor(&test->mPowerAdvisor)
698 .setName(std::string("Injected display for ") +
699 test_info->test_case_name() + "." + test_info->name())
700 .build();
701
702 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
703 ceDisplayArgs);
704 }
705
Dominik Laskowski075d3172018-05-24 15:50:06 -0700706 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
707 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
708 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800709
710 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
711 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
712 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
713 }
714};
715
716// A virtual display supported by the HWC.
717constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
718
719template <int width, int height, Secure secure>
720struct HwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700721 : DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE, secure,
722 Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
723 HwcDisplayVariant<
Peiyong Line9d809e2020-04-14 13:10:48 -0700724 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700725 DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
726 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
727 using Base = DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
728 secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800729 using Self = HwcVirtualDisplayVariant<width, height, secure>;
730
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700731 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
732 DisplayTransactionTest* test) {
733 const ::testing::TestInfo* const test_info =
734 ::testing::UnitTest::GetInstance()->current_test_info();
735
736 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
737 .setUseHwcVirtualDisplays(false)
738 .setPixels({Base::WIDTH, Base::HEIGHT})
739 .setIsSecure(static_cast<bool>(Base::SECURE))
740 .setPowerAdvisor(&test->mPowerAdvisor)
741 .setName(std::string("Injected display for ") +
742 test_info->test_case_name() + "." + test_info->name())
743 .build();
744
745 auto compositionDisplay =
746 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
747 ceDisplayArgs);
748 compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
749
750 // Insert display data so that the HWC thinks it created the virtual display.
751 if (const auto displayId = Base::DISPLAY_ID::get()) {
752 test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
753 }
754
755 return compositionDisplay;
756 }
757
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800758 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
759 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
760 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
761 }
762
763 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
764 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
765 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
766 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
767 }
768};
769
770// For this variant, SurfaceFlinger should not configure itself with wide
771// display support, so the display should not be configured for wide-color
772// support.
773struct WideColorSupportNotConfiguredVariant {
774 static constexpr bool WIDE_COLOR_SUPPORTED = false;
775
776 static void injectConfigChange(DisplayTransactionTest* test) {
777 test->mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700778 test->mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800779 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800780 }
781
782 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
783 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
784 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
785 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
786 }
787};
788
789// For this variant, SurfaceFlinger should configure itself with wide display
790// support, and the display should respond with an non-empty list of supported
791// color modes. Wide-color support should be configured.
792template <typename Display>
793struct WideColorP3ColorimetricSupportedVariant {
794 static constexpr bool WIDE_COLOR_SUPPORTED = true;
795
796 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700797 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800798 test->mFlinger.mutableHasWideColorDisplay() = true;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800799 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800800 }
801
802 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800803 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_DATASPACE)).Times(1);
804
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800805 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
806 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
807 Return(Error::NONE)));
808 EXPECT_CALL(*test->mComposer,
809 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
810 .WillOnce(DoAll(SetArgPointee<2>(
811 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
812 Return(Error::NONE)));
813 EXPECT_CALL(*test->mComposer,
814 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
815 RenderIntent::COLORIMETRIC))
816 .WillOnce(Return(Error::NONE));
817 }
818};
819
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800820// For this variant, SurfaceFlinger should configure itself with wide display
821// support, but the display should respond with an empty list of supported color
822// modes. Wide-color support for the display should not be configured.
823template <typename Display>
824struct WideColorNotSupportedVariant {
825 static constexpr bool WIDE_COLOR_SUPPORTED = false;
826
827 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700828 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800829 test->mFlinger.mutableHasWideColorDisplay() = true;
830 }
831
832 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
833 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
834 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
Chia-I Wu614e1422018-05-23 02:17:03 -0700835 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800836 }
837};
838
839// For this variant, the display is not a HWC display, so no HDR support should
840// be configured.
841struct NonHwcDisplayHdrSupportVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800842 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800843 static constexpr bool HDR10_SUPPORTED = false;
844 static constexpr bool HDR_HLG_SUPPORTED = false;
845 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
846 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
847 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
848 }
849};
850
Valerie Haue9e843a2018-12-18 13:39:23 -0800851template <typename Display>
852struct Hdr10PlusSupportedVariant {
853 static constexpr bool HDR10_PLUS_SUPPORTED = true;
854 static constexpr bool HDR10_SUPPORTED = true;
855 static constexpr bool HDR_HLG_SUPPORTED = false;
856 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
857 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
858 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _))
859 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({
860 Hdr::HDR10_PLUS,
861 Hdr::HDR10,
862 })),
863 Return(Error::NONE)));
864 }
865};
866
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800867// For this variant, the composer should respond with a non-empty list of HDR
868// modes containing HDR10, so HDR10 support should be configured.
869template <typename Display>
870struct Hdr10SupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800871 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800872 static constexpr bool HDR10_SUPPORTED = true;
873 static constexpr bool HDR_HLG_SUPPORTED = false;
874 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
875 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
876 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
877 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
878 Return(Error::NONE)));
879 }
880};
881
882// For this variant, the composer should respond with a non-empty list of HDR
883// modes containing HLG, so HLG support should be configured.
884template <typename Display>
885struct HdrHlgSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800886 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800887 static constexpr bool HDR10_SUPPORTED = false;
888 static constexpr bool HDR_HLG_SUPPORTED = true;
889 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
890 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
891 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
892 .WillOnce(
893 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
894 }
895};
896
897// For this variant, the composer should respond with a non-empty list of HDR
898// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
899template <typename Display>
900struct HdrDolbyVisionSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800901 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800902 static constexpr bool HDR10_SUPPORTED = false;
903 static constexpr bool HDR_HLG_SUPPORTED = false;
904 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
905 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
906 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
907 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
908 Return(Error::NONE)));
909 }
910};
911
912// For this variant, the composer should respond with am empty list of HDR
913// modes, so no HDR support should be configured.
914template <typename Display>
915struct HdrNotSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800916 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800917 static constexpr bool HDR10_SUPPORTED = false;
918 static constexpr bool HDR_HLG_SUPPORTED = false;
919 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
920 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
921 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
922 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
923 }
924};
925
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700926struct NonHwcPerFrameMetadataSupportVariant {
927 static constexpr int PER_FRAME_METADATA_KEYS = 0;
928 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800929 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700930 }
931};
932
933template <typename Display>
934struct NoPerFrameMetadataSupportVariant {
935 static constexpr int PER_FRAME_METADATA_KEYS = 0;
936 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800937 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
938 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700939 }
940};
941
942template <typename Display>
943struct Smpte2086PerFrameMetadataSupportVariant {
944 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::SMPTE2086;
945 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800946 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
947 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800948 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
949 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
950 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
951 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
952 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
953 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
954 PerFrameMetadataKey::WHITE_POINT_X,
955 PerFrameMetadataKey::WHITE_POINT_Y,
956 PerFrameMetadataKey::MAX_LUMINANCE,
957 PerFrameMetadataKey::MIN_LUMINANCE,
958 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700959 }
960};
961
962template <typename Display>
963struct Cta861_3_PerFrameMetadataSupportVariant {
964 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::CTA861_3;
965 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800966 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
967 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800968 PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
969 PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
970 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700971 }
972};
973
Valerie Haue9e843a2018-12-18 13:39:23 -0800974template <typename Display>
975struct Hdr10_Plus_PerFrameMetadataSupportVariant {
976 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::HDR10PLUS;
977 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
978 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
979 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
980 PerFrameMetadataKey::HDR10_PLUS_SEI,
981 })));
982 }
983};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800984/* ------------------------------------------------------------------------
985 * Typical display configurations to test
986 */
987
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700988template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
989 typename PerFrameMetadataSupportPolicy>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800990struct Case {
991 using Display = DisplayPolicy;
992 using WideColorSupport = WideColorSupportPolicy;
993 using HdrSupport = HdrSupportPolicy;
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700994 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800995};
996
997using SimplePrimaryDisplayCase =
998 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700999 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1000 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001001using SimpleExternalDisplayCase =
1002 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001003 HdrNotSupportedVariant<ExternalDisplayVariant>,
1004 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001005using SimpleTertiaryDisplayCase =
1006 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001007 HdrNotSupportedVariant<TertiaryDisplayVariant>,
1008 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001009using NonHwcVirtualDisplayCase =
1010 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001011 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
1012 NonHwcPerFrameMetadataSupportVariant>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001013using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
1014using HwcVirtualDisplayCase =
1015 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
Lloyd Pique438e9e72018-09-04 18:06:08 -07001016 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
tangrobin6753a022018-08-10 10:58:54 +08001017 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001018using WideColorP3ColorimetricDisplayCase =
1019 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001020 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1021 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Valerie Haue9e843a2018-12-18 13:39:23 -08001022using Hdr10PlusDisplayCase =
1023 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1024 Hdr10SupportedVariant<PrimaryDisplayVariant>,
1025 Hdr10_Plus_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001026using Hdr10DisplayCase =
1027 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001028 Hdr10SupportedVariant<PrimaryDisplayVariant>,
1029 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001030using HdrHlgDisplayCase =
1031 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001032 HdrHlgSupportedVariant<PrimaryDisplayVariant>,
1033 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001034using HdrDolbyVisionDisplayCase =
1035 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001036 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>,
1037 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
1038using HdrSmpte2086DisplayCase =
1039 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1040 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1041 Smpte2086PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
1042using HdrCta861_3_DisplayCase =
1043 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1044 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1045 Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Dominik Laskowskif07b85b2018-06-11 12:49:15 -07001046
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001047/* ------------------------------------------------------------------------
Lloyd Pique6cf11032018-01-22 18:57:44 -08001048 *
1049 * SurfaceFlinger::onHotplugReceived
1050 */
1051
1052TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
1053 constexpr int currentSequenceId = 123;
Peiyong Line9d809e2020-04-14 13:10:48 -07001054 constexpr HWDisplayId hwcDisplayId1 = 456;
1055 constexpr HWDisplayId hwcDisplayId2 = 654;
Lloyd Pique6cf11032018-01-22 18:57:44 -08001056
1057 // --------------------------------------------------------------------
1058 // Preconditions
1059
1060 // Set the current sequence id for accepted events
1061 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1062
1063 // Set the main thread id so that the current thread does not appear to be
1064 // the main thread.
1065 mFlinger.mutableMainThreadId() = std::thread::id();
1066
1067 // --------------------------------------------------------------------
1068 // Call Expectations
1069
1070 // We expect invalidate() to be invoked once to trigger display transaction
1071 // processing.
1072 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1073
1074 // --------------------------------------------------------------------
1075 // Invocation
1076
1077 // Simulate two hotplug events (a connect and a disconnect)
Peiyong Line9d809e2020-04-14 13:10:48 -07001078 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, Connection::CONNECTED);
1079 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, Connection::DISCONNECTED);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001080
1081 // --------------------------------------------------------------------
1082 // Postconditions
1083
1084 // The display transaction needed flag should be set.
1085 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1086
1087 // All events should be in the pending event queue.
1088 const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
1089 ASSERT_EQ(2u, pendingEvents.size());
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001090 EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
Peiyong Line9d809e2020-04-14 13:10:48 -07001091 EXPECT_EQ(Connection::CONNECTED, pendingEvents[0].connection);
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001092 EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
Peiyong Line9d809e2020-04-14 13:10:48 -07001093 EXPECT_EQ(Connection::DISCONNECTED, pendingEvents[1].connection);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001094}
1095
1096TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
1097 constexpr int currentSequenceId = 123;
1098 constexpr int otherSequenceId = 321;
Peiyong Line9d809e2020-04-14 13:10:48 -07001099 constexpr HWDisplayId displayId = 456;
Lloyd Pique6cf11032018-01-22 18:57:44 -08001100
1101 // --------------------------------------------------------------------
1102 // Preconditions
1103
1104 // Set the current sequence id for accepted events
1105 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1106
1107 // Set the main thread id so that the current thread does not appear to be
1108 // the main thread.
1109 mFlinger.mutableMainThreadId() = std::thread::id();
1110
1111 // --------------------------------------------------------------------
1112 // Call Expectations
1113
1114 // We do not expect any calls to invalidate().
1115 EXPECT_CALL(*mMessageQueue, invalidate()).Times(0);
1116
1117 // --------------------------------------------------------------------
1118 // Invocation
1119
1120 // Call with an unexpected sequence id
Peiyong Line9d809e2020-04-14 13:10:48 -07001121 mFlinger.onHotplugReceived(otherSequenceId, displayId, Connection::INVALID);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001122
1123 // --------------------------------------------------------------------
1124 // Postconditions
1125
1126 // The display transaction needed flag should not be set
1127 EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1128
1129 // There should be no pending events
1130 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
1131}
1132
1133TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
1134 constexpr int currentSequenceId = 123;
Peiyong Line9d809e2020-04-14 13:10:48 -07001135 constexpr HWDisplayId displayId1 = 456;
Lloyd Pique6cf11032018-01-22 18:57:44 -08001136
1137 // --------------------------------------------------------------------
1138 // Note:
1139 // --------------------------------------------------------------------
1140 // This test case is a bit tricky. We want to verify that
1141 // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we
1142 // don't really want to provide coverage for everything the later function
1143 // does as there are specific tests for it.
1144 // --------------------------------------------------------------------
1145
1146 // --------------------------------------------------------------------
1147 // Preconditions
1148
1149 // Set the current sequence id for accepted events
1150 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1151
1152 // Set the main thread id so that the current thread does appear to be the
1153 // main thread.
1154 mFlinger.mutableMainThreadId() = std::this_thread::get_id();
1155
1156 // --------------------------------------------------------------------
1157 // Call Expectations
1158
1159 // We expect invalidate() to be invoked once to trigger display transaction
1160 // processing.
1161 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1162
1163 // --------------------------------------------------------------------
1164 // Invocation
1165
1166 // Simulate a disconnect on a display id that is not connected. This should
1167 // be enqueued by onHotplugReceived(), and dequeued by
1168 // processDisplayHotplugEventsLocked(), but then ignored as invalid.
Peiyong Line9d809e2020-04-14 13:10:48 -07001169 mFlinger.onHotplugReceived(currentSequenceId, displayId1, Connection::DISCONNECTED);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001170
1171 // --------------------------------------------------------------------
1172 // Postconditions
1173
1174 // The display transaction needed flag should be set.
1175 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1176
1177 // There should be no event queued on return, as it should have been
1178 // processed.
1179 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
1180}
1181
1182/* ------------------------------------------------------------------------
Lloyd Piquea482f992018-01-22 19:00:34 -08001183 * SurfaceFlinger::createDisplay
1184 */
1185
1186TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
1187 const String8 name("virtual.test");
1188
1189 // --------------------------------------------------------------------
1190 // Call Expectations
1191
1192 // The call should notify the interceptor that a display was created.
1193 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1194
1195 // --------------------------------------------------------------------
1196 // Invocation
1197
1198 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
1199
1200 // --------------------------------------------------------------------
1201 // Postconditions
1202
1203 // The display should have been added to the current state
1204 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1205 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001206 EXPECT_TRUE(display.isVirtual());
1207 EXPECT_FALSE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001208 EXPECT_EQ(name.string(), display.displayName);
1209
1210 // --------------------------------------------------------------------
1211 // Cleanup conditions
1212
1213 // Destroying the display invalidates the display state.
1214 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1215}
1216
1217TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForSecureDisplay) {
1218 const String8 name("virtual.test");
1219
1220 // --------------------------------------------------------------------
1221 // Call Expectations
1222
1223 // The call should notify the interceptor that a display was created.
1224 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1225
1226 // --------------------------------------------------------------------
1227 // Invocation
1228
1229 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
1230
1231 // --------------------------------------------------------------------
1232 // Postconditions
1233
1234 // The display should have been added to the current state
1235 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1236 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001237 EXPECT_TRUE(display.isVirtual());
1238 EXPECT_TRUE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001239 EXPECT_EQ(name.string(), display.displayName);
1240
1241 // --------------------------------------------------------------------
1242 // Cleanup conditions
1243
1244 // Destroying the display invalidates the display state.
1245 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1246}
1247
1248/* ------------------------------------------------------------------------
1249 * SurfaceFlinger::destroyDisplay
1250 */
1251
1252TEST_F(DisplayTransactionTest, destroyDisplayClearsCurrentStateForDisplay) {
1253 using Case = NonHwcVirtualDisplayCase;
1254
1255 // --------------------------------------------------------------------
1256 // Preconditions
1257
1258 // A virtual display exists
1259 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1260 existing.inject();
1261
1262 // --------------------------------------------------------------------
1263 // Call Expectations
1264
1265 // The call should notify the interceptor that a display was created.
1266 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
1267
1268 // Destroying the display invalidates the display state.
1269 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1270
1271 // --------------------------------------------------------------------
1272 // Invocation
1273
1274 mFlinger.destroyDisplay(existing.token());
1275
1276 // --------------------------------------------------------------------
1277 // Postconditions
1278
1279 // The display should have been removed from the current state
1280 EXPECT_FALSE(hasCurrentDisplayState(existing.token()));
1281
1282 // Ths display should still exist in the drawing state
1283 EXPECT_TRUE(hasDrawingDisplayState(existing.token()));
1284
1285 // The display transaction needed flasg should be set
1286 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1287}
1288
1289TEST_F(DisplayTransactionTest, destroyDisplayHandlesUnknownDisplay) {
1290 // --------------------------------------------------------------------
1291 // Preconditions
1292
1293 sp<BBinder> displayToken = new BBinder();
1294
1295 // --------------------------------------------------------------------
1296 // Invocation
1297
1298 mFlinger.destroyDisplay(displayToken);
1299}
1300
1301/* ------------------------------------------------------------------------
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001302 * SurfaceFlinger::resetDisplayState
1303 */
1304
1305TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
1306 using Case = NonHwcVirtualDisplayCase;
1307
1308 // --------------------------------------------------------------------
1309 // Preconditions
1310
1311 // vsync is enabled and available
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001312 mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = true;
1313 mFlinger.scheduler()->mutableHWVsyncAvailable() = true;
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001314
1315 // A display exists
1316 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1317 existing.inject();
1318
1319 // --------------------------------------------------------------------
1320 // Call Expectations
1321
1322 // The call disable vsyncs
1323 EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
1324
Lloyd Pique41be5d22018-06-21 13:11:48 -07001325 // The call ends any display resyncs
1326 EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
1327
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001328 // --------------------------------------------------------------------
1329 // Invocation
1330
1331 mFlinger.resetDisplayState();
1332
1333 // --------------------------------------------------------------------
1334 // Postconditions
1335
1336 // vsyncs should be off and not available.
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001337 EXPECT_FALSE(mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled());
1338 EXPECT_FALSE(mFlinger.scheduler()->mutableHWVsyncAvailable());
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001339
1340 // The display should have been removed from the display map.
1341 EXPECT_FALSE(hasDisplayDevice(existing.token()));
1342
1343 // The display should still exist in the current state
1344 EXPECT_TRUE(hasCurrentDisplayState(existing.token()));
1345
1346 // The display should have been removed from the drawing state
1347 EXPECT_FALSE(hasDrawingDisplayState(existing.token()));
1348}
1349
1350/* ------------------------------------------------------------------------
Valerie Hau9758ae02018-10-09 16:05:09 -07001351 * DisplayDevice::GetBestColorMode
1352 */
1353class GetBestColorModeTest : public DisplayTransactionTest {
1354public:
Valerie Hau9758ae02018-10-09 16:05:09 -07001355 void setHasWideColorGamut(bool hasWideColorGamut) { mHasWideColorGamut = hasWideColorGamut; }
1356
1357 void addHwcColorModesMapping(ui::ColorMode colorMode,
1358 std::vector<ui::RenderIntent> renderIntents) {
1359 mHwcColorModes[colorMode] = renderIntents;
1360 }
1361
1362 void setInputDataspace(ui::Dataspace dataspace) { mInputDataspace = dataspace; }
1363
1364 void setInputRenderIntent(ui::RenderIntent renderIntent) { mInputRenderIntent = renderIntent; }
1365
1366 void getBestColorMode() {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001367 auto displayDevice =
1368 injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) {
1369 injector.setHwcColorModes(mHwcColorModes);
1370 injector.setHasWideColorGamut(mHasWideColorGamut);
1371 injector.setNativeWindow(mNativeWindow);
1372 });
Valerie Hau9758ae02018-10-09 16:05:09 -07001373
Lloyd Pique3d0c02e2018-10-19 18:38:12 -07001374 displayDevice->getCompositionDisplay()
1375 ->getDisplayColorProfile()
1376 ->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace,
1377 &mOutColorMode, &mOutRenderIntent);
Valerie Hau9758ae02018-10-09 16:05:09 -07001378 }
1379
1380 ui::Dataspace mOutDataspace;
1381 ui::ColorMode mOutColorMode;
1382 ui::RenderIntent mOutRenderIntent;
1383
1384private:
1385 ui::Dataspace mInputDataspace;
1386 ui::RenderIntent mInputRenderIntent;
1387 bool mHasWideColorGamut = false;
1388 std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> mHwcColorModes;
Valerie Hau9758ae02018-10-09 16:05:09 -07001389};
1390
1391TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeSRGB) {
1392 addHwcColorModesMapping(ui::ColorMode::SRGB,
1393 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1394 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1395 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1396 setHasWideColorGamut(true);
1397
1398 getBestColorMode();
1399
Peiyong Lin14724e62018-12-05 07:27:30 -08001400 ASSERT_EQ(ui::Dataspace::V0_SRGB, mOutDataspace);
Valerie Hau9758ae02018-10-09 16:05:09 -07001401 ASSERT_EQ(ui::ColorMode::SRGB, mOutColorMode);
1402 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1403}
1404
1405TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDisplayP3) {
1406 addHwcColorModesMapping(ui::ColorMode::DISPLAY_P3,
1407 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1408 addHwcColorModesMapping(ui::ColorMode::SRGB,
1409 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1410 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1411 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1412 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1413 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1414 setHasWideColorGamut(true);
1415
1416 getBestColorMode();
1417
1418 ASSERT_EQ(ui::Dataspace::DISPLAY_P3, mOutDataspace);
1419 ASSERT_EQ(ui::ColorMode::DISPLAY_P3, mOutColorMode);
1420 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1421}
1422
1423TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDISPLAY_BT2020) {
1424 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1425 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1426 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1427 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1428 setHasWideColorGamut(true);
1429
1430 getBestColorMode();
1431
1432 ASSERT_EQ(ui::Dataspace::DISPLAY_BT2020, mOutDataspace);
1433 ASSERT_EQ(ui::ColorMode::DISPLAY_BT2020, mOutColorMode);
1434 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1435}
1436
1437/* ------------------------------------------------------------------------
Lloyd Pique33050472019-12-19 17:12:44 -08001438 * DisplayDevice::setProjection
1439 */
1440
1441class DisplayDeviceSetProjectionTest : public DisplayTransactionTest {
1442public:
Lloyd Pique33050472019-12-19 17:12:44 -08001443 static constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1080; // arbitrary
1444 static constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1920; // arbitrary
1445
1446 static constexpr int32_t TRANSFORM_FLAGS_ROT_0 = 0;
1447 static constexpr int32_t TRANSFORM_FLAGS_ROT_90 = HAL_TRANSFORM_ROT_90;
1448 static constexpr int32_t TRANSFORM_FLAGS_ROT_180 = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_FLIP_V;
1449 static constexpr int32_t TRANSFORM_FLAGS_ROT_270 =
1450 HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1451
1452 DisplayDeviceSetProjectionTest(ui::Size flingerDisplaySize, ui::Size hardwareDisplaySize,
1453 ui::Rotation physicalOrientation)
1454 : mFlingerDisplaySize(flingerDisplaySize),
1455 mHardwareDisplaySize(hardwareDisplaySize),
1456 mPhysicalOrientation(physicalOrientation),
1457 mDisplayDevice(createDisplayDevice()) {}
1458
1459 sp<DisplayDevice> createDisplayDevice() {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001460 return injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) {
1461 injector.setPhysicalOrientation(mPhysicalOrientation);
1462 });
Lloyd Pique33050472019-12-19 17:12:44 -08001463 }
1464
1465 ui::Size SwapWH(const ui::Size size) const { return ui::Size(size.height, size.width); }
1466
1467 void setProjectionForRotation0() {
1468 // A logical rotation of 0 uses the SurfaceFlinger display size
1469 mDisplayDevice->setProjection(ui::ROTATION_0, Rect(mFlingerDisplaySize),
1470 Rect(mFlingerDisplaySize));
1471 }
1472
1473 void setProjectionForRotation90() {
1474 // A logical rotation of 90 uses the SurfaceFlinger display size with
1475 // the width/height swapped.
1476 mDisplayDevice->setProjection(ui::ROTATION_90, Rect(SwapWH(mFlingerDisplaySize)),
1477 Rect(SwapWH(mFlingerDisplaySize)));
1478 }
1479
1480 void setProjectionForRotation180() {
1481 // A logical rotation of 180 uses the SurfaceFlinger display size
1482 mDisplayDevice->setProjection(ui::ROTATION_180, Rect(mFlingerDisplaySize),
1483 Rect(mFlingerDisplaySize));
1484 }
1485
1486 void setProjectionForRotation270() {
1487 // A logical rotation of 270 uses the SurfaceFlinger display size with
1488 // the width/height swapped.
1489 mDisplayDevice->setProjection(ui::ROTATION_270, Rect(SwapWH(mFlingerDisplaySize)),
1490 Rect(SwapWH(mFlingerDisplaySize)));
1491 }
1492
1493 void expectStateForHardwareTransform0() {
1494 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1495 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_0, mHardwareDisplaySize.width,
1496 mHardwareDisplaySize.height),
1497 compositionState.transform);
1498 EXPECT_EQ(TRANSFORM_FLAGS_ROT_0, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001499 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1500 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001501 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.frame);
1502 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.viewport);
1503 EXPECT_EQ(false, compositionState.needsFiltering);
1504 }
1505
1506 void expectStateForHardwareTransform90() {
1507 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1508 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_90, mHardwareDisplaySize.width,
1509 mHardwareDisplaySize.height),
1510 compositionState.transform);
1511 EXPECT_EQ(TRANSFORM_FLAGS_ROT_90, compositionState.orientation);
Alec Mouri5a6d8572020-03-23 23:56:15 -07001512 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001513 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001514 // For 90, the frame and viewport have the hardware display size width and height swapped
1515 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
1516 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.viewport);
1517 EXPECT_EQ(false, compositionState.needsFiltering);
1518 }
1519
1520 void expectStateForHardwareTransform180() {
1521 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1522 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_180, mHardwareDisplaySize.width,
1523 mHardwareDisplaySize.height),
1524 compositionState.transform);
1525 EXPECT_EQ(TRANSFORM_FLAGS_ROT_180, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001526 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1527 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001528 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.frame);
1529 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.viewport);
1530 EXPECT_EQ(false, compositionState.needsFiltering);
1531 }
1532
1533 void expectStateForHardwareTransform270() {
1534 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1535 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_270, mHardwareDisplaySize.width,
1536 mHardwareDisplaySize.height),
1537 compositionState.transform);
1538 EXPECT_EQ(TRANSFORM_FLAGS_ROT_270, compositionState.orientation);
Alec Mouri5a6d8572020-03-23 23:56:15 -07001539 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001540 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001541 // For 270, the frame and viewport have the hardware display size width and height swapped
1542 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
1543 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.viewport);
1544 EXPECT_EQ(false, compositionState.needsFiltering);
1545 }
1546
1547 const ui::Size mFlingerDisplaySize;
1548 const ui::Size mHardwareDisplaySize;
1549 const ui::Rotation mPhysicalOrientation;
1550 const sp<DisplayDevice> mDisplayDevice;
1551};
1552
1553struct DisplayDeviceSetProjectionTest_Installed0 : public DisplayDeviceSetProjectionTest {
1554 DisplayDeviceSetProjectionTest_Installed0()
1555 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1556 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1557 ui::ROTATION_0) {}
1558};
1559
1560TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith0OutputRotation) {
1561 setProjectionForRotation0();
1562 expectStateForHardwareTransform0();
1563}
1564
1565TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith90OutputRotation) {
1566 setProjectionForRotation90();
1567 expectStateForHardwareTransform90();
1568}
1569
1570TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith180OutputRotation) {
1571 setProjectionForRotation180();
1572 expectStateForHardwareTransform180();
1573}
1574
1575TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith270OutputRotation) {
1576 setProjectionForRotation270();
1577 expectStateForHardwareTransform270();
1578}
1579
1580struct DisplayDeviceSetProjectionTest_Installed90 : public DisplayDeviceSetProjectionTest {
1581 DisplayDeviceSetProjectionTest_Installed90()
1582 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_HEIGHT, DEFAULT_DISPLAY_WIDTH),
1583 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1584 ui::ROTATION_90) {}
1585};
1586
1587TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith0OutputRotation) {
1588 setProjectionForRotation0();
1589 expectStateForHardwareTransform90();
1590}
1591
1592TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith90OutputRotation) {
1593 setProjectionForRotation90();
1594 expectStateForHardwareTransform180();
1595}
1596
1597TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith180OutputRotation) {
1598 setProjectionForRotation180();
1599 expectStateForHardwareTransform270();
1600}
1601
1602TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith270OutputRotation) {
1603 setProjectionForRotation270();
1604 expectStateForHardwareTransform0();
1605}
1606
1607struct DisplayDeviceSetProjectionTest_Installed180 : public DisplayDeviceSetProjectionTest {
1608 DisplayDeviceSetProjectionTest_Installed180()
1609 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1610 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1611 ui::ROTATION_180) {}
1612};
1613
1614TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith0OutputRotation) {
1615 setProjectionForRotation0();
1616 expectStateForHardwareTransform180();
1617}
1618
1619TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith90OutputRotation) {
1620 setProjectionForRotation90();
1621 expectStateForHardwareTransform270();
1622}
1623
1624TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith180OutputRotation) {
1625 setProjectionForRotation180();
1626 expectStateForHardwareTransform0();
1627}
1628
1629TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith270OutputRotation) {
1630 setProjectionForRotation270();
1631 expectStateForHardwareTransform90();
1632}
1633
1634struct DisplayDeviceSetProjectionTest_Installed270 : public DisplayDeviceSetProjectionTest {
1635 DisplayDeviceSetProjectionTest_Installed270()
1636 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_HEIGHT, DEFAULT_DISPLAY_WIDTH),
1637 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1638 ui::ROTATION_270) {}
1639};
1640
1641TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith0OutputRotation) {
1642 setProjectionForRotation0();
1643 expectStateForHardwareTransform270();
1644}
1645
1646TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith90OutputRotation) {
1647 setProjectionForRotation90();
1648 expectStateForHardwareTransform0();
1649}
1650
1651TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith180OutputRotation) {
1652 setProjectionForRotation180();
1653 expectStateForHardwareTransform90();
1654}
1655
1656TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith270OutputRotation) {
1657 setProjectionForRotation270();
1658 expectStateForHardwareTransform180();
1659}
1660
1661/* ------------------------------------------------------------------------
Daniel Solomon42d04562019-01-20 21:03:19 -08001662 * SurfaceFlinger::getDisplayNativePrimaries
1663 */
1664
1665class GetDisplayNativePrimaries : public DisplayTransactionTest {
1666public:
1667 GetDisplayNativePrimaries();
1668 void populateDummyDisplayNativePrimaries(ui::DisplayPrimaries& primaries);
1669 void checkDummyDisplayNativePrimaries(const ui::DisplayPrimaries& primaries);
1670
1671private:
1672 static constexpr float mStartingTestValue = 1.0f;
1673};
1674
1675GetDisplayNativePrimaries::GetDisplayNativePrimaries() {
1676 SimplePrimaryDisplayCase::Display::injectHwcDisplay(this);
1677 injectFakeNativeWindowSurfaceFactory();
1678}
1679
1680void GetDisplayNativePrimaries::populateDummyDisplayNativePrimaries(
1681 ui::DisplayPrimaries& primaries) {
1682 float startingVal = mStartingTestValue;
1683 primaries.red.X = startingVal++;
1684 primaries.red.Y = startingVal++;
1685 primaries.red.Z = startingVal++;
1686 primaries.green.X = startingVal++;
1687 primaries.green.Y = startingVal++;
1688 primaries.green.Z = startingVal++;
1689 primaries.blue.X = startingVal++;
1690 primaries.blue.Y = startingVal++;
1691 primaries.blue.Z = startingVal++;
1692 primaries.white.X = startingVal++;
1693 primaries.white.Y = startingVal++;
1694 primaries.white.Z = startingVal++;
1695}
1696
1697void GetDisplayNativePrimaries::checkDummyDisplayNativePrimaries(
1698 const ui::DisplayPrimaries& primaries) {
1699 float startingVal = mStartingTestValue;
1700 EXPECT_EQ(primaries.red.X, startingVal++);
1701 EXPECT_EQ(primaries.red.Y, startingVal++);
1702 EXPECT_EQ(primaries.red.Z, startingVal++);
1703 EXPECT_EQ(primaries.green.X, startingVal++);
1704 EXPECT_EQ(primaries.green.Y, startingVal++);
1705 EXPECT_EQ(primaries.green.Z, startingVal++);
1706 EXPECT_EQ(primaries.blue.X, startingVal++);
1707 EXPECT_EQ(primaries.blue.Y, startingVal++);
1708 EXPECT_EQ(primaries.blue.Z, startingVal++);
1709 EXPECT_EQ(primaries.white.X, startingVal++);
1710 EXPECT_EQ(primaries.white.Y, startingVal++);
1711 EXPECT_EQ(primaries.white.Z, startingVal++);
1712}
1713
1714TEST_F(GetDisplayNativePrimaries, nullDisplayToken) {
1715 ui::DisplayPrimaries primaries;
1716 EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(nullptr, primaries));
1717}
1718
Daniel Solomon42d04562019-01-20 21:03:19 -08001719TEST_F(GetDisplayNativePrimaries, internalDisplayWithPrimariesData) {
1720 auto injector = SimplePrimaryDisplayCase::Display::makeFakeExistingDisplayInjector(this);
1721 injector.inject();
1722 auto internalDisplayToken = injector.token();
1723
1724 ui::DisplayPrimaries expectedPrimaries;
1725 populateDummyDisplayNativePrimaries(expectedPrimaries);
1726 mFlinger.setInternalDisplayPrimaries(expectedPrimaries);
1727
1728 ui::DisplayPrimaries primaries;
1729 EXPECT_EQ(NO_ERROR, mFlinger.getDisplayNativePrimaries(internalDisplayToken, primaries));
1730
1731 checkDummyDisplayNativePrimaries(primaries);
1732}
1733
1734TEST_F(GetDisplayNativePrimaries, notInternalDisplayToken) {
1735 sp<BBinder> notInternalDisplayToken = new BBinder();
1736
1737 ui::DisplayPrimaries primaries;
1738 populateDummyDisplayNativePrimaries(primaries);
Dominik Laskowski470df5f2020-04-02 22:27:42 -07001739 EXPECT_EQ(NAME_NOT_FOUND,
1740 mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
Daniel Solomon42d04562019-01-20 21:03:19 -08001741
1742 // Check primaries argument wasn't modified in case of failure
1743 checkDummyDisplayNativePrimaries(primaries);
1744}
1745
1746/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001747 * SurfaceFlinger::setupNewDisplayDeviceInternal
1748 */
1749
1750class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
1751public:
1752 template <typename T>
1753 void setupNewDisplayDeviceInternalTest();
1754};
1755
1756template <typename Case>
1757void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
1758 const sp<BBinder> displayToken = new BBinder();
Lloyd Pique542307f2018-10-19 13:24:08 -07001759 const sp<compositionengine::mock::DisplaySurface> displaySurface =
1760 new compositionengine::mock::DisplaySurface();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001761 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001762
1763 // --------------------------------------------------------------------
1764 // Preconditions
1765
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001766 // Wide color displays support is configured appropriately
1767 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001768
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001769 // The display is setup with the HWC.
1770 Case::Display::injectHwcDisplay(this);
1771
1772 // SurfaceFlinger will use a test-controlled factory for native window
1773 // surfaces.
1774 injectFakeNativeWindowSurfaceFactory();
1775
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001776 // A compositionengine::Display has already been created
1777 auto compositionDisplay = Case::Display::injectCompositionDisplay(this);
1778
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001779 // --------------------------------------------------------------------
1780 // Call Expectations
1781
1782 // Various native window calls will be made.
1783 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
Lloyd Pique3c085a02018-05-09 19:38:32 -07001784 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001785 Case::WideColorSupport::setupComposerCallExpectations(this);
1786 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001787 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001788
1789 // --------------------------------------------------------------------
1790 // Invocation
1791
1792 DisplayDeviceState state;
Dominik Laskowski55c85402020-01-21 16:25:47 -08001793 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1794 const auto displayId = Case::Display::DISPLAY_ID::get();
1795 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001796 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1797 ASSERT_TRUE(hwcDisplayId);
1798 state.physical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001799 }
1800
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001801 state.isSecure = static_cast<bool>(Case::Display::SECURE);
1802
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001803 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
1804 displaySurface, producer);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001805
1806 // --------------------------------------------------------------------
1807 // Postconditions
1808
1809 ASSERT_TRUE(device != nullptr);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001810 EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001811 EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, device->getConnectionType());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001812 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001813 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001814 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001815 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
1816 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
1817 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
Valerie Haue9e843a2018-12-18 13:39:23 -08001818 EXPECT_EQ(Case::HdrSupport::HDR10_PLUS_SUPPORTED, device->hasHDR10PlusSupport());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001819 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
1820 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
1821 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
Lloyd Pique3c085a02018-05-09 19:38:32 -07001822 // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
1823 // remapped, and the test only ever sets up one config. If there were an error
1824 // looking up the remapped index, device->getActiveConfig() would be -1 instead.
Ady Abraham2139f732019-11-13 18:56:40 -08001825 EXPECT_EQ(0, device->getActiveConfig().value());
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001826 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
1827 device->getSupportedPerFrameMetadata());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001828}
1829
1830TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
1831 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
1832}
1833
1834TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
1835 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
1836}
1837
1838TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1839 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1840}
1841
1842TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001843 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001844}
1845
1846TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1847 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1848}
1849
Valerie Haue9e843a2018-12-18 13:39:23 -08001850TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10PlusDisplay) {
1851 setupNewDisplayDeviceInternalTest<Hdr10PlusDisplayCase>();
1852}
1853
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001854TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1855 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1856}
1857
1858TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1859 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1860}
1861
1862TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1863 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1864}
1865
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001866TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
1867 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
1868}
1869
1870TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
1871 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
1872}
1873
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001874/* ------------------------------------------------------------------------
1875 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1876 */
1877
1878class HandleTransactionLockedTest : public DisplayTransactionTest {
1879public:
1880 template <typename Case>
1881 void setupCommonPreconditions();
1882
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001883 template <typename Case, bool connected>
1884 static void expectHotplugReceived(mock::EventThread*);
1885
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001886 template <typename Case>
1887 void setupCommonCallExpectationsForConnectProcessing();
1888
1889 template <typename Case>
1890 void setupCommonCallExpectationsForDisconnectProcessing();
1891
1892 template <typename Case>
1893 void processesHotplugConnectCommon();
1894
1895 template <typename Case>
1896 void ignoresHotplugConnectCommon();
1897
1898 template <typename Case>
1899 void processesHotplugDisconnectCommon();
1900
1901 template <typename Case>
1902 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1903
1904 template <typename Case>
1905 void verifyPhysicalDisplayIsConnected();
1906
1907 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1908};
1909
1910template <typename Case>
1911void HandleTransactionLockedTest::setupCommonPreconditions() {
1912 // Wide color displays support is configured appropriately
1913 Case::WideColorSupport::injectConfigChange(this);
1914
1915 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1916 injectFakeBufferQueueFactory();
1917
1918 // SurfaceFlinger will use a test-controlled factory for native window
1919 // surfaces.
1920 injectFakeNativeWindowSurfaceFactory();
1921}
1922
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001923template <typename Case, bool connected>
1924void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) {
1925 const auto convert = [](auto physicalDisplayId) {
1926 return std::make_optional(DisplayId{physicalDisplayId});
1927 };
1928
1929 EXPECT_CALL(*eventThread,
1930 onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
1931 .Times(1);
1932}
1933
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001934template <typename Case>
1935void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1936 Case::Display::setupHwcHotplugCallExpectations(this);
1937
1938 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1939 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1940 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1941 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1942
1943 Case::WideColorSupport::setupComposerCallExpectations(this);
1944 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001945 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001946
1947 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001948 expectHotplugReceived<Case, true>(mEventThread);
1949 expectHotplugReceived<Case, true>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001950}
1951
1952template <typename Case>
1953void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1954 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
Dominik Laskowski1eba0202019-01-24 09:14:40 -08001955
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001956 expectHotplugReceived<Case, false>(mEventThread);
1957 expectHotplugReceived<Case, false>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001958}
1959
1960template <typename Case>
1961void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1962 // The display device should have been set up in the list of displays.
1963 ASSERT_TRUE(hasDisplayDevice(displayToken));
1964 const auto& device = getDisplayDevice(displayToken);
1965 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001966 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001967
Dominik Laskowski55c85402020-01-21 16:25:47 -08001968 std::optional<DisplayDeviceState::Physical> expectedPhysical;
1969 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1970 const auto displayId = Case::Display::DISPLAY_ID::get();
1971 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001972 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1973 ASSERT_TRUE(hwcDisplayId);
1974 expectedPhysical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001975 }
1976
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001977 // The display should have been set up in the current display state
1978 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1979 const auto& current = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001980 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), current.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001981 EXPECT_EQ(expectedPhysical, current.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001982
1983 // The display should have been set up in the drawing display state
1984 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1985 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001986 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001987 EXPECT_EQ(expectedPhysical, draw.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001988}
1989
1990template <typename Case>
1991void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1992 // HWComposer should have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001993 EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001994
Dominik Laskowski075d3172018-05-24 15:50:06 -07001995 // SF should have a display token.
1996 const auto displayId = Case::Display::DISPLAY_ID::get();
1997 ASSERT_TRUE(displayId);
1998 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
1999 auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002000
2001 verifyDisplayIsConnected<Case>(displayToken);
2002}
2003
2004void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
2005 EXPECT_FALSE(hasDisplayDevice(displayToken));
2006 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2007 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
2008}
2009
2010template <typename Case>
2011void HandleTransactionLockedTest::processesHotplugConnectCommon() {
2012 // --------------------------------------------------------------------
2013 // Preconditions
2014
2015 setupCommonPreconditions<Case>();
2016
2017 // A hotplug connect event is enqueued for a display
Peiyong Line9d809e2020-04-14 13:10:48 -07002018 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002019
2020 // --------------------------------------------------------------------
2021 // Call Expectations
2022
2023 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002024
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002025 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002026
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002027 // --------------------------------------------------------------------
2028 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08002029
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002030 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08002031
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002032 // --------------------------------------------------------------------
2033 // Postconditions
2034
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002035 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002036
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002037 // --------------------------------------------------------------------
2038 // Cleanup conditions
2039
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002040 EXPECT_CALL(*mComposer,
2041 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002042 .WillOnce(Return(Error::NONE));
2043 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08002044}
2045
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002046template <typename Case>
2047void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
2048 // --------------------------------------------------------------------
2049 // Preconditions
2050
2051 setupCommonPreconditions<Case>();
2052
2053 // A hotplug connect event is enqueued for a display
Peiyong Line9d809e2020-04-14 13:10:48 -07002054 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002055
2056 // --------------------------------------------------------------------
2057 // Invocation
2058
2059 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2060
2061 // --------------------------------------------------------------------
2062 // Postconditions
2063
2064 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002065 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002066}
2067
2068template <typename Case>
2069void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
2070 // --------------------------------------------------------------------
2071 // Preconditions
2072
2073 setupCommonPreconditions<Case>();
2074
2075 // A hotplug disconnect event is enqueued for a display
Peiyong Line9d809e2020-04-14 13:10:48 -07002076 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002077
2078 // The display is already completely set up.
2079 Case::Display::injectHwcDisplay(this);
2080 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2081 existing.inject();
2082
2083 // --------------------------------------------------------------------
2084 // Call Expectations
2085
2086 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
Lloyd Pique438e9e72018-09-04 18:06:08 -07002087 EXPECT_CALL(*mComposer, getDisplayIdentificationData(Case::Display::HWC_DISPLAY_ID, _, _))
2088 .Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002089
2090 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2091
2092 // --------------------------------------------------------------------
2093 // Invocation
2094
2095 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2096
2097 // --------------------------------------------------------------------
2098 // Postconditions
2099
2100 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002101 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002102
Dominik Laskowski075d3172018-05-24 15:50:06 -07002103 // SF should not have a display token.
2104 const auto displayId = Case::Display::DISPLAY_ID::get();
2105 ASSERT_TRUE(displayId);
2106 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002107
2108 // The existing token should have been removed
2109 verifyDisplayIsNotConnected(existing.token());
2110}
2111
2112TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
2113 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2114}
2115
2116TEST_F(HandleTransactionLockedTest,
2117 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
2118 // Inject an external display.
2119 ExternalDisplayVariant::injectHwcDisplay(this);
2120
2121 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2122}
2123
2124TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
2125 // Inject a primary display.
2126 PrimaryDisplayVariant::injectHwcDisplay(this);
2127
2128 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
2129}
2130
2131TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
2132 // Inject both a primary and external display.
2133 PrimaryDisplayVariant::injectHwcDisplay(this);
2134 ExternalDisplayVariant::injectHwcDisplay(this);
2135
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002136 // TODO: This is an unnecessary call.
2137 EXPECT_CALL(*mComposer,
2138 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
2139 .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
2140 SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
2141 Return(Error::NONE)));
2142
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002143 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2144
2145 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
2146}
2147
2148TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
2149 // Inject a primary display.
2150 PrimaryDisplayVariant::injectHwcDisplay(this);
2151
2152 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
2153
2154 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
2155}
2156
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002157TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectPrimaryDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002158 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
2159}
2160
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002161TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectExternalDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002162 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
2163}
2164
2165TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
2166 using Case = SimplePrimaryDisplayCase;
2167
2168 // --------------------------------------------------------------------
2169 // Preconditions
2170
2171 setupCommonPreconditions<Case>();
2172
2173 // A hotplug connect event is enqueued for a display
Peiyong Line9d809e2020-04-14 13:10:48 -07002174 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002175 // A hotplug disconnect event is also enqueued for the same display
Peiyong Line9d809e2020-04-14 13:10:48 -07002176 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002177
2178 // --------------------------------------------------------------------
2179 // Call Expectations
2180
2181 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2182
2183 setupCommonCallExpectationsForConnectProcessing<Case>();
2184 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2185
2186 EXPECT_CALL(*mComposer,
2187 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2188 .WillOnce(Return(Error::NONE));
2189 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2190
2191 // --------------------------------------------------------------------
2192 // Invocation
2193
2194 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2195
2196 // --------------------------------------------------------------------
2197 // Postconditions
2198
2199 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002200 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002201
Dominik Laskowski075d3172018-05-24 15:50:06 -07002202 // SF should not have a display token.
2203 const auto displayId = Case::Display::DISPLAY_ID::get();
2204 ASSERT_TRUE(displayId);
2205 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002206}
2207
2208TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
2209 using Case = SimplePrimaryDisplayCase;
2210
2211 // --------------------------------------------------------------------
2212 // Preconditions
2213
2214 setupCommonPreconditions<Case>();
2215
2216 // The display is already completely set up.
2217 Case::Display::injectHwcDisplay(this);
2218 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2219 existing.inject();
2220
2221 // A hotplug disconnect event is enqueued for a display
Peiyong Line9d809e2020-04-14 13:10:48 -07002222 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002223 // A hotplug connect event is also enqueued for the same display
Peiyong Line9d809e2020-04-14 13:10:48 -07002224 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002225
2226 // --------------------------------------------------------------------
2227 // Call Expectations
2228
2229 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2230
2231 setupCommonCallExpectationsForConnectProcessing<Case>();
2232 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2233
2234 // --------------------------------------------------------------------
2235 // Invocation
2236
2237 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2238
2239 // --------------------------------------------------------------------
2240 // Postconditions
2241
2242 // The existing token should have been removed
2243 verifyDisplayIsNotConnected(existing.token());
Dominik Laskowski075d3172018-05-24 15:50:06 -07002244 const auto displayId = Case::Display::DISPLAY_ID::get();
2245 ASSERT_TRUE(displayId);
2246 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
2247 EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002248
2249 // A new display should be connected in its place
2250
2251 verifyPhysicalDisplayIsConnected<Case>();
2252
2253 // --------------------------------------------------------------------
2254 // Cleanup conditions
2255
2256 EXPECT_CALL(*mComposer,
2257 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2258 .WillOnce(Return(Error::NONE));
2259 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2260}
2261
2262TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
2263 using Case = HwcVirtualDisplayCase;
2264
2265 // --------------------------------------------------------------------
2266 // Preconditions
2267
2268 // The HWC supports at least one virtual display
2269 injectMockComposer(1);
2270
2271 setupCommonPreconditions<Case>();
2272
2273 // A virtual display was added to the current state, and it has a
2274 // surface(producer)
2275 sp<BBinder> displayToken = new BBinder();
Lloyd Pique4c2ac022018-04-27 12:08:03 -07002276
Dominik Laskowski075d3172018-05-24 15:50:06 -07002277 DisplayDeviceState state;
2278 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002279
2280 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
Dominik Laskowski075d3172018-05-24 15:50:06 -07002281 state.surface = surface;
2282 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002283
2284 // --------------------------------------------------------------------
2285 // Call Expectations
2286
2287 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
2288 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
2289
2290 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
2291 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
2292 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
2293 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
2294 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
2295 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
2296 Return(NO_ERROR)));
2297 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
2298 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
2299
2300 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
2301
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002302 EXPECT_CALL(*mProducer, connect(_, NATIVE_WINDOW_API_EGL, false, _)).Times(1);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002303 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
2304
2305 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
2306 Case::WideColorSupport::setupComposerCallExpectations(this);
2307 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07002308 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002309
2310 // --------------------------------------------------------------------
2311 // Invocation
2312
2313 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2314
2315 // --------------------------------------------------------------------
2316 // Postconditions
2317
2318 // The display device should have been set up in the list of displays.
2319 verifyDisplayIsConnected<Case>(displayToken);
2320
2321 // --------------------------------------------------------------------
2322 // Cleanup conditions
2323
2324 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
2325 .WillOnce(Return(Error::NONE));
2326 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Pique9e9800c2019-02-26 16:26:09 -08002327
2328 // Cleanup
2329 mFlinger.mutableCurrentState().displays.removeItem(displayToken);
2330 mFlinger.mutableDrawingState().displays.removeItem(displayToken);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002331}
2332
2333TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
2334 using Case = HwcVirtualDisplayCase;
2335
2336 // --------------------------------------------------------------------
2337 // Preconditions
2338
2339 // The HWC supports at least one virtual display
2340 injectMockComposer(1);
2341
2342 setupCommonPreconditions<Case>();
2343
2344 // A virtual display was added to the current state, but it does not have a
2345 // surface.
2346 sp<BBinder> displayToken = new BBinder();
2347
Dominik Laskowski075d3172018-05-24 15:50:06 -07002348 DisplayDeviceState state;
2349 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002350
Dominik Laskowski075d3172018-05-24 15:50:06 -07002351 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002352
2353 // --------------------------------------------------------------------
2354 // Call Expectations
2355
2356 // --------------------------------------------------------------------
2357 // Invocation
2358
2359 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2360
2361 // --------------------------------------------------------------------
2362 // Postconditions
2363
2364 // There will not be a display device set up.
2365 EXPECT_FALSE(hasDisplayDevice(displayToken));
2366
2367 // The drawing display state will be set from the current display state.
2368 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
2369 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07002370 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002371}
2372
2373TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
2374 using Case = HwcVirtualDisplayCase;
2375
2376 // --------------------------------------------------------------------
2377 // Preconditions
2378
2379 // A virtual display is set up but is removed from the current state.
Dominik Laskowski075d3172018-05-24 15:50:06 -07002380 const auto displayId = Case::Display::DISPLAY_ID::get();
2381 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08002382 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002383 Case::Display::injectHwcDisplay(this);
2384 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2385 existing.inject();
2386 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
2387
2388 // --------------------------------------------------------------------
2389 // Call Expectations
2390
2391 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2392
2393 // --------------------------------------------------------------------
2394 // Invocation
2395
2396 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2397
2398 // --------------------------------------------------------------------
2399 // Postconditions
2400
2401 // The existing token should have been removed
2402 verifyDisplayIsNotConnected(existing.token());
2403}
2404
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002405TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
2406 using Case = NonHwcVirtualDisplayCase;
2407
2408 constexpr uint32_t oldLayerStack = 0u;
2409 constexpr uint32_t newLayerStack = 123u;
2410
2411 // --------------------------------------------------------------------
2412 // Preconditions
2413
2414 // A display is set up
2415 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2416 display.inject();
2417
2418 // There is a change to the layerStack state
2419 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
2420 display.mutableCurrentDisplayState().layerStack = newLayerStack;
2421
2422 // --------------------------------------------------------------------
2423 // Invocation
2424
2425 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2426
2427 // --------------------------------------------------------------------
2428 // Postconditions
2429
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002430 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002431}
2432
2433TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
2434 using Case = NonHwcVirtualDisplayCase;
2435
Dominik Laskowski718f9602019-11-09 20:01:35 -08002436 constexpr ui::Rotation oldTransform = ui::ROTATION_0;
2437 constexpr ui::Rotation newTransform = ui::ROTATION_180;
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002438
2439 // --------------------------------------------------------------------
2440 // Preconditions
2441
2442 // A display is set up
2443 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2444 display.inject();
2445
2446 // There is a change to the orientation state
2447 display.mutableDrawingDisplayState().orientation = oldTransform;
2448 display.mutableCurrentDisplayState().orientation = newTransform;
2449
2450 // --------------------------------------------------------------------
2451 // Invocation
2452
2453 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2454
2455 // --------------------------------------------------------------------
2456 // Postconditions
2457
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002458 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002459}
2460
2461TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
2462 using Case = NonHwcVirtualDisplayCase;
2463
2464 const Rect oldViewport(0, 0, 0, 0);
2465 const Rect newViewport(0, 0, 123, 456);
2466
2467 // --------------------------------------------------------------------
2468 // Preconditions
2469
2470 // A display is set up
2471 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2472 display.inject();
2473
2474 // There is a change to the viewport state
2475 display.mutableDrawingDisplayState().viewport = oldViewport;
2476 display.mutableCurrentDisplayState().viewport = newViewport;
2477
2478 // --------------------------------------------------------------------
2479 // Invocation
2480
2481 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2482
2483 // --------------------------------------------------------------------
2484 // Postconditions
2485
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002486 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002487}
2488
2489TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
2490 using Case = NonHwcVirtualDisplayCase;
2491
2492 const Rect oldFrame(0, 0, 0, 0);
2493 const Rect newFrame(0, 0, 123, 456);
2494
2495 // --------------------------------------------------------------------
2496 // Preconditions
2497
2498 // A display is set up
2499 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2500 display.inject();
2501
2502 // There is a change to the viewport state
2503 display.mutableDrawingDisplayState().frame = oldFrame;
2504 display.mutableCurrentDisplayState().frame = newFrame;
2505
2506 // --------------------------------------------------------------------
2507 // Invocation
2508
2509 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2510
2511 // --------------------------------------------------------------------
2512 // Postconditions
2513
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002514 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002515}
2516
2517TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
2518 using Case = NonHwcVirtualDisplayCase;
2519
2520 constexpr int oldWidth = 0;
2521 constexpr int oldHeight = 10;
2522 constexpr int newWidth = 123;
2523
2524 // --------------------------------------------------------------------
2525 // Preconditions
2526
2527 // A display is set up
2528 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002529 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002530 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002531 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2532 display.setNativeWindow(nativeWindow);
2533 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002534 // Setup injection expections
2535 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2536 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2537 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2538 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002539 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2540 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2541 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002542 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002543 display.inject();
2544
2545 // There is a change to the viewport state
2546 display.mutableDrawingDisplayState().width = oldWidth;
2547 display.mutableDrawingDisplayState().height = oldHeight;
2548 display.mutableCurrentDisplayState().width = newWidth;
2549 display.mutableCurrentDisplayState().height = oldHeight;
2550
2551 // --------------------------------------------------------------------
2552 // Call Expectations
2553
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002554 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002555
2556 // --------------------------------------------------------------------
2557 // Invocation
2558
2559 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2560}
2561
2562TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
2563 using Case = NonHwcVirtualDisplayCase;
2564
2565 constexpr int oldWidth = 0;
2566 constexpr int oldHeight = 10;
2567 constexpr int newHeight = 123;
2568
2569 // --------------------------------------------------------------------
2570 // Preconditions
2571
2572 // A display is set up
2573 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002574 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002575 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002576 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2577 display.setNativeWindow(nativeWindow);
2578 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002579 // Setup injection expections
2580 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2581 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2582 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2583 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002584 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2585 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2586 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002587 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002588 display.inject();
2589
2590 // There is a change to the viewport state
2591 display.mutableDrawingDisplayState().width = oldWidth;
2592 display.mutableDrawingDisplayState().height = oldHeight;
2593 display.mutableCurrentDisplayState().width = oldWidth;
2594 display.mutableCurrentDisplayState().height = newHeight;
2595
2596 // --------------------------------------------------------------------
2597 // Call Expectations
2598
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002599 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002600
2601 // --------------------------------------------------------------------
2602 // Invocation
2603
2604 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2605}
2606
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002607/* ------------------------------------------------------------------------
2608 * SurfaceFlinger::setDisplayStateLocked
2609 */
2610
2611TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
2612 // --------------------------------------------------------------------
2613 // Preconditions
2614
2615 // We have an unknown display token not associated with a known display
2616 sp<BBinder> displayToken = new BBinder();
2617
2618 // The requested display state references the unknown display.
2619 DisplayState state;
2620 state.what = DisplayState::eLayerStackChanged;
2621 state.token = displayToken;
2622 state.layerStack = 456;
2623
2624 // --------------------------------------------------------------------
2625 // Invocation
2626
2627 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2628
2629 // --------------------------------------------------------------------
2630 // Postconditions
2631
2632 // The returned flags are empty
2633 EXPECT_EQ(0u, flags);
2634
2635 // The display token still doesn't match anything known.
2636 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2637}
2638
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002639TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
2640 using Case = SimplePrimaryDisplayCase;
2641
2642 // --------------------------------------------------------------------
2643 // Preconditions
2644
2645 // A display is already set up
2646 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2647 display.inject();
2648
2649 // No changes are made to the display
2650 DisplayState state;
2651 state.what = 0;
2652 state.token = display.token();
2653
2654 // --------------------------------------------------------------------
2655 // Invocation
2656
2657 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2658
2659 // --------------------------------------------------------------------
2660 // Postconditions
2661
2662 // The returned flags are empty
2663 EXPECT_EQ(0u, flags);
2664}
2665
2666TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
2667 using Case = SimplePrimaryDisplayCase;
2668
2669 // --------------------------------------------------------------------
2670 // Preconditions
2671
2672 // A display is already set up
2673 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2674 display.inject();
2675
2676 // There is a surface that can be set.
2677 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2678
2679 // The current display state has the surface set
2680 display.mutableCurrentDisplayState().surface = surface;
2681
2682 // The incoming request sets the same surface
2683 DisplayState state;
2684 state.what = DisplayState::eSurfaceChanged;
2685 state.token = display.token();
2686 state.surface = surface;
2687
2688 // --------------------------------------------------------------------
2689 // Invocation
2690
2691 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2692
2693 // --------------------------------------------------------------------
2694 // Postconditions
2695
2696 // The returned flags are empty
2697 EXPECT_EQ(0u, flags);
2698
2699 // The current display state is unchanged.
2700 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2701}
2702
2703TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
2704 using Case = SimplePrimaryDisplayCase;
2705
2706 // --------------------------------------------------------------------
2707 // Preconditions
2708
2709 // A display is already set up
2710 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2711 display.inject();
2712
2713 // There is a surface that can be set.
2714 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2715
2716 // The current display state does not have a surface
2717 display.mutableCurrentDisplayState().surface = nullptr;
2718
2719 // The incoming request sets a surface
2720 DisplayState state;
2721 state.what = DisplayState::eSurfaceChanged;
2722 state.token = display.token();
2723 state.surface = surface;
2724
2725 // --------------------------------------------------------------------
2726 // Invocation
2727
2728 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2729
2730 // --------------------------------------------------------------------
2731 // Postconditions
2732
2733 // The returned flags indicate a transaction is needed
2734 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2735
2736 // The current display layer stack state is set to the new value
2737 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2738}
2739
2740TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
2741 using Case = SimplePrimaryDisplayCase;
2742
2743 // --------------------------------------------------------------------
2744 // Preconditions
2745
2746 // A display is already set up
2747 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2748 display.inject();
2749
2750 // The display has a layer stack set
2751 display.mutableCurrentDisplayState().layerStack = 456u;
2752
2753 // The incoming request sets the same layer stack
2754 DisplayState state;
2755 state.what = DisplayState::eLayerStackChanged;
2756 state.token = display.token();
2757 state.layerStack = 456u;
2758
2759 // --------------------------------------------------------------------
2760 // Invocation
2761
2762 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2763
2764 // --------------------------------------------------------------------
2765 // Postconditions
2766
2767 // The returned flags are empty
2768 EXPECT_EQ(0u, flags);
2769
2770 // The current display state is unchanged
2771 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2772}
2773
2774TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
2775 using Case = SimplePrimaryDisplayCase;
2776
2777 // --------------------------------------------------------------------
2778 // Preconditions
2779
2780 // A display is set up
2781 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2782 display.inject();
2783
2784 // The display has a layer stack set
2785 display.mutableCurrentDisplayState().layerStack = 654u;
2786
2787 // The incoming request sets a different layer stack
2788 DisplayState state;
2789 state.what = DisplayState::eLayerStackChanged;
2790 state.token = display.token();
2791 state.layerStack = 456u;
2792
2793 // --------------------------------------------------------------------
2794 // Invocation
2795
2796 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2797
2798 // --------------------------------------------------------------------
2799 // Postconditions
2800
2801 // The returned flags indicate a transaction is needed
2802 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2803
2804 // The desired display state has been set to the new value.
2805 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2806}
2807
2808TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
2809 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002810 constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002811 const Rect initialFrame = {1, 2, 3, 4};
2812 const Rect initialViewport = {5, 6, 7, 8};
2813
2814 // --------------------------------------------------------------------
2815 // Preconditions
2816
2817 // A display is set up
2818 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2819 display.inject();
2820
2821 // The current display state projection state is all set
2822 display.mutableCurrentDisplayState().orientation = initialOrientation;
2823 display.mutableCurrentDisplayState().frame = initialFrame;
2824 display.mutableCurrentDisplayState().viewport = initialViewport;
2825
2826 // The incoming request sets the same projection state
2827 DisplayState state;
2828 state.what = DisplayState::eDisplayProjectionChanged;
2829 state.token = display.token();
2830 state.orientation = initialOrientation;
2831 state.frame = initialFrame;
2832 state.viewport = initialViewport;
2833
2834 // --------------------------------------------------------------------
2835 // Invocation
2836
2837 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2838
2839 // --------------------------------------------------------------------
2840 // Postconditions
2841
2842 // The returned flags are empty
2843 EXPECT_EQ(0u, flags);
2844
2845 // The current display state is unchanged
2846 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
2847
2848 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
2849 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
2850}
2851
2852TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
2853 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002854 constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
2855 constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002856
2857 // --------------------------------------------------------------------
2858 // Preconditions
2859
2860 // A display is set up
2861 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2862 display.inject();
2863
2864 // The current display state has an orientation set
2865 display.mutableCurrentDisplayState().orientation = initialOrientation;
2866
2867 // The incoming request sets a different orientation
2868 DisplayState state;
2869 state.what = DisplayState::eDisplayProjectionChanged;
2870 state.token = display.token();
2871 state.orientation = desiredOrientation;
2872
2873 // --------------------------------------------------------------------
2874 // Invocation
2875
2876 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2877
2878 // --------------------------------------------------------------------
2879 // Postconditions
2880
2881 // The returned flags indicate a transaction is needed
2882 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2883
2884 // The current display state has the new value.
2885 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2886}
2887
2888TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2889 using Case = SimplePrimaryDisplayCase;
2890 const Rect initialFrame = {0, 0, 0, 0};
2891 const Rect desiredFrame = {5, 6, 7, 8};
2892
2893 // --------------------------------------------------------------------
2894 // Preconditions
2895
2896 // A display is set up
2897 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2898 display.inject();
2899
2900 // The current display state does not have a frame
2901 display.mutableCurrentDisplayState().frame = initialFrame;
2902
2903 // The incoming request sets a frame
2904 DisplayState state;
2905 state.what = DisplayState::eDisplayProjectionChanged;
2906 state.token = display.token();
2907 state.frame = desiredFrame;
2908
2909 // --------------------------------------------------------------------
2910 // Invocation
2911
2912 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2913
2914 // --------------------------------------------------------------------
2915 // Postconditions
2916
2917 // The returned flags indicate a transaction is needed
2918 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2919
2920 // The current display state has the new value.
2921 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2922}
2923
2924TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2925 using Case = SimplePrimaryDisplayCase;
2926 const Rect initialViewport = {0, 0, 0, 0};
2927 const Rect desiredViewport = {5, 6, 7, 8};
2928
2929 // --------------------------------------------------------------------
2930 // Preconditions
2931
2932 // A display is set up
2933 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2934 display.inject();
2935
2936 // The current display state does not have a viewport
2937 display.mutableCurrentDisplayState().viewport = initialViewport;
2938
2939 // The incoming request sets a viewport
2940 DisplayState state;
2941 state.what = DisplayState::eDisplayProjectionChanged;
2942 state.token = display.token();
2943 state.viewport = desiredViewport;
2944
2945 // --------------------------------------------------------------------
2946 // Invocation
2947
2948 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2949
2950 // --------------------------------------------------------------------
2951 // Postconditions
2952
2953 // The returned flags indicate a transaction is needed
2954 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2955
2956 // The current display state has the new value.
2957 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2958}
2959
2960TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2961 using Case = SimplePrimaryDisplayCase;
2962 constexpr uint32_t initialWidth = 1024;
2963 constexpr uint32_t initialHeight = 768;
2964
2965 // --------------------------------------------------------------------
2966 // Preconditions
2967
2968 // A display is set up
2969 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2970 display.inject();
2971
2972 // The current display state has a size set
2973 display.mutableCurrentDisplayState().width = initialWidth;
2974 display.mutableCurrentDisplayState().height = initialHeight;
2975
2976 // The incoming request sets the same display size
2977 DisplayState state;
2978 state.what = DisplayState::eDisplaySizeChanged;
2979 state.token = display.token();
2980 state.width = initialWidth;
2981 state.height = initialHeight;
2982
2983 // --------------------------------------------------------------------
2984 // Invocation
2985
2986 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2987
2988 // --------------------------------------------------------------------
2989 // Postconditions
2990
2991 // The returned flags are empty
2992 EXPECT_EQ(0u, flags);
2993
2994 // The current display state is unchanged
2995 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2996 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2997}
2998
2999TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
3000 using Case = SimplePrimaryDisplayCase;
3001 constexpr uint32_t initialWidth = 0;
3002 constexpr uint32_t desiredWidth = 1024;
3003
3004 // --------------------------------------------------------------------
3005 // Preconditions
3006
3007 // A display is set up
3008 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3009 display.inject();
3010
3011 // The display does not yet have a width
3012 display.mutableCurrentDisplayState().width = initialWidth;
3013
3014 // The incoming request sets a display width
3015 DisplayState state;
3016 state.what = DisplayState::eDisplaySizeChanged;
3017 state.token = display.token();
3018 state.width = desiredWidth;
3019
3020 // --------------------------------------------------------------------
3021 // Invocation
3022
3023 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3024
3025 // --------------------------------------------------------------------
3026 // Postconditions
3027
3028 // The returned flags indicate a transaction is needed
3029 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3030
3031 // The current display state has the new value.
3032 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
3033}
3034
3035TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
3036 using Case = SimplePrimaryDisplayCase;
3037 constexpr uint32_t initialHeight = 0;
3038 constexpr uint32_t desiredHeight = 768;
3039
3040 // --------------------------------------------------------------------
3041 // Preconditions
3042
3043 // A display is set up
3044 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3045 display.inject();
3046
3047 // The display does not yet have a height
3048 display.mutableCurrentDisplayState().height = initialHeight;
3049
3050 // The incoming request sets a display height
3051 DisplayState state;
3052 state.what = DisplayState::eDisplaySizeChanged;
3053 state.token = display.token();
3054 state.height = desiredHeight;
3055
3056 // --------------------------------------------------------------------
3057 // Invocation
3058
3059 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3060
3061 // --------------------------------------------------------------------
3062 // Postconditions
3063
3064 // The returned flags indicate a transaction is needed
3065 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3066
3067 // The current display state has the new value.
3068 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
3069}
3070
Lloyd Pique86016da2018-03-01 16:09:38 -08003071/* ------------------------------------------------------------------------
3072 * SurfaceFlinger::onInitializeDisplays
3073 */
3074
3075TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
3076 using Case = SimplePrimaryDisplayCase;
3077
3078 // --------------------------------------------------------------------
3079 // Preconditions
3080
3081 // A primary display is set up
3082 Case::Display::injectHwcDisplay(this);
3083 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
3084 primaryDisplay.inject();
3085
3086 // --------------------------------------------------------------------
3087 // Call Expectations
3088
3089 // We expect the surface interceptor to possibly be used, but we treat it as
3090 // disabled since it is called as a side effect rather than directly by this
3091 // function.
3092 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
3093
3094 // We expect a call to get the active display config.
3095 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
3096
3097 // We expect invalidate() to be invoked once to trigger display transaction
3098 // processing.
3099 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
3100
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003101 EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
3102
Lloyd Pique86016da2018-03-01 16:09:38 -08003103 // --------------------------------------------------------------------
3104 // Invocation
3105
3106 mFlinger.onInitializeDisplays();
3107
3108 // --------------------------------------------------------------------
3109 // Postconditions
3110
3111 // The primary display should have a current state
3112 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
3113 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
3114 // The layer stack state should be set to zero
3115 EXPECT_EQ(0u, primaryDisplayState.layerStack);
3116 // The orientation state should be set to zero
Dominik Laskowski718f9602019-11-09 20:01:35 -08003117 EXPECT_EQ(ui::ROTATION_0, primaryDisplayState.orientation);
Lloyd Pique86016da2018-03-01 16:09:38 -08003118
3119 // The frame state should be set to INVALID
3120 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
3121
3122 // The viewport state should be set to INVALID
3123 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
3124
3125 // The width and height should both be zero
3126 EXPECT_EQ(0u, primaryDisplayState.width);
3127 EXPECT_EQ(0u, primaryDisplayState.height);
3128
3129 // The display should be set to HWC_POWER_MODE_NORMAL
3130 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
3131 auto displayDevice = primaryDisplay.mutableDisplayDevice();
3132 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
3133
3134 // The display refresh period should be set in the frame tracker.
3135 FrameStats stats;
3136 mFlinger.getAnimFrameTracker().getStats(&stats);
3137 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
3138
3139 // The display transaction needed flag should be set.
3140 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
3141
3142 // The compositor timing should be set to default values
3143 const auto& compositorTiming = mFlinger.getCompositorTiming();
3144 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
3145 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
3146 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
3147}
3148
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003149/* ------------------------------------------------------------------------
3150 * SurfaceFlinger::setPowerModeInternal
3151 */
3152
3153// Used when we simulate a display that supports doze.
Peiyong Lined531a32018-10-26 18:27:56 -07003154template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003155struct DozeIsSupportedVariant {
3156 static constexpr bool DOZE_SUPPORTED = true;
3157 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3158 IComposerClient::PowerMode::DOZE;
3159 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3160 IComposerClient::PowerMode::DOZE_SUSPEND;
Peiyong Lined531a32018-10-26 18:27:56 -07003161
3162 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3163 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
Peiyong Line9d809e2020-04-14 13:10:48 -07003164 .WillOnce(DoAll(SetArgPointee<1>(
3165 std::vector<DisplayCapability>({DisplayCapability::DOZE})),
Peiyong Lined531a32018-10-26 18:27:56 -07003166 Return(Error::NONE)));
3167 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003168};
3169
Peiyong Lined531a32018-10-26 18:27:56 -07003170template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003171// Used when we simulate a display that does not support doze.
3172struct DozeNotSupportedVariant {
3173 static constexpr bool DOZE_SUPPORTED = false;
3174 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3175 IComposerClient::PowerMode::ON;
3176 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3177 IComposerClient::PowerMode::ON;
Peiyong Lined531a32018-10-26 18:27:56 -07003178
3179 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3180 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
Peiyong Line9d809e2020-04-14 13:10:48 -07003181 .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
Peiyong Lined531a32018-10-26 18:27:56 -07003182 Return(Error::NONE)));
3183 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003184};
3185
3186struct EventThreadBaseSupportedVariant {
3187 static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
3188 // The event control thread should not be notified.
3189 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
3190
3191 // The event thread should not be notified.
3192 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
3193 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(0);
3194 }
3195};
3196
3197struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
3198 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3199 // These calls are only expected for the primary display.
3200
3201 // Instead expect no calls.
3202 setupEventAndEventControlThreadNoCallExpectations(test);
3203 }
3204
3205 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3206 // These calls are only expected for the primary display.
3207
3208 // Instead expect no calls.
3209 setupEventAndEventControlThreadNoCallExpectations(test);
3210 }
3211};
3212
3213struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
3214 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3215 // The event control thread should be notified to enable vsyncs
3216 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
3217
3218 // The event thread should be notified that the screen was acquired.
3219 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
3220 }
3221
3222 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3223 // There should be a call to setVsyncEnabled(false)
3224 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
3225
3226 // The event thread should not be notified that the screen was released.
3227 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
3228 }
3229};
3230
Lloyd Pique41be5d22018-06-21 13:11:48 -07003231struct DispSyncIsSupportedVariant {
3232 static void setupBeginResyncCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique41be5d22018-06-21 13:11:48 -07003233 EXPECT_CALL(*test->mPrimaryDispSync, setPeriod(DEFAULT_REFRESH_RATE)).Times(1);
3234 EXPECT_CALL(*test->mPrimaryDispSync, beginResync()).Times(1);
3235 }
3236
3237 static void setupEndResyncCallExpectations(DisplayTransactionTest* test) {
3238 EXPECT_CALL(*test->mPrimaryDispSync, endResync()).Times(1);
3239 }
3240};
3241
3242struct DispSyncNotSupportedVariant {
3243 static void setupBeginResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3244
3245 static void setupEndResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3246};
3247
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003248// --------------------------------------------------------------------
3249// Note:
3250//
3251// There are a large number of transitions we could test, however we only test a
3252// selected subset which provides complete test coverage of the implementation.
3253// --------------------------------------------------------------------
3254
3255template <int initialPowerMode, int targetPowerMode>
3256struct TransitionVariantCommon {
3257 static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
3258 static constexpr auto TARGET_POWER_MODE = targetPowerMode;
3259
3260 static void verifyPostconditions(DisplayTransactionTest*) {}
3261};
3262
3263struct TransitionOffToOnVariant
3264 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
3265 template <typename Case>
3266 static void setupCallExpectations(DisplayTransactionTest* test) {
3267 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3268 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003269 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003270 Case::setupRepaintEverythingCallExpectations(test);
3271 }
3272
3273 static void verifyPostconditions(DisplayTransactionTest* test) {
3274 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3275 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3276 }
3277};
3278
3279struct TransitionOffToDozeSuspendVariant
3280 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
3281 template <typename Case>
3282 static void setupCallExpectations(DisplayTransactionTest* test) {
3283 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3284 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3285 Case::setupRepaintEverythingCallExpectations(test);
3286 }
3287
3288 static void verifyPostconditions(DisplayTransactionTest* test) {
3289 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3290 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3291 }
3292};
3293
3294struct TransitionOnToOffVariant
3295 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
3296 template <typename Case>
3297 static void setupCallExpectations(DisplayTransactionTest* test) {
3298 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003299 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003300 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3301 }
3302
3303 static void verifyPostconditions(DisplayTransactionTest* test) {
3304 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3305 }
3306};
3307
3308struct TransitionDozeSuspendToOffVariant
3309 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
3310 template <typename Case>
3311 static void setupCallExpectations(DisplayTransactionTest* test) {
3312 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3313 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3314 }
3315
3316 static void verifyPostconditions(DisplayTransactionTest* test) {
3317 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3318 }
3319};
3320
3321struct TransitionOnToDozeVariant
3322 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
3323 template <typename Case>
3324 static void setupCallExpectations(DisplayTransactionTest* test) {
3325 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3326 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3327 }
3328};
3329
3330struct TransitionDozeSuspendToDozeVariant
3331 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
3332 template <typename Case>
3333 static void setupCallExpectations(DisplayTransactionTest* test) {
3334 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003335 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003336 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3337 }
3338};
3339
3340struct TransitionDozeToOnVariant
3341 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
3342 template <typename Case>
3343 static void setupCallExpectations(DisplayTransactionTest* test) {
3344 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3345 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3346 }
3347};
3348
3349struct TransitionDozeSuspendToOnVariant
3350 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
3351 template <typename Case>
3352 static void setupCallExpectations(DisplayTransactionTest* test) {
3353 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003354 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003355 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3356 }
3357};
3358
3359struct TransitionOnToDozeSuspendVariant
3360 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
3361 template <typename Case>
3362 static void setupCallExpectations(DisplayTransactionTest* test) {
3363 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003364 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003365 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3366 }
3367};
3368
3369struct TransitionOnToUnknownVariant
3370 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
3371 template <typename Case>
3372 static void setupCallExpectations(DisplayTransactionTest* test) {
3373 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3374 Case::setupNoComposerPowerModeCallExpectations(test);
3375 }
3376};
3377
3378// --------------------------------------------------------------------
3379// Note:
3380//
3381// Rather than testing the cartesian product of of
3382// DozeIsSupported/DozeNotSupported with all other options, we use one for one
3383// display type, and the other for another display type.
3384// --------------------------------------------------------------------
3385
3386template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
Lloyd Pique41be5d22018-06-21 13:11:48 -07003387 typename DispSyncVariant, typename TransitionVariant>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003388struct DisplayPowerCase {
3389 using Display = DisplayVariant;
3390 using Doze = DozeVariant;
3391 using EventThread = EventThreadVariant;
Lloyd Pique41be5d22018-06-21 13:11:48 -07003392 using DispSync = DispSyncVariant;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003393 using Transition = TransitionVariant;
3394
3395 static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003396 Display::injectHwcDisplayWithNoDefaultCapabilities(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003397 auto display = Display::makeFakeExistingDisplayInjector(test);
3398 display.inject();
3399 display.mutableDisplayDevice()->setPowerMode(mode);
3400 return display;
3401 }
3402
3403 static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07003404 test->mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = enabled;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003405 }
3406
3407 static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
3408 EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
3409 }
3410
3411 static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
3412 EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
3413 EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
3414 }
3415
3416 static void setupComposerCallExpectations(DisplayTransactionTest* test,
3417 IComposerClient::PowerMode mode) {
3418 // Any calls to get the active config will return a default value.
3419 EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
3420 .WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
3421 Return(Error::NONE)));
3422
3423 // Any calls to get whether the display supports dozing will return the value set by the
3424 // policy variant.
3425 EXPECT_CALL(*test->mComposer, getDozeSupport(Display::HWC_DISPLAY_ID, _))
3426 .WillRepeatedly(DoAll(SetArgPointee<1>(Doze::DOZE_SUPPORTED), Return(Error::NONE)));
3427
3428 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, mode)).Times(1);
3429 }
3430
3431 static void setupNoComposerPowerModeCallExpectations(DisplayTransactionTest* test) {
3432 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, _)).Times(0);
3433 }
3434};
3435
3436// A sample configuration for the primary display.
3437// In addition to having event thread support, we emulate doze support.
3438template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003439using PrimaryDisplayPowerCase =
3440 DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant<PrimaryDisplayVariant>,
3441 EventThreadIsSupportedVariant, DispSyncIsSupportedVariant,
3442 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003443
3444// A sample configuration for the external display.
3445// In addition to not having event thread support, we emulate not having doze
3446// support.
3447template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003448using ExternalDisplayPowerCase =
3449 DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant<ExternalDisplayVariant>,
3450 EventThreadNotSupportedVariant, DispSyncNotSupportedVariant,
3451 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003452
3453class SetPowerModeInternalTest : public DisplayTransactionTest {
3454public:
3455 template <typename Case>
3456 void transitionDisplayCommon();
3457};
3458
3459template <int PowerMode>
3460struct PowerModeInitialVSyncEnabled : public std::false_type {};
3461
3462template <>
3463struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
3464
3465template <>
3466struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
3467
3468template <typename Case>
3469void SetPowerModeInternalTest::transitionDisplayCommon() {
3470 // --------------------------------------------------------------------
3471 // Preconditions
3472
Peiyong Lined531a32018-10-26 18:27:56 -07003473 Case::Doze::setupComposerCallExpectations(this);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003474 auto display =
3475 Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
3476 Case::setInitialPrimaryHWVsyncEnabled(this,
3477 PowerModeInitialVSyncEnabled<
3478 Case::Transition::INITIAL_POWER_MODE>::value);
3479
3480 // --------------------------------------------------------------------
3481 // Call Expectations
3482
3483 Case::setupSurfaceInterceptorCallExpectations(this, Case::Transition::TARGET_POWER_MODE);
3484 Case::Transition::template setupCallExpectations<Case>(this);
3485
3486 // --------------------------------------------------------------------
3487 // Invocation
3488
3489 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
3490 Case::Transition::TARGET_POWER_MODE);
3491
3492 // --------------------------------------------------------------------
3493 // Postconditions
3494
3495 Case::Transition::verifyPostconditions(this);
3496}
3497
3498TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) {
3499 using Case = SimplePrimaryDisplayCase;
3500
3501 // --------------------------------------------------------------------
3502 // Preconditions
3503
3504 // A primary display device is set up
3505 Case::Display::injectHwcDisplay(this);
3506 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3507 display.inject();
3508
Dominik Laskowskia2edf612018-06-01 13:15:16 -07003509 // The display is already set to HWC_POWER_MODE_NORMAL
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003510 display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
3511
3512 // --------------------------------------------------------------------
3513 // Invocation
3514
3515 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
3516
3517 // --------------------------------------------------------------------
3518 // Postconditions
3519
3520 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3521}
3522
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003523TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) {
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003524 using Case = HwcVirtualDisplayCase;
3525
3526 // --------------------------------------------------------------------
3527 // Preconditions
3528
Dominik Laskowski075d3172018-05-24 15:50:06 -07003529 // Insert display data so that the HWC thinks it created the virtual display.
3530 const auto displayId = Case::Display::DISPLAY_ID::get();
3531 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08003532 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003533
3534 // A virtual display device is set up
3535 Case::Display::injectHwcDisplay(this);
3536 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3537 display.inject();
3538
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003539 // The display is set to HWC_POWER_MODE_NORMAL
3540 getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_NORMAL);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003541
3542 // --------------------------------------------------------------------
3543 // Invocation
3544
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003545 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_OFF);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003546
3547 // --------------------------------------------------------------------
3548 // Postconditions
3549
3550 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3551}
3552
3553TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
3554 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>();
3555}
3556
3557TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) {
3558 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3559}
3560
3561TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) {
3562 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>();
3563}
3564
3565TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) {
3566 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3567}
3568
3569TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) {
3570 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>();
3571}
3572
3573TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) {
3574 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3575}
3576
3577TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) {
3578 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>();
3579}
3580
3581TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) {
3582 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3583}
3584
3585TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) {
3586 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3587}
3588
3589TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) {
3590 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>();
3591}
3592
3593TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) {
3594 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
3595}
3596
3597TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) {
3598 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3599}
3600
3601TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) {
3602 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
3603}
3604
3605TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) {
3606 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3607}
3608
3609TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) {
3610 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>();
3611}
3612
3613TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
3614 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3615}
3616
3617TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) {
3618 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>();
3619}
3620
3621TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
3622 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3623}
3624
3625TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
3626 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3627}
3628
3629TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) {
3630 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
3631}
3632
Lloyd Piquef58625d2017-12-19 13:22:33 -08003633} // namespace
3634} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003635
3636// TODO(b/129481165): remove the #pragma below and fix conversion issues
3637#pragma clang diagnostic pop // ignored "-Wconversion"