blob: 06a0acae49833be33197d93526e36b8d9bbc72fe [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";
chaviw98318de2021-05-19 16:45:23 -0500269 mInputInfo.flags = WindowInfo::Flag::NOT_TOUCH_MODAL;
270 mInputInfo.type = WindowInfo::Type::BASE_APPLICATION;
Siarhei Vishniakouc1ae5562020-06-30 14:22:57 -0500271 mInputInfo.dispatchingTimeout = 5s;
Robert Carre07e1032018-11-26 12:55:53 -0800272 mInputInfo.globalScaleFactor = 1.0;
Vishnu Nair47074b82020-08-14 11:54:47 -0700273 mInputInfo.focusable = true;
Robert Carr1c4c5592018-09-24 13:18:43 -0700274 mInputInfo.hasWallpaper = false;
275 mInputInfo.paused = false;
276
277 mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
278
Robert Carr740167f2018-10-11 19:03:41 -0700279 InputApplicationInfo aInfo;
280 aInfo.token = new BBinder();
281 aInfo.name = "Test app info";
Siarhei Vishniakou70622952020-07-30 11:17:23 -0500282 aInfo.dispatchingTimeoutMillis =
283 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Robert Carr740167f2018-10-11 19:03:41 -0700284
285 mInputInfo.applicationInfo = aInfo;
Robert Carr1c4c5592018-09-24 13:18:43 -0700286 }
287public:
288 sp<SurfaceControl> mSurfaceControl;
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500289 std::shared_ptr<InputChannel> mClientChannel;
Robert Carr1c4c5592018-09-24 13:18:43 -0700290 sp<IInputFlinger> mInputFlinger;
291
chaviw98318de2021-05-19 16:45:23 -0500292 WindowInfo mInputInfo;
Robert Carr1c4c5592018-09-24 13:18:43 -0700293
294 PreallocatedInputEventFactory mInputEventFactory;
295 InputConsumer* mInputConsumer;
296};
297
chaviw39d01472021-04-08 14:26:24 -0500298class BlastInputSurface : public InputSurface {
299public:
300 BlastInputSurface(const sp<SurfaceControl> &sc, const sp<SurfaceControl> &parentSc, int width,
301 int height)
302 : InputSurface(sc, width, height) {
303 mParentSurfaceControl = parentSc;
304 }
305
306 ~BlastInputSurface() = default;
307
308 static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
309 const sp<SurfaceComposerClient> &scc, int width, int height) {
310 sp<SurfaceControl> parentSc =
311 scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
312 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
313 ISurfaceComposerClient::eFXSurfaceContainer);
314
315 sp<SurfaceControl> surfaceControl =
316 scc->createSurface(String8("Test Buffer Surface"), width, height,
317 PIXEL_FORMAT_RGBA_8888,
318 ISurfaceComposerClient::eFXSurfaceBufferState,
319 parentSc->getHandle());
320 return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
321 }
322
323 void doTransaction(
324 std::function<void(SurfaceComposerClient::Transaction &, const sp<SurfaceControl> &)>
325 transactionBody) override {
326 SurfaceComposerClient::Transaction t;
327 transactionBody(t, mParentSurfaceControl);
328 t.apply(true);
329 }
330
331 void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
332 SurfaceComposerClient::Transaction t;
333 t.show(mParentSurfaceControl);
334 t.setLayer(mParentSurfaceControl, LAYER_BASE);
335 t.setPosition(mParentSurfaceControl, x, y);
336 t.setCrop(mParentSurfaceControl, crop);
337
338 t.show(mSurfaceControl);
339 t.setInputWindowInfo(mSurfaceControl, mInputInfo);
340 t.setCrop(mSurfaceControl, crop);
341 t.setAlpha(mSurfaceControl, 1);
342 t.apply(true);
343 }
344
345private:
346 sp<SurfaceControl> mParentSurfaceControl;
347};
348
Robert Carr1c4c5592018-09-24 13:18:43 -0700349class InputSurfacesTest : public ::testing::Test {
350public:
351 InputSurfacesTest() {
352 ProcessState::self()->startThreadPool();
353 }
354
355 void SetUp() {
356 mComposerClient = new SurfaceComposerClient;
357 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
Vishnu Nairde19f852018-12-18 16:11:53 -0800358
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800359 const auto display = mComposerClient->getInternalDisplayToken();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100360 ASSERT_NE(display, nullptr);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800361
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100362 ui::DisplayMode mode;
363 ASSERT_EQ(NO_ERROR, mComposerClient->getActiveDisplayMode(display, &mode));
Vishnu Nairde19f852018-12-18 16:11:53 -0800364
365 // After a new buffer is queued, SurfaceFlinger is notified and will
366 // latch the new buffer on next vsync. Let's heuristically wait for 3
367 // vsyncs.
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100368 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.refreshRate) * 3;
Robert Carr1c4c5592018-09-24 13:18:43 -0700369 }
370
371 void TearDown() {
372 mComposerClient->dispose();
373 }
374
375 std::unique_ptr<InputSurface> makeSurface(int width, int height) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800376 return InputSurface::makeColorInputSurface(mComposerClient, width, height);
377 }
378
chaviw39d01472021-04-08 14:26:24 -0500379 void postBuffer(const sp<SurfaceControl> &layer, int32_t w, int32_t h) {
380 int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
381 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
382 sp<GraphicBuffer> buffer =
383 new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
384 Transaction().setBuffer(layer, buffer).apply(true);
Vishnu Nairde19f852018-12-18 16:11:53 -0800385 usleep(mBufferPostDelay);
Robert Carr1c4c5592018-09-24 13:18:43 -0700386 }
387
388 sp<SurfaceComposerClient> mComposerClient;
Vishnu Nairde19f852018-12-18 16:11:53 -0800389 int32_t mBufferPostDelay;
Robert Carr1c4c5592018-09-24 13:18:43 -0700390};
391
Vishnu Nair16a938f2021-09-24 07:14:54 -0700392void injectTapOnDisplay(int x, int y, int displayId) {
393 char *buf1, *buf2, *bufDisplayId;
Robert Carr1c4c5592018-09-24 13:18:43 -0700394 asprintf(&buf1, "%d", x);
395 asprintf(&buf2, "%d", y);
Vishnu Nair16a938f2021-09-24 07:14:54 -0700396 asprintf(&bufDisplayId, "%d", displayId);
Robert Carr1c4c5592018-09-24 13:18:43 -0700397 if (fork() == 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700398 execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
399 }
400}
401
402void injectTap(int x, int y) {
403 injectTapOnDisplay(x, y, ADISPLAY_ID_DEFAULT);
404}
405
406void injectKeyOnDisplay(uint32_t keycode, int displayId) {
407 char *buf1, *bufDisplayId;
408 asprintf(&buf1, "%d", keycode);
409 asprintf(&bufDisplayId, "%d", displayId);
410 if (fork() == 0) {
411 execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
Robert Carr1c4c5592018-09-24 13:18:43 -0700412 }
413}
414
Vishnu Naira066d902021-09-13 18:40:17 -0700415void injectKey(uint32_t keycode) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700416 injectKeyOnDisplay(keycode, ADISPLAY_ID_NONE);
Vishnu Naira066d902021-09-13 18:40:17 -0700417}
418
Robert Carr1c4c5592018-09-24 13:18:43 -0700419TEST_F(InputSurfacesTest, can_receive_input) {
420 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
421 surface->showAt(100, 100);
422
423 injectTap(101, 101);
424
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100425 EXPECT_NE(surface->consumeEvent(), nullptr);
Robert Carr1c4c5592018-09-24 13:18:43 -0700426}
427
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100428/**
429 * Set up two surfaces side-by-side. Tap each surface.
430 * Next, swap the positions of the two surfaces. Inject tap into the two
431 * original locations. Ensure that the tap is received by the surfaces in the
432 * reverse order.
433 */
Robert Carr1c4c5592018-09-24 13:18:43 -0700434TEST_F(InputSurfacesTest, input_respects_positioning) {
435 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
436 surface->showAt(100, 100);
437
438 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
439 surface2->showAt(200, 200);
440
441 injectTap(201, 201);
442 surface2->expectTap(1, 1);
443
444 injectTap(101, 101);
445 surface->expectTap(1, 1);
446
447 surface2->doTransaction([](auto &t, auto &sc) {
448 t.setPosition(sc, 100, 100);
449 });
450 surface->doTransaction([](auto &t, auto &sc) {
451 t.setPosition(sc, 200, 200);
452 });
453
454 injectTap(101, 101);
455 surface2->expectTap(1, 1);
456
457 injectTap(201, 201);
458 surface->expectTap(1, 1);
459}
460
461TEST_F(InputSurfacesTest, input_respects_layering) {
462 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
463 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
464
465 surface->showAt(10, 10);
466 surface2->showAt(10, 10);
467
468 surface->doTransaction([](auto &t, auto &sc) {
469 t.setLayer(sc, LAYER_BASE + 1);
470 });
471
472 injectTap(11, 11);
473 surface->expectTap(1, 1);
474
475 surface2->doTransaction([](auto &t, auto &sc) {
476 t.setLayer(sc, LAYER_BASE + 1);
477 });
478
479 injectTap(11, 11);
480 surface2->expectTap(1, 1);
481
482 surface2->doTransaction([](auto &t, auto &sc) {
483 t.hide(sc);
484 });
485
486 injectTap(11, 11);
487 surface->expectTap(1, 1);
488}
489
Vishnu Nairde19f852018-12-18 16:11:53 -0800490// Surface Insets are set to offset the client content and draw a border around the client surface
491// (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
492// of the client content.
493TEST_F(InputSurfacesTest, input_respects_surface_insets) {
494 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
495 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
496 bgSurface->showAt(100, 100);
497
498 fgSurface->mInputInfo.surfaceInset = 5;
499 fgSurface->showAt(100, 100);
500
501 injectTap(106, 106);
502 fgSurface->expectTap(1, 1);
503
504 injectTap(101, 101);
505 bgSurface->expectTap(1, 1);
506}
507
508// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
509TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
510 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
511 std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
512 parentSurface->showAt(100, 100);
513
514 childSurface->mInputInfo.surfaceInset = 10;
515 childSurface->showAt(100, 100);
516
517 childSurface->doTransaction([&](auto &t, auto &sc) {
518 t.setPosition(sc, -5, -5);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000519 t.reparent(sc, parentSurface->mSurfaceControl);
Vishnu Nairde19f852018-12-18 16:11:53 -0800520 });
521
522 injectTap(106, 106);
523 childSurface->expectTap(1, 1);
524
525 injectTap(101, 101);
526 parentSurface->expectTap(1, 1);
527}
528
Arthur Hung118b1142019-05-08 21:25:59 +0800529// Ensure a surface whose insets are scaled, handles the touch offset correctly.
530TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
531 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
532 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
533 bgSurface->showAt(100, 100);
534
535 fgSurface->mInputInfo.surfaceInset = 5;
536 fgSurface->showAt(100, 100);
537
538 fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
539
540 // expect = touch / scale - inset
541 injectTap(112, 124);
542 fgSurface->expectTap(1, 1);
543
544 injectTap(101, 101);
545 bgSurface->expectTap(1, 1);
546}
547
Ady Abraham282f1d72019-07-24 18:05:56 -0700548TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700549 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
Ady Abraham282f1d72019-07-24 18:05:56 -0700550 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700551 bgSurface->showAt(100, 100);
552
Ady Abraham282f1d72019-07-24 18:05:56 -0700553 // In case we pass the very big inset without any checking.
554 fgSurface->mInputInfo.surfaceInset = INT32_MAX;
555 fgSurface->showAt(100, 100);
556
557 fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
558
559 // expect no crash for overflow, and inset size to be clamped to surface size
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700560 injectTap(112, 124);
561 bgSurface->expectTap(12, 24);
Ady Abraham282f1d72019-07-24 18:05:56 -0700562}
563
Vishnu Nairde19f852018-12-18 16:11:53 -0800564// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
565TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
566 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
567 surface->doTransaction([](auto &t, auto &sc) {
568 Region transparentRegion(Rect(0, 0, 10, 10));
569 t.setTransparentRegionHint(sc, transparentRegion);
570 });
571 surface->showAt(100, 100);
572 injectTap(101, 101);
573 surface->expectTap(1, 1);
574}
575
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700576// TODO(b/139494112) update tests once we define expected behavior
577// Ensure we still send input to the surface regardless of surface visibility changes due to the
578// first buffer being submitted or alpha changes.
579// Original bug ref: b/120839715
580TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800581 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500582 std::unique_ptr<BlastInputSurface> bufferSurface =
583 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800584
585 bgSurface->showAt(10, 10);
586 bufferSurface->showAt(10, 10);
587
588 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700589 bufferSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800590
chaviw39d01472021-04-08 14:26:24 -0500591 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800592 injectTap(11, 11);
593 bufferSurface->expectTap(1, 1);
594}
595
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000596TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800597 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500598 std::unique_ptr<BlastInputSurface> bufferSurface =
599 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
600 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800601
602 bgSurface->showAt(10, 10);
603 bufferSurface->showAt(10, 10);
604
605 injectTap(11, 11);
606 bufferSurface->expectTap(1, 1);
607
608 bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
609
610 injectTap(11, 11);
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000611 bgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800612}
613
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700614TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800615 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
616 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
617
618 bgSurface->showAt(10, 10);
619 fgSurface->showAt(10, 10);
620
621 injectTap(11, 11);
622 fgSurface->expectTap(1, 1);
623
624 fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
625
626 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700627 fgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800628}
629
630TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
631 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
632 std::unique_ptr<InputSurface> containerSurface =
633 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
634
635 bgSurface->showAt(10, 10);
636 containerSurface->showAt(10, 10);
637
638 injectTap(11, 11);
639 containerSurface->expectTap(1, 1);
640
641 containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
642
643 injectTap(11, 11);
644 bgSurface->expectTap(1, 1);
645}
chaviwfbe5d9c2018-12-26 12:23:37 -0800646
Arthur Hungd20b2702019-01-14 18:16:16 +0800647TEST_F(InputSurfacesTest, input_respects_outscreen) {
648 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
649 surface->showAt(-1, -1);
650
651 injectTap(0, 0);
652 surface->expectTap(1, 1);
653}
arthurhungb4a0f852020-06-16 11:02:50 +0800654
655TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
656 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
657 std::unique_ptr<InputSurface> cursorSurface =
658 InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);
659
660 surface->showAt(10, 10);
arthurhungb4a0f852020-06-16 11:02:50 +0800661 cursorSurface->showAt(10, 10);
662
663 injectTap(11, 11);
664 surface->expectTap(1, 1);
665}
Vishnu Nair958da932020-08-21 17:12:37 -0700666
667TEST_F(InputSurfacesTest, can_be_focused) {
668 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
669 surface->showAt(100, 100);
670 surface->requestFocus();
671
672 surface->assertFocusChange(true);
Vishnu Naira066d902021-09-13 18:40:17 -0700673
674 injectKey(AKEYCODE_V);
675 surface->expectKey(AKEYCODE_V);
Robert Carr1c4c5592018-09-24 13:18:43 -0700676}
chaviw44a6d2b2020-09-08 17:14:16 -0700677
678TEST_F(InputSurfacesTest, rotate_surface) {
679 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
680 surface->showAt(10, 10);
681 surface->doTransaction([](auto &t, auto &sc) {
682 t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
683 });
684 injectTap(8, 11);
685 surface->expectTap(1, 2);
686
687 surface->doTransaction([](auto &t, auto &sc) {
688 t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
689 });
690 injectTap(9, 8);
691 surface->expectTap(1, 2);
692
693 surface->doTransaction([](auto &t, auto &sc) {
694 t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
695 });
696 injectTap(12, 9);
697 surface->expectTap(1, 2);
698}
699
700TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
701 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
702 surface->showAt(10, 10);
703 surface->doTransaction([](auto &t, auto &sc) {
704 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
705 });
706 injectTap(2, 12);
707 surface->expectTap(1, 2);
708
709 surface->doTransaction([](auto &t, auto &sc) {
710 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
711 });
712 injectTap(8, 2);
713 surface->expectTap(1, 2);
714
715 surface->doTransaction([](auto &t, auto &sc) {
716 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
717 });
718 injectTap(18, 8);
719 surface->expectTap(1, 2);
720}
721
722TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
723 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
724 surface->mInputInfo.surfaceInset = 5;
725 surface->showAt(100, 100);
726
727 surface->doTransaction([](auto &t, auto &sc) {
728 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
729 });
730 injectTap(40, 120);
731 surface->expectTap(5, 10);
732
733 surface->doTransaction([](auto &t, auto &sc) {
734 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
735 });
736 injectTap(80, 40);
737 surface->expectTap(5, 10);
738
739 surface->doTransaction([](auto &t, auto &sc) {
740 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
741 });
742 injectTap(160, 80);
743 surface->expectTap(5, 10);
744}
745
chaviw39cfa2e2020-11-04 14:19:02 -0800746TEST_F(InputSurfacesTest, touch_flag_obscured) {
747 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
748 surface->showAt(100, 100);
749
750 // Add non touchable window to fully cover touchable window. Window behind gets touch, but
751 // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
752 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500753 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800754 nonTouchableSurface->mInputInfo.ownerUid = 22222;
Bernardo Rufino602ef712020-12-21 11:02:18 +0000755 // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
756 // the default obscured/untrusted touch filter introduced in S.
757 nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW;
chaviw39cfa2e2020-11-04 14:19:02 -0800758 nonTouchableSurface->showAt(100, 100);
759
760 injectTap(190, 199);
761 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
762}
763
764TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
765 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
766 surface->showAt(100, 100);
767
768 // Add non touchable window to cover touchable window, but parent is cropped to not cover area
769 // that will be tapped. Window behind gets touch, but with flag
770 // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
771 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
772 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500773 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
774 parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800775 nonTouchableSurface->mInputInfo.ownerUid = 22222;
776 parentSurface->mInputInfo.ownerUid = 22222;
777 nonTouchableSurface->showAt(0, 0);
778 parentSurface->showAt(100, 100);
779
780 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800781 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800782 t.reparent(sc, parentSurface->mSurfaceControl);
783 });
784
785 injectTap(190, 199);
786 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
787}
788
789TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
790 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
791 surface->showAt(100, 100);
792
793 // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
794 // the touchable window. Window behind gets touch with no obscured flags.
795 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
796 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500797 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
798 parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800799 nonTouchableSurface->mInputInfo.ownerUid = 22222;
800 parentSurface->mInputInfo.ownerUid = 22222;
801 nonTouchableSurface->showAt(0, 0);
802 parentSurface->showAt(50, 50);
803
804 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800805 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800806 t.reparent(sc, parentSurface->mSurfaceControl);
807 });
808
809 injectTap(101, 110);
810 surface->expectTap(1, 10);
811}
812
chaviw7e72caf2020-12-02 16:50:43 -0800813TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
814 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
815
816 std::unique_ptr<InputSurface> bufferSurface =
817 InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
chaviw98318de2021-05-19 16:45:23 -0500818 bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw7e72caf2020-12-02 16:50:43 -0800819 bufferSurface->mInputInfo.ownerUid = 22222;
820
821 surface->showAt(10, 10);
822 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
823
824 injectTap(11, 11);
825 surface->expectTap(1, 1);
826}
827
828TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
829 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
830
chaviw39d01472021-04-08 14:26:24 -0500831 std::unique_ptr<BlastInputSurface> bufferSurface =
832 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
chaviw98318de2021-05-19 16:45:23 -0500833 bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw7e72caf2020-12-02 16:50:43 -0800834 bufferSurface->mInputInfo.ownerUid = 22222;
835
836 surface->showAt(10, 10);
837 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
838
839 injectTap(11, 11);
840 surface->expectTap(1, 1);
841}
842
Vishnu Naira066d902021-09-13 18:40:17 -0700843TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
844 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
845 surface->doTransaction(
846 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
847 surface->showAt(100, 100);
848
849 injectTap(101, 101);
850
851 EXPECT_NE(surface->consumeEvent(), nullptr);
852 EXPECT_NE(surface->consumeEvent(), nullptr);
853
854 surface->requestFocus();
855 surface->assertFocusChange(true);
856 injectKey(AKEYCODE_V);
857 surface->expectKey(AKEYCODE_V);
858}
859
860TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
861 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
862 surface->doTransaction([&](auto &t, auto &sc) {
863 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
864 t.setMatrix(sc, 2.0, 0, 0, 2.0);
865 });
866 surface->showAt(100, 100);
867
868 injectTap(101, 101);
869
870 EXPECT_NE(surface->consumeEvent(), nullptr);
871 EXPECT_NE(surface->consumeEvent(), nullptr);
872
873 surface->requestFocus();
874 surface->assertFocusChange(true);
875 injectKey(AKEYCODE_V);
876 surface->expectKey(AKEYCODE_V);
877}
878
879TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
880 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
881 surface->mInputInfo.ownerUid = 11111;
882 surface->doTransaction(
883 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
884 surface->showAt(100, 100);
885 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
886 obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
887 obscuringSurface->mInputInfo.ownerUid = 22222;
888 obscuringSurface->showAt(100, 100);
889 injectTap(101, 101);
890 EXPECT_EQ(surface->consumeEvent(100), nullptr);
891
892 surface->requestFocus();
893 surface->assertFocusChange(true);
894 injectKey(AKEYCODE_V);
895 EXPECT_EQ(surface->consumeEvent(100), nullptr);
896}
897
898TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
899 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
900 surface->mInputInfo.ownerUid = 11111;
901 surface->doTransaction(
902 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
903 surface->showAt(100, 100);
904 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
905 obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
906 obscuringSurface->mInputInfo.ownerUid = 22222;
907 obscuringSurface->showAt(190, 190);
908
909 injectTap(101, 101);
910
911 EXPECT_EQ(surface->consumeEvent(100), nullptr);
912
913 surface->requestFocus();
914 surface->assertFocusChange(true);
915 injectKey(AKEYCODE_V);
916 EXPECT_EQ(surface->consumeEvent(100), nullptr);
917}
918
919TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
920 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
921 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
922
923 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
924 surface->showAt(100, 100);
925 surface->doTransaction([&](auto &t, auto &sc) {
926 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
927 t.reparent(sc, parentSurface->mSurfaceControl);
928 t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
929 });
930
931 injectTap(101, 101);
932
933 EXPECT_EQ(surface->consumeEvent(100), nullptr);
934
935 surface->requestFocus();
936 surface->assertFocusChange(true);
937 injectKey(AKEYCODE_V);
938 EXPECT_EQ(surface->consumeEvent(100), nullptr);
939}
940
941TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
942 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
943 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
944
945 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
946 surface->doTransaction([&](auto &t, auto &sc) {
947 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
948 t.reparent(sc, parentSurface->mSurfaceControl);
949 t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
950 });
951 surface->showAt(100, 100);
952
953 injectTap(111, 111);
954
955 EXPECT_EQ(surface->consumeEvent(100), nullptr);
956
957 surface->requestFocus();
958 surface->assertFocusChange(true);
959 injectKey(AKEYCODE_V);
960 EXPECT_EQ(surface->consumeEvent(100), nullptr);
961}
962
Arthur Hung49d525a2021-11-19 15:11:51 +0000963TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
964 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
965
966 std::unique_ptr<BlastInputSurface> bufferSurface =
967 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
968
969 surface->showAt(100, 100);
970 bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200));
971 bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
972
973 injectTap(101, 101);
974 surface->expectTap(1, 1);
975}
976
Vishnu Naira066d902021-09-13 18:40:17 -0700977TEST_F(InputSurfacesTest, drop_input_policy) {
978 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
979 surface->doTransaction(
980 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
981 surface->showAt(100, 100);
982
983 injectTap(101, 101);
984
985 EXPECT_EQ(surface->consumeEvent(100), nullptr);
986
987 surface->requestFocus();
988 surface->assertFocusChange(true);
989 injectKey(AKEYCODE_V);
990 EXPECT_EQ(surface->consumeEvent(100), nullptr);
991}
Vishnu Nair16a938f2021-09-24 07:14:54 -0700992
Prabir Pradhan8c285982022-01-28 09:19:39 -0800993TEST_F(InputSurfacesTest, layer_with_empty_crop_cannot_be_focused) {
994 std::unique_ptr<InputSurface> bufferSurface =
995 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
996
997 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
998
999 bufferSurface->requestFocus();
1000 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
1001
1002 bufferSurface->showAt(50, 50, Rect::INVALID_RECT);
1003
1004 bufferSurface->requestFocus();
1005 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
1006}
1007
1008TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
1009 std::unique_ptr<InputSurface> bufferSurface =
1010 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
1011
1012 bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});
1013
1014 bufferSurface->requestFocus();
1015 bufferSurface->assertFocusChange(true);
1016}
1017
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001018/**
1019 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
1020 * its own crop.
1021 */
1022TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
1023 std::unique_ptr<InputSurface> parentContainer =
1024 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1025 std::unique_ptr<InputSurface> containerSurface =
1026 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1027 containerSurface->doTransaction(
1028 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1029 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1030 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1031 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1032 containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
1033
1034 // Receives events inside its own crop
1035 injectTap(21, 21);
1036 containerSurface->expectTap(1, 1); // Event is in layer space
1037
1038 // Does not receive events outside its crop
1039 injectTap(26, 26);
1040 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1041}
1042
1043/**
1044 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
1045 * in its parent's touchable region. The input events should be in the layer's coordinate space.
1046 */
1047TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
1048 std::unique_ptr<InputSurface> parentContainer =
1049 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1050 std::unique_ptr<InputSurface> containerSurface =
1051 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1052 containerSurface->doTransaction(
1053 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1054 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1055 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1056 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1057 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1058
1059 // Receives events inside parent bounds
1060 injectTap(21, 21);
1061 containerSurface->expectTap(1, 1); // Event is in layer space
1062
1063 // Does not receive events outside parent bounds
1064 injectTap(31, 31);
1065 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1066}
1067
1068/**
1069 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
1070 * layer's bounds. The input events should be in the layer's coordinate space.
1071 */
1072TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
1073 std::unique_ptr<InputSurface> cropLayer =
1074 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1075 cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));
1076
1077 std::unique_ptr<InputSurface> containerSurface =
1078 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1079 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1080 containerSurface->mInputInfo.touchableRegionCropHandle =
1081 cropLayer->mSurfaceControl->getHandle();
1082 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1083
1084 // Receives events inside crop layer bounds
1085 injectTap(51, 51);
1086 containerSurface->expectTap(41, 41); // Event is in layer space
1087
1088 // Does not receive events outside crop layer bounds
1089 injectTap(21, 21);
1090 injectTap(71, 71);
1091 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1092}
1093
Vishnu Nair16a938f2021-09-24 07:14:54 -07001094class MultiDisplayTests : public InputSurfacesTest {
1095public:
1096 MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
Prabir Pradhand0aba782021-12-14 00:44:21 -08001097 void TearDown() override {
1098 for (auto &token : mVirtualDisplays) {
1099 SurfaceComposerClient::destroyDisplay(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001100 }
1101 InputSurfacesTest::TearDown();
1102 }
1103
Prabir Pradhand0aba782021-12-14 00:44:21 -08001104 void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
1105 bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001106 sp<IGraphicBufferConsumer> consumer;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001107 sp<IGraphicBufferProducer> producer;
1108 BufferQueue::createBufferQueue(&producer, &consumer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001109 consumer->setConsumerName(String8("Virtual disp consumer"));
1110 consumer->setDefaultBufferSize(width, height);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001111 mProducers.push_back(producer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001112
Prabir Pradhand0aba782021-12-14 00:44:21 -08001113 std::string name = "VirtualDisplay";
1114 name += std::to_string(mVirtualDisplays.size());
1115 sp<IBinder> token = SurfaceComposerClient::createDisplay(String8(name.c_str()), isSecure);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001116 SurfaceComposerClient::Transaction t;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001117 t.setDisplaySurface(token, producer);
1118 t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
1119 t.setDisplayLayerStack(token, layerStack);
1120 t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
1121 {offsetX, offsetY, offsetX + width, offsetY + height});
Vishnu Nair16a938f2021-09-24 07:14:54 -07001122 t.apply(true);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001123
1124 mVirtualDisplays.push_back(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001125 }
1126
Prabir Pradhand0aba782021-12-14 00:44:21 -08001127 std::vector<sp<IBinder>> mVirtualDisplays;
1128 std::vector<sp<IGraphicBufferProducer>> mProducers;
Vishnu Nair16a938f2021-09-24 07:14:54 -07001129};
1130
Prabir Pradhand0aba782021-12-14 00:44:21 -08001131TEST_F(MultiDisplayTests, drop_input_if_layer_on_invalid_display) {
1132 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1133 // Do not create a display associated with the LayerStack.
1134 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1135 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1136 surface->showAt(100, 100);
1137
1138 injectTapOnDisplay(101, 101, layerStack.id);
1139 surface->requestFocus(layerStack.id);
1140 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1141
1142 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1143}
1144
1145TEST_F(MultiDisplayTests, virtual_display_receives_input) {
1146 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1147 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1148 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1149 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1150 surface->showAt(100, 100);
1151
1152 injectTapOnDisplay(101, 101, layerStack.id);
1153 surface->expectTap(1, 1);
1154
1155 surface->requestFocus(layerStack.id);
1156 surface->assertFocusChange(true);
1157 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1158 surface->expectKey(AKEYCODE_V);
1159}
1160
1161/**
1162 * When multiple DisplayDevices are mapped to the same layerStack, use the configuration for the
1163 * display that can receive input.
1164 */
1165TEST_F(MultiDisplayTests, many_to_one_display_mapping) {
1166 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1167 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1168 100 /*offsetX*/, 100 /*offsetY*/);
1169 createDisplay(1000, 1000, false /*isSecure*/, layerStack, true /*receivesInput*/,
1170 200 /*offsetX*/, 200 /*offsetY*/);
1171 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1172 300 /*offsetX*/, 300 /*offsetY*/);
1173 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1174 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1175 surface->showAt(10, 10);
1176
1177 // Input injection happens in logical display coordinates.
1178 injectTapOnDisplay(11, 11, layerStack.id);
1179 // Expect that the display transform for the display that receives input was used.
1180 surface->expectTapInDisplayCoordinates(211, 211);
1181
1182 surface->requestFocus(layerStack.id);
1183 surface->assertFocusChange(true);
1184 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1185}
1186
Vishnu Nair16a938f2021-09-24 07:14:54 -07001187TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
1188 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1189 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1190 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1191 surface->doTransaction([&](auto &t, auto &sc) {
1192 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1193 t.setLayerStack(sc, layerStack);
1194 });
1195 surface->showAt(100, 100);
1196
Prabir Pradhand0aba782021-12-14 00:44:21 -08001197 injectTapOnDisplay(101, 101, layerStack.id);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001198
1199 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1200
1201 surface->requestFocus(layerStack.id);
1202 surface->assertFocusChange(true);
1203 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1204 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1205}
1206
1207TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
1208 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001209
1210 // Create the secure display as system, because only certain users can create secure displays.
1211 seteuid(AID_SYSTEM);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001212 createDisplay(1000, 1000, true /*isSecure*/, layerStack);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001213 // Change the uid back to root.
1214 seteuid(AID_ROOT);
1215
Vishnu Nair16a938f2021-09-24 07:14:54 -07001216 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1217 surface->doTransaction([&](auto &t, auto &sc) {
1218 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1219 t.setLayerStack(sc, layerStack);
1220 });
1221 surface->showAt(100, 100);
1222
1223 injectTapOnDisplay(101, 101, layerStack.id);
1224 EXPECT_NE(surface->consumeEvent(), nullptr);
1225 EXPECT_NE(surface->consumeEvent(), nullptr);
1226
1227 surface->requestFocus(layerStack.id);
1228 surface->assertFocusChange(true);
1229 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1230
1231 surface->expectKey(AKEYCODE_V);
1232}
1233
Vishnu Nair958da932020-08-21 17:12:37 -07001234} // namespace android::test