blob: 76844d2d83335bcc8e8bf66ea924e8f6e069cfb1 [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) {
549 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
550 // In case we pass the very big inset without any checking.
551 fgSurface->mInputInfo.surfaceInset = INT32_MAX;
552 fgSurface->showAt(100, 100);
553
554 fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
555
556 // expect no crash for overflow, and inset size to be clamped to surface size
557 injectTap(202, 202);
558 fgSurface->expectTap(1, 1);
559}
560
Vishnu Nairde19f852018-12-18 16:11:53 -0800561// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
562TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
563 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
564 surface->doTransaction([](auto &t, auto &sc) {
565 Region transparentRegion(Rect(0, 0, 10, 10));
566 t.setTransparentRegionHint(sc, transparentRegion);
567 });
568 surface->showAt(100, 100);
569 injectTap(101, 101);
570 surface->expectTap(1, 1);
571}
572
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700573// TODO(b/139494112) update tests once we define expected behavior
574// Ensure we still send input to the surface regardless of surface visibility changes due to the
575// first buffer being submitted or alpha changes.
576// Original bug ref: b/120839715
577TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800578 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500579 std::unique_ptr<BlastInputSurface> bufferSurface =
580 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800581
582 bgSurface->showAt(10, 10);
583 bufferSurface->showAt(10, 10);
584
585 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700586 bufferSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800587
chaviw39d01472021-04-08 14:26:24 -0500588 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800589 injectTap(11, 11);
590 bufferSurface->expectTap(1, 1);
591}
592
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000593TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800594 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500595 std::unique_ptr<BlastInputSurface> bufferSurface =
596 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
597 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800598
599 bgSurface->showAt(10, 10);
600 bufferSurface->showAt(10, 10);
601
602 injectTap(11, 11);
603 bufferSurface->expectTap(1, 1);
604
605 bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
606
607 injectTap(11, 11);
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000608 bgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800609}
610
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700611TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800612 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
613 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
614
615 bgSurface->showAt(10, 10);
616 fgSurface->showAt(10, 10);
617
618 injectTap(11, 11);
619 fgSurface->expectTap(1, 1);
620
621 fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
622
623 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700624 fgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800625}
626
627TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
628 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
629 std::unique_ptr<InputSurface> containerSurface =
630 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
631
632 bgSurface->showAt(10, 10);
633 containerSurface->showAt(10, 10);
634
635 injectTap(11, 11);
636 containerSurface->expectTap(1, 1);
637
638 containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
639
640 injectTap(11, 11);
641 bgSurface->expectTap(1, 1);
642}
chaviwfbe5d9c2018-12-26 12:23:37 -0800643
Arthur Hungd20b2702019-01-14 18:16:16 +0800644TEST_F(InputSurfacesTest, input_respects_outscreen) {
645 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
646 surface->showAt(-1, -1);
647
648 injectTap(0, 0);
649 surface->expectTap(1, 1);
650}
arthurhungb4a0f852020-06-16 11:02:50 +0800651
652TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
653 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
654 std::unique_ptr<InputSurface> cursorSurface =
655 InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);
656
657 surface->showAt(10, 10);
arthurhungb4a0f852020-06-16 11:02:50 +0800658 cursorSurface->showAt(10, 10);
659
660 injectTap(11, 11);
661 surface->expectTap(1, 1);
662}
Vishnu Nair958da932020-08-21 17:12:37 -0700663
664TEST_F(InputSurfacesTest, can_be_focused) {
665 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
666 surface->showAt(100, 100);
667 surface->requestFocus();
668
669 surface->assertFocusChange(true);
Vishnu Naira066d902021-09-13 18:40:17 -0700670
671 injectKey(AKEYCODE_V);
672 surface->expectKey(AKEYCODE_V);
Robert Carr1c4c5592018-09-24 13:18:43 -0700673}
chaviw44a6d2b2020-09-08 17:14:16 -0700674
675TEST_F(InputSurfacesTest, rotate_surface) {
676 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
677 surface->showAt(10, 10);
678 surface->doTransaction([](auto &t, auto &sc) {
679 t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
680 });
681 injectTap(8, 11);
682 surface->expectTap(1, 2);
683
684 surface->doTransaction([](auto &t, auto &sc) {
685 t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
686 });
687 injectTap(9, 8);
688 surface->expectTap(1, 2);
689
690 surface->doTransaction([](auto &t, auto &sc) {
691 t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
692 });
693 injectTap(12, 9);
694 surface->expectTap(1, 2);
695}
696
697TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
698 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
699 surface->showAt(10, 10);
700 surface->doTransaction([](auto &t, auto &sc) {
701 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
702 });
703 injectTap(2, 12);
704 surface->expectTap(1, 2);
705
706 surface->doTransaction([](auto &t, auto &sc) {
707 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
708 });
709 injectTap(8, 2);
710 surface->expectTap(1, 2);
711
712 surface->doTransaction([](auto &t, auto &sc) {
713 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
714 });
715 injectTap(18, 8);
716 surface->expectTap(1, 2);
717}
718
719TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
720 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
721 surface->mInputInfo.surfaceInset = 5;
722 surface->showAt(100, 100);
723
724 surface->doTransaction([](auto &t, auto &sc) {
725 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
726 });
727 injectTap(40, 120);
728 surface->expectTap(5, 10);
729
730 surface->doTransaction([](auto &t, auto &sc) {
731 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
732 });
733 injectTap(80, 40);
734 surface->expectTap(5, 10);
735
736 surface->doTransaction([](auto &t, auto &sc) {
737 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
738 });
739 injectTap(160, 80);
740 surface->expectTap(5, 10);
741}
742
chaviw39cfa2e2020-11-04 14:19:02 -0800743TEST_F(InputSurfacesTest, touch_flag_obscured) {
744 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
745 surface->showAt(100, 100);
746
747 // Add non touchable window to fully cover touchable window. Window behind gets touch, but
748 // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
749 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500750 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800751 nonTouchableSurface->mInputInfo.ownerUid = 22222;
Bernardo Rufino602ef712020-12-21 11:02:18 +0000752 // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
753 // the default obscured/untrusted touch filter introduced in S.
754 nonTouchableSurface->mInputInfo.touchOcclusionMode = TouchOcclusionMode::ALLOW;
chaviw39cfa2e2020-11-04 14:19:02 -0800755 nonTouchableSurface->showAt(100, 100);
756
757 injectTap(190, 199);
758 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
759}
760
761TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
762 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
763 surface->showAt(100, 100);
764
765 // Add non touchable window to cover touchable window, but parent is cropped to not cover area
766 // that will be tapped. Window behind gets touch, but with flag
767 // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
768 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
769 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500770 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
771 parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800772 nonTouchableSurface->mInputInfo.ownerUid = 22222;
773 parentSurface->mInputInfo.ownerUid = 22222;
774 nonTouchableSurface->showAt(0, 0);
775 parentSurface->showAt(100, 100);
776
777 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800778 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800779 t.reparent(sc, parentSurface->mSurfaceControl);
780 });
781
782 injectTap(190, 199);
783 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
784}
785
786TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
787 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
788 surface->showAt(100, 100);
789
790 // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
791 // the touchable window. Window behind gets touch with no obscured flags.
792 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
793 std::unique_ptr<InputSurface> nonTouchableSurface = makeSurface(100, 100);
chaviw98318de2021-05-19 16:45:23 -0500794 nonTouchableSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
795 parentSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw39cfa2e2020-11-04 14:19:02 -0800796 nonTouchableSurface->mInputInfo.ownerUid = 22222;
797 parentSurface->mInputInfo.ownerUid = 22222;
798 nonTouchableSurface->showAt(0, 0);
799 parentSurface->showAt(50, 50);
800
801 nonTouchableSurface->doTransaction([&](auto &t, auto &sc) {
chaviw25714502021-02-11 10:01:08 -0800802 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800803 t.reparent(sc, parentSurface->mSurfaceControl);
804 });
805
806 injectTap(101, 110);
807 surface->expectTap(1, 10);
808}
809
chaviw7e72caf2020-12-02 16:50:43 -0800810TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
811 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
812
813 std::unique_ptr<InputSurface> bufferSurface =
814 InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
chaviw98318de2021-05-19 16:45:23 -0500815 bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw7e72caf2020-12-02 16:50:43 -0800816 bufferSurface->mInputInfo.ownerUid = 22222;
817
818 surface->showAt(10, 10);
819 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
820
821 injectTap(11, 11);
822 surface->expectTap(1, 1);
823}
824
825TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
826 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
827
chaviw39d01472021-04-08 14:26:24 -0500828 std::unique_ptr<BlastInputSurface> bufferSurface =
829 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
chaviw98318de2021-05-19 16:45:23 -0500830 bufferSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
chaviw7e72caf2020-12-02 16:50:43 -0800831 bufferSurface->mInputInfo.ownerUid = 22222;
832
833 surface->showAt(10, 10);
834 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
835
836 injectTap(11, 11);
837 surface->expectTap(1, 1);
838}
839
Vishnu Naira066d902021-09-13 18:40:17 -0700840TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
841 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
842 surface->doTransaction(
843 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
844 surface->showAt(100, 100);
845
846 injectTap(101, 101);
847
848 EXPECT_NE(surface->consumeEvent(), nullptr);
849 EXPECT_NE(surface->consumeEvent(), nullptr);
850
851 surface->requestFocus();
852 surface->assertFocusChange(true);
853 injectKey(AKEYCODE_V);
854 surface->expectKey(AKEYCODE_V);
855}
856
857TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
858 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
859 surface->doTransaction([&](auto &t, auto &sc) {
860 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
861 t.setMatrix(sc, 2.0, 0, 0, 2.0);
862 });
863 surface->showAt(100, 100);
864
865 injectTap(101, 101);
866
867 EXPECT_NE(surface->consumeEvent(), nullptr);
868 EXPECT_NE(surface->consumeEvent(), nullptr);
869
870 surface->requestFocus();
871 surface->assertFocusChange(true);
872 injectKey(AKEYCODE_V);
873 surface->expectKey(AKEYCODE_V);
874}
875
876TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
877 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
878 surface->mInputInfo.ownerUid = 11111;
879 surface->doTransaction(
880 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
881 surface->showAt(100, 100);
882 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
883 obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
884 obscuringSurface->mInputInfo.ownerUid = 22222;
885 obscuringSurface->showAt(100, 100);
886 injectTap(101, 101);
887 EXPECT_EQ(surface->consumeEvent(100), nullptr);
888
889 surface->requestFocus();
890 surface->assertFocusChange(true);
891 injectKey(AKEYCODE_V);
892 EXPECT_EQ(surface->consumeEvent(100), nullptr);
893}
894
895TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
896 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
897 surface->mInputInfo.ownerUid = 11111;
898 surface->doTransaction(
899 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
900 surface->showAt(100, 100);
901 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100);
902 obscuringSurface->mInputInfo.flags = WindowInfo::Flag::NOT_TOUCHABLE;
903 obscuringSurface->mInputInfo.ownerUid = 22222;
904 obscuringSurface->showAt(190, 190);
905
906 injectTap(101, 101);
907
908 EXPECT_EQ(surface->consumeEvent(100), nullptr);
909
910 surface->requestFocus();
911 surface->assertFocusChange(true);
912 injectKey(AKEYCODE_V);
913 EXPECT_EQ(surface->consumeEvent(100), nullptr);
914}
915
916TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
917 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
918 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
919
920 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
921 surface->showAt(100, 100);
922 surface->doTransaction([&](auto &t, auto &sc) {
923 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
924 t.reparent(sc, parentSurface->mSurfaceControl);
925 t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
926 });
927
928 injectTap(101, 101);
929
930 EXPECT_EQ(surface->consumeEvent(100), nullptr);
931
932 surface->requestFocus();
933 surface->assertFocusChange(true);
934 injectKey(AKEYCODE_V);
935 EXPECT_EQ(surface->consumeEvent(100), nullptr);
936}
937
938TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
939 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300);
940 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
941
942 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
943 surface->doTransaction([&](auto &t, auto &sc) {
944 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
945 t.reparent(sc, parentSurface->mSurfaceControl);
946 t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
947 });
948 surface->showAt(100, 100);
949
950 injectTap(111, 111);
951
952 EXPECT_EQ(surface->consumeEvent(100), nullptr);
953
954 surface->requestFocus();
955 surface->assertFocusChange(true);
956 injectKey(AKEYCODE_V);
957 EXPECT_EQ(surface->consumeEvent(100), nullptr);
958}
959
Arthur Hung49d525a2021-11-19 15:11:51 +0000960TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
961 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
962
963 std::unique_ptr<BlastInputSurface> bufferSurface =
964 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
965
966 surface->showAt(100, 100);
967 bufferSurface->mInputInfo.touchableRegion.orSelf(Rect(0, 0, 200, 200));
968 bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
969
970 injectTap(101, 101);
971 surface->expectTap(1, 1);
972}
973
Vishnu Naira066d902021-09-13 18:40:17 -0700974TEST_F(InputSurfacesTest, drop_input_policy) {
975 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
976 surface->doTransaction(
977 [&](auto &t, auto &sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
978 surface->showAt(100, 100);
979
980 injectTap(101, 101);
981
982 EXPECT_EQ(surface->consumeEvent(100), nullptr);
983
984 surface->requestFocus();
985 surface->assertFocusChange(true);
986 injectKey(AKEYCODE_V);
987 EXPECT_EQ(surface->consumeEvent(100), nullptr);
988}
Vishnu Nair16a938f2021-09-24 07:14:54 -0700989
Prabir Pradhan8c285982022-01-28 09:19:39 -0800990TEST_F(InputSurfacesTest, layer_with_empty_crop_cannot_be_focused) {
991 std::unique_ptr<InputSurface> bufferSurface =
992 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
993
994 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
995
996 bufferSurface->requestFocus();
997 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
998
999 bufferSurface->showAt(50, 50, Rect::INVALID_RECT);
1000
1001 bufferSurface->requestFocus();
1002 EXPECT_EQ(bufferSurface->consumeEvent(100), nullptr);
1003}
1004
1005TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
1006 std::unique_ptr<InputSurface> bufferSurface =
1007 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
1008
1009 bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});
1010
1011 bufferSurface->requestFocus();
1012 bufferSurface->assertFocusChange(true);
1013}
1014
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001015/**
1016 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
1017 * its own crop.
1018 */
1019TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
1020 std::unique_ptr<InputSurface> parentContainer =
1021 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1022 std::unique_ptr<InputSurface> containerSurface =
1023 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1024 containerSurface->doTransaction(
1025 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1026 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1027 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1028 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1029 containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
1030
1031 // Receives events inside its own crop
1032 injectTap(21, 21);
1033 containerSurface->expectTap(1, 1); // Event is in layer space
1034
1035 // Does not receive events outside its crop
1036 injectTap(26, 26);
1037 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1038}
1039
1040/**
1041 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
1042 * in its parent's touchable region. The input events should be in the layer's coordinate space.
1043 */
1044TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
1045 std::unique_ptr<InputSurface> parentContainer =
1046 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1047 std::unique_ptr<InputSurface> containerSurface =
1048 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1049 containerSurface->doTransaction(
1050 [&](auto &t, auto &sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
1051 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1052 containerSurface->mInputInfo.touchableRegionCropHandle = nullptr;
1053 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1054 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1055
1056 // Receives events inside parent bounds
1057 injectTap(21, 21);
1058 containerSurface->expectTap(1, 1); // Event is in layer space
1059
1060 // Does not receive events outside parent bounds
1061 injectTap(31, 31);
1062 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1063}
1064
1065/**
1066 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
1067 * layer's bounds. The input events should be in the layer's coordinate space.
1068 */
1069TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
1070 std::unique_ptr<InputSurface> cropLayer =
1071 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0);
1072 cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));
1073
1074 std::unique_ptr<InputSurface> containerSurface =
1075 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
1076 containerSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
1077 containerSurface->mInputInfo.touchableRegionCropHandle =
1078 cropLayer->mSurfaceControl->getHandle();
1079 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1080
1081 // Receives events inside crop layer bounds
1082 injectTap(51, 51);
1083 containerSurface->expectTap(41, 41); // Event is in layer space
1084
1085 // Does not receive events outside crop layer bounds
1086 injectTap(21, 21);
1087 injectTap(71, 71);
1088 EXPECT_EQ(containerSurface->consumeEvent(100), nullptr);
1089}
1090
Vishnu Nair16a938f2021-09-24 07:14:54 -07001091class MultiDisplayTests : public InputSurfacesTest {
1092public:
1093 MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
Prabir Pradhand0aba782021-12-14 00:44:21 -08001094 void TearDown() override {
1095 for (auto &token : mVirtualDisplays) {
1096 SurfaceComposerClient::destroyDisplay(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001097 }
1098 InputSurfacesTest::TearDown();
1099 }
1100
Prabir Pradhand0aba782021-12-14 00:44:21 -08001101 void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
1102 bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001103 sp<IGraphicBufferConsumer> consumer;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001104 sp<IGraphicBufferProducer> producer;
1105 BufferQueue::createBufferQueue(&producer, &consumer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001106 consumer->setConsumerName(String8("Virtual disp consumer"));
1107 consumer->setDefaultBufferSize(width, height);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001108 mProducers.push_back(producer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001109
Prabir Pradhand0aba782021-12-14 00:44:21 -08001110 std::string name = "VirtualDisplay";
1111 name += std::to_string(mVirtualDisplays.size());
1112 sp<IBinder> token = SurfaceComposerClient::createDisplay(String8(name.c_str()), isSecure);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001113 SurfaceComposerClient::Transaction t;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001114 t.setDisplaySurface(token, producer);
1115 t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
1116 t.setDisplayLayerStack(token, layerStack);
1117 t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
1118 {offsetX, offsetY, offsetX + width, offsetY + height});
Vishnu Nair16a938f2021-09-24 07:14:54 -07001119 t.apply(true);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001120
1121 mVirtualDisplays.push_back(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001122 }
1123
Prabir Pradhand0aba782021-12-14 00:44:21 -08001124 std::vector<sp<IBinder>> mVirtualDisplays;
1125 std::vector<sp<IGraphicBufferProducer>> mProducers;
Vishnu Nair16a938f2021-09-24 07:14:54 -07001126};
1127
Prabir Pradhand0aba782021-12-14 00:44:21 -08001128TEST_F(MultiDisplayTests, drop_input_if_layer_on_invalid_display) {
1129 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1130 // Do not create a display associated with the LayerStack.
1131 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1132 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1133 surface->showAt(100, 100);
1134
1135 injectTapOnDisplay(101, 101, layerStack.id);
1136 surface->requestFocus(layerStack.id);
1137 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1138
1139 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1140}
1141
1142TEST_F(MultiDisplayTests, virtual_display_receives_input) {
1143 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1144 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1145 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1146 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1147 surface->showAt(100, 100);
1148
1149 injectTapOnDisplay(101, 101, layerStack.id);
1150 surface->expectTap(1, 1);
1151
1152 surface->requestFocus(layerStack.id);
1153 surface->assertFocusChange(true);
1154 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1155 surface->expectKey(AKEYCODE_V);
1156}
1157
1158/**
1159 * When multiple DisplayDevices are mapped to the same layerStack, use the configuration for the
1160 * display that can receive input.
1161 */
1162TEST_F(MultiDisplayTests, many_to_one_display_mapping) {
1163 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1164 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1165 100 /*offsetX*/, 100 /*offsetY*/);
1166 createDisplay(1000, 1000, false /*isSecure*/, layerStack, true /*receivesInput*/,
1167 200 /*offsetX*/, 200 /*offsetY*/);
1168 createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
1169 300 /*offsetX*/, 300 /*offsetY*/);
1170 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1171 surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
1172 surface->showAt(10, 10);
1173
1174 // Input injection happens in logical display coordinates.
1175 injectTapOnDisplay(11, 11, layerStack.id);
1176 // Expect that the display transform for the display that receives input was used.
1177 surface->expectTapInDisplayCoordinates(211, 211);
1178
1179 surface->requestFocus(layerStack.id);
1180 surface->assertFocusChange(true);
1181 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1182}
1183
Vishnu Nair16a938f2021-09-24 07:14:54 -07001184TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
1185 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1186 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1187 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1188 surface->doTransaction([&](auto &t, auto &sc) {
1189 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1190 t.setLayerStack(sc, layerStack);
1191 });
1192 surface->showAt(100, 100);
1193
Prabir Pradhand0aba782021-12-14 00:44:21 -08001194 injectTapOnDisplay(101, 101, layerStack.id);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001195
1196 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1197
1198 surface->requestFocus(layerStack.id);
1199 surface->assertFocusChange(true);
1200 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1201 EXPECT_EQ(surface->consumeEvent(100), nullptr);
1202}
1203
1204TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
1205 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001206
1207 // Create the secure display as system, because only certain users can create secure displays.
1208 seteuid(AID_SYSTEM);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001209 createDisplay(1000, 1000, true /*isSecure*/, layerStack);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001210 // Change the uid back to root.
1211 seteuid(AID_ROOT);
1212
Vishnu Nair16a938f2021-09-24 07:14:54 -07001213 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1214 surface->doTransaction([&](auto &t, auto &sc) {
1215 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1216 t.setLayerStack(sc, layerStack);
1217 });
1218 surface->showAt(100, 100);
1219
1220 injectTapOnDisplay(101, 101, layerStack.id);
1221 EXPECT_NE(surface->consumeEvent(), nullptr);
1222 EXPECT_NE(surface->consumeEvent(), nullptr);
1223
1224 surface->requestFocus(layerStack.id);
1225 surface->assertFocusChange(true);
1226 injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
1227
1228 surface->expectKey(AKEYCODE_V);
1229}
1230
Vishnu Nair958da932020-08-21 17:12:37 -07001231} // namespace android::test