blob: 7077523fc37d56dae75b732276aa1c137dcb91e4 [file] [log] [blame]
Leon Scroggins III85d4b222023-05-09 13:58:18 -04001/*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#undef LOG_TAG
18#define LOG_TAG "LibSurfaceFlingerUnittests"
19
20#include "DisplayTransactionTestHelpers.h"
21
22#include <gmock/gmock.h>
23#include <gtest/gtest.h>
24
25namespace android {
26namespace {
27
28struct ActiveDisplayRotationFlagsTest : DisplayTransactionTest {
29 static constexpr bool kWithMockScheduler = false;
30 ActiveDisplayRotationFlagsTest() : DisplayTransactionTest(kWithMockScheduler) {}
31
32 void SetUp() override {
33 injectMockScheduler(kInnerDisplayId);
34
35 // Inject inner and outer displays with uninitialized power modes.
36 constexpr bool kInitPowerMode = false;
37 {
38 InnerDisplayVariant::injectHwcDisplay<kInitPowerMode>(this);
39 auto injector = InnerDisplayVariant::makeFakeExistingDisplayInjector(this);
40 injector.setPowerMode(std::nullopt);
41 injector.setRefreshRateSelector(mFlinger.scheduler()->refreshRateSelector());
42 mInnerDisplay = injector.inject();
43 }
44 {
45 OuterDisplayVariant::injectHwcDisplay<kInitPowerMode>(this);
46 auto injector = OuterDisplayVariant::makeFakeExistingDisplayInjector(this);
47 injector.setPowerMode(std::nullopt);
48 mOuterDisplay = injector.inject();
49 }
50
51 mFlinger.setPowerModeInternal(mInnerDisplay, PowerMode::ON);
52 mFlinger.setPowerModeInternal(mOuterDisplay, PowerMode::ON);
53
54 // The flags are a static variable, so by modifying them in the test, we
55 // are modifying the real ones used by SurfaceFlinger. Save the original
56 // flags so we can restore them on teardown. This isn't perfect - the
57 // phone may have been rotated during the test, so we're restoring the
58 // wrong flags. But if the phone is rotated, this may also fail the test.
59 mOldRotationFlags = mFlinger.mutableActiveDisplayRotationFlags();
60
61 // Reset to the expected default state.
62 mFlinger.mutableActiveDisplayRotationFlags() = ui::Transform::ROT_0;
63 }
64
65 void TearDown() override { mFlinger.mutableActiveDisplayRotationFlags() = mOldRotationFlags; }
66
67 static inline PhysicalDisplayId kInnerDisplayId = InnerDisplayVariant::DISPLAY_ID::get();
68 static inline PhysicalDisplayId kOuterDisplayId = OuterDisplayVariant::DISPLAY_ID::get();
69
70 sp<DisplayDevice> mInnerDisplay, mOuterDisplay;
71 ui::Transform::RotationFlags mOldRotationFlags;
72};
73
74TEST_F(ActiveDisplayRotationFlagsTest, defaultRotation) {
75 ASSERT_EQ(ui::Transform::ROT_0, SurfaceFlinger::getActiveDisplayRotationFlags());
76}
77
78TEST_F(ActiveDisplayRotationFlagsTest, rotate90) {
79 auto displayToken = mInnerDisplay->getDisplayToken().promote();
80 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
81 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
82 ui::ROTATION_90;
83
84 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
85 ASSERT_EQ(ui::Transform::ROT_90, SurfaceFlinger::getActiveDisplayRotationFlags());
86}
87
88TEST_F(ActiveDisplayRotationFlagsTest, rotate90_inactive) {
89 auto displayToken = mOuterDisplay->getDisplayToken().promote();
90 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
91 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
92 ui::ROTATION_90;
93
94 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
95 ASSERT_EQ(ui::Transform::ROT_0, SurfaceFlinger::getActiveDisplayRotationFlags());
96}
97
98TEST_F(ActiveDisplayRotationFlagsTest, rotateBoth_innerActive) {
99 auto displayToken = mInnerDisplay->getDisplayToken().promote();
100 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
101 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
102 ui::ROTATION_180;
103
104 displayToken = mOuterDisplay->getDisplayToken().promote();
105 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
106 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
107 ui::ROTATION_270;
108
109 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
110 ASSERT_EQ(ui::Transform::ROT_180, SurfaceFlinger::getActiveDisplayRotationFlags());
111}
112
113TEST_F(ActiveDisplayRotationFlagsTest, rotateBoth_outerActive) {
114 mFlinger.mutableActiveDisplayId() = kOuterDisplayId;
115 auto displayToken = mInnerDisplay->getDisplayToken().promote();
116 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
117 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
118 ui::ROTATION_180;
119
120 displayToken = mOuterDisplay->getDisplayToken().promote();
121 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
122 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
123 ui::ROTATION_270;
124
125 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
126 ASSERT_EQ(ui::Transform::ROT_270, SurfaceFlinger::getActiveDisplayRotationFlags());
127}
128
129TEST_F(ActiveDisplayRotationFlagsTest, onActiveDisplayChanged) {
130 auto displayToken = mInnerDisplay->getDisplayToken().promote();
131 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
132 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
133 ui::ROTATION_180;
134
135 displayToken = mOuterDisplay->getDisplayToken().promote();
136 mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
137 mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
138 ui::ROTATION_270;
139
140 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
141 ASSERT_EQ(ui::Transform::ROT_180, SurfaceFlinger::getActiveDisplayRotationFlags());
142
143 mFlinger.onActiveDisplayChanged(mInnerDisplay.get(), *mOuterDisplay);
144 ASSERT_EQ(ui::Transform::ROT_270, SurfaceFlinger::getActiveDisplayRotationFlags());
145}
146
147} // namespace
148} // namespace android