blob: cd114098b18ca777cc62091d32a260f58874603b [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);
Alec Mouri5a6d8572020-03-23 23:56:15 -07001507 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001508 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);
Alec Mouri5a6d8572020-03-23 23:56:15 -07001534 EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08001535 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);
Dominik Laskowski470df5f2020-04-02 22:27:42 -07001734 EXPECT_EQ(NAME_NOT_FOUND,
1735 mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
Daniel Solomon42d04562019-01-20 21:03:19 -08001736
1737 // Check primaries argument wasn't modified in case of failure
1738 checkDummyDisplayNativePrimaries(primaries);
1739}
1740
1741/* ------------------------------------------------------------------------
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001742 * SurfaceFlinger::setupNewDisplayDeviceInternal
1743 */
1744
1745class SetupNewDisplayDeviceInternalTest : public DisplayTransactionTest {
1746public:
1747 template <typename T>
1748 void setupNewDisplayDeviceInternalTest();
1749};
1750
1751template <typename Case>
1752void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
1753 const sp<BBinder> displayToken = new BBinder();
Lloyd Pique542307f2018-10-19 13:24:08 -07001754 const sp<compositionengine::mock::DisplaySurface> displaySurface =
1755 new compositionengine::mock::DisplaySurface();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001756 const sp<mock::GraphicBufferProducer> producer = new mock::GraphicBufferProducer();
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001757
1758 // --------------------------------------------------------------------
1759 // Preconditions
1760
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001761 // Wide color displays support is configured appropriately
1762 Case::WideColorSupport::injectConfigChange(this);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08001763
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001764 // The display is setup with the HWC.
1765 Case::Display::injectHwcDisplay(this);
1766
1767 // SurfaceFlinger will use a test-controlled factory for native window
1768 // surfaces.
1769 injectFakeNativeWindowSurfaceFactory();
1770
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001771 // A compositionengine::Display has already been created
1772 auto compositionDisplay = Case::Display::injectCompositionDisplay(this);
1773
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001774 // --------------------------------------------------------------------
1775 // Call Expectations
1776
1777 // Various native window calls will be made.
1778 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
Lloyd Pique3c085a02018-05-09 19:38:32 -07001779 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001780 Case::WideColorSupport::setupComposerCallExpectations(this);
1781 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001782 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001783
1784 // --------------------------------------------------------------------
1785 // Invocation
1786
1787 DisplayDeviceState state;
Dominik Laskowski55c85402020-01-21 16:25:47 -08001788 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1789 const auto displayId = Case::Display::DISPLAY_ID::get();
1790 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001791 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1792 ASSERT_TRUE(hwcDisplayId);
1793 state.physical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001794 }
1795
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001796 state.isSecure = static_cast<bool>(Case::Display::SECURE);
1797
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001798 auto device = mFlinger.setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
1799 displaySurface, producer);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001800
1801 // --------------------------------------------------------------------
1802 // Postconditions
1803
1804 ASSERT_TRUE(device != nullptr);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001805 EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001806 EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, device->getConnectionType());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001807 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001808 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001809 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001810 EXPECT_EQ(Case::Display::WIDTH, device->getWidth());
1811 EXPECT_EQ(Case::Display::HEIGHT, device->getHeight());
1812 EXPECT_EQ(Case::WideColorSupport::WIDE_COLOR_SUPPORTED, device->hasWideColorGamut());
Valerie Haue9e843a2018-12-18 13:39:23 -08001813 EXPECT_EQ(Case::HdrSupport::HDR10_PLUS_SUPPORTED, device->hasHDR10PlusSupport());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001814 EXPECT_EQ(Case::HdrSupport::HDR10_SUPPORTED, device->hasHDR10Support());
1815 EXPECT_EQ(Case::HdrSupport::HDR_HLG_SUPPORTED, device->hasHLGSupport());
1816 EXPECT_EQ(Case::HdrSupport::HDR_DOLBY_VISION_SUPPORTED, device->hasDolbyVisionSupport());
Lloyd Pique3c085a02018-05-09 19:38:32 -07001817 // Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
1818 // remapped, and the test only ever sets up one config. If there were an error
1819 // looking up the remapped index, device->getActiveConfig() would be -1 instead.
Ady Abraham2139f732019-11-13 18:56:40 -08001820 EXPECT_EQ(0, device->getActiveConfig().value());
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001821 EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
1822 device->getSupportedPerFrameMetadata());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001823}
1824
1825TEST_F(SetupNewDisplayDeviceInternalTest, createSimplePrimaryDisplay) {
1826 setupNewDisplayDeviceInternalTest<SimplePrimaryDisplayCase>();
1827}
1828
1829TEST_F(SetupNewDisplayDeviceInternalTest, createSimpleExternalDisplay) {
1830 setupNewDisplayDeviceInternalTest<SimpleExternalDisplayCase>();
1831}
1832
1833TEST_F(SetupNewDisplayDeviceInternalTest, createNonHwcVirtualDisplay) {
1834 setupNewDisplayDeviceInternalTest<NonHwcVirtualDisplayCase>();
1835}
1836
1837TEST_F(SetupNewDisplayDeviceInternalTest, createHwcVirtualDisplay) {
Lloyd Piqueaad4ebf2019-10-03 17:58:30 -07001838 setupNewDisplayDeviceInternalTest<HwcVirtualDisplayCase>();
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001839}
1840
1841TEST_F(SetupNewDisplayDeviceInternalTest, createWideColorP3Display) {
1842 setupNewDisplayDeviceInternalTest<WideColorP3ColorimetricDisplayCase>();
1843}
1844
Valerie Haue9e843a2018-12-18 13:39:23 -08001845TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10PlusDisplay) {
1846 setupNewDisplayDeviceInternalTest<Hdr10PlusDisplayCase>();
1847}
1848
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001849TEST_F(SetupNewDisplayDeviceInternalTest, createHdr10Display) {
1850 setupNewDisplayDeviceInternalTest<Hdr10DisplayCase>();
1851}
1852
1853TEST_F(SetupNewDisplayDeviceInternalTest, createHdrHlgDisplay) {
1854 setupNewDisplayDeviceInternalTest<HdrHlgDisplayCase>();
1855}
1856
1857TEST_F(SetupNewDisplayDeviceInternalTest, createHdrDolbyVisionDisplay) {
1858 setupNewDisplayDeviceInternalTest<HdrDolbyVisionDisplayCase>();
1859}
1860
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001861TEST_F(SetupNewDisplayDeviceInternalTest, createHdrSmpte2086DisplayCase) {
1862 setupNewDisplayDeviceInternalTest<HdrSmpte2086DisplayCase>();
1863}
1864
1865TEST_F(SetupNewDisplayDeviceInternalTest, createHdrCta816_3_DisplayCase) {
1866 setupNewDisplayDeviceInternalTest<HdrCta861_3_DisplayCase>();
1867}
1868
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001869/* ------------------------------------------------------------------------
1870 * SurfaceFlinger::handleTransactionLocked(eDisplayTransactionNeeded)
1871 */
1872
1873class HandleTransactionLockedTest : public DisplayTransactionTest {
1874public:
1875 template <typename Case>
1876 void setupCommonPreconditions();
1877
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001878 template <typename Case, bool connected>
1879 static void expectHotplugReceived(mock::EventThread*);
1880
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001881 template <typename Case>
1882 void setupCommonCallExpectationsForConnectProcessing();
1883
1884 template <typename Case>
1885 void setupCommonCallExpectationsForDisconnectProcessing();
1886
1887 template <typename Case>
1888 void processesHotplugConnectCommon();
1889
1890 template <typename Case>
1891 void ignoresHotplugConnectCommon();
1892
1893 template <typename Case>
1894 void processesHotplugDisconnectCommon();
1895
1896 template <typename Case>
1897 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
1898
1899 template <typename Case>
1900 void verifyPhysicalDisplayIsConnected();
1901
1902 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
1903};
1904
1905template <typename Case>
1906void HandleTransactionLockedTest::setupCommonPreconditions() {
1907 // Wide color displays support is configured appropriately
1908 Case::WideColorSupport::injectConfigChange(this);
1909
1910 // SurfaceFlinger will use a test-controlled factory for BufferQueues
1911 injectFakeBufferQueueFactory();
1912
1913 // SurfaceFlinger will use a test-controlled factory for native window
1914 // surfaces.
1915 injectFakeNativeWindowSurfaceFactory();
1916}
1917
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001918template <typename Case, bool connected>
1919void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) {
1920 const auto convert = [](auto physicalDisplayId) {
1921 return std::make_optional(DisplayId{physicalDisplayId});
1922 };
1923
1924 EXPECT_CALL(*eventThread,
1925 onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
1926 .Times(1);
1927}
1928
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001929template <typename Case>
1930void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() {
1931 Case::Display::setupHwcHotplugCallExpectations(this);
1932
1933 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
1934 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
1935 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
1936 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
1937
1938 Case::WideColorSupport::setupComposerCallExpectations(this);
1939 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07001940 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001941
1942 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001943 expectHotplugReceived<Case, true>(mEventThread);
1944 expectHotplugReceived<Case, true>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001945}
1946
1947template <typename Case>
1948void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() {
1949 EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1);
Dominik Laskowski1eba0202019-01-24 09:14:40 -08001950
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -08001951 expectHotplugReceived<Case, false>(mEventThread);
1952 expectHotplugReceived<Case, false>(mSFEventThread);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001953}
1954
1955template <typename Case>
1956void HandleTransactionLockedTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
1957 // The display device should have been set up in the list of displays.
1958 ASSERT_TRUE(hasDisplayDevice(displayToken));
1959 const auto& device = getDisplayDevice(displayToken);
1960 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
Dominik Laskowski075d3172018-05-24 15:50:06 -07001961 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001962
Dominik Laskowski55c85402020-01-21 16:25:47 -08001963 std::optional<DisplayDeviceState::Physical> expectedPhysical;
1964 if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
1965 const auto displayId = Case::Display::DISPLAY_ID::get();
1966 ASSERT_TRUE(displayId);
Marin Shalamanov4a42d432020-02-12 20:22:26 +01001967 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
1968 ASSERT_TRUE(hwcDisplayId);
1969 expectedPhysical = {*displayId, *connectionType, *hwcDisplayId};
Dominik Laskowski55c85402020-01-21 16:25:47 -08001970 }
1971
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001972 // The display should have been set up in the current display state
1973 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
1974 const auto& current = getCurrentDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001975 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), current.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001976 EXPECT_EQ(expectedPhysical, current.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001977
1978 // The display should have been set up in the drawing display state
1979 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
1980 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07001981 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Dominik Laskowski55c85402020-01-21 16:25:47 -08001982 EXPECT_EQ(expectedPhysical, draw.physical);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001983}
1984
1985template <typename Case>
1986void HandleTransactionLockedTest::verifyPhysicalDisplayIsConnected() {
1987 // HWComposer should have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07001988 EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001989
Dominik Laskowski075d3172018-05-24 15:50:06 -07001990 // SF should have a display token.
1991 const auto displayId = Case::Display::DISPLAY_ID::get();
1992 ASSERT_TRUE(displayId);
1993 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
1994 auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
Lloyd Piquec11e0d32018-01-22 18:44:59 -08001995
1996 verifyDisplayIsConnected<Case>(displayToken);
1997}
1998
1999void HandleTransactionLockedTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
2000 EXPECT_FALSE(hasDisplayDevice(displayToken));
2001 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2002 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
2003}
2004
2005template <typename Case>
2006void HandleTransactionLockedTest::processesHotplugConnectCommon() {
2007 // --------------------------------------------------------------------
2008 // Preconditions
2009
2010 setupCommonPreconditions<Case>();
2011
2012 // A hotplug connect event is enqueued for a display
2013 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002014
2015 // --------------------------------------------------------------------
2016 // Call Expectations
2017
2018 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillOnce(Return(false));
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002019
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002020 setupCommonCallExpectationsForConnectProcessing<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002021
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002022 // --------------------------------------------------------------------
2023 // Invocation
Lloyd Piquee39cad22017-12-20 17:01:29 -08002024
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002025 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
Lloyd Piquee39cad22017-12-20 17:01:29 -08002026
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002027 // --------------------------------------------------------------------
2028 // Postconditions
2029
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002030 verifyPhysicalDisplayIsConnected<Case>();
Lloyd Piquee39cad22017-12-20 17:01:29 -08002031
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002032 // --------------------------------------------------------------------
2033 // Cleanup conditions
2034
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002035 EXPECT_CALL(*mComposer,
2036 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
Lloyd Pique1fa4d462018-01-22 18:03:16 -08002037 .WillOnce(Return(Error::NONE));
2038 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Piquef58625d2017-12-19 13:22:33 -08002039}
2040
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002041template <typename Case>
2042void HandleTransactionLockedTest::ignoresHotplugConnectCommon() {
2043 // --------------------------------------------------------------------
2044 // Preconditions
2045
2046 setupCommonPreconditions<Case>();
2047
2048 // A hotplug connect event is enqueued for a display
2049 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2050
2051 // --------------------------------------------------------------------
2052 // Invocation
2053
2054 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2055
2056 // --------------------------------------------------------------------
2057 // Postconditions
2058
2059 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002060 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002061}
2062
2063template <typename Case>
2064void HandleTransactionLockedTest::processesHotplugDisconnectCommon() {
2065 // --------------------------------------------------------------------
2066 // Preconditions
2067
2068 setupCommonPreconditions<Case>();
2069
2070 // A hotplug disconnect event is enqueued for a display
2071 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2072
2073 // The display is already completely set up.
2074 Case::Display::injectHwcDisplay(this);
2075 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2076 existing.inject();
2077
2078 // --------------------------------------------------------------------
2079 // Call Expectations
2080
2081 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
Lloyd Pique438e9e72018-09-04 18:06:08 -07002082 EXPECT_CALL(*mComposer, getDisplayIdentificationData(Case::Display::HWC_DISPLAY_ID, _, _))
2083 .Times(0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002084
2085 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2086
2087 // --------------------------------------------------------------------
2088 // Invocation
2089
2090 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2091
2092 // --------------------------------------------------------------------
2093 // Postconditions
2094
2095 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002096 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002097
Dominik Laskowski075d3172018-05-24 15:50:06 -07002098 // SF should not have a display token.
2099 const auto displayId = Case::Display::DISPLAY_ID::get();
2100 ASSERT_TRUE(displayId);
2101 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002102
2103 // The existing token should have been removed
2104 verifyDisplayIsNotConnected(existing.token());
2105}
2106
2107TEST_F(HandleTransactionLockedTest, processesHotplugConnectPrimaryDisplay) {
2108 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2109}
2110
2111TEST_F(HandleTransactionLockedTest,
2112 processesHotplugConnectPrimaryDisplayWithExternalAlreadyConnected) {
2113 // Inject an external display.
2114 ExternalDisplayVariant::injectHwcDisplay(this);
2115
2116 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
2117}
2118
2119TEST_F(HandleTransactionLockedTest, processesHotplugConnectExternalDisplay) {
2120 // Inject a primary display.
2121 PrimaryDisplayVariant::injectHwcDisplay(this);
2122
2123 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
2124}
2125
2126TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
2127 // Inject both a primary and external display.
2128 PrimaryDisplayVariant::injectHwcDisplay(this);
2129 ExternalDisplayVariant::injectHwcDisplay(this);
2130
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002131 // TODO: This is an unnecessary call.
2132 EXPECT_CALL(*mComposer,
2133 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
2134 .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
2135 SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
2136 Return(Error::NONE)));
2137
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002138 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2139
2140 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
2141}
2142
2143TEST_F(HandleTransactionLockedTest, ignoresHotplugConnectIfExternalForVrComposer) {
2144 // Inject a primary display.
2145 PrimaryDisplayVariant::injectHwcDisplay(this);
2146
2147 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(true));
2148
2149 ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
2150}
2151
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002152TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectPrimaryDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002153 processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
2154}
2155
Marin Shalamanov4a42d432020-02-12 20:22:26 +01002156TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectExternalDisplay) {
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002157 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
2158}
2159
2160TEST_F(HandleTransactionLockedTest, processesHotplugConnectThenDisconnectPrimary) {
2161 using Case = SimplePrimaryDisplayCase;
2162
2163 // --------------------------------------------------------------------
2164 // Preconditions
2165
2166 setupCommonPreconditions<Case>();
2167
2168 // A hotplug connect event is enqueued for a display
2169 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2170 // A hotplug disconnect event is also enqueued for the same display
2171 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2172
2173 // --------------------------------------------------------------------
2174 // Call Expectations
2175
2176 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2177
2178 setupCommonCallExpectationsForConnectProcessing<Case>();
2179 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2180
2181 EXPECT_CALL(*mComposer,
2182 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2183 .WillOnce(Return(Error::NONE));
2184 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2185
2186 // --------------------------------------------------------------------
2187 // Invocation
2188
2189 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2190
2191 // --------------------------------------------------------------------
2192 // Postconditions
2193
2194 // HWComposer should not have an entry for the display
Dominik Laskowski075d3172018-05-24 15:50:06 -07002195 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002196
Dominik Laskowski075d3172018-05-24 15:50:06 -07002197 // SF should not have a display token.
2198 const auto displayId = Case::Display::DISPLAY_ID::get();
2199 ASSERT_TRUE(displayId);
2200 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002201}
2202
2203TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
2204 using Case = SimplePrimaryDisplayCase;
2205
2206 // --------------------------------------------------------------------
2207 // Preconditions
2208
2209 setupCommonPreconditions<Case>();
2210
2211 // The display is already completely set up.
2212 Case::Display::injectHwcDisplay(this);
2213 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2214 existing.inject();
2215
2216 // A hotplug disconnect event is enqueued for a display
2217 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
2218 // A hotplug connect event is also enqueued for the same display
2219 Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
2220
2221 // --------------------------------------------------------------------
2222 // Call Expectations
2223
2224 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2225
2226 setupCommonCallExpectationsForConnectProcessing<Case>();
2227 setupCommonCallExpectationsForDisconnectProcessing<Case>();
2228
2229 // --------------------------------------------------------------------
2230 // Invocation
2231
2232 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2233
2234 // --------------------------------------------------------------------
2235 // Postconditions
2236
2237 // The existing token should have been removed
2238 verifyDisplayIsNotConnected(existing.token());
Dominik Laskowski075d3172018-05-24 15:50:06 -07002239 const auto displayId = Case::Display::DISPLAY_ID::get();
2240 ASSERT_TRUE(displayId);
2241 ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
2242 EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002243
2244 // A new display should be connected in its place
2245
2246 verifyPhysicalDisplayIsConnected<Case>();
2247
2248 // --------------------------------------------------------------------
2249 // Cleanup conditions
2250
2251 EXPECT_CALL(*mComposer,
2252 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
2253 .WillOnce(Return(Error::NONE));
2254 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
2255}
2256
2257TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAdded) {
2258 using Case = HwcVirtualDisplayCase;
2259
2260 // --------------------------------------------------------------------
2261 // Preconditions
2262
2263 // The HWC supports at least one virtual display
2264 injectMockComposer(1);
2265
2266 setupCommonPreconditions<Case>();
2267
2268 // A virtual display was added to the current state, and it has a
2269 // surface(producer)
2270 sp<BBinder> displayToken = new BBinder();
Lloyd Pique4c2ac022018-04-27 12:08:03 -07002271
Dominik Laskowski075d3172018-05-24 15:50:06 -07002272 DisplayDeviceState state;
2273 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002274
2275 sp<mock::GraphicBufferProducer> surface{new mock::GraphicBufferProducer()};
Dominik Laskowski075d3172018-05-24 15:50:06 -07002276 state.surface = surface;
2277 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002278
2279 // --------------------------------------------------------------------
2280 // Call Expectations
2281
2282 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
2283 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
2284
2285 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
2286 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
2287 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
2288 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
2289 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
2290 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
2291 Return(NO_ERROR)));
2292 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
2293 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
2294
2295 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
2296
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002297 EXPECT_CALL(*mProducer, connect(_, NATIVE_WINDOW_API_EGL, false, _)).Times(1);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002298 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
2299
2300 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
2301 Case::WideColorSupport::setupComposerCallExpectations(this);
2302 Case::HdrSupport::setupComposerCallExpectations(this);
Lloyd Piqued883d5a2018-04-27 19:32:30 -07002303 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002304
2305 // --------------------------------------------------------------------
2306 // Invocation
2307
2308 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2309
2310 // --------------------------------------------------------------------
2311 // Postconditions
2312
2313 // The display device should have been set up in the list of displays.
2314 verifyDisplayIsConnected<Case>(displayToken);
2315
2316 // --------------------------------------------------------------------
2317 // Cleanup conditions
2318
2319 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
2320 .WillOnce(Return(Error::NONE));
2321 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
Lloyd Pique9e9800c2019-02-26 16:26:09 -08002322
2323 // Cleanup
2324 mFlinger.mutableCurrentState().displays.removeItem(displayToken);
2325 mFlinger.mutableDrawingState().displays.removeItem(displayToken);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002326}
2327
2328TEST_F(HandleTransactionLockedTest, processesVirtualDisplayAddedWithNoSurface) {
2329 using Case = HwcVirtualDisplayCase;
2330
2331 // --------------------------------------------------------------------
2332 // Preconditions
2333
2334 // The HWC supports at least one virtual display
2335 injectMockComposer(1);
2336
2337 setupCommonPreconditions<Case>();
2338
2339 // A virtual display was added to the current state, but it does not have a
2340 // surface.
2341 sp<BBinder> displayToken = new BBinder();
2342
Dominik Laskowski075d3172018-05-24 15:50:06 -07002343 DisplayDeviceState state;
2344 state.isSecure = static_cast<bool>(Case::Display::SECURE);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002345
Dominik Laskowski075d3172018-05-24 15:50:06 -07002346 mFlinger.mutableCurrentState().displays.add(displayToken, state);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002347
2348 // --------------------------------------------------------------------
2349 // Call Expectations
2350
2351 // --------------------------------------------------------------------
2352 // Invocation
2353
2354 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2355
2356 // --------------------------------------------------------------------
2357 // Postconditions
2358
2359 // There will not be a display device set up.
2360 EXPECT_FALSE(hasDisplayDevice(displayToken));
2361
2362 // The drawing display state will be set from the current display state.
2363 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
2364 const auto& draw = getDrawingDisplayState(displayToken);
Dominik Laskowski075d3172018-05-24 15:50:06 -07002365 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002366}
2367
2368TEST_F(HandleTransactionLockedTest, processesVirtualDisplayRemoval) {
2369 using Case = HwcVirtualDisplayCase;
2370
2371 // --------------------------------------------------------------------
2372 // Preconditions
2373
2374 // A virtual display is set up but is removed from the current state.
Dominik Laskowski075d3172018-05-24 15:50:06 -07002375 const auto displayId = Case::Display::DISPLAY_ID::get();
2376 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08002377 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Piquec11e0d32018-01-22 18:44:59 -08002378 Case::Display::injectHwcDisplay(this);
2379 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
2380 existing.inject();
2381 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
2382
2383 // --------------------------------------------------------------------
2384 // Call Expectations
2385
2386 EXPECT_CALL(*mComposer, isUsingVrComposer()).WillRepeatedly(Return(false));
2387
2388 // --------------------------------------------------------------------
2389 // Invocation
2390
2391 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2392
2393 // --------------------------------------------------------------------
2394 // Postconditions
2395
2396 // The existing token should have been removed
2397 verifyDisplayIsNotConnected(existing.token());
2398}
2399
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002400TEST_F(HandleTransactionLockedTest, processesDisplayLayerStackChanges) {
2401 using Case = NonHwcVirtualDisplayCase;
2402
2403 constexpr uint32_t oldLayerStack = 0u;
2404 constexpr uint32_t newLayerStack = 123u;
2405
2406 // --------------------------------------------------------------------
2407 // Preconditions
2408
2409 // A display is set up
2410 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2411 display.inject();
2412
2413 // There is a change to the layerStack state
2414 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
2415 display.mutableCurrentDisplayState().layerStack = newLayerStack;
2416
2417 // --------------------------------------------------------------------
2418 // Invocation
2419
2420 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2421
2422 // --------------------------------------------------------------------
2423 // Postconditions
2424
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002425 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002426}
2427
2428TEST_F(HandleTransactionLockedTest, processesDisplayTransformChanges) {
2429 using Case = NonHwcVirtualDisplayCase;
2430
Dominik Laskowski718f9602019-11-09 20:01:35 -08002431 constexpr ui::Rotation oldTransform = ui::ROTATION_0;
2432 constexpr ui::Rotation newTransform = ui::ROTATION_180;
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002433
2434 // --------------------------------------------------------------------
2435 // Preconditions
2436
2437 // A display is set up
2438 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2439 display.inject();
2440
2441 // There is a change to the orientation state
2442 display.mutableDrawingDisplayState().orientation = oldTransform;
2443 display.mutableCurrentDisplayState().orientation = newTransform;
2444
2445 // --------------------------------------------------------------------
2446 // Invocation
2447
2448 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2449
2450 // --------------------------------------------------------------------
2451 // Postconditions
2452
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002453 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002454}
2455
2456TEST_F(HandleTransactionLockedTest, processesDisplayViewportChanges) {
2457 using Case = NonHwcVirtualDisplayCase;
2458
2459 const Rect oldViewport(0, 0, 0, 0);
2460 const Rect newViewport(0, 0, 123, 456);
2461
2462 // --------------------------------------------------------------------
2463 // Preconditions
2464
2465 // A display is set up
2466 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2467 display.inject();
2468
2469 // There is a change to the viewport state
2470 display.mutableDrawingDisplayState().viewport = oldViewport;
2471 display.mutableCurrentDisplayState().viewport = newViewport;
2472
2473 // --------------------------------------------------------------------
2474 // Invocation
2475
2476 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2477
2478 // --------------------------------------------------------------------
2479 // Postconditions
2480
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002481 EXPECT_EQ(newViewport, display.mutableDisplayDevice()->getViewport());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002482}
2483
2484TEST_F(HandleTransactionLockedTest, processesDisplayFrameChanges) {
2485 using Case = NonHwcVirtualDisplayCase;
2486
2487 const Rect oldFrame(0, 0, 0, 0);
2488 const Rect newFrame(0, 0, 123, 456);
2489
2490 // --------------------------------------------------------------------
2491 // Preconditions
2492
2493 // A display is set up
2494 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2495 display.inject();
2496
2497 // There is a change to the viewport state
2498 display.mutableDrawingDisplayState().frame = oldFrame;
2499 display.mutableCurrentDisplayState().frame = newFrame;
2500
2501 // --------------------------------------------------------------------
2502 // Invocation
2503
2504 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2505
2506 // --------------------------------------------------------------------
2507 // Postconditions
2508
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002509 EXPECT_EQ(newFrame, display.mutableDisplayDevice()->getFrame());
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002510}
2511
2512TEST_F(HandleTransactionLockedTest, processesDisplayWidthChanges) {
2513 using Case = NonHwcVirtualDisplayCase;
2514
2515 constexpr int oldWidth = 0;
2516 constexpr int oldHeight = 10;
2517 constexpr int newWidth = 123;
2518
2519 // --------------------------------------------------------------------
2520 // Preconditions
2521
2522 // A display is set up
2523 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002524 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002525 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002526 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2527 display.setNativeWindow(nativeWindow);
2528 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002529 // Setup injection expections
2530 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2531 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2532 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2533 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002534 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2535 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2536 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002537 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002538 display.inject();
2539
2540 // There is a change to the viewport state
2541 display.mutableDrawingDisplayState().width = oldWidth;
2542 display.mutableDrawingDisplayState().height = oldHeight;
2543 display.mutableCurrentDisplayState().width = newWidth;
2544 display.mutableCurrentDisplayState().height = oldHeight;
2545
2546 // --------------------------------------------------------------------
2547 // Call Expectations
2548
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002549 EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002550
2551 // --------------------------------------------------------------------
2552 // Invocation
2553
2554 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2555}
2556
2557TEST_F(HandleTransactionLockedTest, processesDisplayHeightChanges) {
2558 using Case = NonHwcVirtualDisplayCase;
2559
2560 constexpr int oldWidth = 0;
2561 constexpr int oldHeight = 10;
2562 constexpr int newHeight = 123;
2563
2564 // --------------------------------------------------------------------
2565 // Preconditions
2566
2567 // A display is set up
2568 auto nativeWindow = new mock::NativeWindow();
Lloyd Pique542307f2018-10-19 13:24:08 -07002569 auto displaySurface = new compositionengine::mock::DisplaySurface();
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002570 sp<GraphicBuffer> buf = new GraphicBuffer();
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002571 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2572 display.setNativeWindow(nativeWindow);
2573 display.setDisplaySurface(displaySurface);
Alec Mouri0a9c7b82018-11-16 13:05:25 -08002574 // Setup injection expections
2575 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
2576 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
2577 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
2578 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
Lloyd Pique86fa3db2019-02-04 18:46:01 -08002579 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
2580 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
2581 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
chaviw8beb4142019-04-11 13:09:05 -07002582 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002583 display.inject();
2584
2585 // There is a change to the viewport state
2586 display.mutableDrawingDisplayState().width = oldWidth;
2587 display.mutableDrawingDisplayState().height = oldHeight;
2588 display.mutableCurrentDisplayState().width = oldWidth;
2589 display.mutableCurrentDisplayState().height = newHeight;
2590
2591 // --------------------------------------------------------------------
2592 // Call Expectations
2593
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002594 EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
Lloyd Pique0fa1d4c2018-01-22 18:54:42 -08002595
2596 // --------------------------------------------------------------------
2597 // Invocation
2598
2599 mFlinger.handleTransactionLocked(eDisplayTransactionNeeded);
2600}
2601
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002602/* ------------------------------------------------------------------------
2603 * SurfaceFlinger::setDisplayStateLocked
2604 */
2605
2606TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
2607 // --------------------------------------------------------------------
2608 // Preconditions
2609
2610 // We have an unknown display token not associated with a known display
2611 sp<BBinder> displayToken = new BBinder();
2612
2613 // The requested display state references the unknown display.
2614 DisplayState state;
2615 state.what = DisplayState::eLayerStackChanged;
2616 state.token = displayToken;
2617 state.layerStack = 456;
2618
2619 // --------------------------------------------------------------------
2620 // Invocation
2621
2622 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2623
2624 // --------------------------------------------------------------------
2625 // Postconditions
2626
2627 // The returned flags are empty
2628 EXPECT_EQ(0u, flags);
2629
2630 // The display token still doesn't match anything known.
2631 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
2632}
2633
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002634TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
2635 using Case = SimplePrimaryDisplayCase;
2636
2637 // --------------------------------------------------------------------
2638 // Preconditions
2639
2640 // A display is already set up
2641 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2642 display.inject();
2643
2644 // No changes are made to the display
2645 DisplayState state;
2646 state.what = 0;
2647 state.token = display.token();
2648
2649 // --------------------------------------------------------------------
2650 // Invocation
2651
2652 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2653
2654 // --------------------------------------------------------------------
2655 // Postconditions
2656
2657 // The returned flags are empty
2658 EXPECT_EQ(0u, flags);
2659}
2660
2661TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
2662 using Case = SimplePrimaryDisplayCase;
2663
2664 // --------------------------------------------------------------------
2665 // Preconditions
2666
2667 // A display is already set up
2668 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2669 display.inject();
2670
2671 // There is a surface that can be set.
2672 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2673
2674 // The current display state has the surface set
2675 display.mutableCurrentDisplayState().surface = surface;
2676
2677 // The incoming request sets the same surface
2678 DisplayState state;
2679 state.what = DisplayState::eSurfaceChanged;
2680 state.token = display.token();
2681 state.surface = surface;
2682
2683 // --------------------------------------------------------------------
2684 // Invocation
2685
2686 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2687
2688 // --------------------------------------------------------------------
2689 // Postconditions
2690
2691 // The returned flags are empty
2692 EXPECT_EQ(0u, flags);
2693
2694 // The current display state is unchanged.
2695 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2696}
2697
2698TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
2699 using Case = SimplePrimaryDisplayCase;
2700
2701 // --------------------------------------------------------------------
2702 // Preconditions
2703
2704 // A display is already set up
2705 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2706 display.inject();
2707
2708 // There is a surface that can be set.
2709 sp<mock::GraphicBufferProducer> surface = new mock::GraphicBufferProducer();
2710
2711 // The current display state does not have a surface
2712 display.mutableCurrentDisplayState().surface = nullptr;
2713
2714 // The incoming request sets a surface
2715 DisplayState state;
2716 state.what = DisplayState::eSurfaceChanged;
2717 state.token = display.token();
2718 state.surface = surface;
2719
2720 // --------------------------------------------------------------------
2721 // Invocation
2722
2723 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2724
2725 // --------------------------------------------------------------------
2726 // Postconditions
2727
2728 // The returned flags indicate a transaction is needed
2729 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2730
2731 // The current display layer stack state is set to the new value
2732 EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
2733}
2734
2735TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
2736 using Case = SimplePrimaryDisplayCase;
2737
2738 // --------------------------------------------------------------------
2739 // Preconditions
2740
2741 // A display is already set up
2742 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2743 display.inject();
2744
2745 // The display has a layer stack set
2746 display.mutableCurrentDisplayState().layerStack = 456u;
2747
2748 // The incoming request sets the same layer stack
2749 DisplayState state;
2750 state.what = DisplayState::eLayerStackChanged;
2751 state.token = display.token();
2752 state.layerStack = 456u;
2753
2754 // --------------------------------------------------------------------
2755 // Invocation
2756
2757 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2758
2759 // --------------------------------------------------------------------
2760 // Postconditions
2761
2762 // The returned flags are empty
2763 EXPECT_EQ(0u, flags);
2764
2765 // The current display state is unchanged
2766 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2767}
2768
2769TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
2770 using Case = SimplePrimaryDisplayCase;
2771
2772 // --------------------------------------------------------------------
2773 // Preconditions
2774
2775 // A display is set up
2776 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2777 display.inject();
2778
2779 // The display has a layer stack set
2780 display.mutableCurrentDisplayState().layerStack = 654u;
2781
2782 // The incoming request sets a different layer stack
2783 DisplayState state;
2784 state.what = DisplayState::eLayerStackChanged;
2785 state.token = display.token();
2786 state.layerStack = 456u;
2787
2788 // --------------------------------------------------------------------
2789 // Invocation
2790
2791 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2792
2793 // --------------------------------------------------------------------
2794 // Postconditions
2795
2796 // The returned flags indicate a transaction is needed
2797 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2798
2799 // The desired display state has been set to the new value.
2800 EXPECT_EQ(456u, display.getCurrentDisplayState().layerStack);
2801}
2802
2803TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
2804 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002805 constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002806 const Rect initialFrame = {1, 2, 3, 4};
2807 const Rect initialViewport = {5, 6, 7, 8};
2808
2809 // --------------------------------------------------------------------
2810 // Preconditions
2811
2812 // A display is set up
2813 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2814 display.inject();
2815
2816 // The current display state projection state is all set
2817 display.mutableCurrentDisplayState().orientation = initialOrientation;
2818 display.mutableCurrentDisplayState().frame = initialFrame;
2819 display.mutableCurrentDisplayState().viewport = initialViewport;
2820
2821 // The incoming request sets the same projection state
2822 DisplayState state;
2823 state.what = DisplayState::eDisplayProjectionChanged;
2824 state.token = display.token();
2825 state.orientation = initialOrientation;
2826 state.frame = initialFrame;
2827 state.viewport = initialViewport;
2828
2829 // --------------------------------------------------------------------
2830 // Invocation
2831
2832 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2833
2834 // --------------------------------------------------------------------
2835 // Postconditions
2836
2837 // The returned flags are empty
2838 EXPECT_EQ(0u, flags);
2839
2840 // The current display state is unchanged
2841 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
2842
2843 EXPECT_EQ(initialFrame, display.getCurrentDisplayState().frame);
2844 EXPECT_EQ(initialViewport, display.getCurrentDisplayState().viewport);
2845}
2846
2847TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
2848 using Case = SimplePrimaryDisplayCase;
Dominik Laskowski718f9602019-11-09 20:01:35 -08002849 constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
2850 constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
Lloyd Pique9d9cf402018-02-16 17:47:13 -08002851
2852 // --------------------------------------------------------------------
2853 // Preconditions
2854
2855 // A display is set up
2856 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2857 display.inject();
2858
2859 // The current display state has an orientation set
2860 display.mutableCurrentDisplayState().orientation = initialOrientation;
2861
2862 // The incoming request sets a different orientation
2863 DisplayState state;
2864 state.what = DisplayState::eDisplayProjectionChanged;
2865 state.token = display.token();
2866 state.orientation = desiredOrientation;
2867
2868 // --------------------------------------------------------------------
2869 // Invocation
2870
2871 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2872
2873 // --------------------------------------------------------------------
2874 // Postconditions
2875
2876 // The returned flags indicate a transaction is needed
2877 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2878
2879 // The current display state has the new value.
2880 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
2881}
2882
2883TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
2884 using Case = SimplePrimaryDisplayCase;
2885 const Rect initialFrame = {0, 0, 0, 0};
2886 const Rect desiredFrame = {5, 6, 7, 8};
2887
2888 // --------------------------------------------------------------------
2889 // Preconditions
2890
2891 // A display is set up
2892 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2893 display.inject();
2894
2895 // The current display state does not have a frame
2896 display.mutableCurrentDisplayState().frame = initialFrame;
2897
2898 // The incoming request sets a frame
2899 DisplayState state;
2900 state.what = DisplayState::eDisplayProjectionChanged;
2901 state.token = display.token();
2902 state.frame = desiredFrame;
2903
2904 // --------------------------------------------------------------------
2905 // Invocation
2906
2907 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2908
2909 // --------------------------------------------------------------------
2910 // Postconditions
2911
2912 // The returned flags indicate a transaction is needed
2913 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2914
2915 // The current display state has the new value.
2916 EXPECT_EQ(desiredFrame, display.getCurrentDisplayState().frame);
2917}
2918
2919TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfViewportChanged) {
2920 using Case = SimplePrimaryDisplayCase;
2921 const Rect initialViewport = {0, 0, 0, 0};
2922 const Rect desiredViewport = {5, 6, 7, 8};
2923
2924 // --------------------------------------------------------------------
2925 // Preconditions
2926
2927 // A display is set up
2928 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2929 display.inject();
2930
2931 // The current display state does not have a viewport
2932 display.mutableCurrentDisplayState().viewport = initialViewport;
2933
2934 // The incoming request sets a viewport
2935 DisplayState state;
2936 state.what = DisplayState::eDisplayProjectionChanged;
2937 state.token = display.token();
2938 state.viewport = desiredViewport;
2939
2940 // --------------------------------------------------------------------
2941 // Invocation
2942
2943 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2944
2945 // --------------------------------------------------------------------
2946 // Postconditions
2947
2948 // The returned flags indicate a transaction is needed
2949 EXPECT_EQ(eDisplayTransactionNeeded, flags);
2950
2951 // The current display state has the new value.
2952 EXPECT_EQ(desiredViewport, display.getCurrentDisplayState().viewport);
2953}
2954
2955TEST_F(DisplayTransactionTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
2956 using Case = SimplePrimaryDisplayCase;
2957 constexpr uint32_t initialWidth = 1024;
2958 constexpr uint32_t initialHeight = 768;
2959
2960 // --------------------------------------------------------------------
2961 // Preconditions
2962
2963 // A display is set up
2964 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
2965 display.inject();
2966
2967 // The current display state has a size set
2968 display.mutableCurrentDisplayState().width = initialWidth;
2969 display.mutableCurrentDisplayState().height = initialHeight;
2970
2971 // The incoming request sets the same display size
2972 DisplayState state;
2973 state.what = DisplayState::eDisplaySizeChanged;
2974 state.token = display.token();
2975 state.width = initialWidth;
2976 state.height = initialHeight;
2977
2978 // --------------------------------------------------------------------
2979 // Invocation
2980
2981 uint32_t flags = mFlinger.setDisplayStateLocked(state);
2982
2983 // --------------------------------------------------------------------
2984 // Postconditions
2985
2986 // The returned flags are empty
2987 EXPECT_EQ(0u, flags);
2988
2989 // The current display state is unchanged
2990 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
2991 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
2992}
2993
2994TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
2995 using Case = SimplePrimaryDisplayCase;
2996 constexpr uint32_t initialWidth = 0;
2997 constexpr uint32_t desiredWidth = 1024;
2998
2999 // --------------------------------------------------------------------
3000 // Preconditions
3001
3002 // A display is set up
3003 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3004 display.inject();
3005
3006 // The display does not yet have a width
3007 display.mutableCurrentDisplayState().width = initialWidth;
3008
3009 // The incoming request sets a display width
3010 DisplayState state;
3011 state.what = DisplayState::eDisplaySizeChanged;
3012 state.token = display.token();
3013 state.width = desiredWidth;
3014
3015 // --------------------------------------------------------------------
3016 // Invocation
3017
3018 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3019
3020 // --------------------------------------------------------------------
3021 // Postconditions
3022
3023 // The returned flags indicate a transaction is needed
3024 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3025
3026 // The current display state has the new value.
3027 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
3028}
3029
3030TEST_F(DisplayTransactionTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
3031 using Case = SimplePrimaryDisplayCase;
3032 constexpr uint32_t initialHeight = 0;
3033 constexpr uint32_t desiredHeight = 768;
3034
3035 // --------------------------------------------------------------------
3036 // Preconditions
3037
3038 // A display is set up
3039 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3040 display.inject();
3041
3042 // The display does not yet have a height
3043 display.mutableCurrentDisplayState().height = initialHeight;
3044
3045 // The incoming request sets a display height
3046 DisplayState state;
3047 state.what = DisplayState::eDisplaySizeChanged;
3048 state.token = display.token();
3049 state.height = desiredHeight;
3050
3051 // --------------------------------------------------------------------
3052 // Invocation
3053
3054 uint32_t flags = mFlinger.setDisplayStateLocked(state);
3055
3056 // --------------------------------------------------------------------
3057 // Postconditions
3058
3059 // The returned flags indicate a transaction is needed
3060 EXPECT_EQ(eDisplayTransactionNeeded, flags);
3061
3062 // The current display state has the new value.
3063 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
3064}
3065
Lloyd Pique86016da2018-03-01 16:09:38 -08003066/* ------------------------------------------------------------------------
3067 * SurfaceFlinger::onInitializeDisplays
3068 */
3069
3070TEST_F(DisplayTransactionTest, onInitializeDisplaysSetsUpPrimaryDisplay) {
3071 using Case = SimplePrimaryDisplayCase;
3072
3073 // --------------------------------------------------------------------
3074 // Preconditions
3075
3076 // A primary display is set up
3077 Case::Display::injectHwcDisplay(this);
3078 auto primaryDisplay = Case::Display::makeFakeExistingDisplayInjector(this);
3079 primaryDisplay.inject();
3080
3081 // --------------------------------------------------------------------
3082 // Call Expectations
3083
3084 // We expect the surface interceptor to possibly be used, but we treat it as
3085 // disabled since it is called as a side effect rather than directly by this
3086 // function.
3087 EXPECT_CALL(*mSurfaceInterceptor, isEnabled()).WillOnce(Return(false));
3088
3089 // We expect a call to get the active display config.
3090 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
3091
3092 // We expect invalidate() to be invoked once to trigger display transaction
3093 // processing.
3094 EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
3095
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003096 EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
3097
Lloyd Pique86016da2018-03-01 16:09:38 -08003098 // --------------------------------------------------------------------
3099 // Invocation
3100
3101 mFlinger.onInitializeDisplays();
3102
3103 // --------------------------------------------------------------------
3104 // Postconditions
3105
3106 // The primary display should have a current state
3107 ASSERT_TRUE(hasCurrentDisplayState(primaryDisplay.token()));
3108 const auto& primaryDisplayState = getCurrentDisplayState(primaryDisplay.token());
3109 // The layer stack state should be set to zero
3110 EXPECT_EQ(0u, primaryDisplayState.layerStack);
3111 // The orientation state should be set to zero
Dominik Laskowski718f9602019-11-09 20:01:35 -08003112 EXPECT_EQ(ui::ROTATION_0, primaryDisplayState.orientation);
Lloyd Pique86016da2018-03-01 16:09:38 -08003113
3114 // The frame state should be set to INVALID
3115 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.frame);
3116
3117 // The viewport state should be set to INVALID
3118 EXPECT_EQ(Rect::INVALID_RECT, primaryDisplayState.viewport);
3119
3120 // The width and height should both be zero
3121 EXPECT_EQ(0u, primaryDisplayState.width);
3122 EXPECT_EQ(0u, primaryDisplayState.height);
3123
3124 // The display should be set to HWC_POWER_MODE_NORMAL
3125 ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
3126 auto displayDevice = primaryDisplay.mutableDisplayDevice();
3127 EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
3128
3129 // The display refresh period should be set in the frame tracker.
3130 FrameStats stats;
3131 mFlinger.getAnimFrameTracker().getStats(&stats);
3132 EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
3133
3134 // The display transaction needed flag should be set.
3135 EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
3136
3137 // The compositor timing should be set to default values
3138 const auto& compositorTiming = mFlinger.getCompositorTiming();
3139 EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
3140 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
3141 EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
3142}
3143
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003144/* ------------------------------------------------------------------------
3145 * SurfaceFlinger::setPowerModeInternal
3146 */
3147
3148// Used when we simulate a display that supports doze.
Peiyong Lined531a32018-10-26 18:27:56 -07003149template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003150struct DozeIsSupportedVariant {
3151 static constexpr bool DOZE_SUPPORTED = true;
3152 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3153 IComposerClient::PowerMode::DOZE;
3154 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3155 IComposerClient::PowerMode::DOZE_SUSPEND;
Peiyong Lined531a32018-10-26 18:27:56 -07003156
3157 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3158 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
3159 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>(
3160 {Hwc2::DisplayCapability::DOZE})),
3161 Return(Error::NONE)));
3162 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003163};
3164
Peiyong Lined531a32018-10-26 18:27:56 -07003165template <typename Display>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003166// Used when we simulate a display that does not support doze.
3167struct DozeNotSupportedVariant {
3168 static constexpr bool DOZE_SUPPORTED = false;
3169 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE =
3170 IComposerClient::PowerMode::ON;
3171 static constexpr IComposerClient::PowerMode ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND =
3172 IComposerClient::PowerMode::ON;
Peiyong Lined531a32018-10-26 18:27:56 -07003173
3174 static void setupComposerCallExpectations(DisplayTransactionTest* test) {
3175 EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
3176 .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
3177 Return(Error::NONE)));
3178 }
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003179};
3180
3181struct EventThreadBaseSupportedVariant {
3182 static void setupEventAndEventControlThreadNoCallExpectations(DisplayTransactionTest* test) {
3183 // The event control thread should not be notified.
3184 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(_)).Times(0);
3185
3186 // The event thread should not be notified.
3187 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(0);
3188 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(0);
3189 }
3190};
3191
3192struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
3193 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3194 // These calls are only expected for the primary display.
3195
3196 // Instead expect no calls.
3197 setupEventAndEventControlThreadNoCallExpectations(test);
3198 }
3199
3200 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3201 // These calls are only expected for the primary display.
3202
3203 // Instead expect no calls.
3204 setupEventAndEventControlThreadNoCallExpectations(test);
3205 }
3206};
3207
3208struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
3209 static void setupAcquireAndEnableVsyncCallExpectations(DisplayTransactionTest* test) {
3210 // The event control thread should be notified to enable vsyncs
3211 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(true)).Times(1);
3212
3213 // The event thread should be notified that the screen was acquired.
3214 EXPECT_CALL(*test->mEventThread, onScreenAcquired()).Times(1);
3215 }
3216
3217 static void setupReleaseAndDisableVsyncCallExpectations(DisplayTransactionTest* test) {
3218 // There should be a call to setVsyncEnabled(false)
3219 EXPECT_CALL(*test->mEventControlThread, setVsyncEnabled(false)).Times(1);
3220
3221 // The event thread should not be notified that the screen was released.
3222 EXPECT_CALL(*test->mEventThread, onScreenReleased()).Times(1);
3223 }
3224};
3225
Lloyd Pique41be5d22018-06-21 13:11:48 -07003226struct DispSyncIsSupportedVariant {
3227 static void setupBeginResyncCallExpectations(DisplayTransactionTest* test) {
Lloyd Pique41be5d22018-06-21 13:11:48 -07003228 EXPECT_CALL(*test->mPrimaryDispSync, setPeriod(DEFAULT_REFRESH_RATE)).Times(1);
3229 EXPECT_CALL(*test->mPrimaryDispSync, beginResync()).Times(1);
3230 }
3231
3232 static void setupEndResyncCallExpectations(DisplayTransactionTest* test) {
3233 EXPECT_CALL(*test->mPrimaryDispSync, endResync()).Times(1);
3234 }
3235};
3236
3237struct DispSyncNotSupportedVariant {
3238 static void setupBeginResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3239
3240 static void setupEndResyncCallExpectations(DisplayTransactionTest* /* test */) {}
3241};
3242
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003243// --------------------------------------------------------------------
3244// Note:
3245//
3246// There are a large number of transitions we could test, however we only test a
3247// selected subset which provides complete test coverage of the implementation.
3248// --------------------------------------------------------------------
3249
3250template <int initialPowerMode, int targetPowerMode>
3251struct TransitionVariantCommon {
3252 static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
3253 static constexpr auto TARGET_POWER_MODE = targetPowerMode;
3254
3255 static void verifyPostconditions(DisplayTransactionTest*) {}
3256};
3257
3258struct TransitionOffToOnVariant
3259 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
3260 template <typename Case>
3261 static void setupCallExpectations(DisplayTransactionTest* test) {
3262 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3263 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003264 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003265 Case::setupRepaintEverythingCallExpectations(test);
3266 }
3267
3268 static void verifyPostconditions(DisplayTransactionTest* test) {
3269 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3270 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3271 }
3272};
3273
3274struct TransitionOffToDozeSuspendVariant
3275 : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
3276 template <typename Case>
3277 static void setupCallExpectations(DisplayTransactionTest* test) {
3278 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3279 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3280 Case::setupRepaintEverythingCallExpectations(test);
3281 }
3282
3283 static void verifyPostconditions(DisplayTransactionTest* test) {
3284 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3285 EXPECT_TRUE(test->mFlinger.getHasPoweredOff());
3286 }
3287};
3288
3289struct TransitionOnToOffVariant
3290 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
3291 template <typename Case>
3292 static void setupCallExpectations(DisplayTransactionTest* test) {
3293 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003294 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003295 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3296 }
3297
3298 static void verifyPostconditions(DisplayTransactionTest* test) {
3299 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3300 }
3301};
3302
3303struct TransitionDozeSuspendToOffVariant
3304 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
3305 template <typename Case>
3306 static void setupCallExpectations(DisplayTransactionTest* test) {
3307 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3308 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
3309 }
3310
3311 static void verifyPostconditions(DisplayTransactionTest* test) {
3312 EXPECT_TRUE(test->mFlinger.getVisibleRegionsDirty());
3313 }
3314};
3315
3316struct TransitionOnToDozeVariant
3317 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
3318 template <typename Case>
3319 static void setupCallExpectations(DisplayTransactionTest* test) {
3320 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3321 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3322 }
3323};
3324
3325struct TransitionDozeSuspendToDozeVariant
3326 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
3327 template <typename Case>
3328 static void setupCallExpectations(DisplayTransactionTest* test) {
3329 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003330 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003331 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
3332 }
3333};
3334
3335struct TransitionDozeToOnVariant
3336 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
3337 template <typename Case>
3338 static void setupCallExpectations(DisplayTransactionTest* test) {
3339 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3340 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3341 }
3342};
3343
3344struct TransitionDozeSuspendToOnVariant
3345 : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
3346 template <typename Case>
3347 static void setupCallExpectations(DisplayTransactionTest* test) {
3348 Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003349 Case::DispSync::setupBeginResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003350 Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
3351 }
3352};
3353
3354struct TransitionOnToDozeSuspendVariant
3355 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
3356 template <typename Case>
3357 static void setupCallExpectations(DisplayTransactionTest* test) {
3358 Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
Lloyd Pique41be5d22018-06-21 13:11:48 -07003359 Case::DispSync::setupEndResyncCallExpectations(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003360 Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
3361 }
3362};
3363
3364struct TransitionOnToUnknownVariant
3365 : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
3366 template <typename Case>
3367 static void setupCallExpectations(DisplayTransactionTest* test) {
3368 Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
3369 Case::setupNoComposerPowerModeCallExpectations(test);
3370 }
3371};
3372
3373// --------------------------------------------------------------------
3374// Note:
3375//
3376// Rather than testing the cartesian product of of
3377// DozeIsSupported/DozeNotSupported with all other options, we use one for one
3378// display type, and the other for another display type.
3379// --------------------------------------------------------------------
3380
3381template <typename DisplayVariant, typename DozeVariant, typename EventThreadVariant,
Lloyd Pique41be5d22018-06-21 13:11:48 -07003382 typename DispSyncVariant, typename TransitionVariant>
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003383struct DisplayPowerCase {
3384 using Display = DisplayVariant;
3385 using Doze = DozeVariant;
3386 using EventThread = EventThreadVariant;
Lloyd Pique41be5d22018-06-21 13:11:48 -07003387 using DispSync = DispSyncVariant;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003388 using Transition = TransitionVariant;
3389
3390 static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
Lloyd Pique86fa3db2019-02-04 18:46:01 -08003391 Display::injectHwcDisplayWithNoDefaultCapabilities(test);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003392 auto display = Display::makeFakeExistingDisplayInjector(test);
3393 display.inject();
3394 display.mutableDisplayDevice()->setPowerMode(mode);
3395 return display;
3396 }
3397
3398 static void setInitialPrimaryHWVsyncEnabled(DisplayTransactionTest* test, bool enabled) {
Dominik Laskowski7c9dbf92019-08-01 17:57:31 -07003399 test->mFlinger.scheduler()->mutablePrimaryHWVsyncEnabled() = enabled;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003400 }
3401
3402 static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
3403 EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
3404 }
3405
3406 static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
3407 EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
3408 EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
3409 }
3410
3411 static void setupComposerCallExpectations(DisplayTransactionTest* test,
3412 IComposerClient::PowerMode mode) {
3413 // Any calls to get the active config will return a default value.
3414 EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
3415 .WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
3416 Return(Error::NONE)));
3417
3418 // Any calls to get whether the display supports dozing will return the value set by the
3419 // policy variant.
3420 EXPECT_CALL(*test->mComposer, getDozeSupport(Display::HWC_DISPLAY_ID, _))
3421 .WillRepeatedly(DoAll(SetArgPointee<1>(Doze::DOZE_SUPPORTED), Return(Error::NONE)));
3422
3423 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, mode)).Times(1);
3424 }
3425
3426 static void setupNoComposerPowerModeCallExpectations(DisplayTransactionTest* test) {
3427 EXPECT_CALL(*test->mComposer, setPowerMode(Display::HWC_DISPLAY_ID, _)).Times(0);
3428 }
3429};
3430
3431// A sample configuration for the primary display.
3432// In addition to having event thread support, we emulate doze support.
3433template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003434using PrimaryDisplayPowerCase =
3435 DisplayPowerCase<PrimaryDisplayVariant, DozeIsSupportedVariant<PrimaryDisplayVariant>,
3436 EventThreadIsSupportedVariant, DispSyncIsSupportedVariant,
3437 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003438
3439// A sample configuration for the external display.
3440// In addition to not having event thread support, we emulate not having doze
3441// support.
3442template <typename TransitionVariant>
Peiyong Lined531a32018-10-26 18:27:56 -07003443using ExternalDisplayPowerCase =
3444 DisplayPowerCase<ExternalDisplayVariant, DozeNotSupportedVariant<ExternalDisplayVariant>,
3445 EventThreadNotSupportedVariant, DispSyncNotSupportedVariant,
3446 TransitionVariant>;
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003447
3448class SetPowerModeInternalTest : public DisplayTransactionTest {
3449public:
3450 template <typename Case>
3451 void transitionDisplayCommon();
3452};
3453
3454template <int PowerMode>
3455struct PowerModeInitialVSyncEnabled : public std::false_type {};
3456
3457template <>
3458struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
3459
3460template <>
3461struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
3462
3463template <typename Case>
3464void SetPowerModeInternalTest::transitionDisplayCommon() {
3465 // --------------------------------------------------------------------
3466 // Preconditions
3467
Peiyong Lined531a32018-10-26 18:27:56 -07003468 Case::Doze::setupComposerCallExpectations(this);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003469 auto display =
3470 Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
3471 Case::setInitialPrimaryHWVsyncEnabled(this,
3472 PowerModeInitialVSyncEnabled<
3473 Case::Transition::INITIAL_POWER_MODE>::value);
3474
3475 // --------------------------------------------------------------------
3476 // Call Expectations
3477
3478 Case::setupSurfaceInterceptorCallExpectations(this, Case::Transition::TARGET_POWER_MODE);
3479 Case::Transition::template setupCallExpectations<Case>(this);
3480
3481 // --------------------------------------------------------------------
3482 // Invocation
3483
3484 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(),
3485 Case::Transition::TARGET_POWER_MODE);
3486
3487 // --------------------------------------------------------------------
3488 // Postconditions
3489
3490 Case::Transition::verifyPostconditions(this);
3491}
3492
3493TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfNoChange) {
3494 using Case = SimplePrimaryDisplayCase;
3495
3496 // --------------------------------------------------------------------
3497 // Preconditions
3498
3499 // A primary display device is set up
3500 Case::Display::injectHwcDisplay(this);
3501 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3502 display.inject();
3503
Dominik Laskowskia2edf612018-06-01 13:15:16 -07003504 // The display is already set to HWC_POWER_MODE_NORMAL
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003505 display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
3506
3507 // --------------------------------------------------------------------
3508 // Invocation
3509
3510 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
3511
3512 // --------------------------------------------------------------------
3513 // Postconditions
3514
3515 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3516}
3517
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003518TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) {
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003519 using Case = HwcVirtualDisplayCase;
3520
3521 // --------------------------------------------------------------------
3522 // Preconditions
3523
Dominik Laskowski075d3172018-05-24 15:50:06 -07003524 // Insert display data so that the HWC thinks it created the virtual display.
3525 const auto displayId = Case::Display::DISPLAY_ID::get();
3526 ASSERT_TRUE(displayId);
Dominik Laskowski1af47932018-11-12 10:20:46 -08003527 mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003528
3529 // A virtual display device is set up
3530 Case::Display::injectHwcDisplay(this);
3531 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
3532 display.inject();
3533
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003534 // The display is set to HWC_POWER_MODE_NORMAL
3535 getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_NORMAL);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003536
3537 // --------------------------------------------------------------------
3538 // Invocation
3539
Dominik Laskowskieecd6592018-05-29 10:25:41 -07003540 mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_OFF);
Lloyd Pique7d4aa6c2018-03-01 16:36:35 -08003541
3542 // --------------------------------------------------------------------
3543 // Postconditions
3544
3545 EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
3546}
3547
3548TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
3549 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToOnVariant>>();
3550}
3551
3552TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendPrimaryDisplay) {
3553 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3554}
3555
3556TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffPrimaryDisplay) {
3557 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToOffVariant>>();
3558}
3559
3560TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffPrimaryDisplay) {
3561 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3562}
3563
3564TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozePrimaryDisplay) {
3565 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeVariant>>();
3566}
3567
3568TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozePrimaryDisplay) {
3569 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3570}
3571
3572TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnPrimaryDisplay) {
3573 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeToOnVariant>>();
3574}
3575
3576TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnPrimaryDisplay) {
3577 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3578}
3579
3580TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendPrimaryDisplay) {
3581 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3582}
3583
3584TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownPrimaryDisplay) {
3585 transitionDisplayCommon<PrimaryDisplayPowerCase<TransitionOnToUnknownVariant>>();
3586}
3587
3588TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnExternalDisplay) {
3589 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
3590}
3591
3592TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToDozeSuspendExternalDisplay) {
3593 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToDozeSuspendVariant>>();
3594}
3595
3596TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToOffExternalDisplay) {
3597 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
3598}
3599
3600TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOffExternalDisplay) {
3601 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOffVariant>>();
3602}
3603
3604TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeExternalDisplay) {
3605 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeVariant>>();
3606}
3607
3608TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
3609 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
3610}
3611
3612TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeToOnExternalDisplay) {
3613 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeToOnVariant>>();
3614}
3615
3616TEST_F(SetPowerModeInternalTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
3617 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
3618}
3619
3620TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
3621 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
3622}
3623
3624TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOnToUnknownExternalDisplay) {
3625 transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToUnknownVariant>>();
3626}
3627
Lloyd Piquef58625d2017-12-19 13:22:33 -08003628} // namespace
3629} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003630
3631// TODO(b/129481165): remove the #pragma below and fix conversion issues
3632#pragma clang diagnostic pop // ignored "-Wconversion"