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 "DualDisplayTransactionTest.h"
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 namespace android {
26 namespace {
27 
28 struct ActiveDisplayRotationFlagsTest
29       : DualDisplayTransactionTest<hal::PowerMode::ON, hal::PowerMode::OFF> {
SetUpandroid::__anonc912ddb10111::ActiveDisplayRotationFlagsTest30     void SetUp() override {
31         DualDisplayTransactionTest::SetUp();
32 
33         // The flags are a static variable, so by modifying them in the test, we
34         // are modifying the real ones used by SurfaceFlinger. Save the original
35         // flags so we can restore them on teardown. This isn't perfect - the
36         // phone may have been rotated during the test, so we're restoring the
37         // wrong flags. But if the phone is rotated, this may also fail the test.
38         mOldRotationFlags = mFlinger.mutableActiveDisplayRotationFlags();
39 
40         // Reset to the expected default state.
41         mFlinger.mutableActiveDisplayRotationFlags() = ui::Transform::ROT_0;
42     }
43 
TearDownandroid::__anonc912ddb10111::ActiveDisplayRotationFlagsTest44     void TearDown() override { mFlinger.mutableActiveDisplayRotationFlags() = mOldRotationFlags; }
45 
46     ui::Transform::RotationFlags mOldRotationFlags;
47 };
48 
TEST_F(ActiveDisplayRotationFlagsTest,defaultRotation)49 TEST_F(ActiveDisplayRotationFlagsTest, defaultRotation) {
50     ASSERT_EQ(ui::Transform::ROT_0, SurfaceFlinger::getActiveDisplayRotationFlags());
51 }
52 
TEST_F(ActiveDisplayRotationFlagsTest,rotate90)53 TEST_F(ActiveDisplayRotationFlagsTest, rotate90) {
54     auto displayToken = mInnerDisplay->getDisplayToken().promote();
55     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
56     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
57             ui::ROTATION_90;
58 
59     mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
60     ASSERT_EQ(ui::Transform::ROT_90, SurfaceFlinger::getActiveDisplayRotationFlags());
61 }
62 
TEST_F(ActiveDisplayRotationFlagsTest,rotate90inactive)63 TEST_F(ActiveDisplayRotationFlagsTest, rotate90inactive) {
64     auto displayToken = mOuterDisplay->getDisplayToken().promote();
65     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
66     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
67             ui::ROTATION_90;
68 
69     mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
70     ASSERT_EQ(ui::Transform::ROT_0, SurfaceFlinger::getActiveDisplayRotationFlags());
71 }
72 
TEST_F(ActiveDisplayRotationFlagsTest,rotateBothInnerActive)73 TEST_F(ActiveDisplayRotationFlagsTest, rotateBothInnerActive) {
74     auto displayToken = mInnerDisplay->getDisplayToken().promote();
75     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
76     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
77             ui::ROTATION_180;
78 
79     displayToken = mOuterDisplay->getDisplayToken().promote();
80     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
81     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
82             ui::ROTATION_270;
83 
84     mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
85     ASSERT_EQ(ui::Transform::ROT_180, SurfaceFlinger::getActiveDisplayRotationFlags());
86 }
87 
TEST_F(ActiveDisplayRotationFlagsTest,rotateBothOuterActive)88 TEST_F(ActiveDisplayRotationFlagsTest, rotateBothOuterActive) {
89     mFlinger.mutableActiveDisplayId() = kOuterDisplayId;
90     auto displayToken = mInnerDisplay->getDisplayToken().promote();
91     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
92     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
93             ui::ROTATION_180;
94 
95     displayToken = mOuterDisplay->getDisplayToken().promote();
96     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
97     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
98             ui::ROTATION_270;
99 
100     mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
101     ASSERT_EQ(ui::Transform::ROT_270, SurfaceFlinger::getActiveDisplayRotationFlags());
102 }
103 
TEST_F(ActiveDisplayRotationFlagsTest,onActiveDisplayChanged)104 TEST_F(ActiveDisplayRotationFlagsTest, onActiveDisplayChanged) {
105     auto displayToken = mInnerDisplay->getDisplayToken().promote();
106     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
107     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
108             ui::ROTATION_180;
109 
110     displayToken = mOuterDisplay->getDisplayToken().promote();
111     mFlinger.mutableDrawingState().displays.editValueFor(displayToken).orientation = ui::ROTATION_0;
112     mFlinger.mutableCurrentState().displays.editValueFor(displayToken).orientation =
113             ui::ROTATION_270;
114 
115     mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
116     ASSERT_EQ(ui::Transform::ROT_180, SurfaceFlinger::getActiveDisplayRotationFlags());
117 
118     mFlinger.onActiveDisplayChanged(mInnerDisplay.get(), *mOuterDisplay);
119     ASSERT_EQ(ui::Transform::ROT_270, SurfaceFlinger::getActiveDisplayRotationFlags());
120 }
121 
122 } // namespace
123 } // namespace android
124