xref: /aosp_15_r20/frameworks/native/libs/gui/tests/EndToEndNativeInputTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2018 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <sys/time.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <stdio.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <poll.h>
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker #include <memory>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/BnWindowInfosReportedListener.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <android/keycodes.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <android/native_window.h>
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker #include <binder/Binder.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
34*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
36*38e8c45fSAndroid Build Coastguard Worker 
37*38e8c45fSAndroid Build Coastguard Worker #include <gui/IConsumerListener.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <gui/IGraphicBufferConsumer.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <gui/ISurfaceComposer.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
41*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
42*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceControl.h>
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IInputFlinger.h>
45*38e8c45fSAndroid Build Coastguard Worker #include <gui/WindowInfo.h>
46*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h>
47*38e8c45fSAndroid Build Coastguard Worker #include <input/InputConsumer.h>
48*38e8c45fSAndroid Build Coastguard Worker #include <input/InputTransport.h>
49*38e8c45fSAndroid Build Coastguard Worker 
50*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayMode.h>
51*38e8c45fSAndroid Build Coastguard Worker #include <ui/Rect.h>
52*38e8c45fSAndroid Build Coastguard Worker #include <ui/Region.h>
53*38e8c45fSAndroid Build Coastguard Worker 
54*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
55*38e8c45fSAndroid Build Coastguard Worker 
56*38e8c45fSAndroid Build Coastguard Worker using android::os::IInputFlinger;
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_1::BufferUsage;
59*38e8c45fSAndroid Build Coastguard Worker 
60*38e8c45fSAndroid Build Coastguard Worker using android::gui::FocusRequest;
61*38e8c45fSAndroid Build Coastguard Worker using android::gui::InputApplicationInfo;
62*38e8c45fSAndroid Build Coastguard Worker using android::gui::TouchOcclusionMode;
63*38e8c45fSAndroid Build Coastguard Worker using android::gui::WindowInfo;
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker namespace android {
66*38e8c45fSAndroid Build Coastguard Worker namespace {
toDisplayId(ui::LayerStack layerStack)67*38e8c45fSAndroid Build Coastguard Worker ui::LogicalDisplayId toDisplayId(ui::LayerStack layerStack) {
68*38e8c45fSAndroid Build Coastguard Worker     return ui::LogicalDisplayId{static_cast<int32_t>(layerStack.id)};
69*38e8c45fSAndroid Build Coastguard Worker }
70*38e8c45fSAndroid Build Coastguard Worker } // namespace
71*38e8c45fSAndroid Build Coastguard Worker namespace test {
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker using Transaction = SurfaceComposerClient::Transaction;
74*38e8c45fSAndroid Build Coastguard Worker 
getInputFlinger()75*38e8c45fSAndroid Build Coastguard Worker sp<IInputFlinger> getInputFlinger() {
76*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> input(defaultServiceManager()->waitForService(String16("inputflinger")));
77*38e8c45fSAndroid Build Coastguard Worker     if (input == nullptr) {
78*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Failed to link to input service");
79*38e8c45fSAndroid Build Coastguard Worker     } else {
80*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Linked to input");
81*38e8c45fSAndroid Build Coastguard Worker     }
82*38e8c45fSAndroid Build Coastguard Worker     return interface_cast<IInputFlinger>(input);
83*38e8c45fSAndroid Build Coastguard Worker }
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker // We use the top 10 layers as a way to haphazardly place ourselves above anything else.
86*38e8c45fSAndroid Build Coastguard Worker static const int LAYER_BASE = INT32_MAX - 10;
87*38e8c45fSAndroid Build Coastguard Worker static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker class SynchronousWindowInfosReportedListener : public gui::BnWindowInfosReportedListener {
90*38e8c45fSAndroid Build Coastguard Worker public:
onWindowInfosReported()91*38e8c45fSAndroid Build Coastguard Worker     binder::Status onWindowInfosReported() override {
92*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock lock{mLock};
93*38e8c45fSAndroid Build Coastguard Worker         mWindowInfosReported = true;
94*38e8c45fSAndroid Build Coastguard Worker         mConditionVariable.notify_one();
95*38e8c45fSAndroid Build Coastguard Worker         return binder::Status::ok();
96*38e8c45fSAndroid Build Coastguard Worker     }
97*38e8c45fSAndroid Build Coastguard Worker 
wait()98*38e8c45fSAndroid Build Coastguard Worker     void wait() {
99*38e8c45fSAndroid Build Coastguard Worker         std::unique_lock lock{mLock};
100*38e8c45fSAndroid Build Coastguard Worker         android::base::ScopedLockAssertion assumeLocked(mLock);
101*38e8c45fSAndroid Build Coastguard Worker         mConditionVariable.wait(lock, [&]() REQUIRES(mLock) { return mWindowInfosReported; });
102*38e8c45fSAndroid Build Coastguard Worker     }
103*38e8c45fSAndroid Build Coastguard Worker 
104*38e8c45fSAndroid Build Coastguard Worker private:
105*38e8c45fSAndroid Build Coastguard Worker     std::mutex mLock;
106*38e8c45fSAndroid Build Coastguard Worker     std::condition_variable mConditionVariable;
GUARDED_BY(mLock)107*38e8c45fSAndroid Build Coastguard Worker     bool mWindowInfosReported GUARDED_BY(mLock){false};
108*38e8c45fSAndroid Build Coastguard Worker };
109*38e8c45fSAndroid Build Coastguard Worker 
110*38e8c45fSAndroid Build Coastguard Worker class InputSurface {
111*38e8c45fSAndroid Build Coastguard Worker public:
InputSurface(const sp<SurfaceControl> & sc,int width,int height,bool noInputChannel=false)112*38e8c45fSAndroid Build Coastguard Worker     InputSurface(const sp<SurfaceControl>& sc, int width, int height, bool noInputChannel = false) {
113*38e8c45fSAndroid Build Coastguard Worker         mSurfaceControl = sc;
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker         mInputFlinger = getInputFlinger();
116*38e8c45fSAndroid Build Coastguard Worker         if (noInputChannel) {
117*38e8c45fSAndroid Build Coastguard Worker             mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
118*38e8c45fSAndroid Build Coastguard Worker         } else {
119*38e8c45fSAndroid Build Coastguard Worker             android::os::InputChannelCore tempChannel;
120*38e8c45fSAndroid Build Coastguard Worker             android::binder::Status result =
121*38e8c45fSAndroid Build Coastguard Worker                     mInputFlinger->createInputChannel(sc->getName() + " channel", &tempChannel);
122*38e8c45fSAndroid Build Coastguard Worker             if (!result.isOk()) {
123*38e8c45fSAndroid Build Coastguard Worker                 ADD_FAILURE() << "binder call to createInputChannel failed";
124*38e8c45fSAndroid Build Coastguard Worker             }
125*38e8c45fSAndroid Build Coastguard Worker             mClientChannel = InputChannel::create(std::move(tempChannel));
126*38e8c45fSAndroid Build Coastguard Worker             mInputInfo->editInfo()->token = mClientChannel->getConnectionToken();
127*38e8c45fSAndroid Build Coastguard Worker             mInputConsumer = new InputConsumer(mClientChannel);
128*38e8c45fSAndroid Build Coastguard Worker         }
129*38e8c45fSAndroid Build Coastguard Worker 
130*38e8c45fSAndroid Build Coastguard Worker         mInputInfo->editInfo()->name = "Test info";
131*38e8c45fSAndroid Build Coastguard Worker         mInputInfo->editInfo()->dispatchingTimeout = 5s;
132*38e8c45fSAndroid Build Coastguard Worker         mInputInfo->editInfo()->globalScaleFactor = 1.0;
133*38e8c45fSAndroid Build Coastguard Worker         mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, width, height));
134*38e8c45fSAndroid Build Coastguard Worker 
135*38e8c45fSAndroid Build Coastguard Worker         InputApplicationInfo aInfo;
136*38e8c45fSAndroid Build Coastguard Worker         aInfo.token = new BBinder();
137*38e8c45fSAndroid Build Coastguard Worker         aInfo.name = "Test app info";
138*38e8c45fSAndroid Build Coastguard Worker         aInfo.dispatchingTimeoutMillis =
139*38e8c45fSAndroid Build Coastguard Worker                 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
140*38e8c45fSAndroid Build Coastguard Worker         mInputInfo->editInfo()->applicationInfo = aInfo;
141*38e8c45fSAndroid Build Coastguard Worker     }
142*38e8c45fSAndroid Build Coastguard Worker 
makeColorInputSurface(const sp<SurfaceComposerClient> & scc,int width,int height,const std::string & name)143*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient>& scc,
144*38e8c45fSAndroid Build Coastguard Worker                                                                int width, int height,
145*38e8c45fSAndroid Build Coastguard Worker                                                                const std::string& name) {
146*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
147*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
148*38e8c45fSAndroid Build Coastguard Worker                                    PIXEL_FORMAT_RGBA_8888,
149*38e8c45fSAndroid Build Coastguard Worker                                    ISurfaceComposerClient::eFXSurfaceEffect);
150*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<InputSurface>(surfaceControl, width, height);
151*38e8c45fSAndroid Build Coastguard Worker     }
152*38e8c45fSAndroid Build Coastguard Worker 
makeBufferInputSurface(const sp<SurfaceComposerClient> & scc,int width,int height,const std::string & name="Test Buffer Surface")153*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<InputSurface> makeBufferInputSurface(
154*38e8c45fSAndroid Build Coastguard Worker             const sp<SurfaceComposerClient>& scc, int width, int height,
155*38e8c45fSAndroid Build Coastguard Worker             const std::string& name = "Test Buffer Surface") {
156*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
157*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8(name.c_str()), width, height, PIXEL_FORMAT_RGBA_8888,
158*38e8c45fSAndroid Build Coastguard Worker                                    0 /* flags */);
159*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<InputSurface>(surfaceControl, width, height);
160*38e8c45fSAndroid Build Coastguard Worker     }
161*38e8c45fSAndroid Build Coastguard Worker 
makeContainerInputSurface(const sp<SurfaceComposerClient> & scc,int width,int height,const std::string & name="Test Container Surface")162*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<InputSurface> makeContainerInputSurface(
163*38e8c45fSAndroid Build Coastguard Worker             const sp<SurfaceComposerClient>& scc, int width, int height,
164*38e8c45fSAndroid Build Coastguard Worker             const std::string& name = "Test Container Surface") {
165*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
166*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
167*38e8c45fSAndroid Build Coastguard Worker                                    PIXEL_FORMAT_RGBA_8888,
168*38e8c45fSAndroid Build Coastguard Worker                                    ISurfaceComposerClient::eFXSurfaceContainer);
169*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<InputSurface>(surfaceControl, width, height);
170*38e8c45fSAndroid Build Coastguard Worker     }
171*38e8c45fSAndroid Build Coastguard Worker 
makeContainerInputSurfaceNoInputChannel(const sp<SurfaceComposerClient> & scc,int width,int height,const std::string & name="Test Container Surface")172*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
173*38e8c45fSAndroid Build Coastguard Worker             const sp<SurfaceComposerClient>& scc, int width, int height,
174*38e8c45fSAndroid Build Coastguard Worker             const std::string& name = "Test Container Surface") {
175*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
176*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8(name.c_str()), 100 /* height */, 100 /* width */,
177*38e8c45fSAndroid Build Coastguard Worker                                    PIXEL_FORMAT_RGBA_8888,
178*38e8c45fSAndroid Build Coastguard Worker                                    ISurfaceComposerClient::eFXSurfaceContainer);
179*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<InputSurface>(surfaceControl, width, height,
180*38e8c45fSAndroid Build Coastguard Worker                                               true /* noInputChannel */);
181*38e8c45fSAndroid Build Coastguard Worker     }
182*38e8c45fSAndroid Build Coastguard Worker 
makeCursorInputSurface(const sp<SurfaceComposerClient> & scc,int width,int height,const std::string & name="Test Cursor Surface")183*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<InputSurface> makeCursorInputSurface(
184*38e8c45fSAndroid Build Coastguard Worker             const sp<SurfaceComposerClient>& scc, int width, int height,
185*38e8c45fSAndroid Build Coastguard Worker             const std::string& name = "Test Cursor Surface") {
186*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
187*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
188*38e8c45fSAndroid Build Coastguard Worker                                    PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eCursorWindow);
189*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<InputSurface>(surfaceControl, width, height);
190*38e8c45fSAndroid Build Coastguard Worker     }
191*38e8c45fSAndroid Build Coastguard Worker 
assertFocusChange(bool hasFocus)192*38e8c45fSAndroid Build Coastguard Worker     void assertFocusChange(bool hasFocus) {
193*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev = consumeEvent();
194*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
195*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::FOCUS, ev->getType());
196*38e8c45fSAndroid Build Coastguard Worker         FocusEvent* focusEvent = static_cast<FocusEvent*>(ev);
197*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
198*38e8c45fSAndroid Build Coastguard Worker     }
199*38e8c45fSAndroid Build Coastguard Worker 
expectTap(float x,float y)200*38e8c45fSAndroid Build Coastguard Worker     void expectTap(float x, float y) {
201*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev = consumeEvent();
202*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
203*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
204*38e8c45fSAndroid Build Coastguard Worker         MotionEvent* mev = static_cast<MotionEvent*>(ev);
205*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
206*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(x, mev->getX(0));
207*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(y, mev->getY(0));
208*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
209*38e8c45fSAndroid Build Coastguard Worker 
210*38e8c45fSAndroid Build Coastguard Worker         ev = consumeEvent();
211*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
212*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
213*38e8c45fSAndroid Build Coastguard Worker         mev = static_cast<MotionEvent*>(ev);
214*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
215*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
216*38e8c45fSAndroid Build Coastguard Worker     }
217*38e8c45fSAndroid Build Coastguard Worker 
expectTapWithFlag(int x,int y,int32_t flags)218*38e8c45fSAndroid Build Coastguard Worker     void expectTapWithFlag(int x, int y, int32_t flags) {
219*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev = consumeEvent();
220*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
221*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
222*38e8c45fSAndroid Build Coastguard Worker         MotionEvent* mev = static_cast<MotionEvent*>(ev);
223*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
224*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(x, mev->getX(0));
225*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(y, mev->getY(0));
226*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(flags, mev->getFlags() & flags);
227*38e8c45fSAndroid Build Coastguard Worker 
228*38e8c45fSAndroid Build Coastguard Worker         ev = consumeEvent();
229*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
230*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
231*38e8c45fSAndroid Build Coastguard Worker         mev = static_cast<MotionEvent*>(ev);
232*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
233*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(flags, mev->getFlags() & flags);
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker 
expectTapInDisplayCoordinates(int displayX,int displayY)236*38e8c45fSAndroid Build Coastguard Worker     void expectTapInDisplayCoordinates(int displayX, int displayY) {
237*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev = consumeEvent();
238*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
239*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
240*38e8c45fSAndroid Build Coastguard Worker         MotionEvent* mev = static_cast<MotionEvent*>(ev);
241*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
242*38e8c45fSAndroid Build Coastguard Worker         const PointerCoords& coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
243*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(displayX, coords.getX());
244*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(displayY, coords.getY());
245*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
246*38e8c45fSAndroid Build Coastguard Worker 
247*38e8c45fSAndroid Build Coastguard Worker         ev = consumeEvent();
248*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
249*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::MOTION, ev->getType());
250*38e8c45fSAndroid Build Coastguard Worker         mev = static_cast<MotionEvent*>(ev);
251*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
252*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
253*38e8c45fSAndroid Build Coastguard Worker     }
254*38e8c45fSAndroid Build Coastguard Worker 
expectKey(int32_t keycode)255*38e8c45fSAndroid Build Coastguard Worker     void expectKey(int32_t keycode) {
256*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev = consumeEvent();
257*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
258*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::KEY, ev->getType());
259*38e8c45fSAndroid Build Coastguard Worker         KeyEvent* keyEvent = static_cast<KeyEvent*>(ev);
260*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
261*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(keycode, keyEvent->getKeyCode());
262*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
263*38e8c45fSAndroid Build Coastguard Worker 
264*38e8c45fSAndroid Build Coastguard Worker         ev = consumeEvent();
265*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(ev, nullptr);
266*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(InputEventType::KEY, ev->getType());
267*38e8c45fSAndroid Build Coastguard Worker         keyEvent = static_cast<KeyEvent*>(ev);
268*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
269*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(keycode, keyEvent->getKeyCode());
270*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
271*38e8c45fSAndroid Build Coastguard Worker     }
272*38e8c45fSAndroid Build Coastguard Worker 
assertNoEvent()273*38e8c45fSAndroid Build Coastguard Worker     void assertNoEvent() {
274*38e8c45fSAndroid Build Coastguard Worker         InputEvent* event = consumeEvent(/*timeout=*/100ms);
275*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(event, nullptr) << "Expected no event, but got " << *event;
276*38e8c45fSAndroid Build Coastguard Worker     }
277*38e8c45fSAndroid Build Coastguard Worker 
~InputSurface()278*38e8c45fSAndroid Build Coastguard Worker     virtual ~InputSurface() {
279*38e8c45fSAndroid Build Coastguard Worker         if (mClientChannel) {
280*38e8c45fSAndroid Build Coastguard Worker             mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
281*38e8c45fSAndroid Build Coastguard Worker         }
282*38e8c45fSAndroid Build Coastguard Worker     }
283*38e8c45fSAndroid Build Coastguard Worker 
doTransaction(std::function<void (SurfaceComposerClient::Transaction &,const sp<SurfaceControl> &)> transactionBody)284*38e8c45fSAndroid Build Coastguard Worker     virtual void doTransaction(
285*38e8c45fSAndroid Build Coastguard Worker             std::function<void(SurfaceComposerClient::Transaction&, const sp<SurfaceControl>&)>
286*38e8c45fSAndroid Build Coastguard Worker                     transactionBody) {
287*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
288*38e8c45fSAndroid Build Coastguard Worker         transactionBody(t, mSurfaceControl);
289*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
290*38e8c45fSAndroid Build Coastguard Worker     }
291*38e8c45fSAndroid Build Coastguard Worker 
showAt(int x,int y,Rect crop=Rect (0,0,100,100))292*38e8c45fSAndroid Build Coastguard Worker     virtual void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
293*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
294*38e8c45fSAndroid Build Coastguard Worker         t.show(mSurfaceControl);
295*38e8c45fSAndroid Build Coastguard Worker         t.setInputWindowInfo(mSurfaceControl, mInputInfo);
296*38e8c45fSAndroid Build Coastguard Worker         t.setLayer(mSurfaceControl, LAYER_BASE);
297*38e8c45fSAndroid Build Coastguard Worker         t.setPosition(mSurfaceControl, x, y);
298*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(mSurfaceControl, crop);
299*38e8c45fSAndroid Build Coastguard Worker         t.setAlpha(mSurfaceControl, 1);
300*38e8c45fSAndroid Build Coastguard Worker         auto reportedListener = sp<SynchronousWindowInfosReportedListener>::make();
301*38e8c45fSAndroid Build Coastguard Worker         t.addWindowInfosReportedListener(reportedListener);
302*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
303*38e8c45fSAndroid Build Coastguard Worker         reportedListener->wait();
304*38e8c45fSAndroid Build Coastguard Worker     }
305*38e8c45fSAndroid Build Coastguard Worker 
requestFocus(ui::LogicalDisplayId displayId=ui::LogicalDisplayId::DEFAULT)306*38e8c45fSAndroid Build Coastguard Worker     void requestFocus(ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT) {
307*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
308*38e8c45fSAndroid Build Coastguard Worker         FocusRequest request;
309*38e8c45fSAndroid Build Coastguard Worker         request.token = mInputInfo->getInfo()->token;
310*38e8c45fSAndroid Build Coastguard Worker         request.windowName = mInputInfo->getInfo()->name;
311*38e8c45fSAndroid Build Coastguard Worker         request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
312*38e8c45fSAndroid Build Coastguard Worker         request.displayId = displayId.val();
313*38e8c45fSAndroid Build Coastguard Worker         t.setFocusedWindow(request);
314*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
315*38e8c45fSAndroid Build Coastguard Worker     }
316*38e8c45fSAndroid Build Coastguard Worker 
317*38e8c45fSAndroid Build Coastguard Worker public:
318*38e8c45fSAndroid Build Coastguard Worker     // But should be private
319*38e8c45fSAndroid Build Coastguard Worker     sp<gui::WindowInfoHandle> mInputInfo = sp<gui::WindowInfoHandle>::make();
320*38e8c45fSAndroid Build Coastguard Worker     sp<SurfaceControl> mSurfaceControl;
321*38e8c45fSAndroid Build Coastguard Worker 
322*38e8c45fSAndroid Build Coastguard Worker private:
323*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<InputChannel> mClientChannel;
324*38e8c45fSAndroid Build Coastguard Worker     sp<IInputFlinger> mInputFlinger;
325*38e8c45fSAndroid Build Coastguard Worker 
326*38e8c45fSAndroid Build Coastguard Worker     PreallocatedInputEventFactory mInputEventFactory;
327*38e8c45fSAndroid Build Coastguard Worker     InputConsumer* mInputConsumer;
328*38e8c45fSAndroid Build Coastguard Worker 
consumeEvent(std::chrono::milliseconds timeout=3000ms)329*38e8c45fSAndroid Build Coastguard Worker     InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) {
330*38e8c45fSAndroid Build Coastguard Worker         mClientChannel->waitForMessage(timeout);
331*38e8c45fSAndroid Build Coastguard Worker 
332*38e8c45fSAndroid Build Coastguard Worker         InputEvent* ev;
333*38e8c45fSAndroid Build Coastguard Worker         uint32_t seqId;
334*38e8c45fSAndroid Build Coastguard Worker         status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
335*38e8c45fSAndroid Build Coastguard Worker         if (consumed != OK) {
336*38e8c45fSAndroid Build Coastguard Worker             return nullptr;
337*38e8c45fSAndroid Build Coastguard Worker         }
338*38e8c45fSAndroid Build Coastguard Worker         status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
339*38e8c45fSAndroid Build Coastguard Worker         EXPECT_EQ(OK, status) << "Could not send finished signal";
340*38e8c45fSAndroid Build Coastguard Worker         return ev;
341*38e8c45fSAndroid Build Coastguard Worker     }
342*38e8c45fSAndroid Build Coastguard Worker };
343*38e8c45fSAndroid Build Coastguard Worker 
344*38e8c45fSAndroid Build Coastguard Worker class BlastInputSurface : public InputSurface {
345*38e8c45fSAndroid Build Coastguard Worker public:
BlastInputSurface(const sp<SurfaceControl> & sc,const sp<SurfaceControl> & parentSc,int width,int height)346*38e8c45fSAndroid Build Coastguard Worker     BlastInputSurface(const sp<SurfaceControl>& sc, const sp<SurfaceControl>& parentSc, int width,
347*38e8c45fSAndroid Build Coastguard Worker                       int height)
348*38e8c45fSAndroid Build Coastguard Worker           : InputSurface(sc, width, height) {
349*38e8c45fSAndroid Build Coastguard Worker         mParentSurfaceControl = parentSc;
350*38e8c45fSAndroid Build Coastguard Worker     }
351*38e8c45fSAndroid Build Coastguard Worker 
352*38e8c45fSAndroid Build Coastguard Worker     ~BlastInputSurface() = default;
353*38e8c45fSAndroid Build Coastguard Worker 
makeBlastInputSurface(const sp<SurfaceComposerClient> & scc,int width,int height)354*38e8c45fSAndroid Build Coastguard Worker     static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
355*38e8c45fSAndroid Build Coastguard Worker             const sp<SurfaceComposerClient>& scc, int width, int height) {
356*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> parentSc =
357*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
358*38e8c45fSAndroid Build Coastguard Worker                                    0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
359*38e8c45fSAndroid Build Coastguard Worker                                    ISurfaceComposerClient::eFXSurfaceContainer);
360*38e8c45fSAndroid Build Coastguard Worker 
361*38e8c45fSAndroid Build Coastguard Worker         sp<SurfaceControl> surfaceControl =
362*38e8c45fSAndroid Build Coastguard Worker                 scc->createSurface(String8("Test Buffer Surface"), width, height,
363*38e8c45fSAndroid Build Coastguard Worker                                    PIXEL_FORMAT_RGBA_8888,
364*38e8c45fSAndroid Build Coastguard Worker                                    ISurfaceComposerClient::eFXSurfaceBufferState,
365*38e8c45fSAndroid Build Coastguard Worker                                    parentSc->getHandle());
366*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
367*38e8c45fSAndroid Build Coastguard Worker     }
368*38e8c45fSAndroid Build Coastguard Worker 
doTransaction(std::function<void (SurfaceComposerClient::Transaction &,const sp<SurfaceControl> &)> transactionBody)369*38e8c45fSAndroid Build Coastguard Worker     void doTransaction(
370*38e8c45fSAndroid Build Coastguard Worker             std::function<void(SurfaceComposerClient::Transaction&, const sp<SurfaceControl>&)>
371*38e8c45fSAndroid Build Coastguard Worker                     transactionBody) override {
372*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
373*38e8c45fSAndroid Build Coastguard Worker         transactionBody(t, mParentSurfaceControl);
374*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
375*38e8c45fSAndroid Build Coastguard Worker     }
376*38e8c45fSAndroid Build Coastguard Worker 
showAt(int x,int y,Rect crop=Rect (0,0,100,100))377*38e8c45fSAndroid Build Coastguard Worker     void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
378*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
379*38e8c45fSAndroid Build Coastguard Worker         t.show(mParentSurfaceControl);
380*38e8c45fSAndroid Build Coastguard Worker         t.setLayer(mParentSurfaceControl, LAYER_BASE);
381*38e8c45fSAndroid Build Coastguard Worker         t.setPosition(mParentSurfaceControl, x, y);
382*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(mParentSurfaceControl, crop);
383*38e8c45fSAndroid Build Coastguard Worker 
384*38e8c45fSAndroid Build Coastguard Worker         t.show(mSurfaceControl);
385*38e8c45fSAndroid Build Coastguard Worker         t.setInputWindowInfo(mSurfaceControl, mInputInfo);
386*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(mSurfaceControl, crop);
387*38e8c45fSAndroid Build Coastguard Worker         t.setAlpha(mSurfaceControl, 1);
388*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
389*38e8c45fSAndroid Build Coastguard Worker     }
390*38e8c45fSAndroid Build Coastguard Worker 
391*38e8c45fSAndroid Build Coastguard Worker private:
392*38e8c45fSAndroid Build Coastguard Worker     sp<SurfaceControl> mParentSurfaceControl;
393*38e8c45fSAndroid Build Coastguard Worker };
394*38e8c45fSAndroid Build Coastguard Worker 
395*38e8c45fSAndroid Build Coastguard Worker class InputSurfacesTest : public ::testing::Test {
396*38e8c45fSAndroid Build Coastguard Worker public:
InputSurfacesTest()397*38e8c45fSAndroid Build Coastguard Worker     InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
398*38e8c45fSAndroid Build Coastguard Worker 
SetUp()399*38e8c45fSAndroid Build Coastguard Worker     void SetUp() {
400*38e8c45fSAndroid Build Coastguard Worker         mComposerClient = new SurfaceComposerClient;
401*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
402*38e8c45fSAndroid Build Coastguard Worker         const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
403*38e8c45fSAndroid Build Coastguard Worker         ASSERT_FALSE(ids.empty());
404*38e8c45fSAndroid Build Coastguard Worker         // display 0 is picked for now, can extend to support all displays if needed
405*38e8c45fSAndroid Build Coastguard Worker         const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
406*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NE(display, nullptr);
407*38e8c45fSAndroid Build Coastguard Worker 
408*38e8c45fSAndroid Build Coastguard Worker         ui::DisplayMode mode;
409*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(NO_ERROR, mComposerClient->getActiveDisplayMode(display, &mode));
410*38e8c45fSAndroid Build Coastguard Worker 
411*38e8c45fSAndroid Build Coastguard Worker         // After a new buffer is queued, SurfaceFlinger is notified and will
412*38e8c45fSAndroid Build Coastguard Worker         // latch the new buffer on next vsync.  Let's heuristically wait for 3
413*38e8c45fSAndroid Build Coastguard Worker         // vsyncs.
414*38e8c45fSAndroid Build Coastguard Worker         mBufferPostDelay = static_cast<int32_t>(1e6 / mode.peakRefreshRate) * 3;
415*38e8c45fSAndroid Build Coastguard Worker     }
416*38e8c45fSAndroid Build Coastguard Worker 
TearDown()417*38e8c45fSAndroid Build Coastguard Worker     void TearDown() { mComposerClient->dispose(); }
418*38e8c45fSAndroid Build Coastguard Worker 
makeSurface(int width,int height,const std::string & name="Test Surface") const419*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> makeSurface(int width, int height,
420*38e8c45fSAndroid Build Coastguard Worker                                               const std::string& name = "Test Surface") const {
421*38e8c45fSAndroid Build Coastguard Worker         return InputSurface::makeColorInputSurface(mComposerClient, width, height, name);
422*38e8c45fSAndroid Build Coastguard Worker     }
423*38e8c45fSAndroid Build Coastguard Worker 
postBuffer(const sp<SurfaceControl> & layer,int32_t w,int32_t h)424*38e8c45fSAndroid Build Coastguard Worker     void postBuffer(const sp<SurfaceControl>& layer, int32_t w, int32_t h) {
425*38e8c45fSAndroid Build Coastguard Worker         int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
426*38e8c45fSAndroid Build Coastguard Worker                 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
427*38e8c45fSAndroid Build Coastguard Worker         sp<GraphicBuffer> buffer =
428*38e8c45fSAndroid Build Coastguard Worker                 new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
429*38e8c45fSAndroid Build Coastguard Worker         Transaction().setBuffer(layer, buffer).apply(/*synchronously=*/true);
430*38e8c45fSAndroid Build Coastguard Worker         usleep(mBufferPostDelay);
431*38e8c45fSAndroid Build Coastguard Worker     }
432*38e8c45fSAndroid Build Coastguard Worker 
433*38e8c45fSAndroid Build Coastguard Worker     sp<SurfaceComposerClient> mComposerClient;
434*38e8c45fSAndroid Build Coastguard Worker     int32_t mBufferPostDelay;
435*38e8c45fSAndroid Build Coastguard Worker };
436*38e8c45fSAndroid Build Coastguard Worker 
injectTapOnDisplay(int x,int y,ui::LogicalDisplayId displayId)437*38e8c45fSAndroid Build Coastguard Worker void injectTapOnDisplay(int x, int y, ui::LogicalDisplayId displayId) {
438*38e8c45fSAndroid Build Coastguard Worker     char *buf1, *buf2, *bufDisplayId;
439*38e8c45fSAndroid Build Coastguard Worker     asprintf(&buf1, "%d", x);
440*38e8c45fSAndroid Build Coastguard Worker     asprintf(&buf2, "%d", y);
441*38e8c45fSAndroid Build Coastguard Worker     asprintf(&bufDisplayId, "%d", displayId.val());
442*38e8c45fSAndroid Build Coastguard Worker     if (fork() == 0) {
443*38e8c45fSAndroid Build Coastguard Worker         execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
444*38e8c45fSAndroid Build Coastguard Worker     }
445*38e8c45fSAndroid Build Coastguard Worker }
446*38e8c45fSAndroid Build Coastguard Worker 
injectTap(int x,int y)447*38e8c45fSAndroid Build Coastguard Worker void injectTap(int x, int y) {
448*38e8c45fSAndroid Build Coastguard Worker     injectTapOnDisplay(x, y, ui::LogicalDisplayId::DEFAULT);
449*38e8c45fSAndroid Build Coastguard Worker }
450*38e8c45fSAndroid Build Coastguard Worker 
injectKeyOnDisplay(uint32_t keycode,ui::LogicalDisplayId displayId)451*38e8c45fSAndroid Build Coastguard Worker void injectKeyOnDisplay(uint32_t keycode, ui::LogicalDisplayId displayId) {
452*38e8c45fSAndroid Build Coastguard Worker     char *buf1, *bufDisplayId;
453*38e8c45fSAndroid Build Coastguard Worker     asprintf(&buf1, "%d", keycode);
454*38e8c45fSAndroid Build Coastguard Worker     asprintf(&bufDisplayId, "%d", displayId.val());
455*38e8c45fSAndroid Build Coastguard Worker     if (fork() == 0) {
456*38e8c45fSAndroid Build Coastguard Worker         execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
457*38e8c45fSAndroid Build Coastguard Worker     }
458*38e8c45fSAndroid Build Coastguard Worker }
459*38e8c45fSAndroid Build Coastguard Worker 
injectKey(uint32_t keycode)460*38e8c45fSAndroid Build Coastguard Worker void injectKey(uint32_t keycode) {
461*38e8c45fSAndroid Build Coastguard Worker     injectKeyOnDisplay(keycode, ui::LogicalDisplayId::INVALID);
462*38e8c45fSAndroid Build Coastguard Worker }
463*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,can_receive_input)464*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, can_receive_input) {
465*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
466*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
467*38e8c45fSAndroid Build Coastguard Worker 
468*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
469*38e8c45fSAndroid Build Coastguard Worker 
470*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker 
473*38e8c45fSAndroid Build Coastguard Worker /**
474*38e8c45fSAndroid Build Coastguard Worker  * Set up two surfaces side-by-side. Tap each surface.
475*38e8c45fSAndroid Build Coastguard Worker  * Next, swap the positions of the two surfaces. Inject tap into the two
476*38e8c45fSAndroid Build Coastguard Worker  * original locations. Ensure that the tap is received by the surfaces in the
477*38e8c45fSAndroid Build Coastguard Worker  * reverse order.
478*38e8c45fSAndroid Build Coastguard Worker  */
TEST_F(InputSurfacesTest,input_respects_positioning)479*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_positioning) {
480*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Left Surface");
481*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
482*38e8c45fSAndroid Build Coastguard Worker 
483*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100, "Right Surface");
484*38e8c45fSAndroid Build Coastguard Worker     surface2->showAt(200, 200);
485*38e8c45fSAndroid Build Coastguard Worker 
486*38e8c45fSAndroid Build Coastguard Worker     injectTap(201, 201);
487*38e8c45fSAndroid Build Coastguard Worker     surface2->expectTap(1, 1);
488*38e8c45fSAndroid Build Coastguard Worker 
489*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
490*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
491*38e8c45fSAndroid Build Coastguard Worker 
492*38e8c45fSAndroid Build Coastguard Worker     surface2->doTransaction([](auto& t, auto& sc) { t.setPosition(sc, 100, 100); });
493*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) { t.setPosition(sc, 200, 200); });
494*38e8c45fSAndroid Build Coastguard Worker 
495*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
496*38e8c45fSAndroid Build Coastguard Worker     surface2->expectTap(1, 1);
497*38e8c45fSAndroid Build Coastguard Worker 
498*38e8c45fSAndroid Build Coastguard Worker     injectTap(201, 201);
499*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
500*38e8c45fSAndroid Build Coastguard Worker }
501*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_layering)502*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_layering) {
503*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface 1");
504*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100, "Test Surface 2");
505*38e8c45fSAndroid Build Coastguard Worker 
506*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
507*38e8c45fSAndroid Build Coastguard Worker     surface2->showAt(10, 10);
508*38e8c45fSAndroid Build Coastguard Worker 
509*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) { t.setLayer(sc, LAYER_BASE + 1); });
510*38e8c45fSAndroid Build Coastguard Worker 
511*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
512*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
513*38e8c45fSAndroid Build Coastguard Worker 
514*38e8c45fSAndroid Build Coastguard Worker     surface2->doTransaction([](auto& t, auto& sc) { t.setLayer(sc, LAYER_BASE + 1); });
515*38e8c45fSAndroid Build Coastguard Worker 
516*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
517*38e8c45fSAndroid Build Coastguard Worker     surface2->expectTap(1, 1);
518*38e8c45fSAndroid Build Coastguard Worker 
519*38e8c45fSAndroid Build Coastguard Worker     surface2->doTransaction([](auto& t, auto& sc) { t.hide(sc); });
520*38e8c45fSAndroid Build Coastguard Worker 
521*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
522*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
523*38e8c45fSAndroid Build Coastguard Worker }
524*38e8c45fSAndroid Build Coastguard Worker 
525*38e8c45fSAndroid Build Coastguard Worker // Surface Insets are set to offset the client content and draw a border around the client surface
526*38e8c45fSAndroid Build Coastguard Worker // (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
527*38e8c45fSAndroid Build Coastguard Worker // of the client content.
TEST_F(InputSurfacesTest,input_respects_surface_insets)528*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_surface_insets) {
529*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
530*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
531*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(100, 100);
532*38e8c45fSAndroid Build Coastguard Worker 
533*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
534*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(100, 100);
535*38e8c45fSAndroid Build Coastguard Worker 
536*38e8c45fSAndroid Build Coastguard Worker     injectTap(106, 106);
537*38e8c45fSAndroid Build Coastguard Worker     fgSurface->expectTap(1, 1);
538*38e8c45fSAndroid Build Coastguard Worker 
539*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
540*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(1, 1);
541*38e8c45fSAndroid Build Coastguard Worker }
542*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_surface_insets_with_replaceTouchableRegionWithCrop)543*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableRegionWithCrop) {
544*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
545*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
546*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(100, 100);
547*38e8c45fSAndroid Build Coastguard Worker 
548*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
549*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
550*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(100, 100);
551*38e8c45fSAndroid Build Coastguard Worker 
552*38e8c45fSAndroid Build Coastguard Worker     injectTap(106, 106);
553*38e8c45fSAndroid Build Coastguard Worker     fgSurface->expectTap(1, 1);
554*38e8c45fSAndroid Build Coastguard Worker 
555*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
556*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(1, 1);
557*38e8c45fSAndroid Build Coastguard Worker }
558*38e8c45fSAndroid Build Coastguard Worker 
559*38e8c45fSAndroid Build Coastguard Worker // Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
TEST_F(InputSurfacesTest,input_respects_cropped_surface_insets)560*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
561*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
562*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100, "Child Surface");
563*38e8c45fSAndroid Build Coastguard Worker     parentSurface->showAt(100, 100);
564*38e8c45fSAndroid Build Coastguard Worker 
565*38e8c45fSAndroid Build Coastguard Worker     childSurface->mInputInfo->editInfo()->surfaceInset = 10;
566*38e8c45fSAndroid Build Coastguard Worker     childSurface->showAt(100, 100);
567*38e8c45fSAndroid Build Coastguard Worker 
568*38e8c45fSAndroid Build Coastguard Worker     childSurface->doTransaction([&](auto& t, auto& sc) {
569*38e8c45fSAndroid Build Coastguard Worker         t.setPosition(sc, -5, -5);
570*38e8c45fSAndroid Build Coastguard Worker         t.reparent(sc, parentSurface->mSurfaceControl);
571*38e8c45fSAndroid Build Coastguard Worker     });
572*38e8c45fSAndroid Build Coastguard Worker 
573*38e8c45fSAndroid Build Coastguard Worker     injectTap(106, 106);
574*38e8c45fSAndroid Build Coastguard Worker     childSurface->expectTap(1, 1);
575*38e8c45fSAndroid Build Coastguard Worker 
576*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
577*38e8c45fSAndroid Build Coastguard Worker     parentSurface->expectTap(1, 1);
578*38e8c45fSAndroid Build Coastguard Worker }
579*38e8c45fSAndroid Build Coastguard Worker 
580*38e8c45fSAndroid Build Coastguard Worker // Ensure a surface whose insets are scaled, handles the touch offset correctly.
TEST_F(InputSurfacesTest,input_respects_scaled_surface_insets)581*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
582*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
583*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
584*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(100, 100);
585*38e8c45fSAndroid Build Coastguard Worker 
586*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
587*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(100, 100);
588*38e8c45fSAndroid Build Coastguard Worker 
589*38e8c45fSAndroid Build Coastguard Worker     fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
590*38e8c45fSAndroid Build Coastguard Worker 
591*38e8c45fSAndroid Build Coastguard Worker     // expect = touch / scale - inset
592*38e8c45fSAndroid Build Coastguard Worker     injectTap(112, 124);
593*38e8c45fSAndroid Build Coastguard Worker     fgSurface->expectTap(1, 1);
594*38e8c45fSAndroid Build Coastguard Worker 
595*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
596*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(1, 1);
597*38e8c45fSAndroid Build Coastguard Worker }
598*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_scaled_surface_insets_overflow)599*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
600*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
601*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
602*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(100, 100);
603*38e8c45fSAndroid Build Coastguard Worker 
604*38e8c45fSAndroid Build Coastguard Worker     // In case we pass the very big inset without any checking.
605*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->surfaceInset = INT32_MAX;
606*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(100, 100);
607*38e8c45fSAndroid Build Coastguard Worker 
608*38e8c45fSAndroid Build Coastguard Worker     fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
609*38e8c45fSAndroid Build Coastguard Worker 
610*38e8c45fSAndroid Build Coastguard Worker     // expect no crash for overflow, and inset size to be clamped to surface size
611*38e8c45fSAndroid Build Coastguard Worker     injectTap(112, 124);
612*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(12, 24);
613*38e8c45fSAndroid Build Coastguard Worker }
614*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touchable_region)615*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touchable_region) {
616*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
617*38e8c45fSAndroid Build Coastguard Worker 
618*38e8c45fSAndroid Build Coastguard Worker     surface->mInputInfo->editInfo()->touchableRegion.set(Rect{19, 29, 21, 31});
619*38e8c45fSAndroid Build Coastguard Worker 
620*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(11, 22);
621*38e8c45fSAndroid Build Coastguard Worker 
622*38e8c45fSAndroid Build Coastguard Worker     // A tap within the surface but outside the touchable region should not be sent to the surface.
623*38e8c45fSAndroid Build Coastguard Worker     injectTap(20, 30);
624*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
625*38e8c45fSAndroid Build Coastguard Worker 
626*38e8c45fSAndroid Build Coastguard Worker     injectTap(31, 52);
627*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(20, 30);
628*38e8c45fSAndroid Build Coastguard Worker }
629*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_touchable_region_offset_overflow)630*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) {
631*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
632*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
633*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(100, 100);
634*38e8c45fSAndroid Build Coastguard Worker 
635*38e8c45fSAndroid Build Coastguard Worker     // Set the touchable region to the values at the limit of its corresponding type.
636*38e8c45fSAndroid Build Coastguard Worker     // Since the surface is offset from the origin, the touchable region will be transformed into
637*38e8c45fSAndroid Build Coastguard Worker     // display space, which would trigger an overflow or an underflow. Ensure that we are protected
638*38e8c45fSAndroid Build Coastguard Worker     // against such a situation.
639*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
640*38e8c45fSAndroid Build Coastguard Worker             Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
641*38e8c45fSAndroid Build Coastguard Worker 
642*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(100, 100);
643*38e8c45fSAndroid Build Coastguard Worker 
644*38e8c45fSAndroid Build Coastguard Worker     // Expect no crash for overflow. The overflowed touchable region is ignored, so the background
645*38e8c45fSAndroid Build Coastguard Worker     // surface receives touch.
646*38e8c45fSAndroid Build Coastguard Worker     injectTap(112, 124);
647*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(12, 24);
648*38e8c45fSAndroid Build Coastguard Worker }
649*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_scaled_touchable_region_overflow)650*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) {
651*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
652*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
653*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(0, 0);
654*38e8c45fSAndroid Build Coastguard Worker 
655*38e8c45fSAndroid Build Coastguard Worker     fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
656*38e8c45fSAndroid Build Coastguard Worker             Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
657*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(0, 0);
658*38e8c45fSAndroid Build Coastguard Worker 
659*38e8c45fSAndroid Build Coastguard Worker     fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
660*38e8c45fSAndroid Build Coastguard Worker 
661*38e8c45fSAndroid Build Coastguard Worker     // Expect no crash for overflow.
662*38e8c45fSAndroid Build Coastguard Worker     injectTap(12, 24);
663*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(12, 24);
664*38e8c45fSAndroid Build Coastguard Worker }
665*38e8c45fSAndroid Build Coastguard Worker 
666*38e8c45fSAndroid Build Coastguard Worker // Ensure we ignore transparent region when getting screen bounds when positioning input frame.
TEST_F(InputSurfacesTest,input_ignores_transparent_region)667*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
668*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
669*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
670*38e8c45fSAndroid Build Coastguard Worker         Region transparentRegion(Rect(0, 0, 10, 10));
671*38e8c45fSAndroid Build Coastguard Worker         t.setTransparentRegionHint(sc, transparentRegion);
672*38e8c45fSAndroid Build Coastguard Worker     });
673*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
674*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
675*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
676*38e8c45fSAndroid Build Coastguard Worker }
677*38e8c45fSAndroid Build Coastguard Worker 
678*38e8c45fSAndroid Build Coastguard Worker // TODO(b/139494112) update tests once we define expected behavior
679*38e8c45fSAndroid Build Coastguard Worker // Ensure we still send input to the surface regardless of surface visibility changes due to the
680*38e8c45fSAndroid Build Coastguard Worker // first buffer being submitted or alpha changes.
681*38e8c45fSAndroid Build Coastguard Worker // Original bug ref: b/120839715
TEST_F(InputSurfacesTest,input_ignores_buffer_layer_buffer)682*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
683*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
684*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<BlastInputSurface> bufferSurface =
685*38e8c45fSAndroid Build Coastguard Worker             BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
686*38e8c45fSAndroid Build Coastguard Worker 
687*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(10, 10);
688*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(10, 10);
689*38e8c45fSAndroid Build Coastguard Worker 
690*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
691*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->expectTap(1, 1);
692*38e8c45fSAndroid Build Coastguard Worker 
693*38e8c45fSAndroid Build Coastguard Worker     postBuffer(bufferSurface->mSurfaceControl, 100, 100);
694*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
695*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->expectTap(1, 1);
696*38e8c45fSAndroid Build Coastguard Worker }
697*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_buffer_layer_alpha)698*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
699*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
700*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<BlastInputSurface> bufferSurface =
701*38e8c45fSAndroid Build Coastguard Worker             BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
702*38e8c45fSAndroid Build Coastguard Worker     postBuffer(bufferSurface->mSurfaceControl, 100, 100);
703*38e8c45fSAndroid Build Coastguard Worker 
704*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(10, 10);
705*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(10, 10);
706*38e8c45fSAndroid Build Coastguard Worker 
707*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
708*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->expectTap(1, 1);
709*38e8c45fSAndroid Build Coastguard Worker 
710*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->doTransaction([](auto& t, auto& sc) { t.setAlpha(sc, 0.0); });
711*38e8c45fSAndroid Build Coastguard Worker 
712*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
713*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(1, 1);
714*38e8c45fSAndroid Build Coastguard Worker }
715*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_ignores_color_layer_alpha)716*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
717*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
718*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
719*38e8c45fSAndroid Build Coastguard Worker 
720*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(10, 10);
721*38e8c45fSAndroid Build Coastguard Worker     fgSurface->showAt(10, 10);
722*38e8c45fSAndroid Build Coastguard Worker 
723*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
724*38e8c45fSAndroid Build Coastguard Worker     fgSurface->expectTap(1, 1);
725*38e8c45fSAndroid Build Coastguard Worker 
726*38e8c45fSAndroid Build Coastguard Worker     fgSurface->doTransaction([](auto& t, auto& sc) { t.setAlpha(sc, 0.0); });
727*38e8c45fSAndroid Build Coastguard Worker 
728*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
729*38e8c45fSAndroid Build Coastguard Worker     fgSurface->expectTap(1, 1);
730*38e8c45fSAndroid Build Coastguard Worker }
731*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_container_layer_visiblity)732*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
733*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
734*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> containerSurface =
735*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
736*38e8c45fSAndroid Build Coastguard Worker 
737*38e8c45fSAndroid Build Coastguard Worker     bgSurface->showAt(10, 10);
738*38e8c45fSAndroid Build Coastguard Worker     containerSurface->showAt(10, 10);
739*38e8c45fSAndroid Build Coastguard Worker 
740*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
741*38e8c45fSAndroid Build Coastguard Worker     containerSurface->expectTap(1, 1);
742*38e8c45fSAndroid Build Coastguard Worker 
743*38e8c45fSAndroid Build Coastguard Worker     containerSurface->doTransaction([](auto& t, auto& sc) { t.hide(sc); });
744*38e8c45fSAndroid Build Coastguard Worker 
745*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
746*38e8c45fSAndroid Build Coastguard Worker     bgSurface->expectTap(1, 1);
747*38e8c45fSAndroid Build Coastguard Worker }
748*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_respects_outscreen)749*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_respects_outscreen) {
750*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
751*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(-1, -1);
752*38e8c45fSAndroid Build Coastguard Worker 
753*38e8c45fSAndroid Build Coastguard Worker     injectTap(0, 0);
754*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
755*38e8c45fSAndroid Build Coastguard Worker }
756*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,input_ignores_cursor_layer)757*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
758*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
759*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> cursorSurface =
760*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);
761*38e8c45fSAndroid Build Coastguard Worker 
762*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
763*38e8c45fSAndroid Build Coastguard Worker     cursorSurface->showAt(10, 10);
764*38e8c45fSAndroid Build Coastguard Worker 
765*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
766*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
767*38e8c45fSAndroid Build Coastguard Worker }
768*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,can_be_focused)769*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, can_be_focused) {
770*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
771*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
772*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
773*38e8c45fSAndroid Build Coastguard Worker 
774*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
775*38e8c45fSAndroid Build Coastguard Worker 
776*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
777*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
778*38e8c45fSAndroid Build Coastguard Worker }
779*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,rotate_surface)780*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, rotate_surface) {
781*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
782*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
783*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
784*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
785*38e8c45fSAndroid Build Coastguard Worker     });
786*38e8c45fSAndroid Build Coastguard Worker     injectTap(8, 11);
787*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
788*38e8c45fSAndroid Build Coastguard Worker 
789*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
790*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
791*38e8c45fSAndroid Build Coastguard Worker     });
792*38e8c45fSAndroid Build Coastguard Worker     injectTap(9, 8);
793*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
794*38e8c45fSAndroid Build Coastguard Worker 
795*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
796*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
797*38e8c45fSAndroid Build Coastguard Worker     });
798*38e8c45fSAndroid Build Coastguard Worker     injectTap(12, 9);
799*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
800*38e8c45fSAndroid Build Coastguard Worker }
801*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,rotate_surface_with_scale)802*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
803*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
804*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
805*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
806*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
807*38e8c45fSAndroid Build Coastguard Worker     });
808*38e8c45fSAndroid Build Coastguard Worker     injectTap(2, 12);
809*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
810*38e8c45fSAndroid Build Coastguard Worker 
811*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
812*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
813*38e8c45fSAndroid Build Coastguard Worker     });
814*38e8c45fSAndroid Build Coastguard Worker     injectTap(8, 2);
815*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
816*38e8c45fSAndroid Build Coastguard Worker 
817*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
818*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
819*38e8c45fSAndroid Build Coastguard Worker     });
820*38e8c45fSAndroid Build Coastguard Worker     injectTap(18, 8);
821*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 2);
822*38e8c45fSAndroid Build Coastguard Worker }
823*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,rotate_surface_with_scale_and_insets)824*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
825*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
826*38e8c45fSAndroid Build Coastguard Worker     surface->mInputInfo->editInfo()->surfaceInset = 5;
827*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
828*38e8c45fSAndroid Build Coastguard Worker 
829*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
830*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
831*38e8c45fSAndroid Build Coastguard Worker     });
832*38e8c45fSAndroid Build Coastguard Worker     injectTap(40, 120);
833*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(5, 10);
834*38e8c45fSAndroid Build Coastguard Worker 
835*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
836*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
837*38e8c45fSAndroid Build Coastguard Worker     });
838*38e8c45fSAndroid Build Coastguard Worker     injectTap(80, 40);
839*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(5, 10);
840*38e8c45fSAndroid Build Coastguard Worker 
841*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([](auto& t, auto& sc) {
842*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
843*38e8c45fSAndroid Build Coastguard Worker     });
844*38e8c45fSAndroid Build Coastguard Worker     injectTap(160, 80);
845*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(5, 10);
846*38e8c45fSAndroid Build Coastguard Worker }
847*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touch_flag_obscured)848*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touch_flag_obscured) {
849*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Touchable Surface");
850*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
851*38e8c45fSAndroid Build Coastguard Worker 
852*38e8c45fSAndroid Build Coastguard Worker     // Add non touchable window to fully cover touchable window. Window behind gets touch, but
853*38e8c45fSAndroid Build Coastguard Worker     // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
854*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> nonTouchableSurface =
855*38e8c45fSAndroid Build Coastguard Worker             makeSurface(100, 100, "Non-Touchable Surface");
856*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()
857*38e8c45fSAndroid Build Coastguard Worker             ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
858*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
859*38e8c45fSAndroid Build Coastguard Worker     // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
860*38e8c45fSAndroid Build Coastguard Worker     // the default obscured/untrusted touch filter introduced in S.
861*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()->touchOcclusionMode = TouchOcclusionMode::ALLOW;
862*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->showAt(100, 100);
863*38e8c45fSAndroid Build Coastguard Worker 
864*38e8c45fSAndroid Build Coastguard Worker     injectTap(190, 199);
865*38e8c45fSAndroid Build Coastguard Worker     surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
866*38e8c45fSAndroid Build Coastguard Worker }
867*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touch_flag_partially_obscured_with_crop)868*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
869*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
870*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
871*38e8c45fSAndroid Build Coastguard Worker 
872*38e8c45fSAndroid Build Coastguard Worker     // Add non touchable window to cover touchable window, but parent is cropped to not cover area
873*38e8c45fSAndroid Build Coastguard Worker     // that will be tapped. Window behind gets touch, but with flag
874*38e8c45fSAndroid Build Coastguard Worker     // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
875*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
876*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> nonTouchableSurface =
877*38e8c45fSAndroid Build Coastguard Worker             makeSurface(100, 100, "Non-Touchable Surface");
878*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()
879*38e8c45fSAndroid Build Coastguard Worker             ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
880*38e8c45fSAndroid Build Coastguard Worker     parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
881*38e8c45fSAndroid Build Coastguard Worker                                                           true);
882*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
883*38e8c45fSAndroid Build Coastguard Worker     parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
884*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->showAt(0, 0);
885*38e8c45fSAndroid Build Coastguard Worker     parentSurface->showAt(100, 100);
886*38e8c45fSAndroid Build Coastguard Worker 
887*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->doTransaction([&](auto& t, auto& sc) {
888*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
889*38e8c45fSAndroid Build Coastguard Worker         t.reparent(sc, parentSurface->mSurfaceControl);
890*38e8c45fSAndroid Build Coastguard Worker     });
891*38e8c45fSAndroid Build Coastguard Worker 
892*38e8c45fSAndroid Build Coastguard Worker     injectTap(190, 199);
893*38e8c45fSAndroid Build Coastguard Worker     surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
894*38e8c45fSAndroid Build Coastguard Worker }
895*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touch_not_obscured_with_crop)896*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
897*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
898*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
899*38e8c45fSAndroid Build Coastguard Worker 
900*38e8c45fSAndroid Build Coastguard Worker     // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
901*38e8c45fSAndroid Build Coastguard Worker     // the touchable window. Window behind gets touch with no obscured flags.
902*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
903*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> nonTouchableSurface =
904*38e8c45fSAndroid Build Coastguard Worker             makeSurface(100, 100, "Non-Touchable Surface");
905*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()
906*38e8c45fSAndroid Build Coastguard Worker             ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
907*38e8c45fSAndroid Build Coastguard Worker     parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
908*38e8c45fSAndroid Build Coastguard Worker                                                           true);
909*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
910*38e8c45fSAndroid Build Coastguard Worker     parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
911*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->showAt(0, 0);
912*38e8c45fSAndroid Build Coastguard Worker     parentSurface->showAt(50, 50);
913*38e8c45fSAndroid Build Coastguard Worker 
914*38e8c45fSAndroid Build Coastguard Worker     nonTouchableSurface->doTransaction([&](auto& t, auto& sc) {
915*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
916*38e8c45fSAndroid Build Coastguard Worker         t.reparent(sc, parentSurface->mSurfaceControl);
917*38e8c45fSAndroid Build Coastguard Worker     });
918*38e8c45fSAndroid Build Coastguard Worker 
919*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 110);
920*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 10);
921*38e8c45fSAndroid Build Coastguard Worker }
922*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touch_not_obscured_with_zero_sized_bql)923*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
924*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
925*38e8c45fSAndroid Build Coastguard Worker 
926*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bufferSurface =
927*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
928*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
929*38e8c45fSAndroid Build Coastguard Worker                                                           true);
930*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
931*38e8c45fSAndroid Build Coastguard Worker 
932*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
933*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
934*38e8c45fSAndroid Build Coastguard Worker 
935*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
936*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
937*38e8c45fSAndroid Build Coastguard Worker }
938*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,touch_not_obscured_with_zero_sized_blast)939*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
940*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
941*38e8c45fSAndroid Build Coastguard Worker 
942*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<BlastInputSurface> bufferSurface =
943*38e8c45fSAndroid Build Coastguard Worker             BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
944*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
945*38e8c45fSAndroid Build Coastguard Worker                                                           true);
946*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
947*38e8c45fSAndroid Build Coastguard Worker 
948*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(10, 10);
949*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
950*38e8c45fSAndroid Build Coastguard Worker 
951*38e8c45fSAndroid Build Coastguard Worker     injectTap(11, 11);
952*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
953*38e8c45fSAndroid Build Coastguard Worker }
954*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_unobscured_window)955*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
956*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
957*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction(
958*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
959*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
960*38e8c45fSAndroid Build Coastguard Worker 
961*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
962*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
963*38e8c45fSAndroid Build Coastguard Worker 
964*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
965*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
966*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
967*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
968*38e8c45fSAndroid Build Coastguard Worker }
969*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_scaled_without_crop_window)970*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
971*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
972*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) {
973*38e8c45fSAndroid Build Coastguard Worker         t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
974*38e8c45fSAndroid Build Coastguard Worker         t.setMatrix(sc, 2.0, 0, 0, 2.0);
975*38e8c45fSAndroid Build Coastguard Worker     });
976*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
977*38e8c45fSAndroid Build Coastguard Worker 
978*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
979*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(.5, .5);
980*38e8c45fSAndroid Build Coastguard Worker 
981*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
982*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
983*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
984*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
985*38e8c45fSAndroid Build Coastguard Worker }
986*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_obscured_window)987*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
988*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
989*38e8c45fSAndroid Build Coastguard Worker     surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
990*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction(
991*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
992*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
993*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100, "Obscuring Surface");
994*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
995*38e8c45fSAndroid Build Coastguard Worker                                                              true);
996*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
997*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->showAt(100, 100);
998*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
999*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1000*38e8c45fSAndroid Build Coastguard Worker 
1001*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
1002*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1003*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
1004*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1005*38e8c45fSAndroid Build Coastguard Worker }
1006*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_partially_obscured_window)1007*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
1008*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
1009*38e8c45fSAndroid Build Coastguard Worker     surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
1010*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction(
1011*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
1012*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1013*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100, "Obscuring Surface");
1014*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
1015*38e8c45fSAndroid Build Coastguard Worker                                                              true);
1016*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
1017*38e8c45fSAndroid Build Coastguard Worker     obscuringSurface->showAt(190, 190);
1018*38e8c45fSAndroid Build Coastguard Worker 
1019*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1020*38e8c45fSAndroid Build Coastguard Worker 
1021*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1022*38e8c45fSAndroid Build Coastguard Worker 
1023*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
1024*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1025*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
1026*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1027*38e8c45fSAndroid Build Coastguard Worker }
1028*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_alpha_window)1029*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
1030*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300, "Parent Surface");
1031*38e8c45fSAndroid Build Coastguard Worker     parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
1032*38e8c45fSAndroid Build Coastguard Worker 
1033*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
1034*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1035*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) {
1036*38e8c45fSAndroid Build Coastguard Worker         t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
1037*38e8c45fSAndroid Build Coastguard Worker         t.reparent(sc, parentSurface->mSurfaceControl);
1038*38e8c45fSAndroid Build Coastguard Worker         t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
1039*38e8c45fSAndroid Build Coastguard Worker     });
1040*38e8c45fSAndroid Build Coastguard Worker 
1041*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1042*38e8c45fSAndroid Build Coastguard Worker 
1043*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1044*38e8c45fSAndroid Build Coastguard Worker 
1045*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
1046*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1047*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
1048*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1049*38e8c45fSAndroid Build Coastguard Worker }
1050*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,strict_unobscured_input_cropped_window)1051*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
1052*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300, "Parent Surface");
1053*38e8c45fSAndroid Build Coastguard Worker     parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
1054*38e8c45fSAndroid Build Coastguard Worker 
1055*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
1056*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) {
1057*38e8c45fSAndroid Build Coastguard Worker         t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
1058*38e8c45fSAndroid Build Coastguard Worker         t.reparent(sc, parentSurface->mSurfaceControl);
1059*38e8c45fSAndroid Build Coastguard Worker         t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
1060*38e8c45fSAndroid Build Coastguard Worker     });
1061*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1062*38e8c45fSAndroid Build Coastguard Worker 
1063*38e8c45fSAndroid Build Coastguard Worker     injectTap(111, 111);
1064*38e8c45fSAndroid Build Coastguard Worker 
1065*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1066*38e8c45fSAndroid Build Coastguard Worker 
1067*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
1068*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1069*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
1070*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1071*38e8c45fSAndroid Build Coastguard Worker }
1072*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,ignore_touch_region_with_zero_sized_blast)1073*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
1074*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1075*38e8c45fSAndroid Build Coastguard Worker 
1076*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<BlastInputSurface> bufferSurface =
1077*38e8c45fSAndroid Build Coastguard Worker             BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
1078*38e8c45fSAndroid Build Coastguard Worker 
1079*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1080*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, 200, 200));
1081*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
1082*38e8c45fSAndroid Build Coastguard Worker 
1083*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1084*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
1085*38e8c45fSAndroid Build Coastguard Worker }
1086*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,drop_input_policy)1087*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, drop_input_policy) {
1088*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1089*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction(
1090*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
1091*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1092*38e8c45fSAndroid Build Coastguard Worker 
1093*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1094*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1095*38e8c45fSAndroid Build Coastguard Worker 
1096*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus();
1097*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1098*38e8c45fSAndroid Build Coastguard Worker     injectKey(AKEYCODE_V);
1099*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1100*38e8c45fSAndroid Build Coastguard Worker }
1101*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,layer_with_valid_crop_can_be_focused)1102*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
1103*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bufferSurface =
1104*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
1105*38e8c45fSAndroid Build Coastguard Worker 
1106*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});
1107*38e8c45fSAndroid Build Coastguard Worker 
1108*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->requestFocus();
1109*38e8c45fSAndroid Build Coastguard Worker     bufferSurface->assertFocusChange(true);
1110*38e8c45fSAndroid Build Coastguard Worker }
1111*38e8c45fSAndroid Build Coastguard Worker 
1112*38e8c45fSAndroid Build Coastguard Worker /**
1113*38e8c45fSAndroid Build Coastguard Worker  * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
1114*38e8c45fSAndroid Build Coastguard Worker  * its own crop.
1115*38e8c45fSAndroid Build Coastguard Worker  */
TEST_F(InputSurfacesTest,cropped_container_replaces_touchable_region_with_null_crop)1116*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
1117*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentContainer =
1118*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1119*38e8c45fSAndroid Build Coastguard Worker                                                     "Parent Container Surface");
1120*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> containerSurface =
1121*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 100, 100,
1122*38e8c45fSAndroid Build Coastguard Worker                                                     "Test Container Surface");
1123*38e8c45fSAndroid Build Coastguard Worker     containerSurface->doTransaction(
1124*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1125*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1126*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
1127*38e8c45fSAndroid Build Coastguard Worker     parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1128*38e8c45fSAndroid Build Coastguard Worker     containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
1129*38e8c45fSAndroid Build Coastguard Worker 
1130*38e8c45fSAndroid Build Coastguard Worker     // Receives events inside its own crop
1131*38e8c45fSAndroid Build Coastguard Worker     injectTap(21, 21);
1132*38e8c45fSAndroid Build Coastguard Worker     containerSurface->expectTap(1, 1); // Event is in layer space
1133*38e8c45fSAndroid Build Coastguard Worker 
1134*38e8c45fSAndroid Build Coastguard Worker     // Does not receive events outside its crop
1135*38e8c45fSAndroid Build Coastguard Worker     injectTap(26, 26);
1136*38e8c45fSAndroid Build Coastguard Worker     containerSurface->assertNoEvent();
1137*38e8c45fSAndroid Build Coastguard Worker }
1138*38e8c45fSAndroid Build Coastguard Worker 
1139*38e8c45fSAndroid Build Coastguard Worker /**
1140*38e8c45fSAndroid Build Coastguard Worker  * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
1141*38e8c45fSAndroid Build Coastguard Worker  * in its parent's touchable region. The input events should be in the layer's coordinate space.
1142*38e8c45fSAndroid Build Coastguard Worker  */
TEST_F(InputSurfacesTest,uncropped_container_replaces_touchable_region_with_null_crop)1143*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
1144*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> bgContainer =
1145*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1146*38e8c45fSAndroid Build Coastguard Worker                                                     "Background Container Surface");
1147*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parentContainer =
1148*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1149*38e8c45fSAndroid Build Coastguard Worker                                                     "Parent Container Surface");
1150*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> containerSurface =
1151*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 100, 100,
1152*38e8c45fSAndroid Build Coastguard Worker                                                     "Test Container Surface");
1153*38e8c45fSAndroid Build Coastguard Worker     containerSurface->doTransaction(
1154*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1155*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1156*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
1157*38e8c45fSAndroid Build Coastguard Worker     parentContainer->doTransaction(
1158*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.reparent(sc, bgContainer->mSurfaceControl); });
1159*38e8c45fSAndroid Build Coastguard Worker     bgContainer->showAt(0, 0, Rect(0, 0, 100, 100));
1160*38e8c45fSAndroid Build Coastguard Worker     parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1161*38e8c45fSAndroid Build Coastguard Worker     containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1162*38e8c45fSAndroid Build Coastguard Worker 
1163*38e8c45fSAndroid Build Coastguard Worker     // Receives events inside parent bounds
1164*38e8c45fSAndroid Build Coastguard Worker     injectTap(21, 21);
1165*38e8c45fSAndroid Build Coastguard Worker     containerSurface->expectTap(1, 1); // Event is in layer space
1166*38e8c45fSAndroid Build Coastguard Worker 
1167*38e8c45fSAndroid Build Coastguard Worker     // Does not receive events outside parent bounds
1168*38e8c45fSAndroid Build Coastguard Worker     injectTap(31, 31);
1169*38e8c45fSAndroid Build Coastguard Worker     containerSurface->assertNoEvent();
1170*38e8c45fSAndroid Build Coastguard Worker }
1171*38e8c45fSAndroid Build Coastguard Worker 
1172*38e8c45fSAndroid Build Coastguard Worker /**
1173*38e8c45fSAndroid Build Coastguard Worker  * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
1174*38e8c45fSAndroid Build Coastguard Worker  * layer's bounds. The input events should be in the layer's coordinate space.
1175*38e8c45fSAndroid Build Coastguard Worker  */
TEST_F(InputSurfacesTest,replace_touchable_region_with_crop)1176*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
1177*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> cropLayer =
1178*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 0, 0, "Crop Layer Surface");
1179*38e8c45fSAndroid Build Coastguard Worker     cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));
1180*38e8c45fSAndroid Build Coastguard Worker 
1181*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> containerSurface =
1182*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurface(mComposerClient, 100, 100, "Container Surface");
1183*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1184*38e8c45fSAndroid Build Coastguard Worker     containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle =
1185*38e8c45fSAndroid Build Coastguard Worker             cropLayer->mSurfaceControl->getHandle();
1186*38e8c45fSAndroid Build Coastguard Worker     containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1187*38e8c45fSAndroid Build Coastguard Worker 
1188*38e8c45fSAndroid Build Coastguard Worker     // Receives events inside crop layer bounds
1189*38e8c45fSAndroid Build Coastguard Worker     injectTap(51, 51);
1190*38e8c45fSAndroid Build Coastguard Worker     containerSurface->expectTap(41, 41); // Event is in layer space
1191*38e8c45fSAndroid Build Coastguard Worker 
1192*38e8c45fSAndroid Build Coastguard Worker     // Does not receive events outside crop layer bounds
1193*38e8c45fSAndroid Build Coastguard Worker     injectTap(21, 21);
1194*38e8c45fSAndroid Build Coastguard Worker     injectTap(71, 71);
1195*38e8c45fSAndroid Build Coastguard Worker     containerSurface->assertNoEvent();
1196*38e8c45fSAndroid Build Coastguard Worker }
1197*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(InputSurfacesTest,child_container_with_no_input_channel_blocks_parent)1198*38e8c45fSAndroid Build Coastguard Worker TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
1199*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> parent = makeSurface(100, 100);
1200*38e8c45fSAndroid Build Coastguard Worker 
1201*38e8c45fSAndroid Build Coastguard Worker     parent->showAt(100, 100);
1202*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1203*38e8c45fSAndroid Build Coastguard Worker     parent->expectTap(1, 1);
1204*38e8c45fSAndroid Build Coastguard Worker 
1205*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> childContainerSurface =
1206*38e8c45fSAndroid Build Coastguard Worker             InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
1207*38e8c45fSAndroid Build Coastguard Worker     childContainerSurface->showAt(0, 0);
1208*38e8c45fSAndroid Build Coastguard Worker     childContainerSurface->doTransaction(
1209*38e8c45fSAndroid Build Coastguard Worker             [&](auto& t, auto& sc) { t.reparent(sc, parent->mSurfaceControl); });
1210*38e8c45fSAndroid Build Coastguard Worker     injectTap(101, 101);
1211*38e8c45fSAndroid Build Coastguard Worker 
1212*38e8c45fSAndroid Build Coastguard Worker     parent->assertNoEvent();
1213*38e8c45fSAndroid Build Coastguard Worker }
1214*38e8c45fSAndroid Build Coastguard Worker 
1215*38e8c45fSAndroid Build Coastguard Worker class MultiDisplayTests : public InputSurfacesTest {
1216*38e8c45fSAndroid Build Coastguard Worker public:
MultiDisplayTests()1217*38e8c45fSAndroid Build Coastguard Worker     MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
1218*38e8c45fSAndroid Build Coastguard Worker 
TearDown()1219*38e8c45fSAndroid Build Coastguard Worker     void TearDown() override {
1220*38e8c45fSAndroid Build Coastguard Worker         std::for_each(mVirtualDisplays.begin(), mVirtualDisplays.end(),
1221*38e8c45fSAndroid Build Coastguard Worker                       SurfaceComposerClient::destroyVirtualDisplay);
1222*38e8c45fSAndroid Build Coastguard Worker         InputSurfacesTest::TearDown();
1223*38e8c45fSAndroid Build Coastguard Worker     }
1224*38e8c45fSAndroid Build Coastguard Worker 
createDisplay(int32_t width,int32_t height,bool isSecure,ui::LayerStack layerStack,bool receivesInput=true,int32_t offsetX=0,int32_t offsetY=0)1225*38e8c45fSAndroid Build Coastguard Worker     void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
1226*38e8c45fSAndroid Build Coastguard Worker                        bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
1227*38e8c45fSAndroid Build Coastguard Worker         sp<IGraphicBufferConsumer> consumer;
1228*38e8c45fSAndroid Build Coastguard Worker         sp<IGraphicBufferProducer> producer;
1229*38e8c45fSAndroid Build Coastguard Worker         BufferQueue::createBufferQueue(&producer, &consumer);
1230*38e8c45fSAndroid Build Coastguard Worker         consumer->setConsumerName(String8("Virtual disp consumer (MultiDisplayTests)"));
1231*38e8c45fSAndroid Build Coastguard Worker         consumer->setDefaultBufferSize(width, height);
1232*38e8c45fSAndroid Build Coastguard Worker 
1233*38e8c45fSAndroid Build Coastguard Worker         class StubConsumerListener : public BnConsumerListener {
1234*38e8c45fSAndroid Build Coastguard Worker             virtual void onFrameAvailable(const BufferItem&) override {}
1235*38e8c45fSAndroid Build Coastguard Worker             virtual void onBuffersReleased() override {}
1236*38e8c45fSAndroid Build Coastguard Worker             virtual void onSidebandStreamChanged() override {}
1237*38e8c45fSAndroid Build Coastguard Worker         };
1238*38e8c45fSAndroid Build Coastguard Worker 
1239*38e8c45fSAndroid Build Coastguard Worker         consumer->consumerConnect(sp<StubConsumerListener>::make(), true);
1240*38e8c45fSAndroid Build Coastguard Worker         mBufferQueues.push_back({consumer, producer});
1241*38e8c45fSAndroid Build Coastguard Worker 
1242*38e8c45fSAndroid Build Coastguard Worker         std::string name = "VirtualDisplay";
1243*38e8c45fSAndroid Build Coastguard Worker         name += std::to_string(mVirtualDisplays.size());
1244*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> token = SurfaceComposerClient::createVirtualDisplay(name, isSecure);
1245*38e8c45fSAndroid Build Coastguard Worker         SurfaceComposerClient::Transaction t;
1246*38e8c45fSAndroid Build Coastguard Worker         t.setDisplaySurface(token, producer);
1247*38e8c45fSAndroid Build Coastguard Worker         t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
1248*38e8c45fSAndroid Build Coastguard Worker         t.setDisplayLayerStack(token, layerStack);
1249*38e8c45fSAndroid Build Coastguard Worker         t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
1250*38e8c45fSAndroid Build Coastguard Worker                                {offsetX, offsetY, offsetX + width, offsetY + height});
1251*38e8c45fSAndroid Build Coastguard Worker         t.apply(/*synchronously=*/true);
1252*38e8c45fSAndroid Build Coastguard Worker 
1253*38e8c45fSAndroid Build Coastguard Worker         mVirtualDisplays.push_back(token);
1254*38e8c45fSAndroid Build Coastguard Worker     }
1255*38e8c45fSAndroid Build Coastguard Worker 
1256*38e8c45fSAndroid Build Coastguard Worker     std::vector<sp<IBinder>> mVirtualDisplays;
1257*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::tuple<sp<IGraphicBufferConsumer>, sp<IGraphicBufferProducer>>> mBufferQueues;
1258*38e8c45fSAndroid Build Coastguard Worker };
1259*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(MultiDisplayTests,drop_touch_if_layer_on_invalid_display)1260*38e8c45fSAndroid Build Coastguard Worker TEST_F(MultiDisplayTests, drop_touch_if_layer_on_invalid_display) {
1261*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1262*38e8c45fSAndroid Build Coastguard Worker     // Do not create a display associated with the LayerStack.
1263*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1264*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) { t.setLayerStack(sc, layerStack); });
1265*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1266*38e8c45fSAndroid Build Coastguard Worker 
1267*38e8c45fSAndroid Build Coastguard Worker     // Touches should be dropped if the layer is on an invalid display.
1268*38e8c45fSAndroid Build Coastguard Worker     injectTapOnDisplay(101, 101, toDisplayId(layerStack));
1269*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1270*38e8c45fSAndroid Build Coastguard Worker 
1271*38e8c45fSAndroid Build Coastguard Worker     // However, we still let the window be focused and receive keys.
1272*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus(toDisplayId(layerStack));
1273*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1274*38e8c45fSAndroid Build Coastguard Worker 
1275*38e8c45fSAndroid Build Coastguard Worker     injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
1276*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
1277*38e8c45fSAndroid Build Coastguard Worker }
1278*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(MultiDisplayTests,virtual_display_receives_input)1279*38e8c45fSAndroid Build Coastguard Worker TEST_F(MultiDisplayTests, virtual_display_receives_input) {
1280*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1281*38e8c45fSAndroid Build Coastguard Worker     createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1282*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1283*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) { t.setLayerStack(sc, layerStack); });
1284*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1285*38e8c45fSAndroid Build Coastguard Worker 
1286*38e8c45fSAndroid Build Coastguard Worker     injectTapOnDisplay(101, 101, toDisplayId(layerStack));
1287*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
1288*38e8c45fSAndroid Build Coastguard Worker 
1289*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus(toDisplayId(layerStack));
1290*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1291*38e8c45fSAndroid Build Coastguard Worker     injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
1292*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
1293*38e8c45fSAndroid Build Coastguard Worker }
1294*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(MultiDisplayTests,drop_input_for_secure_layer_on_nonsecure_display)1295*38e8c45fSAndroid Build Coastguard Worker TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
1296*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1297*38e8c45fSAndroid Build Coastguard Worker     createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1298*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1299*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) {
1300*38e8c45fSAndroid Build Coastguard Worker         t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1301*38e8c45fSAndroid Build Coastguard Worker         t.setLayerStack(sc, layerStack);
1302*38e8c45fSAndroid Build Coastguard Worker     });
1303*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1304*38e8c45fSAndroid Build Coastguard Worker 
1305*38e8c45fSAndroid Build Coastguard Worker     injectTapOnDisplay(101, 101, toDisplayId(layerStack));
1306*38e8c45fSAndroid Build Coastguard Worker 
1307*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1308*38e8c45fSAndroid Build Coastguard Worker 
1309*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus(toDisplayId(layerStack));
1310*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1311*38e8c45fSAndroid Build Coastguard Worker     injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
1312*38e8c45fSAndroid Build Coastguard Worker     surface->assertNoEvent();
1313*38e8c45fSAndroid Build Coastguard Worker }
1314*38e8c45fSAndroid Build Coastguard Worker 
TEST_F(MultiDisplayTests,dont_drop_input_for_secure_layer_on_secure_display)1315*38e8c45fSAndroid Build Coastguard Worker TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
1316*38e8c45fSAndroid Build Coastguard Worker     ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1317*38e8c45fSAndroid Build Coastguard Worker 
1318*38e8c45fSAndroid Build Coastguard Worker     // Create the secure display as system, because only certain users can create secure displays.
1319*38e8c45fSAndroid Build Coastguard Worker     seteuid(AID_SYSTEM);
1320*38e8c45fSAndroid Build Coastguard Worker     createDisplay(1000, 1000, true /*isSecure*/, layerStack);
1321*38e8c45fSAndroid Build Coastguard Worker     // Change the uid back to root.
1322*38e8c45fSAndroid Build Coastguard Worker     seteuid(AID_ROOT);
1323*38e8c45fSAndroid Build Coastguard Worker 
1324*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1325*38e8c45fSAndroid Build Coastguard Worker     surface->doTransaction([&](auto& t, auto& sc) {
1326*38e8c45fSAndroid Build Coastguard Worker         t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1327*38e8c45fSAndroid Build Coastguard Worker         t.setLayerStack(sc, layerStack);
1328*38e8c45fSAndroid Build Coastguard Worker     });
1329*38e8c45fSAndroid Build Coastguard Worker     surface->showAt(100, 100);
1330*38e8c45fSAndroid Build Coastguard Worker 
1331*38e8c45fSAndroid Build Coastguard Worker     injectTapOnDisplay(101, 101, toDisplayId(layerStack));
1332*38e8c45fSAndroid Build Coastguard Worker     surface->expectTap(1, 1);
1333*38e8c45fSAndroid Build Coastguard Worker 
1334*38e8c45fSAndroid Build Coastguard Worker     surface->requestFocus(toDisplayId(layerStack));
1335*38e8c45fSAndroid Build Coastguard Worker     surface->assertFocusChange(true);
1336*38e8c45fSAndroid Build Coastguard Worker     injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
1337*38e8c45fSAndroid Build Coastguard Worker 
1338*38e8c45fSAndroid Build Coastguard Worker     surface->expectKey(AKEYCODE_V);
1339*38e8c45fSAndroid Build Coastguard Worker }
1340*38e8c45fSAndroid Build Coastguard Worker 
1341*38e8c45fSAndroid Build Coastguard Worker } // namespace test
1342*38e8c45fSAndroid Build Coastguard Worker } // namespace android
1343