• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gui/WindowInfosUpdate.h>
20 #include <private/android_filesystem_config.h>
21 #include <cstdint>
22 #include <future>
23 #include "utils/WindowInfosListenerUtils.h"
24 
25 namespace android {
26 using Transaction = SurfaceComposerClient::Transaction;
27 using gui::DisplayInfo;
28 using gui::WindowInfo;
29 constexpr auto findMatchingWindowInfo = WindowInfosListenerUtils::findMatchingWindowInfo;
30 
31 using WindowInfosPredicate = std::function<bool(const std::vector<WindowInfo>&)>;
32 
33 class WindowInfosListenerTest : public ::testing::Test {
34 protected:
SetUp()35     void SetUp() override {
36         seteuid(AID_SYSTEM);
37         mClient = sp<SurfaceComposerClient>::make();
38     }
39 
TearDown()40     void TearDown() override { seteuid(AID_ROOT); }
41 
42     sp<SurfaceComposerClient> mClient;
43     WindowInfosListenerUtils mWindowInfosListenerUtils;
44 
waitForWindowInfosPredicate(const WindowInfosPredicate & predicate)45     bool waitForWindowInfosPredicate(const WindowInfosPredicate& predicate) {
46         return mWindowInfosListenerUtils.waitForWindowInfosPredicate(std::move(predicate));
47     }
48 };
49 
TEST_F(WindowInfosListenerTest,WindowInfoAddedAndRemoved)50 TEST_F(WindowInfosListenerTest, WindowInfoAddedAndRemoved) {
51     std::string name = "Test Layer";
52     sp<IBinder> token = sp<BBinder>::make();
53     WindowInfo windowInfo;
54     windowInfo.name = name;
55     windowInfo.token = token;
56     sp<SurfaceControl> surfaceControl =
57             mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
58                                    ISurfaceComposerClient::eFXSurfaceBufferState);
59 
60     Transaction()
61             .setLayerStack(surfaceControl, ui::DEFAULT_LAYER_STACK)
62             .show(surfaceControl)
63             .setLayer(surfaceControl, INT32_MAX - 1)
64             .setInputWindowInfo(surfaceControl, windowInfo)
65             .apply();
66 
67     auto windowPresent = [&](const std::vector<WindowInfo>& windowInfos) {
68         return findMatchingWindowInfo(windowInfo, windowInfos);
69     };
70     ASSERT_TRUE(waitForWindowInfosPredicate(windowPresent));
71 
72     Transaction().reparent(surfaceControl, nullptr).apply();
73 
74     auto windowNotPresent = [&](const std::vector<WindowInfo>& windowInfos) {
75         return !findMatchingWindowInfo(windowInfo, windowInfos);
76     };
77     ASSERT_TRUE(waitForWindowInfosPredicate(windowNotPresent));
78 }
79 
TEST_F(WindowInfosListenerTest,WindowInfoChanged)80 TEST_F(WindowInfosListenerTest, WindowInfoChanged) {
81     std::string name = "Test Layer";
82     sp<IBinder> token = sp<BBinder>::make();
83     WindowInfo windowInfo;
84     windowInfo.name = name;
85     windowInfo.token = token;
86     sp<SurfaceControl> surfaceControl =
87             mClient->createSurface(String8(name.c_str()), 100, 100, PIXEL_FORMAT_RGBA_8888,
88                                    ISurfaceComposerClient::eFXSurfaceBufferState);
89     const Rect crop(0, 0, 100, 100);
90     Transaction()
91             .setLayerStack(surfaceControl, ui::DEFAULT_LAYER_STACK)
92             .show(surfaceControl)
93             .setLayer(surfaceControl, INT32_MAX - 1)
94             .setCrop(surfaceControl, crop)
95             .setInputWindowInfo(surfaceControl, windowInfo)
96             .apply();
97 
98     auto windowIsPresentAndTouchableRegionEmpty = [&](const std::vector<WindowInfo>& windowInfos) {
99         auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
100         if (!foundWindowInfo) {
101             return false;
102         }
103         return foundWindowInfo->touchableRegion.isEmpty();
104     };
105     ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionEmpty));
106 
107     windowInfo.addTouchableRegion({0, 0, 50, 50});
108     Transaction().setInputWindowInfo(surfaceControl, windowInfo).apply();
109 
110     auto windowIsPresentAndTouchableRegionMatches =
111             [&](const std::vector<WindowInfo>& windowInfos) {
112                 auto foundWindowInfo = findMatchingWindowInfo(windowInfo, windowInfos);
113                 if (!foundWindowInfo) {
114                     return false;
115                 }
116 
117                 auto touchableRegion =
118                         foundWindowInfo->transform.transform(foundWindowInfo->touchableRegion);
119                 return touchableRegion.hasSameRects(windowInfo.touchableRegion);
120             };
121     ASSERT_TRUE(waitForWindowInfosPredicate(windowIsPresentAndTouchableRegionMatches));
122 }
123 
124 } // namespace android
125