blob: 24eeac70a4a33085d8442e368261346ae2eb26f3 [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
Lloyd Piquee39cad22017-12-20 17:01:29 -080058using testing::_;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070059using testing::AnyNumber;
Lloyd Piquee39cad22017-12-20 17:01:29 -080060using testing::DoAll;
61using testing::Mock;
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -080062using testing::ResultOf;
Lloyd Piquee39cad22017-12-20 17:01:29 -080063using testing::Return;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070064using testing::ReturnRefOfCopy;
Lloyd Piquee39cad22017-12-20 17:01:29 -080065using testing::SetArgPointee;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -070066using testing::StrictMock;
Lloyd Piquee39cad22017-12-20 17:01:29 -080067
Lloyd Piqued883d5a2018-04-27 19:32:30 -070068using android::Hwc2::ColorMode;
Lloyd Piquee39cad22017-12-20 17:01:29 -080069using android::Hwc2::Error;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070070using android::Hwc2::Hdr;
Lloyd Piquee39cad22017-12-20 17:01:29 -080071using android::Hwc2::IComposer;
72using android::Hwc2::IComposerClient;
Lloyd Piqued883d5a2018-04-27 19:32:30 -070073using android::Hwc2::PerFrameMetadataKey;
74using android::Hwc2::RenderIntent;
Lloyd Piquee39cad22017-12-20 17:01:29 -080075
Lloyd Piquec11e0d32018-01-22 18:44:59 -080076using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
77using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
Lloyd Pique1fa4d462018-01-22 18:03:16 -080078using HotplugEvent = TestableSurfaceFlinger::HotplugEvent;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080079using HWC2Display = TestableSurfaceFlinger::HWC2Display;
Lloyd Piquebc792092018-01-17 11:52:30 -080080
Lloyd Piquec11e0d32018-01-22 18:44:59 -080081constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
Lloyd Piquee39cad22017-12-20 17:01:29 -080082constexpr int32_t DEFAULT_DPI = 320;
Lloyd Piquec11e0d32018-01-22 18:44:59 -080083constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
Lloyd Piquee39cad22017-12-20 17:01:29 -080084
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -080085constexpr int HWC_POWER_MODE_LEET = 1337; // An out of range power mode value
86
Lloyd Piquec11e0d32018-01-22 18:44:59 -080087/* ------------------------------------------------------------------------
88 * Boolean avoidance
89 *
90 * To make calls and template instantiations more readable, we define some
91 * local enums along with an implicit bool conversion.
92 */
93
94#define BOOL_SUBSTITUTE(TYPENAME) enum class TYPENAME : bool { FALSE = false, TRUE = true };
95
Lloyd Piquec11e0d32018-01-22 18:44:59 -080096BOOL_SUBSTITUTE(Async);
Dominik Laskowski075d3172018-05-24 15:50:06 -070097BOOL_SUBSTITUTE(Critical);
98BOOL_SUBSTITUTE(Primary);
Lloyd Piquec11e0d32018-01-22 18:44:59 -080099BOOL_SUBSTITUTE(Secure);
Dominik Laskowski075d3172018-05-24 15:50:06 -0700100BOOL_SUBSTITUTE(Virtual);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800101
102/* ------------------------------------------------------------------------
103 *
104 */
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800105
Lloyd Piquef58625d2017-12-19 13:22:33 -0800106class DisplayTransactionTest : public testing::Test {
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800107public:
Lloyd Piquef58625d2017-12-19 13:22:33 -0800108 DisplayTransactionTest();
109 ~DisplayTransactionTest() override;
110
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800111 // --------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800112 // Mock/Fake injection
Lloyd Piquef58625d2017-12-19 13:22:33 -0800113
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700114 void injectMockScheduler();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800115 void injectMockComposer(int virtualDisplayCount);
116 void injectFakeBufferQueueFactory();
117 void injectFakeNativeWindowSurfaceFactory();
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700118 sp<DisplayDevice> injectDefaultInternalDisplay(std::function<void(FakeDisplayDeviceInjector&)>);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800119
120 // --------------------------------------------------------------------
121 // Postcondition helpers
122
Dominik Laskowski075d3172018-05-24 15:50:06 -0700123 bool hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId);
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800124 bool hasTransactionFlagSet(int flag);
125 bool hasDisplayDevice(sp<IBinder> displayToken);
126 sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
127 bool hasCurrentDisplayState(sp<IBinder> displayToken);
128 const DisplayDeviceState& getCurrentDisplayState(sp<IBinder> displayToken);
129 bool hasDrawingDisplayState(sp<IBinder> displayToken);
130 const DisplayDeviceState& getDrawingDisplayState(sp<IBinder> displayToken);
131
132 // --------------------------------------------------------------------
133 // Test instances
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800134
Lloyd Piquef58625d2017-12-19 13:22:33 -0800135 TestableSurfaceFlinger mFlinger;
Alec Mouriba013fa2018-10-16 12:43:11 -0700136 sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
Alec Mouri0a9c7b82018-11-16 13:05:25 -0800137 sp<GraphicBuffer> mBuffer = new GraphicBuffer();
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700138 Hwc2::mock::PowerAdvisor mPowerAdvisor;
Lloyd Piquee39cad22017-12-20 17:01:29 -0800139
140 // These mocks are created by the test, but are destroyed by SurfaceFlinger
141 // by virtue of being stored into a std::unique_ptr. However we still need
142 // to keep a reference to them for use in setting up call expectations.
Peiyong Lin833074a2018-08-28 11:53:54 -0700143 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800144 Hwc2::mock::Composer* mComposer = nullptr;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800145 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
146 mock::SurfaceInterceptor* mSurfaceInterceptor = new mock::SurfaceInterceptor();
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700147
148 mock::DispSync* mPrimaryDispSync = new mock::DispSync;
149 mock::EventControlThread* mEventControlThread = new mock::EventControlThread;
150 mock::EventThread* mEventThread = new mock::EventThread;
151 mock::EventThread* mSFEventThread = new mock::EventThread;
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800152
153 // These mocks are created only when expected to be created via a factory.
154 sp<mock::GraphicBufferConsumer> mConsumer;
155 sp<mock::GraphicBufferProducer> mProducer;
Lloyd Pique22098362018-09-13 11:46:49 -0700156 surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
Lloyd Piquef58625d2017-12-19 13:22:33 -0800157};
158
159DisplayTransactionTest::DisplayTransactionTest() {
160 const ::testing::TestInfo* const test_info =
161 ::testing::UnitTest::GetInstance()->current_test_info();
162 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Lloyd Piquee39cad22017-12-20 17:01:29 -0800163
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800164 // Default to no wide color display support configured
165 mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700166 mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800167 mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800168
169 // Default to using HWC virtual displays
170 mFlinger.mutableUseHwcVirtualDisplays() = true;
171
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800172 mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
173 ADD_FAILURE() << "Unexpected request to create a buffer queue.";
174 });
175
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800176 mFlinger.setCreateNativeWindowSurface([](auto) {
177 ADD_FAILURE() << "Unexpected request to create a native window surface.";
178 return nullptr;
179 });
180
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700181 injectMockScheduler();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800182 mFlinger.mutableEventQueue().reset(mMessageQueue);
Peiyong Lin833074a2018-08-28 11:53:54 -0700183 mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800184 mFlinger.mutableInterceptor().reset(mSurfaceInterceptor);
Lloyd Piquee39cad22017-12-20 17:01:29 -0800185
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800186 injectMockComposer(0);
Lloyd Piquef58625d2017-12-19 13:22:33 -0800187}
188
189DisplayTransactionTest::~DisplayTransactionTest() {
190 const ::testing::TestInfo* const test_info =
191 ::testing::UnitTest::GetInstance()->current_test_info();
192 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
193}
194
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700195void DisplayTransactionTest::injectMockScheduler() {
Ana Krulecafb45842019-02-13 13:33:03 -0800196 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700197 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
198 .WillOnce(Return(new EventThreadConnection(mEventThread, ResyncCallback(),
199 ISurfaceComposer::eConfigChangedSuppress)));
200
Ana Krulecafb45842019-02-13 13:33:03 -0800201 EXPECT_CALL(*mSFEventThread, registerDisplayEventConnection(_));
Dominik Laskowski98041832019-08-01 18:35:59 -0700202 EXPECT_CALL(*mSFEventThread, createEventConnection(_, _))
203 .WillOnce(Return(new EventThreadConnection(mSFEventThread, ResyncCallback(),
204 ISurfaceComposer::eConfigChangedSuppress)));
Ana Krulecafb45842019-02-13 13:33:03 -0800205
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -0700206 mFlinger.setupScheduler(std::unique_ptr<DispSync>(mPrimaryDispSync),
207 std::unique_ptr<EventControlThread>(mEventControlThread),
208 std::unique_ptr<EventThread>(mEventThread),
209 std::unique_ptr<EventThread>(mSFEventThread));
Ana Krulecafb45842019-02-13 13:33:03 -0800210}
211
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800212void DisplayTransactionTest::injectMockComposer(int virtualDisplayCount) {
213 mComposer = new Hwc2::mock::Composer();
Lloyd Piquee39cad22017-12-20 17:01:29 -0800214 EXPECT_CALL(*mComposer, getMaxVirtualDisplayCount()).WillOnce(Return(virtualDisplayCount));
215 mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
Lloyd Piquef58625d2017-12-19 13:22:33 -0800216
Lloyd Piquee39cad22017-12-20 17:01:29 -0800217 Mock::VerifyAndClear(mComposer);
218}
219
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800220void DisplayTransactionTest::injectFakeBufferQueueFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800221 // This setup is only expected once per test.
222 ASSERT_TRUE(mConsumer == nullptr && mProducer == nullptr);
223
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800224 mConsumer = new mock::GraphicBufferConsumer();
225 mProducer = new mock::GraphicBufferProducer();
226
227 mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
228 *outProducer = mProducer;
229 *outConsumer = mConsumer;
230 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800231}
Lloyd Pique5b36f3f2018-01-17 11:57:07 -0800232
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800233void DisplayTransactionTest::injectFakeNativeWindowSurfaceFactory() {
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800234 // This setup is only expected once per test.
235 ASSERT_TRUE(mNativeWindowSurface == nullptr);
236
Lloyd Pique22098362018-09-13 11:46:49 -0700237 mNativeWindowSurface = new surfaceflinger::mock::NativeWindowSurface();
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800238
Lloyd Pique22098362018-09-13 11:46:49 -0700239 mFlinger.setCreateNativeWindowSurface([this](auto) {
240 return std::unique_ptr<surfaceflinger::NativeWindowSurface>(mNativeWindowSurface);
241 });
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800242}
243
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700244sp<DisplayDevice> DisplayTransactionTest::injectDefaultInternalDisplay(
245 std::function<void(FakeDisplayDeviceInjector&)> injectExtra) {
246 constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
247 constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
248 constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100249 constexpr hwc2_display_t DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700250
251 // The DisplayDevice is required to have a framebuffer (behind the
252 // ANativeWindow interface) which uses the actual hardware display
253 // size.
254 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
255 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
256 EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
257 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
258 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT));
259 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT));
260 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64));
261 EXPECT_CALL(*mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(AnyNumber());
262
263 auto compositionDisplay = compositionengine::impl::
264 createDisplay(mFlinger.getCompositionEngine(),
265 compositionengine::DisplayCreationArgsBuilder()
266 .setPhysical(
267 {DEFAULT_DISPLAY_ID, DisplayConnectionType::Internal})
268 .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
269 .setPowerAdvisor(&mPowerAdvisor)
270 .build());
271
272 auto injector =
273 FakeDisplayDeviceInjector(mFlinger, compositionDisplay, DisplayConnectionType::Internal,
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100274 DEFAULT_DISPLAY_HWC_DISPLAY_ID, true /* isPrimary */);
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700275
276 injector.setNativeWindow(mNativeWindow);
277 if (injectExtra) {
278 injectExtra(injector);
279 }
280
281 auto displayDevice = injector.inject();
282
283 Mock::VerifyAndClear(mNativeWindow.get());
284
285 return displayDevice;
286}
287
Dominik Laskowski075d3172018-05-24 15:50:06 -0700288bool DisplayTransactionTest::hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId) {
289 return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800290}
291
292bool DisplayTransactionTest::hasTransactionFlagSet(int flag) {
293 return mFlinger.mutableTransactionFlags() & flag;
294}
295
296bool DisplayTransactionTest::hasDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700297 return mFlinger.mutableDisplays().count(displayToken) == 1;
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800298}
299
300sp<DisplayDevice> DisplayTransactionTest::getDisplayDevice(sp<IBinder> displayToken) {
Dominik Laskowski9fae1022018-05-29 13:17:40 -0700301 return mFlinger.mutableDisplays()[displayToken];
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800302}
303
304bool DisplayTransactionTest::hasCurrentDisplayState(sp<IBinder> displayToken) {
305 return mFlinger.mutableCurrentState().displays.indexOfKey(displayToken) >= 0;
306}
307
308const DisplayDeviceState& DisplayTransactionTest::getCurrentDisplayState(sp<IBinder> displayToken) {
309 return mFlinger.mutableCurrentState().displays.valueFor(displayToken);
310}
311
312bool DisplayTransactionTest::hasDrawingDisplayState(sp<IBinder> displayToken) {
313 return mFlinger.mutableDrawingState().displays.indexOfKey(displayToken) >= 0;
314}
315
316const DisplayDeviceState& DisplayTransactionTest::getDrawingDisplayState(sp<IBinder> displayToken) {
317 return mFlinger.mutableDrawingState().displays.valueFor(displayToken);
318}
319
320/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800321 *
Lloyd Pique1fa4d462018-01-22 18:03:16 -0800322 */
323
Dominik Laskowski075d3172018-05-24 15:50:06 -0700324template <typename PhysicalDisplay>
325struct PhysicalDisplayId {};
326
Dominik Laskowski34157762018-10-31 13:07:19 -0700327template <DisplayId::Type displayId>
328using VirtualDisplayId = std::integral_constant<DisplayId::Type, displayId>;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700329
330struct NoDisplayId {};
331
332template <typename>
333struct IsPhysicalDisplayId : std::bool_constant<false> {};
334
335template <typename PhysicalDisplay>
336struct IsPhysicalDisplayId<PhysicalDisplayId<PhysicalDisplay>> : std::bool_constant<true> {};
337
338template <typename>
339struct DisplayIdGetter;
340
341template <typename PhysicalDisplay>
342struct DisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
343 static std::optional<DisplayId> get() {
344 if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
345 return getFallbackDisplayId(static_cast<bool>(PhysicalDisplay::PRIMARY)
346 ? HWC_DISPLAY_PRIMARY
347 : HWC_DISPLAY_EXTERNAL);
348 }
349
350 const auto info =
351 parseDisplayIdentificationData(PhysicalDisplay::PORT,
352 PhysicalDisplay::GET_IDENTIFICATION_DATA());
353 return info ? std::make_optional(info->id) : std::nullopt;
354 }
355};
356
Dominik Laskowski34157762018-10-31 13:07:19 -0700357template <DisplayId::Type displayId>
Dominik Laskowski075d3172018-05-24 15:50:06 -0700358struct DisplayIdGetter<VirtualDisplayId<displayId>> {
Dominik Laskowski34157762018-10-31 13:07:19 -0700359 static std::optional<DisplayId> get() { return DisplayId{displayId}; }
Dominik Laskowski075d3172018-05-24 15:50:06 -0700360};
361
362template <>
363struct DisplayIdGetter<NoDisplayId> {
364 static std::optional<DisplayId> get() { return {}; }
365};
366
Dominik Laskowski55c85402020-01-21 16:25:47 -0800367template <typename>
368struct DisplayConnectionTypeGetter {
369 static constexpr std::optional<DisplayConnectionType> value;
370};
371
372template <typename PhysicalDisplay>
373struct DisplayConnectionTypeGetter<PhysicalDisplayId<PhysicalDisplay>> {
374 static constexpr std::optional<DisplayConnectionType> value = PhysicalDisplay::CONNECTION_TYPE;
375};
376
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100377template <typename>
378struct HwcDisplayIdGetter {
379 static constexpr std::optional<hwc2_display_t> value;
380};
381
382constexpr hwc2_display_t HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
383
384template <DisplayId::Type displayId>
385struct HwcDisplayIdGetter<VirtualDisplayId<displayId>> {
386 static constexpr std::optional<hwc2_display_t> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
387};
388
389template <typename PhysicalDisplay>
390struct HwcDisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
391 static constexpr std::optional<hwc2_display_t> value = PhysicalDisplay::HWC_DISPLAY_ID;
392};
393
Dominik Laskowski075d3172018-05-24 15:50:06 -0700394// DisplayIdType can be:
395// 1) PhysicalDisplayId<...> for generated ID of physical display backed by HWC.
396// 2) VirtualDisplayId<...> for hard-coded ID of virtual display backed by HWC.
397// 3) NoDisplayId for virtual display without HWC backing.
398template <typename DisplayIdType, int width, int height, Critical critical, Async async,
399 Secure secure, Primary primary, int grallocUsage>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800400struct DisplayVariant {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700401 using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
Dominik Laskowski55c85402020-01-21 16:25:47 -0800402 using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100403 using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700404
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800405 // The display width and height
406 static constexpr int WIDTH = width;
407 static constexpr int HEIGHT = height;
408
409 static constexpr int GRALLOC_USAGE = grallocUsage;
410
Dominik Laskowski075d3172018-05-24 15:50:06 -0700411 // Whether the display is virtual or physical
412 static constexpr Virtual VIRTUAL =
413 IsPhysicalDisplayId<DisplayIdType>{} ? Virtual::FALSE : Virtual::TRUE;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800414
415 // When creating native window surfaces for the framebuffer, whether those should be critical
416 static constexpr Critical CRITICAL = critical;
417
418 // When creating native window surfaces for the framebuffer, whether those should be async
419 static constexpr Async ASYNC = async;
420
421 // Whether the display should be treated as secure
422 static constexpr Secure SECURE = secure;
423
Dominik Laskowski075d3172018-05-24 15:50:06 -0700424 // Whether the display is primary
425 static constexpr Primary PRIMARY = primary;
426
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800427 static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700428 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
429 if (auto displayId = DISPLAY_ID::get()) {
430 ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal});
431 } else {
432 ceDisplayArgs.setUseHwcVirtualDisplays(false);
433 }
434 ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build();
435
436 auto compositionDisplay =
437 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
438 ceDisplayArgs.build());
439
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100440 auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
441 CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
442 static_cast<bool>(PRIMARY));
Dominik Laskowski075d3172018-05-24 15:50:06 -0700443
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800444 injector.setSecure(static_cast<bool>(SECURE));
Alec Mouriba013fa2018-10-16 12:43:11 -0700445 injector.setNativeWindow(test->mNativeWindow);
446
447 // Creating a DisplayDevice requires getting default dimensions from the
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800448 // native window along with some other initial setup.
Alec Mouriba013fa2018-10-16 12:43:11 -0700449 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
450 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
451 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
452 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800453 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
454 .WillRepeatedly(Return(0));
455 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
456 .WillRepeatedly(Return(0));
457 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
458 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700459 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
460 .WillRepeatedly(Return(0));
461
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800462 return injector;
463 }
464
465 // Called by tests to set up any native window creation call expectations.
466 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
467 EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
468 .WillOnce(Return(test->mNativeWindow));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800469
Alec Mouriba013fa2018-10-16 12:43:11 -0700470 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
471 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
472 EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
473 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800474 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT))
475 .WillRepeatedly(Return(0));
476 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_CONNECT))
477 .WillRepeatedly(Return(0));
478 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_USAGE64))
479 .WillRepeatedly(Return(0));
chaviw8beb4142019-04-11 13:09:05 -0700480 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT))
481 .WillRepeatedly(Return(0));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800482 }
483
484 static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
485 EXPECT_CALL(*test->mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
486 EXPECT_CALL(*test->mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
487 EXPECT_CALL(*test->mConsumer, setConsumerUsageBits(GRALLOC_USAGE))
488 .WillRepeatedly(Return(NO_ERROR));
489 EXPECT_CALL(*test->mConsumer, setDefaultBufferSize(WIDTH, HEIGHT))
490 .WillRepeatedly(Return(NO_ERROR));
491 EXPECT_CALL(*test->mConsumer, setMaxAcquiredBufferCount(_))
492 .WillRepeatedly(Return(NO_ERROR));
493 }
494
495 static void setupFramebufferProducerBufferQueueCallExpectations(DisplayTransactionTest* test) {
496 EXPECT_CALL(*test->mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
497 }
498};
499
Dominik Laskowski075d3172018-05-24 15:50:06 -0700500template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant,
501 typename PhysicalDisplay = void>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800502struct HwcDisplayVariant {
503 // The display id supplied by the HWC
504 static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
505
506 // The HWC display type
507 static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
508
509 // The HWC active configuration id
Lloyd Pique3c085a02018-05-09 19:38:32 -0700510 static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700511 static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800512
513 static void injectPendingHotplugEvent(DisplayTransactionTest* test,
514 HWC2::Connection connection) {
515 test->mFlinger.mutablePendingHotplugEvents().emplace_back(
516 HotplugEvent{HWC_DISPLAY_ID, connection});
517 }
518
519 // Called by tests to inject a HWC display setup
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800520 static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
Dominik Laskowski075d3172018-05-24 15:50:06 -0700521 const auto displayId = DisplayVariant::DISPLAY_ID::get();
522 ASSERT_TRUE(displayId);
523 FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
524 static_cast<bool>(DisplayVariant::PRIMARY))
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800525 .setHwcDisplayId(HWC_DISPLAY_ID)
526 .setWidth(DisplayVariant::WIDTH)
527 .setHeight(DisplayVariant::HEIGHT)
528 .setActiveConfig(HWC_ACTIVE_CONFIG_ID)
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700529 .setPowerMode(INIT_POWER_MODE)
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800530 .inject(&test->mFlinger, test->mComposer);
531 }
532
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800533 // Called by tests to inject a HWC display setup
534 static void injectHwcDisplay(DisplayTransactionTest* test) {
535 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
536 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
537 Return(Error::NONE)));
Peiyong Lin1336e6e2019-05-28 09:23:50 -0700538 EXPECT_CALL(*test->mComposer,
539 setPowerMode(HWC_DISPLAY_ID,
540 static_cast<Hwc2::IComposerClient::PowerMode>(INIT_POWER_MODE)))
541 .WillOnce(Return(Error::NONE));
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800542 injectHwcDisplayWithNoDefaultCapabilities(test);
543 }
544
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700545 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
546 DisplayTransactionTest* test) {
547 const ::testing::TestInfo* const test_info =
548 ::testing::UnitTest::GetInstance()->current_test_info();
549
550 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
551 .setPhysical({*DisplayVariant::DISPLAY_ID::get(),
552 PhysicalDisplay::CONNECTION_TYPE})
553 .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
554 .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
555 .setPowerAdvisor(&test->mPowerAdvisor)
556 .setName(std::string("Injected display for ") +
557 test_info->test_case_name() + "." + test_info->name())
558 .build();
559
560 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
561 ceDisplayArgs);
562 }
563
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800564 static void setupHwcHotplugCallExpectations(DisplayTransactionTest* test) {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800565 constexpr auto CONNECTION_TYPE =
566 PhysicalDisplay::CONNECTION_TYPE == DisplayConnectionType::Internal
567 ? IComposerClient::DisplayConnectionType::INTERNAL
568 : IComposerClient::DisplayConnectionType::EXTERNAL;
569
570 EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
571 .WillOnce(
572 DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(Hwc2::V2_4::Error::NONE)));
573
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800574 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
575 EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
576 .WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
577 Return(Error::NONE)));
578 EXPECT_CALL(*test->mComposer,
579 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
580 IComposerClient::Attribute::WIDTH, _))
581 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::WIDTH), Return(Error::NONE)));
582 EXPECT_CALL(*test->mComposer,
583 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
584 IComposerClient::Attribute::HEIGHT, _))
585 .WillOnce(DoAll(SetArgPointee<3>(DisplayVariant::HEIGHT), Return(Error::NONE)));
586 EXPECT_CALL(*test->mComposer,
587 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
588 IComposerClient::Attribute::VSYNC_PERIOD, _))
589 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
590 EXPECT_CALL(*test->mComposer,
591 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
592 IComposerClient::Attribute::DPI_X, _))
593 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
594 EXPECT_CALL(*test->mComposer,
595 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
596 IComposerClient::Attribute::DPI_Y, _))
597 .WillOnce(DoAll(SetArgPointee<3>(DEFAULT_DPI), Return(Error::NONE)));
Ady Abraham7159f572019-10-11 11:10:18 -0700598 EXPECT_CALL(*test->mComposer,
599 getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
600 IComposerClient::Attribute::CONFIG_GROUP, _))
601 .WillOnce(DoAll(SetArgPointee<3>(-1), Return(Error::NONE)));
Dominik Laskowski075d3172018-05-24 15:50:06 -0700602
603 if (PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
604 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
605 .WillOnce(DoAll(SetArgPointee<1>(PhysicalDisplay::PORT),
606 SetArgPointee<2>(PhysicalDisplay::GET_IDENTIFICATION_DATA()),
607 Return(Error::NONE)));
608 } else {
609 EXPECT_CALL(*test->mComposer, getDisplayIdentificationData(HWC_DISPLAY_ID, _, _))
610 .WillOnce(Return(Error::UNSUPPORTED));
611 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800612 }
613
614 // Called by tests to set up HWC call expectations
615 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
616 EXPECT_CALL(*test->mComposer, getActiveConfig(HWC_DISPLAY_ID, _))
Lloyd Pique3c085a02018-05-09 19:38:32 -0700617 .WillRepeatedly(DoAll(SetArgPointee<1>(HWC_ACTIVE_CONFIG_ID), Return(Error::NONE)));
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800618 }
619};
620
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800621// Physical displays are expected to be synchronous, secure, and have a HWC display for output.
622constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
623 GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
624
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100625template <typename PhysicalDisplay, int width, int height, Critical critical>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800626struct PhysicalDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700627 : DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height, critical, Async::FALSE,
628 Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100629 HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, HWC2::DisplayType::Physical,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700630 DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height,
631 critical, Async::FALSE, Secure::TRUE,
632 PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
633 PhysicalDisplay> {};
634
635template <bool hasIdentificationData>
636struct PrimaryDisplay {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800637 static constexpr auto CONNECTION_TYPE = DisplayConnectionType::Internal;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700638 static constexpr Primary PRIMARY = Primary::TRUE;
639 static constexpr uint8_t PORT = 255;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100640 static constexpr hwc2_display_t HWC_DISPLAY_ID = 1001;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700641 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
642 static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
643};
644
645template <bool hasIdentificationData>
646struct ExternalDisplay {
Dominik Laskowski55c85402020-01-21 16:25:47 -0800647 static constexpr auto CONNECTION_TYPE = DisplayConnectionType::External;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700648 static constexpr Primary PRIMARY = Primary::FALSE;
649 static constexpr uint8_t PORT = 254;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100650 static constexpr hwc2_display_t HWC_DISPLAY_ID = 1002;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700651 static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
652 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
653};
654
655struct TertiaryDisplay {
656 static constexpr Primary PRIMARY = Primary::FALSE;
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800657 static constexpr uint8_t PORT = 253;
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100658 static constexpr hwc2_display_t HWC_DISPLAY_ID = 1003;
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800659 static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
Dominik Laskowski075d3172018-05-24 15:50:06 -0700660};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800661
662// A primary display is a physical display that is critical
663using PrimaryDisplayVariant =
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100664 PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800665
666// An external display is physical display that is not critical.
667using ExternalDisplayVariant =
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100668 PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800669
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100670using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800671
672// A virtual display not supported by the HWC.
673constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
674
675template <int width, int height, Secure secure>
676struct NonHwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700677 : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
678 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
679 using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
680 Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
681
682 static void injectHwcDisplay(DisplayTransactionTest*) {}
683
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700684 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
685 DisplayTransactionTest* test) {
686 const ::testing::TestInfo* const test_info =
687 ::testing::UnitTest::GetInstance()->current_test_info();
688
689 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
690 .setPixels({Base::WIDTH, Base::HEIGHT})
691 .setIsSecure(static_cast<bool>(Base::SECURE))
692 .setPowerAdvisor(&test->mPowerAdvisor)
693 .setName(std::string("Injected display for ") +
694 test_info->test_case_name() + "." + test_info->name())
695 .build();
696
697 return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
698 ceDisplayArgs);
699 }
700
Dominik Laskowski075d3172018-05-24 15:50:06 -0700701 static void setupHwcGetActiveConfigCallExpectations(DisplayTransactionTest* test) {
702 EXPECT_CALL(*test->mComposer, getActiveConfig(_, _)).Times(0);
703 }
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800704
705 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
706 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
707 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
708 }
709};
710
711// A virtual display supported by the HWC.
712constexpr uint32_t GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY = GRALLOC_USAGE_HW_COMPOSER;
713
714template <int width, int height, Secure secure>
715struct HwcVirtualDisplayVariant
Dominik Laskowski075d3172018-05-24 15:50:06 -0700716 : DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE, secure,
717 Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
718 HwcDisplayVariant<
Marin Shalamanov4a42d432020-02-12 20:22:26 +0100719 HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, HWC2::DisplayType::Virtual,
Dominik Laskowski075d3172018-05-24 15:50:06 -0700720 DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
721 secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
722 using Base = DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
723 secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800724 using Self = HwcVirtualDisplayVariant<width, height, secure>;
725
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -0700726 static std::shared_ptr<compositionengine::Display> injectCompositionDisplay(
727 DisplayTransactionTest* test) {
728 const ::testing::TestInfo* const test_info =
729 ::testing::UnitTest::GetInstance()->current_test_info();
730
731 auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
732 .setUseHwcVirtualDisplays(false)
733 .setPixels({Base::WIDTH, Base::HEIGHT})
734 .setIsSecure(static_cast<bool>(Base::SECURE))
735 .setPowerAdvisor(&test->mPowerAdvisor)
736 .setName(std::string("Injected display for ") +
737 test_info->test_case_name() + "." + test_info->name())
738 .build();
739
740 auto compositionDisplay =
741 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
742 ceDisplayArgs);
743 compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
744
745 // Insert display data so that the HWC thinks it created the virtual display.
746 if (const auto displayId = Base::DISPLAY_ID::get()) {
747 test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
748 }
749
750 return compositionDisplay;
751 }
752
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800753 static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
754 Base::setupNativeWindowSurfaceCreationCallExpectations(test);
755 EXPECT_CALL(*test->mNativeWindow, setSwapInterval(0)).Times(1);
756 }
757
758 static void setupHwcVirtualDisplayCreationCallExpectations(DisplayTransactionTest* test) {
759 EXPECT_CALL(*test->mComposer, createVirtualDisplay(Base::WIDTH, Base::HEIGHT, _, _))
760 .WillOnce(DoAll(SetArgPointee<3>(Self::HWC_DISPLAY_ID), Return(Error::NONE)));
761 EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
762 }
763};
764
765// For this variant, SurfaceFlinger should not configure itself with wide
766// display support, so the display should not be configured for wide-color
767// support.
768struct WideColorSupportNotConfiguredVariant {
769 static constexpr bool WIDE_COLOR_SUPPORTED = false;
770
771 static void injectConfigChange(DisplayTransactionTest* test) {
772 test->mFlinger.mutableHasWideColorDisplay() = false;
Peiyong Lin13effd12018-07-24 17:01:47 -0700773 test->mFlinger.mutableUseColorManagement() = false;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800774 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800775 }
776
777 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
778 EXPECT_CALL(*test->mComposer, getColorModes(_, _)).Times(0);
779 EXPECT_CALL(*test->mComposer, getRenderIntents(_, _, _)).Times(0);
780 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
781 }
782};
783
784// For this variant, SurfaceFlinger should configure itself with wide display
785// support, and the display should respond with an non-empty list of supported
786// color modes. Wide-color support should be configured.
787template <typename Display>
788struct WideColorP3ColorimetricSupportedVariant {
789 static constexpr bool WIDE_COLOR_SUPPORTED = true;
790
791 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700792 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800793 test->mFlinger.mutableHasWideColorDisplay() = true;
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800794 test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::kUnmanaged;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800795 }
796
797 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -0800798 EXPECT_CALL(*test->mNativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_DATASPACE)).Times(1);
799
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800800 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
801 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::DISPLAY_P3})),
802 Return(Error::NONE)));
803 EXPECT_CALL(*test->mComposer,
804 getRenderIntents(Display::HWC_DISPLAY_ID, ColorMode::DISPLAY_P3, _))
805 .WillOnce(DoAll(SetArgPointee<2>(
806 std::vector<RenderIntent>({RenderIntent::COLORIMETRIC})),
807 Return(Error::NONE)));
808 EXPECT_CALL(*test->mComposer,
809 setColorMode(Display::HWC_DISPLAY_ID, ColorMode::SRGB,
810 RenderIntent::COLORIMETRIC))
811 .WillOnce(Return(Error::NONE));
812 }
813};
814
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800815// For this variant, SurfaceFlinger should configure itself with wide display
816// support, but the display should respond with an empty list of supported color
817// modes. Wide-color support for the display should not be configured.
818template <typename Display>
819struct WideColorNotSupportedVariant {
820 static constexpr bool WIDE_COLOR_SUPPORTED = false;
821
822 static void injectConfigChange(DisplayTransactionTest* test) {
Peiyong Lin13effd12018-07-24 17:01:47 -0700823 test->mFlinger.mutableUseColorManagement() = true;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800824 test->mFlinger.mutableHasWideColorDisplay() = true;
825 }
826
827 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
828 EXPECT_CALL(*test->mComposer, getColorModes(Display::HWC_DISPLAY_ID, _))
829 .WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>()), Return(Error::NONE)));
Chia-I Wu614e1422018-05-23 02:17:03 -0700830 EXPECT_CALL(*test->mComposer, setColorMode(_, _, _)).Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800831 }
832};
833
834// For this variant, the display is not a HWC display, so no HDR support should
835// be configured.
836struct NonHwcDisplayHdrSupportVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800837 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800838 static constexpr bool HDR10_SUPPORTED = false;
839 static constexpr bool HDR_HLG_SUPPORTED = false;
840 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
841 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
842 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _)).Times(0);
843 }
844};
845
Valerie Haue9e843a2018-12-18 13:39:23 -0800846template <typename Display>
847struct Hdr10PlusSupportedVariant {
848 static constexpr bool HDR10_PLUS_SUPPORTED = true;
849 static constexpr bool HDR10_SUPPORTED = true;
850 static constexpr bool HDR_HLG_SUPPORTED = false;
851 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
852 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
853 EXPECT_CALL(*test->mComposer, getHdrCapabilities(_, _, _, _, _))
854 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({
855 Hdr::HDR10_PLUS,
856 Hdr::HDR10,
857 })),
858 Return(Error::NONE)));
859 }
860};
861
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800862// For this variant, the composer should respond with a non-empty list of HDR
863// modes containing HDR10, so HDR10 support should be configured.
864template <typename Display>
865struct Hdr10SupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800866 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800867 static constexpr bool HDR10_SUPPORTED = true;
868 static constexpr bool HDR_HLG_SUPPORTED = false;
869 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
870 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
871 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
872 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HDR10})),
873 Return(Error::NONE)));
874 }
875};
876
877// For this variant, the composer should respond with a non-empty list of HDR
878// modes containing HLG, so HLG support should be configured.
879template <typename Display>
880struct HdrHlgSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800881 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800882 static constexpr bool HDR10_SUPPORTED = false;
883 static constexpr bool HDR_HLG_SUPPORTED = true;
884 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
885 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
886 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
887 .WillOnce(
888 DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::HLG})), Return(Error::NONE)));
889 }
890};
891
892// For this variant, the composer should respond with a non-empty list of HDR
893// modes containing DOLBY_VISION, so DOLBY_VISION support should be configured.
894template <typename Display>
895struct HdrDolbyVisionSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800896 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800897 static constexpr bool HDR10_SUPPORTED = false;
898 static constexpr bool HDR_HLG_SUPPORTED = false;
899 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = true;
900 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
901 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
902 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>({Hdr::DOLBY_VISION})),
903 Return(Error::NONE)));
904 }
905};
906
907// For this variant, the composer should respond with am empty list of HDR
908// modes, so no HDR support should be configured.
909template <typename Display>
910struct HdrNotSupportedVariant {
Valerie Haue9e843a2018-12-18 13:39:23 -0800911 static constexpr bool HDR10_PLUS_SUPPORTED = false;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800912 static constexpr bool HDR10_SUPPORTED = false;
913 static constexpr bool HDR_HLG_SUPPORTED = false;
914 static constexpr bool HDR_DOLBY_VISION_SUPPORTED = false;
915 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
916 EXPECT_CALL(*test->mComposer, getHdrCapabilities(Display::HWC_DISPLAY_ID, _, _, _, _))
917 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
918 }
919};
920
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700921struct NonHwcPerFrameMetadataSupportVariant {
922 static constexpr int PER_FRAME_METADATA_KEYS = 0;
923 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800924 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(_)).Times(0);
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700925 }
926};
927
928template <typename Display>
929struct NoPerFrameMetadataSupportVariant {
930 static constexpr int PER_FRAME_METADATA_KEYS = 0;
931 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800932 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
933 .WillOnce(Return(std::vector<PerFrameMetadataKey>()));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700934 }
935};
936
937template <typename Display>
938struct Smpte2086PerFrameMetadataSupportVariant {
939 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::SMPTE2086;
940 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800941 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
942 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800943 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
944 PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
945 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
946 PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
947 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
948 PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
949 PerFrameMetadataKey::WHITE_POINT_X,
950 PerFrameMetadataKey::WHITE_POINT_Y,
951 PerFrameMetadataKey::MAX_LUMINANCE,
952 PerFrameMetadataKey::MIN_LUMINANCE,
953 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700954 }
955};
956
957template <typename Display>
958struct Cta861_3_PerFrameMetadataSupportVariant {
959 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::CTA861_3;
960 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
Chia-I Wud7e01d72018-06-21 13:39:09 +0800961 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
962 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
Valerie Haue9e843a2018-12-18 13:39:23 -0800963 PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
964 PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
965 })));
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700966 }
967};
968
Valerie Haue9e843a2018-12-18 13:39:23 -0800969template <typename Display>
970struct Hdr10_Plus_PerFrameMetadataSupportVariant {
971 static constexpr int PER_FRAME_METADATA_KEYS = HdrMetadata::Type::HDR10PLUS;
972 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
973 EXPECT_CALL(*test->mComposer, getPerFrameMetadataKeys(Display::HWC_DISPLAY_ID))
974 .WillOnce(Return(std::vector<PerFrameMetadataKey>({
975 PerFrameMetadataKey::HDR10_PLUS_SEI,
976 })));
977 }
978};
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800979/* ------------------------------------------------------------------------
980 * Typical display configurations to test
981 */
982
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700983template <typename DisplayPolicy, typename WideColorSupportPolicy, typename HdrSupportPolicy,
984 typename PerFrameMetadataSupportPolicy>
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800985struct Case {
986 using Display = DisplayPolicy;
987 using WideColorSupport = WideColorSupportPolicy;
988 using HdrSupport = HdrSupportPolicy;
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700989 using PerFrameMetadataSupport = PerFrameMetadataSupportPolicy;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800990};
991
992using SimplePrimaryDisplayCase =
993 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700994 HdrNotSupportedVariant<PrimaryDisplayVariant>,
995 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -0800996using SimpleExternalDisplayCase =
997 Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -0700998 HdrNotSupportedVariant<ExternalDisplayVariant>,
999 NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001000using SimpleTertiaryDisplayCase =
1001 Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001002 HdrNotSupportedVariant<TertiaryDisplayVariant>,
1003 NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001004using NonHwcVirtualDisplayCase =
1005 Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001006 WideColorSupportNotConfiguredVariant, NonHwcDisplayHdrSupportVariant,
1007 NonHwcPerFrameMetadataSupportVariant>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001008using SimpleHwcVirtualDisplayVariant = HwcVirtualDisplayVariant<1024, 768, Secure::TRUE>;
1009using HwcVirtualDisplayCase =
1010 Case<SimpleHwcVirtualDisplayVariant, WideColorSupportNotConfiguredVariant,
Lloyd Pique438e9e72018-09-04 18:06:08 -07001011 HdrNotSupportedVariant<SimpleHwcVirtualDisplayVariant>,
tangrobin6753a022018-08-10 10:58:54 +08001012 NoPerFrameMetadataSupportVariant<SimpleHwcVirtualDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001013using WideColorP3ColorimetricDisplayCase =
1014 Case<PrimaryDisplayVariant, WideColorP3ColorimetricSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001015 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1016 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Valerie Haue9e843a2018-12-18 13:39:23 -08001017using Hdr10PlusDisplayCase =
1018 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1019 Hdr10SupportedVariant<PrimaryDisplayVariant>,
1020 Hdr10_Plus_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001021using Hdr10DisplayCase =
1022 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001023 Hdr10SupportedVariant<PrimaryDisplayVariant>,
1024 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001025using HdrHlgDisplayCase =
1026 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001027 HdrHlgSupportedVariant<PrimaryDisplayVariant>,
1028 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001029using HdrDolbyVisionDisplayCase =
1030 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001031 HdrDolbyVisionSupportedVariant<PrimaryDisplayVariant>,
1032 NoPerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
1033using HdrSmpte2086DisplayCase =
1034 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1035 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1036 Smpte2086PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
1037using HdrCta861_3_DisplayCase =
1038 Case<PrimaryDisplayVariant, WideColorNotSupportedVariant<PrimaryDisplayVariant>,
1039 HdrNotSupportedVariant<PrimaryDisplayVariant>,
1040 Cta861_3_PerFrameMetadataSupportVariant<PrimaryDisplayVariant>>;
Dominik Laskowskif07b85b2018-06-11 12:49:15 -07001041
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001042/* ------------------------------------------------------------------------
Lloyd Pique6cf11032018-01-22 18:57:44 -08001043 *
1044 * SurfaceFlinger::onHotplugReceived
1045 */
1046
1047TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
1048 constexpr int currentSequenceId = 123;
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001049 constexpr hwc2_display_t hwcDisplayId1 = 456;
1050 constexpr hwc2_display_t hwcDisplayId2 = 654;
Lloyd Pique6cf11032018-01-22 18:57:44 -08001051
1052 // --------------------------------------------------------------------
1053 // Preconditions
1054
1055 // Set the current sequence id for accepted events
1056 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1057
1058 // Set the main thread id so that the current thread does not appear to be
1059 // the main thread.
1060 mFlinger.mutableMainThreadId() = std::thread::id();
1061
1062 // --------------------------------------------------------------------
1063 // Call Expectations
1064
1065 // We expect invalidate() to be invoked once to trigger display transaction
1066 // processing.
1067 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1068
1069 // --------------------------------------------------------------------
1070 // Invocation
1071
1072 // Simulate two hotplug events (a connect and a disconnect)
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001073 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, HWC2::Connection::Connected);
1074 mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, HWC2::Connection::Disconnected);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001075
1076 // --------------------------------------------------------------------
1077 // Postconditions
1078
1079 // The display transaction needed flag should be set.
1080 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1081
1082 // All events should be in the pending event queue.
1083 const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
1084 ASSERT_EQ(2u, pendingEvents.size());
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001085 EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001086 EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
Dominik Laskowskia2edf612018-06-01 13:15:16 -07001087 EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
Lloyd Pique6cf11032018-01-22 18:57:44 -08001088 EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
1089}
1090
1091TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
1092 constexpr int currentSequenceId = 123;
1093 constexpr int otherSequenceId = 321;
1094 constexpr hwc2_display_t displayId = 456;
1095
1096 // --------------------------------------------------------------------
1097 // Preconditions
1098
1099 // Set the current sequence id for accepted events
1100 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1101
1102 // Set the main thread id so that the current thread does not appear to be
1103 // the main thread.
1104 mFlinger.mutableMainThreadId() = std::thread::id();
1105
1106 // --------------------------------------------------------------------
1107 // Call Expectations
1108
1109 // We do not expect any calls to invalidate().
1110 EXPECT_CALL(*mMessageQueue, invalidate()).Times(0);
1111
1112 // --------------------------------------------------------------------
1113 // Invocation
1114
1115 // Call with an unexpected sequence id
1116 mFlinger.onHotplugReceived(otherSequenceId, displayId, HWC2::Connection::Invalid);
1117
1118 // --------------------------------------------------------------------
1119 // Postconditions
1120
1121 // The display transaction needed flag should not be set
1122 EXPECT_FALSE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1123
1124 // There should be no pending events
1125 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
1126}
1127
1128TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
1129 constexpr int currentSequenceId = 123;
1130 constexpr hwc2_display_t displayId1 = 456;
1131
1132 // --------------------------------------------------------------------
1133 // Note:
1134 // --------------------------------------------------------------------
1135 // This test case is a bit tricky. We want to verify that
1136 // onHotplugReceived() calls processDisplayHotplugEventsLocked(), but we
1137 // don't really want to provide coverage for everything the later function
1138 // does as there are specific tests for it.
1139 // --------------------------------------------------------------------
1140
1141 // --------------------------------------------------------------------
1142 // Preconditions
1143
1144 // Set the current sequence id for accepted events
1145 mFlinger.mutableComposerSequenceId() = currentSequenceId;
1146
1147 // Set the main thread id so that the current thread does appear to be the
1148 // main thread.
1149 mFlinger.mutableMainThreadId() = std::this_thread::get_id();
1150
1151 // --------------------------------------------------------------------
1152 // Call Expectations
1153
1154 // We expect invalidate() to be invoked once to trigger display transaction
1155 // processing.
1156 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1157
1158 // --------------------------------------------------------------------
1159 // Invocation
1160
1161 // Simulate a disconnect on a display id that is not connected. This should
1162 // be enqueued by onHotplugReceived(), and dequeued by
1163 // processDisplayHotplugEventsLocked(), but then ignored as invalid.
1164 mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Disconnected);
1165
1166 // --------------------------------------------------------------------
1167 // Postconditions
1168
1169 // The display transaction needed flag should be set.
1170 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1171
1172 // There should be no event queued on return, as it should have been
1173 // processed.
1174 EXPECT_TRUE(mFlinger.mutablePendingHotplugEvents().empty());
1175}
1176
1177/* ------------------------------------------------------------------------
Lloyd Piquea482f992018-01-22 19:00:34 -08001178 * SurfaceFlinger::createDisplay
1179 */
1180
1181TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForNonsecureDisplay) {
1182 const String8 name("virtual.test");
1183
1184 // --------------------------------------------------------------------
1185 // Call Expectations
1186
1187 // The call should notify the interceptor that a display was created.
1188 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1189
1190 // --------------------------------------------------------------------
1191 // Invocation
1192
1193 sp<IBinder> displayToken = mFlinger.createDisplay(name, false);
1194
1195 // --------------------------------------------------------------------
1196 // Postconditions
1197
1198 // The display should have been added to the current state
1199 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1200 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001201 EXPECT_TRUE(display.isVirtual());
1202 EXPECT_FALSE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001203 EXPECT_EQ(name.string(), display.displayName);
1204
1205 // --------------------------------------------------------------------
1206 // Cleanup conditions
1207
1208 // Destroying the display invalidates the display state.
1209 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1210}
1211
1212TEST_F(DisplayTransactionTest, createDisplaySetsCurrentStateForSecureDisplay) {
1213 const String8 name("virtual.test");
1214
1215 // --------------------------------------------------------------------
1216 // Call Expectations
1217
1218 // The call should notify the interceptor that a display was created.
1219 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
1220
1221 // --------------------------------------------------------------------
1222 // Invocation
1223
1224 sp<IBinder> displayToken = mFlinger.createDisplay(name, true);
1225
1226 // --------------------------------------------------------------------
1227 // Postconditions
1228
1229 // The display should have been added to the current state
1230 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1231 const auto& display = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001232 EXPECT_TRUE(display.isVirtual());
1233 EXPECT_TRUE(display.isSecure);
Lloyd Piquea482f992018-01-22 19:00:34 -08001234 EXPECT_EQ(name.string(), display.displayName);
1235
1236 // --------------------------------------------------------------------
1237 // Cleanup conditions
1238
1239 // Destroying the display invalidates the display state.
1240 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1241}
1242
1243/* ------------------------------------------------------------------------
1244 * SurfaceFlinger::destroyDisplay
1245 */
1246
1247TEST_F(DisplayTransactionTest, destroyDisplayClearsCurrentStateForDisplay) {
1248 using Case = NonHwcVirtualDisplayCase;
1249
1250 // --------------------------------------------------------------------
1251 // Preconditions
1252
1253 // A virtual display exists
1254 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1255 existing.inject();
1256
1257 // --------------------------------------------------------------------
1258 // Call Expectations
1259
1260 // The call should notify the interceptor that a display was created.
1261 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
1262
1263 // Destroying the display invalidates the display state.
1264 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
1265
1266 // --------------------------------------------------------------------
1267 // Invocation
1268
1269 mFlinger.destroyDisplay(existing.token());
1270
1271 // --------------------------------------------------------------------
1272 // Postconditions
1273
1274 // The display should have been removed from the current state
1275 EXPECT_FALSE(hasCurrentDisplayState(existing.token()));
1276
1277 // Ths display should still exist in the drawing state
1278 EXPECT_TRUE(hasDrawingDisplayState(existing.token()));
1279
1280 // The display transaction needed flasg should be set
1281 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
1282}
1283
1284TEST_F(DisplayTransactionTest, destroyDisplayHandlesUnknownDisplay) {
1285 // --------------------------------------------------------------------
1286 // Preconditions
1287
1288 sp<BBinder> displayToken = new BBinder();
1289
1290 // --------------------------------------------------------------------
1291 // Invocation
1292
1293 mFlinger.destroyDisplay(displayToken);
1294}
1295
1296/* ------------------------------------------------------------------------
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001297 * SurfaceFlinger::resetDisplayState
1298 */
1299
1300TEST_F(DisplayTransactionTest, resetDisplayStateClearsState) {
1301 using Case = NonHwcVirtualDisplayCase;
1302
1303 // --------------------------------------------------------------------
1304 // Preconditions
1305
1306 // vsync is enabled and available
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001307 mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = true;
1308 mFlinger.scheduler()->mutableHWVsyncAvailable() = true;
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001309
1310 // A display exists
1311 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
1312 existing.inject();
1313
1314 // --------------------------------------------------------------------
1315 // Call Expectations
1316
1317 // The call disable vsyncs
1318 EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
1319
Lloyd Pique41be5d22018-06-21 13:11:48 -07001320 // The call ends any display resyncs
1321 EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
1322
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001323 // --------------------------------------------------------------------
1324 // Invocation
1325
1326 mFlinger.resetDisplayState();
1327
1328 // --------------------------------------------------------------------
1329 // Postconditions
1330
1331 // vsyncs should be off and not available.
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07001332 EXPECT_FALSE(mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled());
1333 EXPECT_FALSE(mFlinger.scheduler()->mutableHWVsyncAvailable());
Lloyd Piqued6fbb8a2018-01-22 19:08:36 -08001334
1335 // The display should have been removed from the display map.
1336 EXPECT_FALSE(hasDisplayDevice(existing.token()));
1337
1338 // The display should still exist in the current state
1339 EXPECT_TRUE(hasCurrentDisplayState(existing.token()));
1340
1341 // The display should have been removed from the drawing state
1342 EXPECT_FALSE(hasDrawingDisplayState(existing.token()));
1343}
1344
1345/* ------------------------------------------------------------------------
Valerie Hau9758ae02018-10-09 16:05:09 -07001346 * DisplayDevice::GetBestColorMode
1347 */
1348class GetBestColorModeTest : public DisplayTransactionTest {
1349public:
Valerie Hau9758ae02018-10-09 16:05:09 -07001350 void setHasWideColorGamut(bool hasWideColorGamut) { mHasWideColorGamut = hasWideColorGamut; }
1351
1352 void addHwcColorModesMapping(ui::ColorMode colorMode,
1353 std::vector<ui::RenderIntent> renderIntents) {
1354 mHwcColorModes[colorMode] = renderIntents;
1355 }
1356
1357 void setInputDataspace(ui::Dataspace dataspace) { mInputDataspace = dataspace; }
1358
1359 void setInputRenderIntent(ui::RenderIntent renderIntent) { mInputRenderIntent = renderIntent; }
1360
1361 void getBestColorMode() {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001362 auto displayDevice =
1363 injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) {
1364 injector.setHwcColorModes(mHwcColorModes);
1365 injector.setHasWideColorGamut(mHasWideColorGamut);
1366 injector.setNativeWindow(mNativeWindow);
1367 });
Valerie Hau9758ae02018-10-09 16:05:09 -07001368
Lloyd Pique3d0c02e2018-10-19 18:38:12 -07001369 displayDevice->getCompositionDisplay()
1370 ->getDisplayColorProfile()
1371 ->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace,
1372 &mOutColorMode, &mOutRenderIntent);
Valerie Hau9758ae02018-10-09 16:05:09 -07001373 }
1374
1375 ui::Dataspace mOutDataspace;
1376 ui::ColorMode mOutColorMode;
1377 ui::RenderIntent mOutRenderIntent;
1378
1379private:
1380 ui::Dataspace mInputDataspace;
1381 ui::RenderIntent mInputRenderIntent;
1382 bool mHasWideColorGamut = false;
1383 std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> mHwcColorModes;
Valerie Hau9758ae02018-10-09 16:05:09 -07001384};
1385
1386TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeSRGB) {
1387 addHwcColorModesMapping(ui::ColorMode::SRGB,
1388 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1389 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1390 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1391 setHasWideColorGamut(true);
1392
1393 getBestColorMode();
1394
Peiyong Lin14724e62018-12-05 07:27:30 -08001395 ASSERT_EQ(ui::Dataspace::V0_SRGB, mOutDataspace);
Valerie Hau9758ae02018-10-09 16:05:09 -07001396 ASSERT_EQ(ui::ColorMode::SRGB, mOutColorMode);
1397 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1398}
1399
1400TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDisplayP3) {
1401 addHwcColorModesMapping(ui::ColorMode::DISPLAY_P3,
1402 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1403 addHwcColorModesMapping(ui::ColorMode::SRGB,
1404 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1405 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1406 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1407 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1408 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1409 setHasWideColorGamut(true);
1410
1411 getBestColorMode();
1412
1413 ASSERT_EQ(ui::Dataspace::DISPLAY_P3, mOutDataspace);
1414 ASSERT_EQ(ui::ColorMode::DISPLAY_P3, mOutColorMode);
1415 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1416}
1417
1418TEST_F(GetBestColorModeTest, DataspaceDisplayP3_ColorModeDISPLAY_BT2020) {
1419 addHwcColorModesMapping(ui::ColorMode::DISPLAY_BT2020,
1420 std::vector<ui::RenderIntent>(1, RenderIntent::COLORIMETRIC));
1421 setInputDataspace(ui::Dataspace::DISPLAY_P3);
1422 setInputRenderIntent(ui::RenderIntent::COLORIMETRIC);
1423 setHasWideColorGamut(true);
1424
1425 getBestColorMode();
1426
1427 ASSERT_EQ(ui::Dataspace::DISPLAY_BT2020, mOutDataspace);
1428 ASSERT_EQ(ui::ColorMode::DISPLAY_BT2020, mOutColorMode);
1429 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mOutRenderIntent);
1430}
1431
1432/* ------------------------------------------------------------------------
Lloyd Pique33050472019-12-19 17:12:44 -08001433 * DisplayDevice::setProjection
1434 */
1435
1436class DisplayDeviceSetProjectionTest : public DisplayTransactionTest {
1437public:
Lloyd Pique33050472019-12-19 17:12:44 -08001438 static constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1080; // arbitrary
1439 static constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1920; // arbitrary
1440
1441 static constexpr int32_t TRANSFORM_FLAGS_ROT_0 = 0;
1442 static constexpr int32_t TRANSFORM_FLAGS_ROT_90 = HAL_TRANSFORM_ROT_90;
1443 static constexpr int32_t TRANSFORM_FLAGS_ROT_180 = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_FLIP_V;
1444 static constexpr int32_t TRANSFORM_FLAGS_ROT_270 =
1445 HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1446
1447 DisplayDeviceSetProjectionTest(ui::Size flingerDisplaySize, ui::Size hardwareDisplaySize,
1448 ui::Rotation physicalOrientation)
1449 : mFlingerDisplaySize(flingerDisplaySize),
1450 mHardwareDisplaySize(hardwareDisplaySize),
1451 mPhysicalOrientation(physicalOrientation),
1452 mDisplayDevice(createDisplayDevice()) {}
1453
1454 sp<DisplayDevice> createDisplayDevice() {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001455 return injectDefaultInternalDisplay([this](FakeDisplayDeviceInjector& injector) {
1456 injector.setPhysicalOrientation(mPhysicalOrientation);
1457 });
Lloyd Pique33050472019-12-19 17:12:44 -08001458 }
1459
1460 ui::Size SwapWH(const ui::Size size) const { return ui::Size(size.height, size.width); }
1461
1462 void setProjectionForRotation0() {
1463 // A logical rotation of 0 uses the SurfaceFlinger display size
1464 mDisplayDevice->setProjection(ui::ROTATION_0, Rect(mFlingerDisplaySize),
1465 Rect(mFlingerDisplaySize));
1466 }
1467
1468 void setProjectionForRotation90() {
1469 // A logical rotation of 90 uses the SurfaceFlinger display size with
1470 // the width/height swapped.
1471 mDisplayDevice->setProjection(ui::ROTATION_90, Rect(SwapWH(mFlingerDisplaySize)),
1472 Rect(SwapWH(mFlingerDisplaySize)));
1473 }
1474
1475 void setProjectionForRotation180() {
1476 // A logical rotation of 180 uses the SurfaceFlinger display size
1477 mDisplayDevice->setProjection(ui::ROTATION_180, Rect(mFlingerDisplaySize),
1478 Rect(mFlingerDisplaySize));
1479 }
1480
1481 void setProjectionForRotation270() {
1482 // A logical rotation of 270 uses the SurfaceFlinger display size with
1483 // the width/height swapped.
1484 mDisplayDevice->setProjection(ui::ROTATION_270, Rect(SwapWH(mFlingerDisplaySize)),
1485 Rect(SwapWH(mFlingerDisplaySize)));
1486 }
1487
1488 void expectStateForHardwareTransform0() {
1489 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1490 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_0, mHardwareDisplaySize.width,
1491 mHardwareDisplaySize.height),
1492 compositionState.transform);
1493 EXPECT_EQ(TRANSFORM_FLAGS_ROT_0, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001494 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1495 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001496 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.frame);
1497 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.viewport);
1498 EXPECT_EQ(false, compositionState.needsFiltering);
1499 }
1500
1501 void expectStateForHardwareTransform90() {
1502 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1503 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_90, mHardwareDisplaySize.width,
1504 mHardwareDisplaySize.height),
1505 compositionState.transform);
1506 EXPECT_EQ(TRANSFORM_FLAGS_ROT_90, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001507 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1508 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001509 // For 90, the frame and viewport have the hardware display size width and height swapped
1510 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
1511 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.viewport);
1512 EXPECT_EQ(false, compositionState.needsFiltering);
1513 }
1514
1515 void expectStateForHardwareTransform180() {
1516 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1517 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_180, mHardwareDisplaySize.width,
1518 mHardwareDisplaySize.height),
1519 compositionState.transform);
1520 EXPECT_EQ(TRANSFORM_FLAGS_ROT_180, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001521 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1522 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001523 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.frame);
1524 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.viewport);
1525 EXPECT_EQ(false, compositionState.needsFiltering);
1526 }
1527
1528 void expectStateForHardwareTransform270() {
1529 const auto& compositionState = mDisplayDevice->getCompositionDisplay()->getState();
1530 EXPECT_EQ(ui::Transform(TRANSFORM_FLAGS_ROT_270, mHardwareDisplaySize.width,
1531 mHardwareDisplaySize.height),
1532 compositionState.transform);
1533 EXPECT_EQ(TRANSFORM_FLAGS_ROT_270, compositionState.orientation);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001534 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
1535 EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
Lloyd Pique33050472019-12-19 17:12:44 -08001536 // For 270, the frame and viewport have the hardware display size width and height swapped
1537 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
1538 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.viewport);
1539 EXPECT_EQ(false, compositionState.needsFiltering);
1540 }
1541
1542 const ui::Size mFlingerDisplaySize;
1543 const ui::Size mHardwareDisplaySize;
1544 const ui::Rotation mPhysicalOrientation;
1545 const sp<DisplayDevice> mDisplayDevice;
1546};
1547
1548struct DisplayDeviceSetProjectionTest_Installed0 : public DisplayDeviceSetProjectionTest {
1549 DisplayDeviceSetProjectionTest_Installed0()
1550 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1551 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1552 ui::ROTATION_0) {}
1553};
1554
1555TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith0OutputRotation) {
1556 setProjectionForRotation0();
1557 expectStateForHardwareTransform0();
1558}
1559
1560TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith90OutputRotation) {
1561 setProjectionForRotation90();
1562 expectStateForHardwareTransform90();
1563}
1564
1565TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith180OutputRotation) {
1566 setProjectionForRotation180();
1567 expectStateForHardwareTransform180();
1568}
1569
1570TEST_F(DisplayDeviceSetProjectionTest_Installed0, checkWith270OutputRotation) {
1571 setProjectionForRotation270();
1572 expectStateForHardwareTransform270();
1573}
1574
1575struct DisplayDeviceSetProjectionTest_Installed90 : public DisplayDeviceSetProjectionTest {
1576 DisplayDeviceSetProjectionTest_Installed90()
1577 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_HEIGHT, DEFAULT_DISPLAY_WIDTH),
1578 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1579 ui::ROTATION_90) {}
1580};
1581
1582TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith0OutputRotation) {
1583 setProjectionForRotation0();
1584 expectStateForHardwareTransform90();
1585}
1586
1587TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith90OutputRotation) {
1588 setProjectionForRotation90();
1589 expectStateForHardwareTransform180();
1590}
1591
1592TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith180OutputRotation) {
1593 setProjectionForRotation180();
1594 expectStateForHardwareTransform270();
1595}
1596
1597TEST_F(DisplayDeviceSetProjectionTest_Installed90, checkWith270OutputRotation) {
1598 setProjectionForRotation270();
1599 expectStateForHardwareTransform0();
1600}
1601
1602struct DisplayDeviceSetProjectionTest_Installed180 : public DisplayDeviceSetProjectionTest {
1603 DisplayDeviceSetProjectionTest_Installed180()
1604 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1605 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1606 ui::ROTATION_180) {}
1607};
1608
1609TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith0OutputRotation) {
1610 setProjectionForRotation0();
1611 expectStateForHardwareTransform180();
1612}
1613
1614TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith90OutputRotation) {
1615 setProjectionForRotation90();
1616 expectStateForHardwareTransform270();
1617}
1618
1619TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith180OutputRotation) {
1620 setProjectionForRotation180();
1621 expectStateForHardwareTransform0();
1622}
1623
1624TEST_F(DisplayDeviceSetProjectionTest_Installed180, checkWith270OutputRotation) {
1625 setProjectionForRotation270();
1626 expectStateForHardwareTransform90();
1627}
1628
1629struct DisplayDeviceSetProjectionTest_Installed270 : public DisplayDeviceSetProjectionTest {
1630 DisplayDeviceSetProjectionTest_Installed270()
1631 : DisplayDeviceSetProjectionTest(ui::Size(DEFAULT_DISPLAY_HEIGHT, DEFAULT_DISPLAY_WIDTH),
1632 ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1633 ui::ROTATION_270) {}
1634};
1635
1636TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith0OutputRotation) {
1637 setProjectionForRotation0();
1638 expectStateForHardwareTransform270();
1639}
1640
1641TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith90OutputRotation) {
1642 setProjectionForRotation90();
1643 expectStateForHardwareTransform0();
1644}
1645
1646TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith180OutputRotation) {
1647 setProjectionForRotation180();
1648 expectStateForHardwareTransform90();
1649}
1650
1651TEST_F(DisplayDeviceSetProjectionTest_Installed270, checkWith270OutputRotation) {
1652 setProjectionForRotation270();
1653 expectStateForHardwareTransform180();
1654}
1655
1656/* ------------------------------------------------------------------------
Daniel Solomon42d04562019-01-20 21:03:19 -08001657 * SurfaceFlinger::getDisplayNativePrimaries
1658 */
1659
1660class GetDisplayNativePrimaries : public DisplayTransactionTest {
1661public:
1662 GetDisplayNativePrimaries();
1663 void populateDummyDisplayNativePrimaries(ui::DisplayPrimaries& primaries);
1664 void checkDummyDisplayNativePrimaries(const ui::DisplayPrimaries& primaries);
1665
1666private:
1667 static constexpr float mStartingTestValue = 1.0f;
1668};
1669
1670GetDisplayNativePrimaries::GetDisplayNativePrimaries() {
1671 SimplePrimaryDisplayCase::Display::injectHwcDisplay(this);
1672 injectFakeNativeWindowSurfaceFactory();
1673}
1674
1675void GetDisplayNativePrimaries::populateDummyDisplayNativePrimaries(
1676 ui::DisplayPrimaries& primaries) {
1677 float startingVal = mStartingTestValue;
1678 primaries.red.X = startingVal++;
1679 primaries.red.Y = startingVal++;
1680 primaries.red.Z = startingVal++;
1681 primaries.green.X = startingVal++;
1682 primaries.green.Y = startingVal++;
1683 primaries.green.Z = startingVal++;
1684 primaries.blue.X = startingVal++;
1685 primaries.blue.Y = startingVal++;
1686 primaries.blue.Z = startingVal++;
1687 primaries.white.X = startingVal++;
1688 primaries.white.Y = startingVal++;
1689 primaries.white.Z = startingVal++;
1690}
1691
1692void GetDisplayNativePrimaries::checkDummyDisplayNativePrimaries(
1693 const ui::DisplayPrimaries& primaries) {
1694 float startingVal = mStartingTestValue;
1695 EXPECT_EQ(primaries.red.X, startingVal++);
1696 EXPECT_EQ(primaries.red.Y, startingVal++);
1697 EXPECT_EQ(primaries.red.Z, startingVal++);
1698 EXPECT_EQ(primaries.green.X, startingVal++);
1699 EXPECT_EQ(primaries.green.Y, startingVal++);
1700 EXPECT_EQ(primaries.green.Z, startingVal++);
1701 EXPECT_EQ(primaries.blue.X, startingVal++);
1702 EXPECT_EQ(primaries.blue.Y, startingVal++);
1703 EXPECT_EQ(primaries.blue.Z, startingVal++);
1704 EXPECT_EQ(primaries.white.X, startingVal++);
1705 EXPECT_EQ(primaries.white.Y, startingVal++);
1706 EXPECT_EQ(primaries.white.Z, startingVal++);
1707}
1708
1709TEST_F(GetDisplayNativePrimaries, nullDisplayToken) {
1710 ui::DisplayPrimaries primaries;
1711 EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(nullptr, primaries));
1712}
1713
Daniel Solomon42d04562019-01-20 21:03:19 -08001714TEST_F(GetDisplayNativePrimaries, internalDisplayWithPrimariesData) {
1715 auto injector = SimplePrimaryDisplayCase::Display::makeFakeExistingDisplayInjector(this);
1716 injector.inject();
1717 auto internalDisplayToken = injector.token();
1718
1719 ui::DisplayPrimaries expectedPrimaries;
1720 populateDummyDisplayNativePrimaries(expectedPrimaries);
1721 mFlinger.setInternalDisplayPrimaries(expectedPrimaries);
1722
1723 ui::DisplayPrimaries primaries;
1724 EXPECT_EQ(NO_ERROR, mFlinger.getDisplayNativePrimaries(internalDisplayToken, primaries));
1725
1726 checkDummyDisplayNativePrimaries(primaries);
1727}
1728
1729TEST_F(GetDisplayNativePrimaries, notInternalDisplayToken) {
1730 sp<BBinder> notInternalDisplayToken = new BBinder();
1731
1732 ui::DisplayPrimaries primaries;
1733 populateDummyDisplayNativePrimaries(primaries);
1734 EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
1735
1736 // Check primaries argument wasn't modified in case of failure
1737 checkDummyDisplayNativePrimaries(primaries);
1738}
1739
1740/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001741 * SurfaceFlinger::setupNewDisplayDeviceInternal
1742 */
1743
1744class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
1745public:
1746 template <typename T>
1747 void setupNewDisplayDeviceInternalTest();
1748};
1749
1750template <typename Case>
1751void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
1752 const sp<BBinder> displayToken = new BBinder();
Lloyd Pique542307f2018-10-19 13:24:08 -07001753 const sp<compositionengine::mock::DisplaySurface> displaySurface =
1754 new compositionengine::mock::DisplaySurface();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001755 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001756
1757 // --------------------------------------------------------------------
1758 // Preconditions
1759
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001760 // Wide color displays support is configured appropriately
1761 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001762
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001763 // The display is setup with the HWC.
1764 Case::Display::injectHwcDisplay(this);
1765
1766 // SurfaceFlinger will use a test-controlled factory for native window
1767 // surfaces.
1768 injectFakeNativeWindowSurfaceFactory();
1769
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001770 // A compositionengine::Display has already been created
1771 auto compositionDisplay = Case::Display::injectCompositionDisplay(this);
1772
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001773 // --------------------------------------------------------------------
1774 // Call Expectations
1775
1776 // Various native window calls will be made.
1777 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
Lloyd Pique3c085a02018-05-09 19:38:32 -07001778 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001779 Case::WideColorSupport::setupComposerCallExpectations(this);
1780 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001781 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001782
1783 // --------------------------------------------------------------------
1784 // Invocation
1785
1786 DisplayDeviceState state;
Dominik Laskowski55c85402020-01-21 16:25:47 -08001787 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1788 const auto displayId = Case::Display::DISPLAY_ID::get();
1789 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001790 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1791 ASSERT_TRUE(hwcDisplayId);
1792 state.physical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001793 }
1794
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001795 state.isSecure = static_cast<bool>(Case::Display::SECURE);
1796
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001797 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
1798 displaySurface, producer);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001799
1800 // --------------------------------------------------------------------
1801 // Postconditions
1802
1803 ASSERT_TRUE(device != nullptr);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001804 EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001805 EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, device->getConnectionType());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001806 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001807 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001808 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001809 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
1810 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
1811 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
Valerie Haue9e843a2018-12-18 13:39:23 -08001812 EXPECT_EQ(Case::HdrSupport::HDR10_PLUS_SUPPORTED, device->hasHDR10PlusSupport());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001813 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
1814 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
1815 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
Lloyd Pique3c085a02018-05-09 19:38:32 -07001816 // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
1817 // remapped, and the test only ever sets up one config. If there were an error
1818 // looking up the remapped index, device->getActiveConfig() would be -1 instead.
Ady Abraham2139f732019-11-13 18:56:40 -08001819 EXPECT_EQ(0, device->getActiveConfig().value());
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001820 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
1821 device->getSupportedPerFrameMetadata());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001822}
1823
1824TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
1825 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
1826}
1827
1828TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
1829 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
1830}
1831
1832TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1833 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1834}
1835
1836TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001837 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001838}
1839
1840TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1841 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1842}
1843
Valerie Haue9e843a2018-12-18 13:39:23 -08001844TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10PlusDisplay) {
1845 setupNewDisplayDeviceInternalTest<Hdr10PlusDisplayCase>();
1846}
1847
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001848TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1849 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1850}
1851
1852TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1853 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1854}
1855
1856TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1857 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1858}
1859
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001860TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
1861 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
1862}
1863
1864TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
1865 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
1866}
1867
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001868/* ------------------------------------------------------------------------
1869 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1870 */
1871
1872class HandleTransactionLockedTest : public DisplayTransactionTest {
1873public:
1874 template <typename Case>
1875 void setupCommonPreconditions();
1876
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001877 template <typename Case, bool connected>
1878 static void expectHotplugReceived(mock::EventThread*);
1879
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001880 template <typename Case>
1881 void setupCommonCallExpectationsForConnectProcessing();
1882
1883 template <typename Case>
1884 void setupCommonCallExpectationsForDisconnectProcessing();
1885
1886 template <typename Case>
1887 void processesHotplugConnectCommon();
1888
1889 template <typename Case>
1890 void ignoresHotplugConnectCommon();
1891
1892 template <typename Case>
1893 void processesHotplugDisconnectCommon();
1894
1895 template <typename Case>
1896 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1897
1898 template <typename Case>
1899 void verifyPhysicalDisplayIsConnected();
1900
1901 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1902};
1903
1904template <typename Case>
1905void HandleTransactionLockedTest::setupCommonPreconditions() {
1906 // Wide color displays support is configured appropriately
1907 Case::WideColorSupport::injectConfigChange(this);
1908
1909 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1910 injectFakeBufferQueueFactory();
1911
1912 // SurfaceFlinger will use a test-controlled factory for native window
1913 // surfaces.
1914 injectFakeNativeWindowSurfaceFactory();
1915}
1916
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001917template <typename Case, bool connected>
1918void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) {
1919 const auto convert = [](auto physicalDisplayId) {
1920 return std::make_optional(DisplayId{physicalDisplayId});
1921 };
1922
1923 EXPECT_CALL(*eventThread,
1924 onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
1925 .Times(1);
1926}
1927
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001928template <typename Case>
1929void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1930 Case::Display::setupHwcHotplugCallExpectations(this);
1931
1932 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1933 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1934 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1935 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1936
1937 Case::WideColorSupport::setupComposerCallExpectations(this);
1938 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001939 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001940
1941 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001942 expectHotplugReceived<Case, true>(mEventThread);
1943 expectHotplugReceived<Case, true>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001944}
1945
1946template <typename Case>
1947void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1948 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
Dominik Laskowski1eba0202019-01-24 09:14:40 -08001949
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001950 expectHotplugReceived<Case, false>(mEventThread);
1951 expectHotplugReceived<Case, false>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001952}
1953
1954template <typename Case>
1955void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1956 // The display device should have been set up in the list of displays.
1957 ASSERT_TRUE(hasDisplayDevice(displayToken));
1958 const auto& device = getDisplayDevice(displayToken);
1959 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001960 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001961
Dominik Laskowski55c85402020-01-21 16:25:47 -08001962 std::optional<DisplayDeviceState::Physical> expectedPhysical;
1963 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1964 const auto displayId = Case::Display::DISPLAY_ID::get();
1965 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001966 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1967 ASSERT_TRUE(hwcDisplayId);
1968 expectedPhysical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001969 }
1970
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001971 // The display should have been set up in the current display state
1972 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1973 const auto& current = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001974 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), current.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001975 EXPECT_EQ(expectedPhysical, current.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001976
1977 // The display should have been set up in the drawing display state
1978 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1979 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001980 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001981 EXPECT_EQ(expectedPhysical, draw.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001982}
1983
1984template <typename Case>
1985void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1986 // HWComposer should have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001987 EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001988
Dominik Laskowski075d3172018-05-24 15:50:06 -07001989 // SF should have a display token.
1990 const auto displayId = Case::Display::DISPLAY_ID::get();
1991 ASSERT_TRUE(displayId);
1992 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
1993 auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001994
1995 verifyDisplayIsConnected<Case>(displayToken);
1996}
1997
1998void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
1999 EXPECT_FALSE(hasDisplayDevice(displayToken));
2000 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2001 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
2002}
2003
2004template <typename Case>
2005void HandleTransactionLockedTest::processesHotplugConnectCommon() {
2006 // --------------------------------------------------------------------
2007 // Preconditions
2008
2009 setupCommonPreconditions<Case>();
2010
2011 // A hotplug connect event is enqueued for a display
2012 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002013
2014 // --------------------------------------------------------------------
2015 // Call Expectations
2016
2017 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002018
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002019 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002020
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002021 // --------------------------------------------------------------------
2022 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08002023
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002024 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08002025
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002026 // --------------------------------------------------------------------
2027 // Postconditions
2028
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002029 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002030
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002031 // --------------------------------------------------------------------
2032 // Cleanup conditions
2033
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002034 EXPECT_CALL(*mComposer,
2035 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002036 .WillOnce(Return(Error::NONE));
2037 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08002038}
2039
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002040template <typename Case>
2041void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
2042 // --------------------------------------------------------------------
2043 // Preconditions
2044
2045 setupCommonPreconditions<Case>();
2046
2047 // A hotplug connect event is enqueued for a display
2048 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2049
2050 // --------------------------------------------------------------------
2051 // Invocation
2052
2053 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2054
2055 // --------------------------------------------------------------------
2056 // Postconditions
2057
2058 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002059 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002060}
2061
2062template <typename Case>
2063void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
2064 // --------------------------------------------------------------------
2065 // Preconditions
2066
2067 setupCommonPreconditions<Case>();
2068
2069 // A hotplug disconnect event is enqueued for a display
2070 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2071
2072 // The display is already completely set up.
2073 Case::Display::injectHwcDisplay(this);
2074 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2075 existing.inject();
2076
2077 // --------------------------------------------------------------------
2078 // Call Expectations
2079
2080 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
Lloyd Pique438e9e72018-09-04 18:06:08 -07002081 EXPECT_CALL(*mComposer, getDisplayIdentificationData(Case::Display::HWC_DISPLAY_ID, _, _))
2082 .Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002083
2084 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2085
2086 // --------------------------------------------------------------------
2087 // Invocation
2088
2089 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2090
2091 // --------------------------------------------------------------------
2092 // Postconditions
2093
2094 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002095 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002096
Dominik Laskowski075d3172018-05-24 15:50:06 -07002097 // SF should not have a display token.
2098 const auto displayId = Case::Display::DISPLAY_ID::get();
2099 ASSERT_TRUE(displayId);
2100 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002101
2102 // The existing token should have been removed
2103 verifyDisplayIsNotConnected(existing.token());
2104}
2105
2106TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
2107 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2108}
2109
2110TEST_F(HandleTransactionLockedTest,
2111 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
2112 // Inject an external display.
2113 ExternalDisplayVariant::injectHwcDisplay(this);
2114
2115 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2116}
2117
2118TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
2119 // Inject a primary display.
2120 PrimaryDisplayVariant::injectHwcDisplay(this);
2121
2122 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
2123}
2124
2125TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
2126 // Inject both a primary and external display.
2127 PrimaryDisplayVariant::injectHwcDisplay(this);
2128 ExternalDisplayVariant::injectHwcDisplay(this);
2129
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002130 // TODO: This is an unnecessary call.
2131 EXPECT_CALL(*mComposer,
2132 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
2133 .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
2134 SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
2135 Return(Error::NONE)));
2136
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002137 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2138
2139 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
2140}
2141
2142TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
2143 // Inject a primary display.
2144 PrimaryDisplayVariant::injectHwcDisplay(this);
2145
2146 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
2147
2148 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
2149}
2150
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002151TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectPrimaryDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002152 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
2153}
2154
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002155TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectExternalDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002156 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
2157}
2158
2159TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
2160 using Case = SimplePrimaryDisplayCase;
2161
2162 // --------------------------------------------------------------------
2163 // Preconditions
2164
2165 setupCommonPreconditions<Case>();
2166
2167 // A hotplug connect event is enqueued for a display
2168 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2169 // A hotplug disconnect event is also enqueued for the same display
2170 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2171
2172 // --------------------------------------------------------------------
2173 // Call Expectations
2174
2175 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2176
2177 setupCommonCallExpectationsForConnectProcessing<Case>();
2178 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2179
2180 EXPECT_CALL(*mComposer,
2181 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2182 .WillOnce(Return(Error::NONE));
2183 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2184
2185 // --------------------------------------------------------------------
2186 // Invocation
2187
2188 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2189
2190 // --------------------------------------------------------------------
2191 // Postconditions
2192
2193 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002194 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002195
Dominik Laskowski075d3172018-05-24 15:50:06 -07002196 // SF should not have a display token.
2197 const auto displayId = Case::Display::DISPLAY_ID::get();
2198 ASSERT_TRUE(displayId);
2199 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002200}
2201
2202TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
2203 using Case = SimplePrimaryDisplayCase;
2204
2205 // --------------------------------------------------------------------
2206 // Preconditions
2207
2208 setupCommonPreconditions<Case>();
2209
2210 // The display is already completely set up.
2211 Case::Display::injectHwcDisplay(this);
2212 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2213 existing.inject();
2214
2215 // A hotplug disconnect event is enqueued for a display
2216 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2217 // A hotplug connect event is also enqueued for the same display
2218 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2219
2220 // --------------------------------------------------------------------
2221 // Call Expectations
2222
2223 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2224
2225 setupCommonCallExpectationsForConnectProcessing<Case>();
2226 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2227
2228 // --------------------------------------------------------------------
2229 // Invocation
2230
2231 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2232
2233 // --------------------------------------------------------------------
2234 // Postconditions
2235
2236 // The existing token should have been removed
2237 verifyDisplayIsNotConnected(existing.token());
Dominik Laskowski075d3172018-05-24 15:50:06 -07002238 const auto displayId = Case::Display::DISPLAY_ID::get();
2239 ASSERT_TRUE(displayId);
2240 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
2241 EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002242
2243 // A new display should be connected in its place
2244
2245 verifyPhysicalDisplayIsConnected<Case>();
2246
2247 // --------------------------------------------------------------------
2248 // Cleanup conditions
2249
2250 EXPECT_CALL(*mComposer,
2251 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2252 .WillOnce(Return(Error::NONE));
2253 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2254}
2255
2256TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
2257 using Case = HwcVirtualDisplayCase;
2258
2259 // --------------------------------------------------------------------
2260 // Preconditions
2261
2262 // The HWC supports at least one virtual display
2263 injectMockComposer(1);
2264
2265 setupCommonPreconditions<Case>();
2266
2267 // A virtual display was added to the current state, and it has a
2268 // surface(producer)
2269 sp<BBinder> displayToken = new BBinder();
Lloyd Pique4c2ac022018-04-27 12:08:03 -07002270
Dominik Laskowski075d3172018-05-24 15:50:06 -07002271 DisplayDeviceState state;
2272 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002273
2274 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
Dominik Laskowski075d3172018-05-24 15:50:06 -07002275 state.surface = surface;
2276 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002277
2278 // --------------------------------------------------------------------
2279 // Call Expectations
2280
2281 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
2282 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
2283
2284 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
2285 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
2286 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
2287 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
2288 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
2289 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
2290 Return(NO_ERROR)));
2291 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
2292 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
2293
2294 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
2295
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002296 EXPECT_CALL(*mProducer, connect(_, NATIVE_WINDOW_API_EGL, false, _)).Times(1);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002297 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
2298
2299 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
2300 Case::WideColorSupport::setupComposerCallExpectations(this);
2301 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07002302 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002303
2304 // --------------------------------------------------------------------
2305 // Invocation
2306
2307 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2308
2309 // --------------------------------------------------------------------
2310 // Postconditions
2311
2312 // The display device should have been set up in the list of displays.
2313 verifyDisplayIsConnected<Case>(displayToken);
2314
2315 // --------------------------------------------------------------------
2316 // Cleanup conditions
2317
2318 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
2319 .WillOnce(Return(Error::NONE));
2320 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Pique9e9800c2019-02-26 16:26:09 -08002321
2322 // Cleanup
2323 mFlinger.mutableCurrentState().displays.removeItem(displayToken);
2324 mFlinger.mutableDrawingState().displays.removeItem(displayToken);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002325}
2326
2327TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
2328 using Case = HwcVirtualDisplayCase;
2329
2330 // --------------------------------------------------------------------
2331 // Preconditions
2332
2333 // The HWC supports at least one virtual display
2334 injectMockComposer(1);
2335
2336 setupCommonPreconditions<Case>();
2337
2338 // A virtual display was added to the current state, but it does not have a
2339 // surface.
2340 sp<BBinder> displayToken = new BBinder();
2341
Dominik Laskowski075d3172018-05-24 15:50:06 -07002342 DisplayDeviceState state;
2343 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002344
Dominik Laskowski075d3172018-05-24 15:50:06 -07002345 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002346
2347 // --------------------------------------------------------------------
2348 // Call Expectations
2349
2350 // --------------------------------------------------------------------
2351 // Invocation
2352
2353 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2354
2355 // --------------------------------------------------------------------
2356 // Postconditions
2357
2358 // There will not be a display device set up.
2359 EXPECT_FALSE(hasDisplayDevice(displayToken));
2360
2361 // The drawing display state will be set from the current display state.
2362 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
2363 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07002364 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002365}
2366
2367TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
2368 using Case = HwcVirtualDisplayCase;
2369
2370 // --------------------------------------------------------------------
2371 // Preconditions
2372
2373 // A virtual display is set up but is removed from the current state.
Dominik Laskowski075d3172018-05-24 15:50:06 -07002374 const auto displayId = Case::Display::DISPLAY_ID::get();
2375 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08002376 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002377 Case::Display::injectHwcDisplay(this);
2378 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2379 existing.inject();
2380 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
2381
2382 // --------------------------------------------------------------------
2383 // Call Expectations
2384
2385 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2386
2387 // --------------------------------------------------------------------
2388 // Invocation
2389
2390 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2391
2392 // --------------------------------------------------------------------
2393 // Postconditions
2394
2395 // The existing token should have been removed
2396 verifyDisplayIsNotConnected(existing.token());
2397}
2398
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002399TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
2400 using Case = NonHwcVirtualDisplayCase;
2401
2402 constexpr uint32_t oldLayerStack = 0u;
2403 constexpr uint32_t newLayerStack = 123u;
2404
2405 // --------------------------------------------------------------------
2406 // Preconditions
2407
2408 // A display is set up
2409 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2410 display.inject();
2411
2412 // There is a change to the layerStack state
2413 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
2414 display.mutableCurrentDisplayState().layerStack = newLayerStack;
2415
2416 // --------------------------------------------------------------------
2417 // Invocation
2418
2419 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2420
2421 // --------------------------------------------------------------------
2422 // Postconditions
2423
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002424 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002425}
2426
2427TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
2428 using Case = NonHwcVirtualDisplayCase;
2429
Dominik Laskowski718f9602019-11-09 20:01:35 -08002430 constexpr ui::Rotation oldTransform = ui::ROTATION_0;
2431 constexpr ui::Rotation newTransform = ui::ROTATION_180;
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002432
2433 // --------------------------------------------------------------------
2434 // Preconditions
2435
2436 // A display is set up
2437 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2438 display.inject();
2439
2440 // There is a change to the orientation state
2441 display.mutableDrawingDisplayState().orientation = oldTransform;
2442 display.mutableCurrentDisplayState().orientation = newTransform;
2443
2444 // --------------------------------------------------------------------
2445 // Invocation
2446
2447 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2448
2449 // --------------------------------------------------------------------
2450 // Postconditions
2451
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002452 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002453}
2454
2455TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
2456 using Case = NonHwcVirtualDisplayCase;
2457
2458 const Rect oldViewport(0, 0, 0, 0);
2459 const Rect newViewport(0, 0, 123, 456);
2460
2461 // --------------------------------------------------------------------
2462 // Preconditions
2463
2464 // A display is set up
2465 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2466 display.inject();
2467
2468 // There is a change to the viewport state
2469 display.mutableDrawingDisplayState().viewport = oldViewport;
2470 display.mutableCurrentDisplayState().viewport = newViewport;
2471
2472 // --------------------------------------------------------------------
2473 // Invocation
2474
2475 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2476
2477 // --------------------------------------------------------------------
2478 // Postconditions
2479
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002480 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002481}
2482
2483TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
2484 using Case = NonHwcVirtualDisplayCase;
2485
2486 const Rect oldFrame(0, 0, 0, 0);
2487 const Rect newFrame(0, 0, 123, 456);
2488
2489 // --------------------------------------------------------------------
2490 // Preconditions
2491
2492 // A display is set up
2493 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2494 display.inject();
2495
2496 // There is a change to the viewport state
2497 display.mutableDrawingDisplayState().frame = oldFrame;
2498 display.mutableCurrentDisplayState().frame = newFrame;
2499
2500 // --------------------------------------------------------------------
2501 // Invocation
2502
2503 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2504
2505 // --------------------------------------------------------------------
2506 // Postconditions
2507
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002508 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002509}
2510
2511TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
2512 using Case = NonHwcVirtualDisplayCase;
2513
2514 constexpr int oldWidth = 0;
2515 constexpr int oldHeight = 10;
2516 constexpr int newWidth = 123;
2517
2518 // --------------------------------------------------------------------
2519 // Preconditions
2520
2521 // A display is set up
2522 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002523 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002524 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002525 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2526 display.setNativeWindow(nativeWindow);
2527 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002528 // Setup injection expections
2529 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2530 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2531 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2532 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002533 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2534 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2535 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002536 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002537 display.inject();
2538
2539 // There is a change to the viewport state
2540 display.mutableDrawingDisplayState().width = oldWidth;
2541 display.mutableDrawingDisplayState().height = oldHeight;
2542 display.mutableCurrentDisplayState().width = newWidth;
2543 display.mutableCurrentDisplayState().height = oldHeight;
2544
2545 // --------------------------------------------------------------------
2546 // Call Expectations
2547
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002548 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002549
2550 // --------------------------------------------------------------------
2551 // Invocation
2552
2553 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2554}
2555
2556TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
2557 using Case = NonHwcVirtualDisplayCase;
2558
2559 constexpr int oldWidth = 0;
2560 constexpr int oldHeight = 10;
2561 constexpr int newHeight = 123;
2562
2563 // --------------------------------------------------------------------
2564 // Preconditions
2565
2566 // A display is set up
2567 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002568 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002569 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002570 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2571 display.setNativeWindow(nativeWindow);
2572 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002573 // Setup injection expections
2574 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2575 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2576 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2577 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002578 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2579 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2580 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002581 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002582 display.inject();
2583
2584 // There is a change to the viewport state
2585 display.mutableDrawingDisplayState().width = oldWidth;
2586 display.mutableDrawingDisplayState().height = oldHeight;
2587 display.mutableCurrentDisplayState().width = oldWidth;
2588 display.mutableCurrentDisplayState().height = newHeight;
2589
2590 // --------------------------------------------------------------------
2591 // Call Expectations
2592
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002593 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002594
2595 // --------------------------------------------------------------------
2596 // Invocation
2597
2598 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2599}
2600
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002601/* ------------------------------------------------------------------------
2602 * SurfaceFlinger::setDisplayStateLocked
2603 */
2604
2605TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
2606 // --------------------------------------------------------------------
2607 // Preconditions
2608
2609 // We have an unknown display token not associated with a known display
2610 sp<BBinder> displayToken = new BBinder();
2611
2612 // The requested display state references the unknown display.
2613 DisplayState state;
2614 state.what = DisplayState::eLayerStackChanged;
2615 state.token = displayToken;
2616 state.layerStack = 456;
2617
2618 // --------------------------------------------------------------------
2619 // Invocation
2620
2621 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2622
2623 // --------------------------------------------------------------------
2624 // Postconditions
2625
2626 // The returned flags are empty
2627 EXPECT_EQ(0u, flags);
2628
2629 // The display token still doesn't match anything known.
2630 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2631}
2632
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002633TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
2634 using Case = SimplePrimaryDisplayCase;
2635
2636 // --------------------------------------------------------------------
2637 // Preconditions
2638
2639 // A display is already set up
2640 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2641 display.inject();
2642
2643 // No changes are made to the display
2644 DisplayState state;
2645 state.what = 0;
2646 state.token = display.token();
2647
2648 // --------------------------------------------------------------------
2649 // Invocation
2650
2651 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2652
2653 // --------------------------------------------------------------------
2654 // Postconditions
2655
2656 // The returned flags are empty
2657 EXPECT_EQ(0u, flags);
2658}
2659
2660TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
2661 using Case = SimplePrimaryDisplayCase;
2662
2663 // --------------------------------------------------------------------
2664 // Preconditions
2665
2666 // A display is already set up
2667 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2668 display.inject();
2669
2670 // There is a surface that can be set.
2671 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2672
2673 // The current display state has the surface set
2674 display.mutableCurrentDisplayState().surface = surface;
2675
2676 // The incoming request sets the same surface
2677 DisplayState state;
2678 state.what = DisplayState::eSurfaceChanged;
2679 state.token = display.token();
2680 state.surface = surface;
2681
2682 // --------------------------------------------------------------------
2683 // Invocation
2684
2685 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2686
2687 // --------------------------------------------------------------------
2688 // Postconditions
2689
2690 // The returned flags are empty
2691 EXPECT_EQ(0u, flags);
2692
2693 // The current display state is unchanged.
2694 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2695}
2696
2697TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
2698 using Case = SimplePrimaryDisplayCase;
2699
2700 // --------------------------------------------------------------------
2701 // Preconditions
2702
2703 // A display is already set up
2704 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2705 display.inject();
2706
2707 // There is a surface that can be set.
2708 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2709
2710 // The current display state does not have a surface
2711 display.mutableCurrentDisplayState().surface = nullptr;
2712
2713 // The incoming request sets a surface
2714 DisplayState state;
2715 state.what = DisplayState::eSurfaceChanged;
2716 state.token = display.token();
2717 state.surface = surface;
2718
2719 // --------------------------------------------------------------------
2720 // Invocation
2721
2722 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2723
2724 // --------------------------------------------------------------------
2725 // Postconditions
2726
2727 // The returned flags indicate a transaction is needed
2728 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2729
2730 // The current display layer stack state is set to the new value
2731 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2732}
2733
2734TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
2735 using Case = SimplePrimaryDisplayCase;
2736
2737 // --------------------------------------------------------------------
2738 // Preconditions
2739
2740 // A display is already set up
2741 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2742 display.inject();
2743
2744 // The display has a layer stack set
2745 display.mutableCurrentDisplayState().layerStack = 456u;
2746
2747 // The incoming request sets the same layer stack
2748 DisplayState state;
2749 state.what = DisplayState::eLayerStackChanged;
2750 state.token = display.token();
2751 state.layerStack = 456u;
2752
2753 // --------------------------------------------------------------------
2754 // Invocation
2755
2756 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2757
2758 // --------------------------------------------------------------------
2759 // Postconditions
2760
2761 // The returned flags are empty
2762 EXPECT_EQ(0u, flags);
2763
2764 // The current display state is unchanged
2765 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2766}
2767
2768TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
2769 using Case = SimplePrimaryDisplayCase;
2770
2771 // --------------------------------------------------------------------
2772 // Preconditions
2773
2774 // A display is set up
2775 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2776 display.inject();
2777
2778 // The display has a layer stack set
2779 display.mutableCurrentDisplayState().layerStack = 654u;
2780
2781 // The incoming request sets a different layer stack
2782 DisplayState state;
2783 state.what = DisplayState::eLayerStackChanged;
2784 state.token = display.token();
2785 state.layerStack = 456u;
2786
2787 // --------------------------------------------------------------------
2788 // Invocation
2789
2790 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2791
2792 // --------------------------------------------------------------------
2793 // Postconditions
2794
2795 // The returned flags indicate a transaction is needed
2796 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2797
2798 // The desired display state has been set to the new value.
2799 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2800}
2801
2802TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
2803 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002804 constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002805 const Rect initialFrame = {1, 2, 3, 4};
2806 const Rect initialViewport = {5, 6, 7, 8};
2807
2808 // --------------------------------------------------------------------
2809 // Preconditions
2810
2811 // A display is set up
2812 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2813 display.inject();
2814
2815 // The current display state projection state is all set
2816 display.mutableCurrentDisplayState().orientation = initialOrientation;
2817 display.mutableCurrentDisplayState().frame = initialFrame;
2818 display.mutableCurrentDisplayState().viewport = initialViewport;
2819
2820 // The incoming request sets the same projection state
2821 DisplayState state;
2822 state.what = DisplayState::eDisplayProjectionChanged;
2823 state.token = display.token();
2824 state.orientation = initialOrientation;
2825 state.frame = initialFrame;
2826 state.viewport = initialViewport;
2827
2828 // --------------------------------------------------------------------
2829 // Invocation
2830
2831 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2832
2833 // --------------------------------------------------------------------
2834 // Postconditions
2835
2836 // The returned flags are empty
2837 EXPECT_EQ(0u, flags);
2838
2839 // The current display state is unchanged
2840 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
2841
2842 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
2843 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
2844}
2845
2846TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
2847 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002848 constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
2849 constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002850
2851 // --------------------------------------------------------------------
2852 // Preconditions
2853
2854 // A display is set up
2855 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2856 display.inject();
2857
2858 // The current display state has an orientation set
2859 display.mutableCurrentDisplayState().orientation = initialOrientation;
2860
2861 // The incoming request sets a different orientation
2862 DisplayState state;
2863 state.what = DisplayState::eDisplayProjectionChanged;
2864 state.token = display.token();
2865 state.orientation = desiredOrientation;
2866
2867 // --------------------------------------------------------------------
2868 // Invocation
2869
2870 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2871
2872 // --------------------------------------------------------------------
2873 // Postconditions
2874
2875 // The returned flags indicate a transaction is needed
2876 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2877
2878 // The current display state has the new value.
2879 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2880}
2881
2882TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2883 using Case = SimplePrimaryDisplayCase;
2884 const Rect initialFrame = {0, 0, 0, 0};
2885 const Rect desiredFrame = {5, 6, 7, 8};
2886
2887 // --------------------------------------------------------------------
2888 // Preconditions
2889
2890 // A display is set up
2891 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2892 display.inject();
2893
2894 // The current display state does not have a frame
2895 display.mutableCurrentDisplayState().frame = initialFrame;
2896
2897 // The incoming request sets a frame
2898 DisplayState state;
2899 state.what = DisplayState::eDisplayProjectionChanged;
2900 state.token = display.token();
2901 state.frame = desiredFrame;
2902
2903 // --------------------------------------------------------------------
2904 // Invocation
2905
2906 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2907
2908 // --------------------------------------------------------------------
2909 // Postconditions
2910
2911 // The returned flags indicate a transaction is needed
2912 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2913
2914 // The current display state has the new value.
2915 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2916}
2917
2918TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2919 using Case = SimplePrimaryDisplayCase;
2920 const Rect initialViewport = {0, 0, 0, 0};
2921 const Rect desiredViewport = {5, 6, 7, 8};
2922
2923 // --------------------------------------------------------------------
2924 // Preconditions
2925
2926 // A display is set up
2927 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2928 display.inject();
2929
2930 // The current display state does not have a viewport
2931 display.mutableCurrentDisplayState().viewport = initialViewport;
2932
2933 // The incoming request sets a viewport
2934 DisplayState state;
2935 state.what = DisplayState::eDisplayProjectionChanged;
2936 state.token = display.token();
2937 state.viewport = desiredViewport;
2938
2939 // --------------------------------------------------------------------
2940 // Invocation
2941
2942 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2943
2944 // --------------------------------------------------------------------
2945 // Postconditions
2946
2947 // The returned flags indicate a transaction is needed
2948 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2949
2950 // The current display state has the new value.
2951 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2952}
2953
2954TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2955 using Case = SimplePrimaryDisplayCase;
2956 constexpr uint32_t initialWidth = 1024;
2957 constexpr uint32_t initialHeight = 768;
2958
2959 // --------------------------------------------------------------------
2960 // Preconditions
2961
2962 // A display is set up
2963 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2964 display.inject();
2965
2966 // The current display state has a size set
2967 display.mutableCurrentDisplayState().width = initialWidth;
2968 display.mutableCurrentDisplayState().height = initialHeight;
2969
2970 // The incoming request sets the same display size
2971 DisplayState state;
2972 state.what = DisplayState::eDisplaySizeChanged;
2973 state.token = display.token();
2974 state.width = initialWidth;
2975 state.height = initialHeight;
2976
2977 // --------------------------------------------------------------------
2978 // Invocation
2979
2980 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2981
2982 // --------------------------------------------------------------------
2983 // Postconditions
2984
2985 // The returned flags are empty
2986 EXPECT_EQ(0u, flags);
2987
2988 // The current display state is unchanged
2989 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2990 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2991}
2992
2993TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
2994 using Case = SimplePrimaryDisplayCase;
2995 constexpr uint32_t initialWidth = 0;
2996 constexpr uint32_t desiredWidth = 1024;
2997
2998 // --------------------------------------------------------------------
2999 // Preconditions
3000
3001 // A display is set up
3002 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3003 display.inject();
3004
3005 // The display does not yet have a width
3006 display.mutableCurrentDisplayState().width = initialWidth;
3007
3008 // The incoming request sets a display width
3009 DisplayState state;
3010 state.what = DisplayState::eDisplaySizeChanged;
3011 state.token = display.token();
3012 state.width = desiredWidth;
3013
3014 // --------------------------------------------------------------------
3015 // Invocation
3016
3017 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3018
3019 // --------------------------------------------------------------------
3020 // Postconditions
3021
3022 // The returned flags indicate a transaction is needed
3023 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3024
3025 // The current display state has the new value.
3026 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
3027}
3028
3029TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
3030 using Case = SimplePrimaryDisplayCase;
3031 constexpr uint32_t initialHeight = 0;
3032 constexpr uint32_t desiredHeight = 768;
3033
3034 // --------------------------------------------------------------------
3035 // Preconditions
3036
3037 // A display is set up
3038 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3039 display.inject();
3040
3041 // The display does not yet have a height
3042 display.mutableCurrentDisplayState().height = initialHeight;
3043
3044 // The incoming request sets a display height
3045 DisplayState state;
3046 state.what = DisplayState::eDisplaySizeChanged;
3047 state.token = display.token();
3048 state.height = desiredHeight;
3049
3050 // --------------------------------------------------------------------
3051 // Invocation
3052
3053 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3054
3055 // --------------------------------------------------------------------
3056 // Postconditions
3057
3058 // The returned flags indicate a transaction is needed
3059 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3060
3061 // The current display state has the new value.
3062 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
3063}
3064
Lloyd Pique86016da2018-03-01 16:09:38 -08003065/* ------------------------------------------------------------------------
3066 * SurfaceFlinger::onInitializeDisplays
3067 */
3068
3069TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
3070 using Case = SimplePrimaryDisplayCase;
3071
3072 // --------------------------------------------------------------------
3073 // Preconditions
3074
3075 // A primary display is set up
3076 Case::Display::injectHwcDisplay(this);
3077 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
3078 primaryDisplay.inject();
3079
3080 // --------------------------------------------------------------------
3081 // Call Expectations
3082
3083 // We expect the surface interceptor to possibly be used, but we treat it as
3084 // disabled since it is called as a side effect rather than directly by this
3085 // function.
3086 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
3087
3088 // We expect a call to get the active display config.
3089 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
3090
3091 // We expect invalidate() to be invoked once to trigger display transaction
3092 // processing.
3093 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
3094
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003095 EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
3096
Lloyd Pique86016da2018-03-01 16:09:38 -08003097 // --------------------------------------------------------------------
3098 // Invocation
3099
3100 mFlinger.onInitializeDisplays();
3101
3102 // --------------------------------------------------------------------
3103 // Postconditions
3104
3105 // The primary display should have a current state
3106 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
3107 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
3108 // The layer stack state should be set to zero
3109 EXPECT_EQ(0u, primaryDisplayState.layerStack);
3110 // The orientation state should be set to zero
Dominik Laskowski718f9602019-11-09 20:01:35 -08003111 EXPECT_EQ(ui::ROTATION_0, primaryDisplayState.orientation);
Lloyd Pique86016da2018-03-01 16:09:38 -08003112
3113 // The frame state should be set to INVALID
3114 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
3115
3116 // The viewport state should be set to INVALID
3117 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
3118
3119 // The width and height should both be zero
3120 EXPECT_EQ(0u, primaryDisplayState.width);
3121 EXPECT_EQ(0u, primaryDisplayState.height);
3122
3123 // The display should be set to HWC_POWER_MODE_NORMAL
3124 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
3125 auto displayDevice = primaryDisplay.mutableDisplayDevice();
3126 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
3127
3128 // The display refresh period should be set in the frame tracker.
3129 FrameStats stats;
3130 mFlinger.getAnimFrameTracker().getStats(&stats);
3131 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
3132
3133 // The display transaction needed flag should be set.
3134 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
3135
3136 // The compositor timing should be set to default values
3137 const auto& compositorTiming = mFlinger.getCompositorTiming();
3138 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
3139 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
3140 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
3141}
3142
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003143/* ------------------------------------------------------------------------
3144 * SurfaceFlinger::setPowerModeInternal
3145 */
3146
3147// Used when we simulate a display that supports doze.
Peiyong Lined531a32018-10-26 18:27:56 -07003148template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003149struct DozeIsSupportedVariant {
3150 static constexpr bool DOZE_SUPPORTED = true;
3151 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3152 IComposerClient::PowerMode::DOZE;
3153 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3154 IComposerClient::PowerMode::DOZE_SUSPEND;
Peiyong Lined531a32018-10-26 18:27:56 -07003155
3156 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3157 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
3158 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>(
3159 {Hwc2::DisplayCapability::DOZE})),
3160 Return(Error::NONE)));
3161 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003162};
3163
Peiyong Lined531a32018-10-26 18:27:56 -07003164template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003165// Used when we simulate a display that does not support doze.
3166struct DozeNotSupportedVariant {
3167 static constexpr bool DOZE_SUPPORTED = false;
3168 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3169 IComposerClient::PowerMode::ON;
3170 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3171 IComposerClient::PowerMode::ON;
Peiyong Lined531a32018-10-26 18:27:56 -07003172
3173 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3174 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
3175 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
3176 Return(Error::NONE)));
3177 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003178};
3179
3180struct EventThreadBaseSupportedVariant {
3181 static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
3182 // The event control thread should not be notified.
3183 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
3184
3185 // The event thread should not be notified.
3186 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
3187 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(0);
3188 }
3189};
3190
3191struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
3192 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3193 // These calls are only expected for the primary display.
3194
3195 // Instead expect no calls.
3196 setupEventAndEventControlThreadNoCallExpectations(test);
3197 }
3198
3199 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3200 // These calls are only expected for the primary display.
3201
3202 // Instead expect no calls.
3203 setupEventAndEventControlThreadNoCallExpectations(test);
3204 }
3205};
3206
3207struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
3208 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3209 // The event control thread should be notified to enable vsyncs
3210 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
3211
3212 // The event thread should be notified that the screen was acquired.
3213 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
3214 }
3215
3216 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3217 // There should be a call to setVsyncEnabled(false)
3218 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
3219
3220 // The event thread should not be notified that the screen was released.
3221 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
3222 }
3223};
3224
Lloyd Pique41be5d22018-06-21 13:11:48 -07003225struct DispSyncIsSupportedVariant {
3226 static void setupBeginResyncCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique41be5d22018-06-21 13:11:48 -07003227 EXPECT_CALL(*test->mPrimaryDispSync, setPeriod(DEFAULT_REFRESH_RATE)).Times(1);
3228 EXPECT_CALL(*test->mPrimaryDispSync, beginResync()).Times(1);
3229 }
3230
3231 static void setupEndResyncCallExpectations(DisplayTransactionTest* test) {
3232 EXPECT_CALL(*test->mPrimaryDispSync, endResync()).Times(1);
3233 }
3234};
3235
3236struct DispSyncNotSupportedVariant {
3237 static void setupBeginResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3238
3239 static void setupEndResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3240};
3241
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003242// --------------------------------------------------------------------
3243// Note:
3244//
3245// There are a large number of transitions we could test, however we only test a
3246// selected subset which provides complete test coverage of the implementation.
3247// --------------------------------------------------------------------
3248
3249template <int initialPowerMode, int targetPowerMode>
3250struct TransitionVariantCommon {
3251 static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
3252 static constexpr auto TARGET_POWER_MODE = targetPowerMode;
3253
3254 static void verifyPostconditions(DisplayTransactionTest*) {}
3255};
3256
3257struct TransitionOffToOnVariant
3258 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
3259 template <typename Case>
3260 static void setupCallExpectations(DisplayTransactionTest* test) {
3261 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3262 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003263 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003264 Case::setupRepaintEverythingCallExpectations(test);
3265 }
3266
3267 static void verifyPostconditions(DisplayTransactionTest* test) {
3268 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3269 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3270 }
3271};
3272
3273struct TransitionOffToDozeSuspendVariant
3274 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
3275 template <typename Case>
3276 static void setupCallExpectations(DisplayTransactionTest* test) {
3277 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3278 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3279 Case::setupRepaintEverythingCallExpectations(test);
3280 }
3281
3282 static void verifyPostconditions(DisplayTransactionTest* test) {
3283 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3284 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3285 }
3286};
3287
3288struct TransitionOnToOffVariant
3289 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
3290 template <typename Case>
3291 static void setupCallExpectations(DisplayTransactionTest* test) {
3292 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003293 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003294 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3295 }
3296
3297 static void verifyPostconditions(DisplayTransactionTest* test) {
3298 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3299 }
3300};
3301
3302struct TransitionDozeSuspendToOffVariant
3303 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
3304 template <typename Case>
3305 static void setupCallExpectations(DisplayTransactionTest* test) {
3306 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3307 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3308 }
3309
3310 static void verifyPostconditions(DisplayTransactionTest* test) {
3311 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3312 }
3313};
3314
3315struct TransitionOnToDozeVariant
3316 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
3317 template <typename Case>
3318 static void setupCallExpectations(DisplayTransactionTest* test) {
3319 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3320 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3321 }
3322};
3323
3324struct TransitionDozeSuspendToDozeVariant
3325 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
3326 template <typename Case>
3327 static void setupCallExpectations(DisplayTransactionTest* test) {
3328 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003329 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003330 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3331 }
3332};
3333
3334struct TransitionDozeToOnVariant
3335 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
3336 template <typename Case>
3337 static void setupCallExpectations(DisplayTransactionTest* test) {
3338 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3339 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3340 }
3341};
3342
3343struct TransitionDozeSuspendToOnVariant
3344 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
3345 template <typename Case>
3346 static void setupCallExpectations(DisplayTransactionTest* test) {
3347 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003348 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003349 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3350 }
3351};
3352
3353struct TransitionOnToDozeSuspendVariant
3354 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
3355 template <typename Case>
3356 static void setupCallExpectations(DisplayTransactionTest* test) {
3357 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003358 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003359 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3360 }
3361};
3362
3363struct TransitionOnToUnknownVariant
3364 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
3365 template <typename Case>
3366 static void setupCallExpectations(DisplayTransactionTest* test) {
3367 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3368 Case::setupNoComposerPowerModeCallExpectations(test);
3369 }
3370};
3371
3372// --------------------------------------------------------------------
3373// Note:
3374//
3375// Rather than testing the cartesian product of of
3376// DozeIsSupported/DozeNotSupported with all other options, we use one for one
3377// display type, and the other for another display type.
3378// --------------------------------------------------------------------
3379
3380template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
Lloyd Pique41be5d22018-06-21 13:11:48 -07003381 typename DispSyncVariant, typename TransitionVariant>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003382struct DisplayPowerCase {
3383 using Display = DisplayVariant;
3384 using Doze = DozeVariant;
3385 using EventThread = EventThreadVariant;
Lloyd Pique41be5d22018-06-21 13:11:48 -07003386 using DispSync = DispSyncVariant;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003387 using Transition = TransitionVariant;
3388
3389 static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003390 Display::injectHwcDisplayWithNoDefaultCapabilities(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003391 auto display = Display::makeFakeExistingDisplayInjector(test);
3392 display.inject();
3393 display.mutableDisplayDevice()->setPowerMode(mode);
3394 return display;
3395 }
3396
3397 static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07003398 test->mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = enabled;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003399 }
3400
3401 static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
3402 EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
3403 }
3404
3405 static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
3406 EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
3407 EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
3408 }
3409
3410 static void setupComposerCallExpectations(DisplayTransactionTest* test,
3411 IComposerClient::PowerMode mode) {
3412 // Any calls to get the active config will return a default value.
3413 EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
3414 .WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
3415 Return(Error::NONE)));
3416
3417 // Any calls to get whether the display supports dozing will return the value set by the
3418 // policy variant.
3419 EXPECT_CALL(*test->mComposer, getDozeSupport(Display::HWC_DISPLAY_ID, _))
3420 .WillRepeatedly(DoAll(SetArgPointee<1>(Doze::DOZE_SUPPORTED), Return(Error::NONE)));
3421
3422 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, mode)).Times(1);
3423 }
3424
3425 static void setupNoComposerPowerModeCallExpectations(DisplayTransactionTest* test) {
3426 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, _)).Times(0);
3427 }
3428};
3429
3430// A sample configuration for the primary display.
3431// In addition to having event thread support, we emulate doze support.
3432template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003433using PrimaryDisplayPowerCase =
3434 DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant<PrimaryDisplayVariant>,
3435 EventThreadIsSupportedVariant, DispSyncIsSupportedVariant,
3436 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003437
3438// A sample configuration for the external display.
3439// In addition to not having event thread support, we emulate not having doze
3440// support.
3441template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003442using ExternalDisplayPowerCase =
3443 DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant<ExternalDisplayVariant>,
3444 EventThreadNotSupportedVariant, DispSyncNotSupportedVariant,
3445 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003446
3447class SetPowerModeInternalTest : public DisplayTransactionTest {
3448public:
3449 template <typename Case>
3450 void transitionDisplayCommon();
3451};
3452
3453template <int PowerMode>
3454struct PowerModeInitialVSyncEnabled : public std::false_type {};
3455
3456template <>
3457struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
3458
3459template <>
3460struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
3461
3462template <typename Case>
3463void SetPowerModeInternalTest::transitionDisplayCommon() {
3464 // --------------------------------------------------------------------
3465 // Preconditions
3466
Peiyong Lined531a32018-10-26 18:27:56 -07003467 Case::Doze::setupComposerCallExpectations(this);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003468 auto display =
3469 Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
3470 Case::setInitialPrimaryHWVsyncEnabled(this,
3471 PowerModeInitialVSyncEnabled<
3472 Case::Transition::INITIAL_POWER_MODE>::value);
3473
3474 // --------------------------------------------------------------------
3475 // Call Expectations
3476
3477 Case::setupSurfaceInterceptorCallExpectations(this, Case::Transition::TARGET_POWER_MODE);
3478 Case::Transition::template setupCallExpectations<Case>(this);
3479
3480 // --------------------------------------------------------------------
3481 // Invocation
3482
3483 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
3484 Case::Transition::TARGET_POWER_MODE);
3485
3486 // --------------------------------------------------------------------
3487 // Postconditions
3488
3489 Case::Transition::verifyPostconditions(this);
3490}
3491
3492TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) {
3493 using Case = SimplePrimaryDisplayCase;
3494
3495 // --------------------------------------------------------------------
3496 // Preconditions
3497
3498 // A primary display device is set up
3499 Case::Display::injectHwcDisplay(this);
3500 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3501 display.inject();
3502
Dominik Laskowskia2edf612018-06-01 13:15:16 -07003503 // The display is already set to HWC_POWER_MODE_NORMAL
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003504 display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
3505
3506 // --------------------------------------------------------------------
3507 // Invocation
3508
3509 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
3510
3511 // --------------------------------------------------------------------
3512 // Postconditions
3513
3514 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3515}
3516
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003517TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) {
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003518 using Case = HwcVirtualDisplayCase;
3519
3520 // --------------------------------------------------------------------
3521 // Preconditions
3522
Dominik Laskowski075d3172018-05-24 15:50:06 -07003523 // Insert display data so that the HWC thinks it created the virtual display.
3524 const auto displayId = Case::Display::DISPLAY_ID::get();
3525 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08003526 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003527
3528 // A virtual display device is set up
3529 Case::Display::injectHwcDisplay(this);
3530 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3531 display.inject();
3532
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003533 // The display is set to HWC_POWER_MODE_NORMAL
3534 getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_NORMAL);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003535
3536 // --------------------------------------------------------------------
3537 // Invocation
3538
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003539 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_OFF);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003540
3541 // --------------------------------------------------------------------
3542 // Postconditions
3543
3544 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3545}
3546
3547TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
3548 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>();
3549}
3550
3551TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) {
3552 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3553}
3554
3555TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) {
3556 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>();
3557}
3558
3559TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) {
3560 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3561}
3562
3563TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) {
3564 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>();
3565}
3566
3567TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) {
3568 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3569}
3570
3571TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) {
3572 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>();
3573}
3574
3575TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) {
3576 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3577}
3578
3579TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) {
3580 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3581}
3582
3583TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) {
3584 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>();
3585}
3586
3587TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) {
3588 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
3589}
3590
3591TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) {
3592 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3593}
3594
3595TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) {
3596 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
3597}
3598
3599TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) {
3600 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3601}
3602
3603TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) {
3604 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>();
3605}
3606
3607TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
3608 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3609}
3610
3611TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) {
3612 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>();
3613}
3614
3615TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
3616 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3617}
3618
3619TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
3620 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3621}
3622
3623TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) {
3624 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
3625}
3626
Lloyd Piquef58625d2017-12-19 13:22:33 -08003627} // namespace
3628} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003629
3630// TODO(b/129481165): remove the #pragma below and fix conversion issues
3631#pragma clang diagnostic pop // ignored "-Wconversion"