1 /*
2  * Copyright 2020 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 #include <thread>
18 
19 #include <gtest/gtest.h>
20 
21 #include <gui/AidlStatusUtil.h>
22 #include <gui/SurfaceComposerClient.h>
23 #include <private/gui/ComposerService.h>
24 #include <private/gui/ComposerServiceAIDL.h>
25 #include <chrono>
26 
27 namespace android {
28 
29 using gui::aidl_utils::statusTFromBinderStatus;
30 
31 struct BootDisplayModeTest : public ::testing::Test {
32 protected:
SetUpandroid::BootDisplayModeTest33     void SetUp() override {
34         mSf = ComposerServiceAIDL::getComposerService();
35 
36         const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
37         ASSERT_FALSE(ids.empty());
38         mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
39         bool bootModeSupport = false;
40         binder::Status status = mSf->getBootDisplayModeSupport(&bootModeSupport);
41         ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
42 
43         if (!bootModeSupport) {
44             GTEST_SKIP() << "Boot mode not supported";
45         }
46 
47         gui::DynamicDisplayInfo info;
48         status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
49         ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
50         mOldMode = info.preferredBootDisplayMode;
51         const auto newMode = [&]() -> std::optional<ui::DisplayModeId> {
52             for (const auto& mode : info.supportedDisplayModes) {
53                 if (mode.id != mOldMode) {
54                     return std::optional(mode.id);
55                 }
56             }
57             return std::nullopt;
58         }();
59 
60         if (!newMode) {
61             GTEST_SKIP() << "Only a single mode is supported";
62         }
63 
64         mNewMode = *newMode;
65     }
66 
TearDownandroid::BootDisplayModeTest67     void TearDown() override {
68         binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mOldMode);
69         EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
70 
71         gui::DynamicDisplayInfo info;
72         status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
73         EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
74         EXPECT_EQ(mOldMode, info.preferredBootDisplayMode);
75     }
76 
77     ui::DisplayModeId mOldMode;
78     ui::DisplayModeId mNewMode;
79     sp<gui::ISurfaceComposer> mSf;
80     sp<IBinder> mDisplayToken;
81 };
82 
TEST_F(BootDisplayModeTest,setBootDisplayMode)83 TEST_F(BootDisplayModeTest, setBootDisplayMode) {
84     // Set a new mode and check that it got applied
85     binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mNewMode);
86     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
87 
88     gui::DynamicDisplayInfo info;
89     status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
90     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
91     EXPECT_EQ(mNewMode, info.preferredBootDisplayMode);
92 }
93 
TEST_F(BootDisplayModeTest,clearBootDisplayMode)94 TEST_F(BootDisplayModeTest, clearBootDisplayMode) {
95     // Clear once to figure out what the system default is
96     binder::Status status = mSf->clearBootDisplayMode(mDisplayToken);
97     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
98 
99     gui::DynamicDisplayInfo info;
100     status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
101     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
102 
103     const ui::DisplayModeId systemMode = info.preferredBootDisplayMode;
104     const ui::DisplayModeId newMode = systemMode == mOldMode ? mNewMode : mOldMode;
105 
106     // Now set a new mode and clear the boot mode again to figure out if the api worked.
107     status = mSf->setBootDisplayMode(mDisplayToken, newMode);
108     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
109 
110     status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
111     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
112     EXPECT_EQ(newMode, info.preferredBootDisplayMode);
113 
114     status = mSf->clearBootDisplayMode(mDisplayToken);
115     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
116 
117     status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
118     EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
119     EXPECT_EQ(systemMode, info.preferredBootDisplayMode);
120 }
121 
122 } // namespace android
123