• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
25 namespace android {
26 namespace {
27 
28 struct ActiveDisplayRotationFlagsTest : DisplayTransactionTest {
29     static constexpr bool kWithMockScheduler = false;
ActiveDisplayRotationFlagsTestandroid::__anonc1a479800111::ActiveDisplayRotationFlagsTest30     ActiveDisplayRotationFlagsTest() : DisplayTransactionTest(kWithMockScheduler) {}
31 
SetUpandroid::__anonc1a479800111::ActiveDisplayRotationFlagsTest32     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 
TearDownandroid::__anonc1a479800111::ActiveDisplayRotationFlagsTest65     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 
TEST_F(ActiveDisplayRotationFlagsTest,defaultRotation)74 TEST_F(ActiveDisplayRotationFlagsTest, defaultRotation) {
75     ASSERT_EQ(ui::Transform::ROT_0, SurfaceFlinger::getActiveDisplayRotationFlags());
76 }
77 
TEST_F(ActiveDisplayRotationFlagsTest,rotate90)78 TEST_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 
TEST_F(ActiveDisplayRotationFlagsTest,rotate90_inactive)88 TEST_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 
TEST_F(ActiveDisplayRotationFlagsTest,rotateBoth_innerActive)98 TEST_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 
TEST_F(ActiveDisplayRotationFlagsTest,rotateBoth_outerActive)113 TEST_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 
TEST_F(ActiveDisplayRotationFlagsTest,onActiveDisplayChanged)129 TEST_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
149