1 /*
2 * Copyright 2021 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 <gtest/gtest.h>
18 #include <gui/SurfaceComposerClient.h>
19 #include <private/android_filesystem_config.h>
20 #include <future>
21 #include "utils/TransactionUtils.h"
22
23 namespace android {
24 using Transaction = SurfaceComposerClient::Transaction;
25 using gui::WindowInfo;
26
27 class WindowInfosListenerTest : public ::testing::Test {
28 protected:
SetUp()29 void SetUp() override {
30 seteuid(AID_SYSTEM);
31 mClient = new SurfaceComposerClient;
32 mWindowInfosListener = new SyncWindowInfosListener();
33 mClient->addWindowInfosListener(mWindowInfosListener);
34 }
35
TearDown()36 void TearDown() override {
37 mClient->removeWindowInfosListener(mWindowInfosListener);
38 seteuid(AID_ROOT);
39 }
40
41 struct SyncWindowInfosListener : public gui::WindowInfosListener {
42 public:
onWindowInfosChangedandroid::WindowInfosListenerTest::SyncWindowInfosListener43 void onWindowInfosChanged(const std::vector<WindowInfo>& windowInfos) override {
44 windowInfosPromise.set_value(windowInfos);
45 }
46
waitForWindowInfosandroid::WindowInfosListenerTest::SyncWindowInfosListener47 std::vector<WindowInfo> waitForWindowInfos() {
48 std::future<std::vector<WindowInfo>> windowInfosFuture =
49 windowInfosPromise.get_future();
50 std::vector<WindowInfo> windowInfos = windowInfosFuture.get();
51 windowInfosPromise = std::promise<std::vector<WindowInfo>>();
52 return windowInfos;
53 }
54
55 private:
56 std::promise<std::vector<WindowInfo>> windowInfosPromise;
57 };
58
59 sp<SurfaceComposerClient> mClient;
60 sp<SyncWindowInfosListener> mWindowInfosListener;
61 };
62
findMatchingWindowInfo(WindowInfo targetWindowInfo,std::vector<WindowInfo> windowInfos)63 std::optional<WindowInfo> findMatchingWindowInfo(WindowInfo targetWindowInfo,
64 std::vector<WindowInfo> windowInfos) {
65 std::optional<WindowInfo> foundWindowInfo = std::nullopt;
66 for (WindowInfo windowInfo : windowInfos) {
67 if (windowInfo.token == targetWindowInfo.token) {
68 foundWindowInfo = std::make_optional<>(windowInfo);
69 break;
70 }
71 }
72
73 return foundWindowInfo;
74 }
75
TEST_F(WindowInfosListenerTest,WindowInfoAddedAndRemoved)76 TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
77 std::string name = "Test Layer";
78 sp<IBinder> token = new BBinder();
79 WindowInfo windowInfo;
80 windowInfo.name = name;
81 windowInfo.token = token;
82 sp<SurfaceControl> surfaceControl =
83 mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
84 ISurfaceComposerClient::eFXSurfaceBufferState);
85
86 Transaction()
87 .setLayerStack(surfaceControl, 0)
88 .show(surfaceControl)
89 .setLayer(surfaceControl, INT32_MAX - 1)
90 .setInputWindowInfo(surfaceControl, windowInfo)
91 .apply();
92
93 std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
94 std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
95 ASSERT_NE(std::nullopt, foundWindowInfo);
96
97 Transaction().reparent(surfaceControl, nullptr).apply();
98
99 windowInfos = mWindowInfosListener->waitForWindowInfos();
100 foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
101 ASSERT_EQ(std::nullopt, foundWindowInfo);
102 }
103
TEST_F(WindowInfosListenerTest,WindowInfoChanged)104 TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
105 std::string name = "Test Layer";
106 sp<IBinder> token = new BBinder();
107 WindowInfo windowInfo;
108 windowInfo.name = name;
109 windowInfo.token = token;
110 sp<SurfaceControl> surfaceControl =
111 mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
112 ISurfaceComposerClient::eFXSurfaceBufferState);
113 const Rect crop(0, 0, 100, 100);
114 Transaction()
115 .setLayerStack(surfaceControl, 0)
116 .show(surfaceControl)
117 .setLayer(surfaceControl, INT32_MAX - 1)
118 .setCrop(surfaceControl, crop)
119 .setInputWindowInfo(surfaceControl, windowInfo)
120 .apply();
121
122 std::vector<WindowInfo> windowInfos = mWindowInfosListener->waitForWindowInfos();
123 std::optional<WindowInfo> foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
124 ASSERT_NE(std::nullopt, foundWindowInfo);
125 ASSERT_TRUE(foundWindowInfo->touchableRegion.isEmpty());
126
127 Rect touchableRegions(0, 0, 50, 50);
128 windowInfo.addTouchableRegion(Rect(0, 0, 50, 50));
129 Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();
130
131 windowInfos = mWindowInfosListener->waitForWindowInfos();
132 foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
133 ASSERT_NE(std::nullopt, foundWindowInfo);
134 ASSERT_TRUE(foundWindowInfo->touchableRegion.hasSameRects(windowInfo.touchableRegion));
135 }
136
137 } // namespace android
138