blob: fcfe21bee2029d173cfee272ce09b90ab1454e4f [file] [log] [blame]
Robert Carr1c4c5592018-09-24 13:18:43 -07001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18#include <stdlib.h>
19#include <unistd.h>
20#include <sys/time.h>
21#include <sys/types.h>
22#include <stdio.h>
23#include <poll.h>
24
25#include <memory>
26
Vishnu Naira066d902021-09-13 18:40:17 -070027#include <android/keycodes.h>
Vishnu Nairde19f852018-12-18 16:11:53 -080028#include <android/native_window.h>
29
Robert Carr1c4c5592018-09-24 13:18:43 -070030#include <binder/Binder.h>
31#include <binder/IServiceManager.h>
32#include <binder/Parcel.h>
33#include <binder/ProcessState.h>
34
Vishnu Nairde19f852018-12-18 16:11:53 -080035#include <gui/ISurfaceComposer.h>
36#include <gui/Surface.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070037#include <gui/SurfaceComposerClient.h>
38#include <gui/SurfaceControl.h>
39
Chris Ye0783e992020-06-02 21:34:49 -070040#include <android/os/IInputFlinger.h>
chaviw98318de2021-05-19 16:45:23 -050041#include <gui/WindowInfo.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070042#include <input/Input.h>
Chris Ye0783e992020-06-02 21:34:49 -070043#include <input/InputTransport.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070044
Marin Shalamanova7fe3042021-01-29 21:02:08 +010045#include <ui/DisplayMode.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070046#include <ui/Rect.h>
47#include <ui/Region.h>
48
Prabir Pradhand0aba782021-12-14 00:44:21 -080049#include <private/android_filesystem_config.h>
50
Chris Ye0783e992020-06-02 21:34:49 -070051using android::os::IInputFlinger;
Robert Carr1c4c5592018-09-24 13:18:43 -070052
chaviw39d01472021-04-08 14:26:24 -050053using android::hardware::graphics::common::V1_1::BufferUsage;
54
chaviw98318de2021-05-19 16:45:23 -050055using android::gui::FocusRequest;
56using android::gui::InputApplicationInfo;
57using android::gui::TouchOcclusionMode;
58using android::gui::WindowInfo;
59
Vishnu Nair958da932020-08-21 17:12:37 -070060namespace android::test {
Robert Carr1c4c5592018-09-24 13:18:43 -070061
Vishnu Nairde19f852018-12-18 16:11:53 -080062using Transaction = SurfaceComposerClient::Transaction;
63
Robert Carr1c4c5592018-09-24 13:18:43 -070064sp<IInputFlinger> getInputFlinger() {
65 sp<IBinder> input(defaultServiceManager()->getService(
66 String16("inputflinger")));
67 if (input == nullptr) {
68 ALOGE("Failed to link to input service");
69 } else { ALOGE("Linked to input"); }
70 return interface_cast<IInputFlinger>(input);
71}
72
73// We use the top 10 layers as a way to haphazardly place ourselves above anything else.
74static const int LAYER_BASE = INT32_MAX - 10;
Chris Ye6c4243b2020-07-22 12:07:12 -070075static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Robert Carr1c4c5592018-09-24 13:18:43 -070076
77class InputSurface {
78public:
Vishnu Nairde19f852018-12-18 16:11:53 -080079 InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
80 mSurfaceControl = sc;
Robert Carr1c4c5592018-09-24 13:18:43 -070081
82 mInputFlinger = getInputFlinger();
Garfield Tan15601662020-09-22 15:32:38 -070083 mClientChannel = std::make_shared<InputChannel>();
84 mInputFlinger->createInputChannel("testchannels", mClientChannel.get());
Robert Carr1c4c5592018-09-24 13:18:43 -070085
86 populateInputInfo(width, height);
87
88 mInputConsumer = new InputConsumer(mClientChannel);
89 }
90
Vishnu Nairde19f852018-12-18 16:11:53 -080091 static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
92 int width, int height) {
93 sp<SurfaceControl> surfaceControl =
94 scc->createSurface(String8("Test Surface"), 0 /* bufHeight */, 0 /* bufWidth */,
Vishnu Nairfa247b12020-02-11 08:58:26 -080095 PIXEL_FORMAT_RGBA_8888,
96 ISurfaceComposerClient::eFXSurfaceEffect);
Vishnu Nairde19f852018-12-18 16:11:53 -080097 return std::make_unique<InputSurface>(surfaceControl, width, height);
98 }
99
100 static std::unique_ptr<InputSurface> makeBufferInputSurface(
101 const sp<SurfaceComposerClient> &scc, int width, int height) {
102 sp<SurfaceControl> surfaceControl =
103 scc->createSurface(String8("Test Buffer Surface"), width, height,
104 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
105 return std::make_unique<InputSurface>(surfaceControl, width, height);
106 }
107
108 static std::unique_ptr<InputSurface> makeContainerInputSurface(
109 const sp<SurfaceComposerClient> &scc, int width, int height) {
110 sp<SurfaceControl> surfaceControl =
111 scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */,
112 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
113 ISurfaceComposerClient::eFXSurfaceContainer);
114 return std::make_unique<InputSurface>(surfaceControl, width, height);
115 }
116
arthurhungb4a0f852020-06-16 11:02:50 +0800117 static std::unique_ptr<InputSurface> makeCursorInputSurface(
118 const sp<SurfaceComposerClient> &scc, int width, int height) {
119 sp<SurfaceControl> surfaceControl =
120 scc->createSurface(String8("Test Cursor Surface"), 0 /* bufHeight */,
121 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
122 ISurfaceComposerClient::eCursorWindow);
123 return std::make_unique<InputSurface>(surfaceControl, width, height);
124 }
125
Vishnu Naira066d902021-09-13 18:40:17 -0700126 InputEvent *consumeEvent(int timeoutMs = 3000) {
127 waitForEventAvailable(timeoutMs);
Robert Carr1c4c5592018-09-24 13:18:43 -0700128
129 InputEvent *ev;
130 uint32_t seqId;
131 status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
132 if (consumed != OK) {
133 return nullptr;
134 }
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100135 status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
136 EXPECT_EQ(OK, status) << "Could not send finished signal";
Robert Carr1c4c5592018-09-24 13:18:43 -0700137 return ev;
138 }
139
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100140 void assertFocusChange(bool hasFocus) {
141 InputEvent *ev = consumeEvent();
142 ASSERT_NE(ev, nullptr);
143 ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType());
144 FocusEvent *focusEvent = static_cast<FocusEvent *>(ev);
145 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
146 }
147
Robert Carr1c4c5592018-09-24 13:18:43 -0700148 void expectTap(int x, int y) {
149 InputEvent* ev = consumeEvent();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100150 ASSERT_NE(ev, nullptr);
151 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
Robert Carr1c4c5592018-09-24 13:18:43 -0700152 MotionEvent* mev = static_cast<MotionEvent*>(ev);
153 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
154 EXPECT_EQ(x, mev->getX(0));
155 EXPECT_EQ(y, mev->getY(0));
arthurhungb4a0f852020-06-16 11:02:50 +0800156 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
Robert Carr1c4c5592018-09-24 13:18:43 -0700157
158 ev = consumeEvent();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100159 ASSERT_NE(ev, nullptr);
160 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
Robert Carr1c4c5592018-09-24 13:18:43 -0700161 mev = static_cast<MotionEvent*>(ev);
162 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
arthurhungb4a0f852020-06-16 11:02:50 +0800163 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
Robert Carr1c4c5592018-09-24 13:18:43 -0700164 }
165
chaviw39cfa2e2020-11-04 14:19:02 -0800166 void expectTapWithFlag(int x, int y, int32_t flags) {
167 InputEvent *ev = consumeEvent();
168 ASSERT_NE(ev, nullptr);
169 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
170 MotionEvent *mev = static_cast<MotionEvent *>(ev);
171 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
172 EXPECT_EQ(x, mev->getX(0));
173 EXPECT_EQ(y, mev->getY(0));
174 EXPECT_EQ(flags, mev->getFlags() & flags);
175
176 ev = consumeEvent();
177 ASSERT_NE(ev, nullptr);
178 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
179 mev = static_cast<MotionEvent *>(ev);
180 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
181 EXPECT_EQ(flags, mev->getFlags() & flags);
182 }
183
Prabir Pradhand0aba782021-12-14 00:44:21 -0800184 void expectTapInDisplayCoordinates(int displayX, int displayY) {
185 InputEvent *ev = consumeEvent();
186 ASSERT_NE(ev, nullptr);
187 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
188 MotionEvent *mev = static_cast<MotionEvent *>(ev);
189 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
190 const PointerCoords &coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
191 EXPECT_EQ(displayX, coords.getX());
192 EXPECT_EQ(displayY, coords.getY());
193 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
194
195 ev = consumeEvent();
196 ASSERT_NE(ev, nullptr);
197 ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
198 mev = static_cast<MotionEvent *>(ev);
199 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
200 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
201 }
202
Vishnu Naira066d902021-09-13 18:40:17 -0700203 void expectKey(uint32_t keycode) {
204 InputEvent *ev = consumeEvent();
205 ASSERT_NE(ev, nullptr);
206 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
207 KeyEvent *keyEvent = static_cast<KeyEvent *>(ev);
208 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
209 EXPECT_EQ(keycode, keyEvent->getKeyCode());
210 EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
211
212 ev = consumeEvent();
213 ASSERT_NE(ev, nullptr);
214 ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
215 keyEvent = static_cast<KeyEvent *>(ev);
216 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
217 EXPECT_EQ(keycode, keyEvent->getKeyCode());
218 EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
219 }
220
chaviw39d01472021-04-08 14:26:24 -0500221 virtual ~InputSurface() {
222 mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
223 }
Robert Carr1c4c5592018-09-24 13:18:43 -0700224
chaviw39d01472021-04-08 14:26:24 -0500225 virtual void doTransaction(
226 std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
227 transactionBody) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700228 SurfaceComposerClient::Transaction t;
229 transactionBody(t, mSurfaceControl);
230 t.apply(true);
231 }
232
chaviw39d01472021-04-08 14:26:24 -0500233 virtual void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700234 SurfaceComposerClient::Transaction t;
235 t.show(mSurfaceControl);
236 t.setInputWindowInfo(mSurfaceControl, mInputInfo);
237 t.setLayer(mSurfaceControl, LAYER_BASE);
238 t.setPosition(mSurfaceControl, x, y);
chaviw25714502021-02-11 10:01:08 -0800239 t.setCrop(mSurfaceControl, crop);
Robert Carr1c4c5592018-09-24 13:18:43 -0700240 t.setAlpha(mSurfaceControl, 1);
241 t.apply(true);
242 }
243
Vishnu Nair16a938f2021-09-24 07:14:54 -0700244 void requestFocus(int displayId = ADISPLAY_ID_DEFAULT) {
Vishnu Nair958da932020-08-21 17:12:37 -0700245 SurfaceComposerClient::Transaction t;
Vishnu Nair9ad01462021-01-15 12:55:14 -0800246 FocusRequest request;
247 request.token = mInputInfo.token;
248 request.windowName = mInputInfo.name;
249 request.focusedToken = nullptr;
250 request.focusedWindowName = "";
251 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
Vishnu Nair16a938f2021-09-24 07:14:54 -0700252 request.displayId = displayId;
Vishnu Nair9ad01462021-01-15 12:55:14 -0800253 t.setFocusedWindow(request);
Vishnu Nair958da932020-08-21 17:12:37 -0700254 t.apply(true);
255 }
256
Robert Carr1c4c5592018-09-24 13:18:43 -0700257private:
Vishnu Naira066d902021-09-13 18:40:17 -0700258 void waitForEventAvailable(int timeoutMs) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700259 struct pollfd fd;
260
261 fd.fd = mClientChannel->getFd();
262 fd.events = POLLIN;
Vishnu Naira066d902021-09-13 18:40:17 -0700263 poll(&fd, 1, timeoutMs);
Robert Carr1c4c5592018-09-24 13:18:43 -0700264 }
265
266 void populateInputInfo(int width, int height) {
Garfield Tan15601662020-09-22 15:32:38 -0700267 mInputInfo.token = mClientChannel->getConnectionToken();
Robert Carr1c4c5592018-09-24 13:18:43 -0700268 mInputInfo.name = "Test info";
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500269 mInputInfo.dispatchingTimeout = 5s;
Robert Carre07e1032018-11-26 12:55:53 -0800270 mInputInfo.globalScaleFactor = 1.0;
Robert Carr1c4c5592018-09-24 13:18:43 -0700271 mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
272
Robert Carr740167f2018-10-11 19:03:41 -0700273 InputApplicationInfo aInfo;
274 aInfo.token = new BBinder();
275 aInfo.name = "Test app info";
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500276 aInfo.dispatchingTimeoutMillis =
277 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Robert Carr740167f2018-10-11 19:03:41 -0700278
279 mInputInfo.applicationInfo = aInfo;
Robert Carr1c4c5592018-09-24 13:18:43 -0700280 }
281public:
282 sp<SurfaceControl> mSurfaceControl;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500283 std::shared_ptr<InputChannel> mClientChannel;
Robert Carr1c4c5592018-09-24 13:18:43 -0700284 sp<IInputFlinger> mInputFlinger;
285
chaviw98318de2021-05-19 16:45:23 -0500286 WindowInfo mInputInfo;
Robert Carr1c4c5592018-09-24 13:18:43 -0700287
288 PreallocatedInputEventFactory mInputEventFactory;
289 InputConsumer* mInputConsumer;
290};
291
chaviw39d01472021-04-08 14:26:24 -0500292class BlastInputSurface : public InputSurface {
293public:
294 BlastInputSurface(const sp<SurfaceControl> &sc, const sp<SurfaceControl> &parentSc, int width,
295 int height)
296 : InputSurface(sc, width, height) {
297 mParentSurfaceControl = parentSc;
298 }
299
300 ~BlastInputSurface() = default;
301
302 static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
303 const sp<SurfaceComposerClient> &scc, int width, int height) {
304 sp<SurfaceControl> parentSc =
305 scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
306 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
307 ISurfaceComposerClient::eFXSurfaceContainer);
308
309 sp<SurfaceControl> surfaceControl =
310 scc->createSurface(String8("Test Buffer Surface"), width, height,
311 PIXEL_FORMAT_RGBA_8888,
312 ISurfaceComposerClient::eFXSurfaceBufferState,
313 parentSc->getHandle());
314 return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
315 }
316
317 void doTransaction(
318 std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
319 transactionBody) override {
320 SurfaceComposerClient::Transaction t;
321 transactionBody(t, mParentSurfaceControl);
322 t.apply(true);
323 }
324
325 void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
326 SurfaceComposerClient::Transaction t;
327 t.show(mParentSurfaceControl);
328 t.setLayer(mParentSurfaceControl, LAYER_BASE);
329 t.setPosition(mParentSurfaceControl, x, y);
330 t.setCrop(mParentSurfaceControl, crop);
331
332 t.show(mSurfaceControl);
333 t.setInputWindowInfo(mSurfaceControl, mInputInfo);
334 t.setCrop(mSurfaceControl, crop);
335 t.setAlpha(mSurfaceControl, 1);
336 t.apply(true);
337 }
338
339private:
340 sp<SurfaceControl> mParentSurfaceControl;
341};
342
Robert Carr1c4c5592018-09-24 13:18:43 -0700343class InputSurfacesTest : public ::testing::Test {
344public:
345 InputSurfacesTest() {
346 ProcessState::self()->startThreadPool();
347 }
348
349 void SetUp() {
350 mComposerClient = new SurfaceComposerClient;
351 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
Vishnu Nairde19f852018-12-18 16:11:53 -0800352
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800353 const auto display = mComposerClient->getInternalDisplayToken();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100354 ASSERT_NE(display, nullptr);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800355
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100356 ui::DisplayMode mode;
357 ASSERT_EQ(NO_ERROR, mComposerClient->getActiveDisplayMode(display, &mode));
Vishnu Nairde19f852018-12-18 16:11:53 -0800358
359 // After a new buffer is queued, SurfaceFlinger is notified and will
360 // latch the new buffer on next vsync. Let's heuristically wait for 3
361 // vsyncs.
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100362 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
Robert Carr1c4c5592018-09-24 13:18:43 -0700363 }
364
365 void TearDown() {
366 mComposerClient->dispose();
367 }
368
369 std::unique_ptr<InputSurface> makeSurface(int width, int height) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800370 return InputSurface::makeColorInputSurface(mComposerClient, width, height);
371 }
372
chaviw39d01472021-04-08 14:26:24 -0500373 void postBuffer(const sp<SurfaceControl> &layer, int32_t w, int32_t h) {
374 int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
375 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
376 sp<GraphicBuffer> buffer =
377 new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
378 Transaction().setBuffer(layer, buffer).apply(true);
Vishnu Nairde19f852018-12-18 16:11:53 -0800379 usleep(mBufferPostDelay);
Robert Carr1c4c5592018-09-24 13:18:43 -0700380 }
381
382 sp<SurfaceComposerClient> mComposerClient;
Vishnu Nairde19f852018-12-18 16:11:53 -0800383 int32_t mBufferPostDelay;
Robert Carr1c4c5592018-09-24 13:18:43 -0700384};
385
Vishnu Nair16a938f2021-09-24 07:14:54 -0700386void injectTapOnDisplay(int x, int y, int displayId) {
387 char *buf1, *buf2, *bufDisplayId;
Robert Carr1c4c5592018-09-24 13:18:43 -0700388 asprintf(&buf1, "%d", x);
389 asprintf(&buf2, "%d", y);
Vishnu Nair16a938f2021-09-24 07:14:54 -0700390 asprintf(&bufDisplayId, "%d", displayId);
Robert Carr1c4c5592018-09-24 13:18:43 -0700391 if (fork() == 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700392 execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
393 }
394}
395
396void injectTap(int x, int y) {
397 injectTapOnDisplay(x, y, ADISPLAY_ID_DEFAULT);
398}
399
400void injectKeyOnDisplay(uint32_t keycode, int displayId) {
401 char *buf1, *bufDisplayId;
402 asprintf(&buf1, "%d", keycode);
403 asprintf(&bufDisplayId, "%d", displayId);
404 if (fork() == 0) {
405 execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
Robert Carr1c4c5592018-09-24 13:18:43 -0700406 }
407}
408
Vishnu Naira066d902021-09-13 18:40:17 -0700409void injectKey(uint32_t keycode) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700410 injectKeyOnDisplay(keycode, ADISPLAY_ID_NONE);
Vishnu Naira066d902021-09-13 18:40:17 -0700411}
412
Robert Carr1c4c5592018-09-24 13:18:43 -0700413TEST_F(InputSurfacesTest, can_receive_input) {
414 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
415 surface->showAt(100, 100);
416
417 injectTap(101, 101);
418
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100419 EXPECT_NE(surface->consumeEvent(), nullptr);
Robert Carr1c4c5592018-09-24 13:18:43 -0700420}
421
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100422/**
423 * Set up two surfaces side-by-side. Tap each surface.
424 * Next, swap the positions of the two surfaces. Inject tap into the two
425 * original locations. Ensure that the tap is received by the surfaces in the
426 * reverse order.
427 */
Robert Carr1c4c5592018-09-24 13:18:43 -0700428TEST_F(InputSurfacesTest, input_respects_positioning) {
429 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
430 surface->showAt(100, 100);
431
432 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
433 surface2->showAt(200, 200);
434
435 injectTap(201, 201);
436 surface2->expectTap(1, 1);
437
438 injectTap(101, 101);
439 surface->expectTap(1, 1);
440
441 surface2->doTransaction([](auto &t, auto &sc) {
442 t.setPosition(sc, 100, 100);
443 });
444 surface->doTransaction([](auto &t, auto &sc) {
445 t.setPosition(sc, 200, 200);
446 });
447
448 injectTap(101, 101);
449 surface2->expectTap(1, 1);
450
451 injectTap(201, 201);
452 surface->expectTap(1, 1);
453}
454
455TEST_F(InputSurfacesTest, input_respects_layering) {
456 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
457 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
458
459 surface->showAt(10, 10);
460 surface2->showAt(10, 10);
461
462 surface->doTransaction([](auto &t, auto &sc) {
463 t.setLayer(sc, LAYER_BASE + 1);
464 });
465
466 injectTap(11, 11);
467 surface->expectTap(1, 1);
468
469 surface2->doTransaction([](auto &t, auto &sc) {
470 t.setLayer(sc, LAYER_BASE + 1);
471 });
472
473 injectTap(11, 11);
474 surface2->expectTap(1, 1);
475
476 surface2->doTransaction([](auto &t, auto &sc) {
477 t.hide(sc);
478 });
479
480 injectTap(11, 11);
481 surface->expectTap(1, 1);
482}
483
Vishnu Nairde19f852018-12-18 16:11:53 -0800484// Surface Insets are set to offset the client content and draw a border around the client surface
485// (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
486// of the client content.
487TEST_F(InputSurfacesTest, input_respects_surface_insets) {
488 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
489 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
490 bgSurface->showAt(100, 100);
491
492 fgSurface->mInputInfo.surfaceInset = 5;
493 fgSurface->showAt(100, 100);
494
495 injectTap(106, 106);
496 fgSurface->expectTap(1, 1);
497
498 injectTap(101, 101);
499 bgSurface->expectTap(1, 1);
500}
501
502// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
503TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
504 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
505 std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
506 parentSurface->showAt(100, 100);
507
508 childSurface->mInputInfo.surfaceInset = 10;
509 childSurface->showAt(100, 100);
510
511 childSurface->doTransaction([&](auto &t, auto &sc) {
512 t.setPosition(sc, -5, -5);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000513 t.reparent(sc, parentSurface->mSurfaceControl);
Vishnu Nairde19f852018-12-18 16:11:53 -0800514 });
515
516 injectTap(106, 106);
517 childSurface->expectTap(1, 1);
518
519 injectTap(101, 101);
520 parentSurface->expectTap(1, 1);
521}
522
Arthur Hung118b1142019-05-08 21:25:59 +0800523// Ensure a surface whose insets are scaled, handles the touch offset correctly.
524TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
525 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
526 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
527 bgSurface->showAt(100, 100);
528
529 fgSurface->mInputInfo.surfaceInset = 5;
530 fgSurface->showAt(100, 100);
531
532 fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
533
534 // expect = touch / scale - inset
535 injectTap(112, 124);
536 fgSurface->expectTap(1, 1);
537
538 injectTap(101, 101);
539 bgSurface->expectTap(1, 1);
540}
541
Ady Abraham282f1d72019-07-24 18:05:56 -0700542TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700543 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
Ady Abraham282f1d72019-07-24 18:05:56 -0700544 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700545 bgSurface->showAt(100, 100);
546
Ady Abraham282f1d72019-07-24 18:05:56 -0700547 // In case we pass the very big inset without any checking.
548 fgSurface->mInputInfo.surfaceInset = INT32_MAX;
549 fgSurface->showAt(100, 100);
550
551 fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
552
553 // expect no crash for overflow, and inset size to be clamped to surface size
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700554 injectTap(112, 124);
555 bgSurface->expectTap(12, 24);
Ady Abraham282f1d72019-07-24 18:05:56 -0700556}
557
Vishnu Nairde19f852018-12-18 16:11:53 -0800558// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
559TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
560 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
561 surface->doTransaction([](auto &t, auto &sc) {
562 Region transparentRegion(Rect(0, 0, 10, 10));
563 t.setTransparentRegionHint(sc, transparentRegion);
564 });
565 surface->showAt(100, 100);
566 injectTap(101, 101);
567 surface->expectTap(1, 1);
568}
569
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700570// TODO(b/139494112) update tests once we define expected behavior
571// Ensure we still send input to the surface regardless of surface visibility changes due to the
572// first buffer being submitted or alpha changes.
573// Original bug ref: b/120839715
574TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800575 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500576 std::unique_ptr<BlastInputSurface> bufferSurface =
577 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800578
579 bgSurface->showAt(10, 10);
580 bufferSurface->showAt(10, 10);
581
582 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700583 bufferSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800584
chaviw39d01472021-04-08 14:26:24 -0500585 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800586 injectTap(11, 11);
587 bufferSurface->expectTap(1, 1);
588}
589
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000590TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800591 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500592 std::unique_ptr<BlastInputSurface> bufferSurface =
593 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
594 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800595
596 bgSurface->showAt(10, 10);
597 bufferSurface->showAt(10, 10);
598
599 injectTap(11, 11);
600 bufferSurface->expectTap(1, 1);
601
602 bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
603
604 injectTap(11, 11);
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000605 bgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800606}
607
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700608TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800609 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
610 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
611
612 bgSurface->showAt(10, 10);
613 fgSurface->showAt(10, 10);
614
615 injectTap(11, 11);
616 fgSurface->expectTap(1, 1);
617
618 fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
619
620 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700621 fgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800622}
623
624TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
625 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
626 std::unique_ptr<InputSurface> containerSurface =
627 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
628
629 bgSurface->showAt(10, 10);
630 containerSurface->showAt(10, 10);
631
632 injectTap(11, 11);
633 containerSurface->expectTap(1, 1);
634
635 containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
636
637 injectTap(11, 11);
638 bgSurface->expectTap(1, 1);
639}
chaviwfbe5d9c2018-12-26 12:23:37 -0800640
Arthur Hungd20b2702019-01-14 18:16:16 +0800641TEST_F(InputSurfacesTest, input_respects_outscreen) {
642 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
643 surface->showAt(-1, -1);
644
645 injectTap(0, 0);
646 surface->expectTap(1, 1);
647}
arthurhungb4a0f852020-06-16 11:02:50 +0800648
649TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
650 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
651 std::unique_ptr<InputSurface> cursorSurface =
652 InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);
653
654 surface->showAt(10, 10);
arthurhungb4a0f852020-06-16 11:02:50 +0800655 cursorSurface->showAt(10, 10);
656
657 injectTap(11, 11);
658 surface->expectTap(1, 1);
659}
Vishnu Nair958da932020-08-21 17:12:37 -0700660
661TEST_F(InputSurfacesTest, can_be_focused) {
662 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
663 surface->showAt(100, 100);
664 surface->requestFocus();
665
666 surface->assertFocusChange(true);
Vishnu Naira066d902021-09-13 18:40:17 -0700667
668 injectKey(AKEYCODE_V);
669 surface->expectKey(AKEYCODE_V);
Robert Carr1c4c5592018-09-24 13:18:43 -0700670}
chaviw44a6d2b2020-09-08 17:14:16 -0700671
672TEST_F(InputSurfacesTest, rotate_surface) {
673 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
674 surface->showAt(10, 10);
675 surface->doTransaction([](auto &t, auto &sc) {
676 t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
677 });
678 injectTap(8, 11);
679 surface->expectTap(1, 2);
680
681 surface->doTransaction([](auto &t, auto &sc) {
682 t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
683 });
684 injectTap(9, 8);
685 surface->expectTap(1, 2);
686
687 surface->doTransaction([](auto &t, auto &sc) {
688 t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
689 });
690 injectTap(12, 9);
691 surface->expectTap(1, 2);
692}
693
694TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
695 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
696 surface->showAt(10, 10);
697 surface->doTransaction([](auto &t, auto &sc) {
698 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
699 });
700 injectTap(2, 12);
701 surface->expectTap(1, 2);
702
703 surface->doTransaction([](auto &t, auto &sc) {
704 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
705 });
706 injectTap(8, 2);
707 surface->expectTap(1, 2);
708
709 surface->doTransaction([](auto &t, auto &sc) {
710 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
711 });
712 injectTap(18, 8);
713 surface->expectTap(1, 2);
714}
715
716TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
717 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
718 surface->mInputInfo.surfaceInset = 5;
719 surface->showAt(100, 100);
720
721 surface->doTransaction([](auto &t, auto &sc) {
722 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
723 });
724 injectTap(40, 120);
725 surface->expectTap(5, 10);
726
727 surface->doTransaction([](auto &t, auto &sc) {
728 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
729 });
730 injectTap(80, 40);
731 surface->expectTap(5, 10);
732
733 surface->doTransaction([](auto &t, auto &sc) {
734 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
735 });
736 injectTap(160, 80);
737 surface->expectTap(5, 10);
738}
739
chaviw39cfa2e2020-11-04 14:19:02 -0800740TEST_F(InputSurfacesTest, touch_flag_obscured) {
741 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
742 surface->showAt(100, 100);
743
744 // Add non touchable window to fully cover touchable window. Window behind gets touch, but
745 // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
746 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800747 nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
chaviw39cfa2e2020-11-04 14:19:02 -0800748 nonTouchableSurface->mInputInfo.ownerUid = 22222;
Bernardo Rufino602ef712020-12-21 11:02:18 +0000749 // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
750 // the default obscured/untrusted touch filter introduced in S.
751 nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW;
chaviw39cfa2e2020-11-04 14:19:02 -0800752 nonTouchableSurface->showAt(100, 100);
753
754 injectTap(190, 199);
755 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
756}
757
758TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
759 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
760 surface->showAt(100, 100);
761
762 // Add non touchable window to cover touchable window, but parent is cropped to not cover area
763 // that will be tapped. Window behind gets touch, but with flag
764 // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
765 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
766 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800767 nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
768 parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
chaviw39cfa2e2020-11-04 14:19:02 -0800769 nonTouchableSurface->mInputInfo.ownerUid = 22222;
770 parentSurface->mInputInfo.ownerUid = 22222;
771 nonTouchableSurface->showAt(0, 0);
772 parentSurface->showAt(100, 100);
773
774 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800775 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800776 t.reparent(sc, parentSurface->mSurfaceControl);
777 });
778
779 injectTap(190, 199);
780 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
781}
782
783TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
784 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
785 surface->showAt(100, 100);
786
787 // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
788 // the touchable window. Window behind gets touch with no obscured flags.
789 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
790 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800791 nonTouchableSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
792 parentSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
chaviw39cfa2e2020-11-04 14:19:02 -0800793 nonTouchableSurface->mInputInfo.ownerUid = 22222;
794 parentSurface->mInputInfo.ownerUid = 22222;
795 nonTouchableSurface->showAt(0, 0);
796 parentSurface->showAt(50, 50);
797
798 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800799 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800800 t.reparent(sc, parentSurface->mSurfaceControl);
801 });
802
803 injectTap(101, 110);
804 surface->expectTap(1, 10);
805}
806
chaviw7e72caf2020-12-02 16:50:43 -0800807TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
808 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
809
810 std::unique_ptr<InputSurface> bufferSurface =
811 InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800812 bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
chaviw7e72caf2020-12-02 16:50:43 -0800813 bufferSurface->mInputInfo.ownerUid = 22222;
814
815 surface->showAt(10, 10);
816 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
817
818 injectTap(11, 11);
819 surface->expectTap(1, 1);
820}
821
822TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
823 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
824
chaviw39d01472021-04-08 14:26:24 -0500825 std::unique_ptr<BlastInputSurface> bufferSurface =
826 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800827 bufferSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
chaviw7e72caf2020-12-02 16:50:43 -0800828 bufferSurface->mInputInfo.ownerUid = 22222;
829
830 surface->showAt(10, 10);
831 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
832
833 injectTap(11, 11);
834 surface->expectTap(1, 1);
835}
836
Vishnu Naira066d902021-09-13 18:40:17 -0700837TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
838 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
839 surface->doTransaction(
840 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
841 surface->showAt(100, 100);
842
843 injectTap(101, 101);
844
845 EXPECT_NE(surface->consumeEvent(), nullptr);
846 EXPECT_NE(surface->consumeEvent(), nullptr);
847
848 surface->requestFocus();
849 surface->assertFocusChange(true);
850 injectKey(AKEYCODE_V);
851 surface->expectKey(AKEYCODE_V);
852}
853
854TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
855 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
856 surface->doTransaction([&](auto &t, auto &sc) {
857 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
858 t.setMatrix(sc, 2.0, 0, 0, 2.0);
859 });
860 surface->showAt(100, 100);
861
862 injectTap(101, 101);
863
864 EXPECT_NE(surface->consumeEvent(), nullptr);
865 EXPECT_NE(surface->consumeEvent(), nullptr);
866
867 surface->requestFocus();
868 surface->assertFocusChange(true);
869 injectKey(AKEYCODE_V);
870 surface->expectKey(AKEYCODE_V);
871}
872
873TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
874 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
875 surface->mInputInfo.ownerUid = 11111;
876 surface->doTransaction(
877 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
878 surface->showAt(100, 100);
879 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800880 obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
Vishnu Naira066d902021-09-13 18:40:17 -0700881 obscuringSurface->mInputInfo.ownerUid = 22222;
882 obscuringSurface->showAt(100, 100);
883 injectTap(101, 101);
884 EXPECT_EQ(surface->consumeEvent(100), nullptr);
885
886 surface->requestFocus();
887 surface->assertFocusChange(true);
888 injectKey(AKEYCODE_V);
889 EXPECT_EQ(surface->consumeEvent(100), nullptr);
890}
891
892TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
893 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
894 surface->mInputInfo.ownerUid = 11111;
895 surface->doTransaction(
896 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
897 surface->showAt(100, 100);
898 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
Prabir Pradhan4d5c52f2022-01-31 08:52:10 -0800899 obscuringSurface->mInputInfo.setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
Vishnu Naira066d902021-09-13 18:40:17 -0700900 obscuringSurface->mInputInfo.ownerUid = 22222;
901 obscuringSurface->showAt(190, 190);
902
903 injectTap(101, 101);
904
905 EXPECT_EQ(surface->consumeEvent(100), nullptr);
906
907 surface->requestFocus();
908 surface->assertFocusChange(true);
909 injectKey(AKEYCODE_V);
910 EXPECT_EQ(surface->consumeEvent(100), nullptr);
911}
912
913TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
914 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
915 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
916
917 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
918 surface->showAt(100, 100);
919 surface->doTransaction([&](auto &t, auto &sc) {
920 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
921 t.reparent(sc, parentSurface->mSurfaceControl);
922 t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
923 });
924
925 injectTap(101, 101);
926
927 EXPECT_EQ(surface->consumeEvent(100), nullptr);
928
929 surface->requestFocus();
930 surface->assertFocusChange(true);
931 injectKey(AKEYCODE_V);
932 EXPECT_EQ(surface->consumeEvent(100), nullptr);
933}
934
935TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
936 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
937 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
938
939 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
940 surface->doTransaction([&](auto &t, auto &sc) {
941 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
942 t.reparent(sc, parentSurface->mSurfaceControl);
943 t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
944 });
945 surface->showAt(100, 100);
946
947 injectTap(111, 111);
948
949 EXPECT_EQ(surface->consumeEvent(100), nullptr);
950
951 surface->requestFocus();
952 surface->assertFocusChange(true);
953 injectKey(AKEYCODE_V);
954 EXPECT_EQ(surface->consumeEvent(100), nullptr);
955}
956
Arthur Hung49d525a2021-11-19 15:11:51 +0000957TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
958 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
959
960 std::unique_ptr<BlastInputSurface> bufferSurface =
961 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
962
963 surface->showAt(100, 100);
964 bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200));
965 bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
966
967 injectTap(101, 101);
968 surface->expectTap(1, 1);
969}
970
Vishnu Naira066d902021-09-13 18:40:17 -0700971TEST_F(InputSurfacesTest, drop_input_policy) {
972 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
973 surface->doTransaction(
974 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
975 surface->showAt(100, 100);
976
977 injectTap(101, 101);
978
979 EXPECT_EQ(surface->consumeEvent(100), nullptr);
980
981 surface->requestFocus();
982 surface->assertFocusChange(true);
983 injectKey(AKEYCODE_V);
984 EXPECT_EQ(surface->consumeEvent(100), nullptr);
985}
Vishnu Nair16a938f2021-09-24 07:14:54 -0700986
Prabir Pradhan8c285982022-01-28 09:19:39 -0800987TEST_F(InputSurfacesTest, layer_with_empty_crop_cannot_be_focused) {
988 std::unique_ptr<InputSurface> bufferSurface =
989 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
990
991 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
992
993 bufferSurface->requestFocus();
994 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
995
996 bufferSurface->showAt(50, 50, Rect::INVALID_RECT);
997
998 bufferSurface->requestFocus();
999 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
1000}
1001
1002TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
1003 std::unique_ptr<InputSurface> bufferSurface =
1004 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
1005
1006 bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});
1007
1008 bufferSurface->requestFocus();
1009 bufferSurface->assertFocusChange(true);
1010}
1011
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001012/**
1013 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
1014 * its own crop.
1015 */
1016TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
1017 std::unique_ptr<InputSurface> parentContainer =
1018 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1019 std::unique_ptr<InputSurface> containerSurface =
1020 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1021 containerSurface->doTransaction(
1022 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1023 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1024 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1025 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1026 containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
1027
1028 // Receives events inside its own crop
1029 injectTap(21, 21);
1030 containerSurface->expectTap(1, 1); // Event is in layer space
1031
1032 // Does not receive events outside its crop
1033 injectTap(26, 26);
1034 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1035}
1036
1037/**
1038 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
1039 * in its parent's touchable region. The input events should be in the layer's coordinate space.
1040 */
1041TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
1042 std::unique_ptr<InputSurface> parentContainer =
1043 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1044 std::unique_ptr<InputSurface> containerSurface =
1045 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1046 containerSurface->doTransaction(
1047 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1048 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1049 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1050 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1051 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1052
1053 // Receives events inside parent bounds
1054 injectTap(21, 21);
1055 containerSurface->expectTap(1, 1); // Event is in layer space
1056
1057 // Does not receive events outside parent bounds
1058 injectTap(31, 31);
1059 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1060}
1061
1062/**
1063 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
1064 * layer's bounds. The input events should be in the layer's coordinate space.
1065 */
1066TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
1067 std::unique_ptr<InputSurface> cropLayer =
1068 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1069 cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));
1070
1071 std::unique_ptr<InputSurface> containerSurface =
1072 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1073 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1074 containerSurface->mInputInfo.touchableRegionCropHandle =
1075 cropLayer->mSurfaceControl->getHandle();
1076 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1077
1078 // Receives events inside crop layer bounds
1079 injectTap(51, 51);
1080 containerSurface->expectTap(41, 41); // Event is in layer space
1081
1082 // Does not receive events outside crop layer bounds
1083 injectTap(21, 21);
1084 injectTap(71, 71);
1085 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1086}
1087
Vishnu Nair16a938f2021-09-24 07:14:54 -07001088class MultiDisplayTests : public InputSurfacesTest {
1089public:
1090 MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
Prabir Pradhand0aba782021-12-14 00:44:21 -08001091 void TearDown() override {
1092 for (auto &token : mVirtualDisplays) {
1093 SurfaceComposerClient::destroyDisplay(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001094 }
1095 InputSurfacesTest::TearDown();
1096 }
1097
Prabir Pradhand0aba782021-12-14 00:44:21 -08001098 void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
1099 bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001100 sp<IGraphicBufferConsumer> consumer;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001101 sp<IGraphicBufferProducer> producer;
1102 BufferQueue::createBufferQueue(&producer, &consumer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001103 consumer->setConsumerName(String8("Virtual disp consumer"));
1104 consumer->setDefaultBufferSize(width, height);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001105 mProducers.push_back(producer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001106
Prabir Pradhand0aba782021-12-14 00:44:21 -08001107 std::string name = "VirtualDisplay";
1108 name += std::to_string(mVirtualDisplays.size());
1109 sp<IBinder> token = SurfaceComposerClient::createDisplay(String8(name.c_str()), isSecure);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001110 SurfaceComposerClient::Transaction t;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001111 t.setDisplaySurface(token, producer);
1112 t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
1113 t.setDisplayLayerStack(token, layerStack);
1114 t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
1115 {offsetX, offsetY, offsetX + width, offsetY + height});
Vishnu Nair16a938f2021-09-24 07:14:54 -07001116 t.apply(true);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001117
1118 mVirtualDisplays.push_back(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001119 }
1120
Prabir Pradhand0aba782021-12-14 00:44:21 -08001121 std::vector<sp<IBinder>> mVirtualDisplays;
1122 std::vector<sp<IGraphicBufferProducer>> mProducers;
Vishnu Nair16a938f2021-09-24 07:14:54 -07001123};
1124
Prabir Pradhand0aba782021-12-14 00:44:21 -08001125TEST_F(MultiDisplayTests, drop_input_if_layer_on_invalid_display) {
1126 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1127 // Do not create a display associated with the LayerStack.
1128 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1129 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1130 surface->showAt(100, 100);
1131
1132 injectTapOnDisplay(101, 101, layerStack.id);
1133 surface->requestFocus(layerStack.id);
1134 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1135
1136 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1137}
1138
1139TEST_F(MultiDisplayTests, virtual_display_receives_input) {
1140 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1141 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1142 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1143 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1144 surface->showAt(100, 100);
1145
1146 injectTapOnDisplay(101, 101, layerStack.id);
1147 surface->expectTap(1, 1);
1148
1149 surface->requestFocus(layerStack.id);
1150 surface->assertFocusChange(true);
1151 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1152 surface->expectKey(AKEYCODE_V);
1153}
1154
1155/**
1156 * When multiple DisplayDevices are mapped to the same layerStack, use the configuration for the
1157 * display that can receive input.
1158 */
1159TEST_F(MultiDisplayTests, many_to_one_display_mapping) {
1160 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1161 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1162 100 /*offsetX*/, 100 /*offsetY*/);
1163 createDisplay(1000, 1000, false /*isSecure*/, layerStack, true /*receivesInput*/,
1164 200 /*offsetX*/, 200 /*offsetY*/);
1165 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1166 300 /*offsetX*/, 300 /*offsetY*/);
1167 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1168 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1169 surface->showAt(10, 10);
1170
1171 // Input injection happens in logical display coordinates.
1172 injectTapOnDisplay(11, 11, layerStack.id);
1173 // Expect that the display transform for the display that receives input was used.
1174 surface->expectTapInDisplayCoordinates(211, 211);
1175
1176 surface->requestFocus(layerStack.id);
1177 surface->assertFocusChange(true);
1178 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1179}
1180
Vishnu Nair16a938f2021-09-24 07:14:54 -07001181TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
1182 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1183 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1184 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1185 surface->doTransaction([&](auto &t, auto &sc) {
1186 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1187 t.setLayerStack(sc, layerStack);
1188 });
1189 surface->showAt(100, 100);
1190
Prabir Pradhand0aba782021-12-14 00:44:21 -08001191 injectTapOnDisplay(101, 101, layerStack.id);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001192
1193 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1194
1195 surface->requestFocus(layerStack.id);
1196 surface->assertFocusChange(true);
1197 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1198 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1199}
1200
1201TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
1202 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001203
1204 // Create the secure display as system, because only certain users can create secure displays.
1205 seteuid(AID_SYSTEM);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001206 createDisplay(1000, 1000, true /*isSecure*/, layerStack);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001207 // Change the uid back to root.
1208 seteuid(AID_ROOT);
1209
Vishnu Nair16a938f2021-09-24 07:14:54 -07001210 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1211 surface->doTransaction([&](auto &t, auto &sc) {
1212 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1213 t.setLayerStack(sc, layerStack);
1214 });
1215 surface->showAt(100, 100);
1216
1217 injectTapOnDisplay(101, 101, layerStack.id);
1218 EXPECT_NE(surface->consumeEvent(), nullptr);
1219 EXPECT_NE(surface->consumeEvent(), nullptr);
1220
1221 surface->requestFocus(layerStack.id);
1222 surface->assertFocusChange(true);
1223 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1224
1225 surface->expectKey(AKEYCODE_V);
1226}
1227
Vishnu Nair958da932020-08-21 17:12:37 -07001228} // namespace android::test