blob: 45f41f1e8fcacd54523f651a99ff2c3a62fe86b4 [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
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -070027#include <android-base/thread_annotations.h>
Patrick Williams0a4981a2023-07-28 15:08:52 -050028#include <android/gui/BnWindowInfosReportedListener.h>
Vishnu Naira066d902021-09-13 18:40:17 -070029#include <android/keycodes.h>
Vishnu Nairde19f852018-12-18 16:11:53 -080030#include <android/native_window.h>
31
Robert Carr1c4c5592018-09-24 13:18:43 -070032#include <binder/Binder.h>
33#include <binder/IServiceManager.h>
34#include <binder/Parcel.h>
35#include <binder/ProcessState.h>
36
Vishnu Nairde19f852018-12-18 16:11:53 -080037#include <gui/ISurfaceComposer.h>
38#include <gui/Surface.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070039#include <gui/SurfaceComposerClient.h>
40#include <gui/SurfaceControl.h>
41
Chris Ye0783e992020-06-02 21:34:49 -070042#include <android/os/IInputFlinger.h>
chaviw98318de2021-05-19 16:45:23 -050043#include <gui/WindowInfo.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070044#include <input/Input.h>
Siarhei Vishniakou0438ca82024-03-12 14:27:25 -070045#include <input/InputConsumer.h>
Chris Ye0783e992020-06-02 21:34:49 -070046#include <input/InputTransport.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070047
Marin Shalamanova7fe3042021-01-29 21:02:08 +010048#include <ui/DisplayMode.h>
Robert Carr1c4c5592018-09-24 13:18:43 -070049#include <ui/Rect.h>
50#include <ui/Region.h>
51
Prabir Pradhand0aba782021-12-14 00:44:21 -080052#include <private/android_filesystem_config.h>
53
Chris Ye0783e992020-06-02 21:34:49 -070054using android::os::IInputFlinger;
Robert Carr1c4c5592018-09-24 13:18:43 -070055
chaviw39d01472021-04-08 14:26:24 -050056using android::hardware::graphics::common::V1_1::BufferUsage;
57
chaviw98318de2021-05-19 16:45:23 -050058using android::gui::FocusRequest;
59using android::gui::InputApplicationInfo;
60using android::gui::TouchOcclusionMode;
61using android::gui::WindowInfo;
62
Linnan Li13bf76a2024-05-05 19:18:02 +080063namespace android {
64namespace {
65ui::LogicalDisplayId toDisplayId(ui::LayerStack layerStack) {
66 return ui::LogicalDisplayId{static_cast<int32_t>(layerStack.id)};
67}
68} // namespace
69namespace test {
Robert Carr1c4c5592018-09-24 13:18:43 -070070
Vishnu Nairde19f852018-12-18 16:11:53 -080071using Transaction = SurfaceComposerClient::Transaction;
72
Robert Carr1c4c5592018-09-24 13:18:43 -070073sp<IInputFlinger> getInputFlinger() {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -080074 sp<IBinder> input(defaultServiceManager()->waitForService(String16("inputflinger")));
Robert Carr1c4c5592018-09-24 13:18:43 -070075 if (input == nullptr) {
76 ALOGE("Failed to link to input service");
Linnan Li13bf76a2024-05-05 19:18:02 +080077 } else {
Harry Cutts917d6da2024-12-02 18:33:09 +000078 ALOGI("Linked to input");
Linnan Li13bf76a2024-05-05 19:18:02 +080079 }
Robert Carr1c4c5592018-09-24 13:18:43 -070080 return interface_cast<IInputFlinger>(input);
81}
82
83// We use the top 10 layers as a way to haphazardly place ourselves above anything else.
84static const int LAYER_BASE = INT32_MAX - 10;
Chris Ye6c4243b2020-07-22 12:07:12 -070085static constexpr std::chrono::nanoseconds DISPATCHING_TIMEOUT = 5s;
Robert Carr1c4c5592018-09-24 13:18:43 -070086
Patrick Williams0a4981a2023-07-28 15:08:52 -050087class SynchronousWindowInfosReportedListener : public gui::BnWindowInfosReportedListener {
88public:
89 binder::Status onWindowInfosReported() override {
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -070090 std::scoped_lock lock{mLock};
Patrick Williams0a4981a2023-07-28 15:08:52 -050091 mWindowInfosReported = true;
92 mConditionVariable.notify_one();
93 return binder::Status::ok();
94 }
95
96 void wait() {
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -070097 std::unique_lock lock{mLock};
98 android::base::ScopedLockAssertion assumeLocked(mLock);
99 mConditionVariable.wait(lock, [&]() REQUIRES(mLock) { return mWindowInfosReported; });
Patrick Williams0a4981a2023-07-28 15:08:52 -0500100 }
101
102private:
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700103 std::mutex mLock;
Patrick Williams0a4981a2023-07-28 15:08:52 -0500104 std::condition_variable mConditionVariable;
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700105 bool mWindowInfosReported GUARDED_BY(mLock){false};
Patrick Williams0a4981a2023-07-28 15:08:52 -0500106};
107
Robert Carr1c4c5592018-09-24 13:18:43 -0700108class InputSurface {
109public:
Linnan Li13bf76a2024-05-05 19:18:02 +0800110 InputSurface(const sp<SurfaceControl>& sc, int width, int height, bool noInputChannel = false) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800111 mSurfaceControl = sc;
Robert Carr1c4c5592018-09-24 13:18:43 -0700112
113 mInputFlinger = getInputFlinger();
Linus Tufvessona1858822022-03-04 09:32:07 +0000114 if (noInputChannel) {
Patrick Williams87602162024-11-05 10:13:19 -0600115 mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NO_INPUT_CHANNEL, true);
Linus Tufvessona1858822022-03-04 09:32:07 +0000116 } else {
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800117 android::os::InputChannelCore tempChannel;
118 android::binder::Status result =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000119 mInputFlinger->createInputChannel(sc->getName() + " channel", &tempChannel);
Siarhei Vishniakou8d660132024-01-11 16:48:44 -0800120 if (!result.isOk()) {
121 ADD_FAILURE() << "binder call to createInputChannel failed";
122 }
123 mClientChannel = InputChannel::create(std::move(tempChannel));
Patrick Williams87602162024-11-05 10:13:19 -0600124 mInputInfo->editInfo()->token = mClientChannel->getConnectionToken();
Linus Tufvessona1858822022-03-04 09:32:07 +0000125 mInputConsumer = new InputConsumer(mClientChannel);
126 }
Robert Carr1c4c5592018-09-24 13:18:43 -0700127
Patrick Williams87602162024-11-05 10:13:19 -0600128 mInputInfo->editInfo()->name = "Test info";
129 mInputInfo->editInfo()->dispatchingTimeout = 5s;
130 mInputInfo->editInfo()->globalScaleFactor = 1.0;
131 mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, width, height));
Robert Carr1c4c5592018-09-24 13:18:43 -0700132
Linus Tufvessona1858822022-03-04 09:32:07 +0000133 InputApplicationInfo aInfo;
134 aInfo.token = new BBinder();
135 aInfo.name = "Test app info";
136 aInfo.dispatchingTimeoutMillis =
137 std::chrono::duration_cast<std::chrono::milliseconds>(DISPATCHING_TIMEOUT).count();
Patrick Williams87602162024-11-05 10:13:19 -0600138 mInputInfo->editInfo()->applicationInfo = aInfo;
Robert Carr1c4c5592018-09-24 13:18:43 -0700139 }
140
Linnan Li13bf76a2024-05-05 19:18:02 +0800141 static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient>& scc,
Arpit Singha9ec7d42024-12-04 14:34:05 +0000142 int width, int height,
143 const std::string& name) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800144 sp<SurfaceControl> surfaceControl =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000145 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
Vishnu Nairfa247b12020-02-11 08:58:26 -0800146 PIXEL_FORMAT_RGBA_8888,
147 ISurfaceComposerClient::eFXSurfaceEffect);
Vishnu Nairde19f852018-12-18 16:11:53 -0800148 return std::make_unique<InputSurface>(surfaceControl, width, height);
149 }
150
151 static std::unique_ptr<InputSurface> makeBufferInputSurface(
Arpit Singha9ec7d42024-12-04 14:34:05 +0000152 const sp<SurfaceComposerClient>& scc, int width, int height,
153 const std::string& name = "Test Buffer Surface") {
Vishnu Nairde19f852018-12-18 16:11:53 -0800154 sp<SurfaceControl> surfaceControl =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000155 scc->createSurface(String8(name.c_str()), width, height, PIXEL_FORMAT_RGBA_8888,
156 0 /* flags */);
Vishnu Nairde19f852018-12-18 16:11:53 -0800157 return std::make_unique<InputSurface>(surfaceControl, width, height);
158 }
159
160 static std::unique_ptr<InputSurface> makeContainerInputSurface(
Arpit Singha9ec7d42024-12-04 14:34:05 +0000161 const sp<SurfaceComposerClient>& scc, int width, int height,
162 const std::string& name = "Test Container Surface") {
Vishnu Nairde19f852018-12-18 16:11:53 -0800163 sp<SurfaceControl> surfaceControl =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000164 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
165 PIXEL_FORMAT_RGBA_8888,
Vishnu Nairde19f852018-12-18 16:11:53 -0800166 ISurfaceComposerClient::eFXSurfaceContainer);
167 return std::make_unique<InputSurface>(surfaceControl, width, height);
168 }
169
Linus Tufvessona1858822022-03-04 09:32:07 +0000170 static std::unique_ptr<InputSurface> makeContainerInputSurfaceNoInputChannel(
Arpit Singha9ec7d42024-12-04 14:34:05 +0000171 const sp<SurfaceComposerClient>& scc, int width, int height,
172 const std::string& name = "Test Container Surface") {
Linus Tufvessona1858822022-03-04 09:32:07 +0000173 sp<SurfaceControl> surfaceControl =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000174 scc->createSurface(String8(name.c_str()), 100 /* height */, 100 /* width */,
175 PIXEL_FORMAT_RGBA_8888,
Linus Tufvessona1858822022-03-04 09:32:07 +0000176 ISurfaceComposerClient::eFXSurfaceContainer);
177 return std::make_unique<InputSurface>(surfaceControl, width, height,
178 true /* noInputChannel */);
179 }
180
arthurhungb4a0f852020-06-16 11:02:50 +0800181 static std::unique_ptr<InputSurface> makeCursorInputSurface(
Arpit Singha9ec7d42024-12-04 14:34:05 +0000182 const sp<SurfaceComposerClient>& scc, int width, int height,
183 const std::string& name = "Test Cursor Surface") {
arthurhungb4a0f852020-06-16 11:02:50 +0800184 sp<SurfaceControl> surfaceControl =
Arpit Singha9ec7d42024-12-04 14:34:05 +0000185 scc->createSurface(String8(name.c_str()), 0 /* bufHeight */, 0 /* bufWidth */,
186 PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eCursorWindow);
arthurhungb4a0f852020-06-16 11:02:50 +0800187 return std::make_unique<InputSurface>(surfaceControl, width, height);
188 }
189
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100190 void assertFocusChange(bool hasFocus) {
Linnan Li13bf76a2024-05-05 19:18:02 +0800191 InputEvent* ev = consumeEvent();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100192 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700193 ASSERT_EQ(InputEventType::FOCUS, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800194 FocusEvent* focusEvent = static_cast<FocusEvent*>(ev);
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100195 EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
196 }
197
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -0700198 void expectTap(float x, float y) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700199 InputEvent* ev = consumeEvent();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100200 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700201 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Robert Carr1c4c5592018-09-24 13:18:43 -0700202 MotionEvent* mev = static_cast<MotionEvent*>(ev);
203 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
204 EXPECT_EQ(x, mev->getX(0));
205 EXPECT_EQ(y, mev->getY(0));
arthurhungb4a0f852020-06-16 11:02:50 +0800206 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
Robert Carr1c4c5592018-09-24 13:18:43 -0700207
208 ev = consumeEvent();
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100209 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700210 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Robert Carr1c4c5592018-09-24 13:18:43 -0700211 mev = static_cast<MotionEvent*>(ev);
212 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
arthurhungb4a0f852020-06-16 11:02:50 +0800213 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
Robert Carr1c4c5592018-09-24 13:18:43 -0700214 }
215
chaviw39cfa2e2020-11-04 14:19:02 -0800216 void expectTapWithFlag(int x, int y, int32_t flags) {
Linnan Li13bf76a2024-05-05 19:18:02 +0800217 InputEvent* ev = consumeEvent();
chaviw39cfa2e2020-11-04 14:19:02 -0800218 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700219 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800220 MotionEvent* mev = static_cast<MotionEvent*>(ev);
chaviw39cfa2e2020-11-04 14:19:02 -0800221 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
222 EXPECT_EQ(x, mev->getX(0));
223 EXPECT_EQ(y, mev->getY(0));
224 EXPECT_EQ(flags, mev->getFlags() & flags);
225
226 ev = consumeEvent();
227 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700228 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800229 mev = static_cast<MotionEvent*>(ev);
chaviw39cfa2e2020-11-04 14:19:02 -0800230 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
231 EXPECT_EQ(flags, mev->getFlags() & flags);
232 }
233
Prabir Pradhand0aba782021-12-14 00:44:21 -0800234 void expectTapInDisplayCoordinates(int displayX, int displayY) {
Linnan Li13bf76a2024-05-05 19:18:02 +0800235 InputEvent* ev = consumeEvent();
Prabir Pradhand0aba782021-12-14 00:44:21 -0800236 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700237 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800238 MotionEvent* mev = static_cast<MotionEvent*>(ev);
Prabir Pradhand0aba782021-12-14 00:44:21 -0800239 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
Linnan Li13bf76a2024-05-05 19:18:02 +0800240 const PointerCoords& coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
Prabir Pradhand0aba782021-12-14 00:44:21 -0800241 EXPECT_EQ(displayX, coords.getX());
242 EXPECT_EQ(displayY, coords.getY());
243 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
244
245 ev = consumeEvent();
246 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700247 ASSERT_EQ(InputEventType::MOTION, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800248 mev = static_cast<MotionEvent*>(ev);
Prabir Pradhand0aba782021-12-14 00:44:21 -0800249 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
250 EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
251 }
252
Siarhei Vishniakoubf98a572024-03-29 13:34:42 -0700253 void expectKey(int32_t keycode) {
Linnan Li13bf76a2024-05-05 19:18:02 +0800254 InputEvent* ev = consumeEvent();
Vishnu Naira066d902021-09-13 18:40:17 -0700255 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700256 ASSERT_EQ(InputEventType::KEY, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800257 KeyEvent* keyEvent = static_cast<KeyEvent*>(ev);
Vishnu Naira066d902021-09-13 18:40:17 -0700258 EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
259 EXPECT_EQ(keycode, keyEvent->getKeyCode());
260 EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
261
262 ev = consumeEvent();
263 ASSERT_NE(ev, nullptr);
Siarhei Vishniakou63b63612023-04-12 11:00:23 -0700264 ASSERT_EQ(InputEventType::KEY, ev->getType());
Linnan Li13bf76a2024-05-05 19:18:02 +0800265 keyEvent = static_cast<KeyEvent*>(ev);
Vishnu Naira066d902021-09-13 18:40:17 -0700266 EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
267 EXPECT_EQ(keycode, keyEvent->getKeyCode());
268 EXPECT_EQ(0, keyEvent->getFlags() & VERIFIED_KEY_EVENT_FLAGS);
269 }
270
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -0700271 void assertNoEvent() {
272 InputEvent* event = consumeEvent(/*timeout=*/100ms);
273 ASSERT_EQ(event, nullptr) << "Expected no event, but got " << *event;
274 }
275
chaviw39d01472021-04-08 14:26:24 -0500276 virtual ~InputSurface() {
Linus Tufvessona1858822022-03-04 09:32:07 +0000277 if (mClientChannel) {
278 mInputFlinger->removeInputChannel(mClientChannel->getConnectionToken());
279 }
chaviw39d01472021-04-08 14:26:24 -0500280 }
Robert Carr1c4c5592018-09-24 13:18:43 -0700281
chaviw39d01472021-04-08 14:26:24 -0500282 virtual void doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +0800283 std::function<void(SurfaceComposerClient::Transaction&, const sp<SurfaceControl>&)>
chaviw39d01472021-04-08 14:26:24 -0500284 transactionBody) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700285 SurfaceComposerClient::Transaction t;
286 transactionBody(t, mSurfaceControl);
Prabir Pradhana97fd942024-10-28 21:21:53 +0000287 t.apply(/*synchronously=*/true);
Robert Carr1c4c5592018-09-24 13:18:43 -0700288 }
289
chaviw39d01472021-04-08 14:26:24 -0500290 virtual void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) {
Robert Carr1c4c5592018-09-24 13:18:43 -0700291 SurfaceComposerClient::Transaction t;
292 t.show(mSurfaceControl);
293 t.setInputWindowInfo(mSurfaceControl, mInputInfo);
294 t.setLayer(mSurfaceControl, LAYER_BASE);
295 t.setPosition(mSurfaceControl, x, y);
chaviw25714502021-02-11 10:01:08 -0800296 t.setCrop(mSurfaceControl, crop);
Robert Carr1c4c5592018-09-24 13:18:43 -0700297 t.setAlpha(mSurfaceControl, 1);
Patrick Williams0a4981a2023-07-28 15:08:52 -0500298 auto reportedListener = sp<SynchronousWindowInfosReportedListener>::make();
299 t.addWindowInfosReportedListener(reportedListener);
Prabir Pradhana97fd942024-10-28 21:21:53 +0000300 t.apply(/*synchronously=*/true);
Patrick Williams0a4981a2023-07-28 15:08:52 -0500301 reportedListener->wait();
Robert Carr1c4c5592018-09-24 13:18:43 -0700302 }
303
Siarhei Vishniakoucfbee532024-05-10 13:41:35 -0700304 void requestFocus(ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT) {
Vishnu Nair958da932020-08-21 17:12:37 -0700305 SurfaceComposerClient::Transaction t;
Vishnu Nair9ad01462021-01-15 12:55:14 -0800306 FocusRequest request;
Patrick Williams87602162024-11-05 10:13:19 -0600307 request.token = mInputInfo->getInfo()->token;
308 request.windowName = mInputInfo->getInfo()->name;
Vishnu Nair9ad01462021-01-15 12:55:14 -0800309 request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
Linnan Li13bf76a2024-05-05 19:18:02 +0800310 request.displayId = displayId.val();
Vishnu Nair9ad01462021-01-15 12:55:14 -0800311 t.setFocusedWindow(request);
Prabir Pradhana97fd942024-10-28 21:21:53 +0000312 t.apply(/*synchronously=*/true);
Vishnu Nair958da932020-08-21 17:12:37 -0700313 }
314
Robert Carr1c4c5592018-09-24 13:18:43 -0700315public:
Siarhei Vishniakou1d038d42024-10-29 11:25:58 -0700316 // But should be private
Patrick Williams87602162024-11-05 10:13:19 -0600317 sp<gui::WindowInfoHandle> mInputInfo = sp<gui::WindowInfoHandle>::make();
Robert Carr1c4c5592018-09-24 13:18:43 -0700318 sp<SurfaceControl> mSurfaceControl;
Siarhei Vishniakou1d038d42024-10-29 11:25:58 -0700319
320private:
Siarhei Vishniakouce5ab082020-07-09 17:03:21 -0500321 std::shared_ptr<InputChannel> mClientChannel;
Robert Carr1c4c5592018-09-24 13:18:43 -0700322 sp<IInputFlinger> mInputFlinger;
323
Robert Carr1c4c5592018-09-24 13:18:43 -0700324 PreallocatedInputEventFactory mInputEventFactory;
325 InputConsumer* mInputConsumer;
Siarhei Vishniakou1d038d42024-10-29 11:25:58 -0700326
327 InputEvent* consumeEvent(std::chrono::milliseconds timeout = 3000ms) {
328 mClientChannel->waitForMessage(timeout);
329
330 InputEvent* ev;
331 uint32_t seqId;
332 status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
333 if (consumed != OK) {
334 return nullptr;
335 }
336 status_t status = mInputConsumer->sendFinishedSignal(seqId, true);
337 EXPECT_EQ(OK, status) << "Could not send finished signal";
338 return ev;
339 }
Robert Carr1c4c5592018-09-24 13:18:43 -0700340};
341
chaviw39d01472021-04-08 14:26:24 -0500342class BlastInputSurface : public InputSurface {
343public:
Linnan Li13bf76a2024-05-05 19:18:02 +0800344 BlastInputSurface(const sp<SurfaceControl>& sc, const sp<SurfaceControl>& parentSc, int width,
chaviw39d01472021-04-08 14:26:24 -0500345 int height)
346 : InputSurface(sc, width, height) {
347 mParentSurfaceControl = parentSc;
348 }
349
350 ~BlastInputSurface() = default;
351
352 static std::unique_ptr<BlastInputSurface> makeBlastInputSurface(
Linnan Li13bf76a2024-05-05 19:18:02 +0800353 const sp<SurfaceComposerClient>& scc, int width, int height) {
chaviw39d01472021-04-08 14:26:24 -0500354 sp<SurfaceControl> parentSc =
355 scc->createSurface(String8("Test Parent Surface"), 0 /* bufHeight */,
356 0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
357 ISurfaceComposerClient::eFXSurfaceContainer);
358
359 sp<SurfaceControl> surfaceControl =
360 scc->createSurface(String8("Test Buffer Surface"), width, height,
361 PIXEL_FORMAT_RGBA_8888,
362 ISurfaceComposerClient::eFXSurfaceBufferState,
363 parentSc->getHandle());
364 return std::make_unique<BlastInputSurface>(surfaceControl, parentSc, width, height);
365 }
366
367 void doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +0800368 std::function<void(SurfaceComposerClient::Transaction&, const sp<SurfaceControl>&)>
chaviw39d01472021-04-08 14:26:24 -0500369 transactionBody) override {
370 SurfaceComposerClient::Transaction t;
371 transactionBody(t, mParentSurfaceControl);
Prabir Pradhana97fd942024-10-28 21:21:53 +0000372 t.apply(/*synchronously=*/true);
chaviw39d01472021-04-08 14:26:24 -0500373 }
374
375 void showAt(int x, int y, Rect crop = Rect(0, 0, 100, 100)) override {
376 SurfaceComposerClient::Transaction t;
377 t.show(mParentSurfaceControl);
378 t.setLayer(mParentSurfaceControl, LAYER_BASE);
379 t.setPosition(mParentSurfaceControl, x, y);
380 t.setCrop(mParentSurfaceControl, crop);
381
382 t.show(mSurfaceControl);
383 t.setInputWindowInfo(mSurfaceControl, mInputInfo);
384 t.setCrop(mSurfaceControl, crop);
385 t.setAlpha(mSurfaceControl, 1);
Prabir Pradhana97fd942024-10-28 21:21:53 +0000386 t.apply(/*synchronously=*/true);
chaviw39d01472021-04-08 14:26:24 -0500387 }
388
389private:
390 sp<SurfaceControl> mParentSurfaceControl;
391};
392
Robert Carr1c4c5592018-09-24 13:18:43 -0700393class InputSurfacesTest : public ::testing::Test {
394public:
Linnan Li13bf76a2024-05-05 19:18:02 +0800395 InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
Robert Carr1c4c5592018-09-24 13:18:43 -0700396
397 void SetUp() {
398 mComposerClient = new SurfaceComposerClient;
399 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
Huihong Luo31b5ac22022-08-15 20:38:10 -0700400 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
401 ASSERT_FALSE(ids.empty());
402 // display 0 is picked for now, can extend to support all displays if needed
403 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100404 ASSERT_NE(display, nullptr);
Dominik Laskowskidcb38bb2019-01-25 02:35:50 -0800405
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100406 ui::DisplayMode mode;
407 ASSERT_EQ(NO_ERROR, mComposerClient->getActiveDisplayMode(display, &mode));
Vishnu Nairde19f852018-12-18 16:11:53 -0800408
409 // After a new buffer is queued, SurfaceFlinger is notified and will
410 // latch the new buffer on next vsync. Let's heuristically wait for 3
411 // vsyncs.
Alec Mouri55e31032023-10-02 20:34:18 +0000412 mBufferPostDelay = static_cast<int32_t>(1e6 / mode.peakRefreshRate) * 3;
Robert Carr1c4c5592018-09-24 13:18:43 -0700413 }
414
Linnan Li13bf76a2024-05-05 19:18:02 +0800415 void TearDown() { mComposerClient->dispose(); }
Robert Carr1c4c5592018-09-24 13:18:43 -0700416
Arpit Singha9ec7d42024-12-04 14:34:05 +0000417 std::unique_ptr<InputSurface> makeSurface(int width, int height,
418 const std::string& name = "Test Surface") const {
419 return InputSurface::makeColorInputSurface(mComposerClient, width, height, name);
Vishnu Nairde19f852018-12-18 16:11:53 -0800420 }
421
Linnan Li13bf76a2024-05-05 19:18:02 +0800422 void postBuffer(const sp<SurfaceControl>& layer, int32_t w, int32_t h) {
chaviw39d01472021-04-08 14:26:24 -0500423 int64_t usageFlags = BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
424 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE;
425 sp<GraphicBuffer> buffer =
426 new GraphicBuffer(w, h, PIXEL_FORMAT_RGBA_8888, 1, usageFlags, "test");
Prabir Pradhana97fd942024-10-28 21:21:53 +0000427 Transaction().setBuffer(layer, buffer).apply(/*synchronously=*/true);
Vishnu Nairde19f852018-12-18 16:11:53 -0800428 usleep(mBufferPostDelay);
Robert Carr1c4c5592018-09-24 13:18:43 -0700429 }
430
431 sp<SurfaceComposerClient> mComposerClient;
Vishnu Nairde19f852018-12-18 16:11:53 -0800432 int32_t mBufferPostDelay;
Robert Carr1c4c5592018-09-24 13:18:43 -0700433};
434
Linnan Li13bf76a2024-05-05 19:18:02 +0800435void injectTapOnDisplay(int x, int y, ui::LogicalDisplayId displayId) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700436 char *buf1, *buf2, *bufDisplayId;
Robert Carr1c4c5592018-09-24 13:18:43 -0700437 asprintf(&buf1, "%d", x);
438 asprintf(&buf2, "%d", y);
Linnan Li13bf76a2024-05-05 19:18:02 +0800439 asprintf(&bufDisplayId, "%d", displayId.val());
Robert Carr1c4c5592018-09-24 13:18:43 -0700440 if (fork() == 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700441 execlp("input", "input", "-d", bufDisplayId, "tap", buf1, buf2, NULL);
442 }
443}
444
445void injectTap(int x, int y) {
Siarhei Vishniakoucfbee532024-05-10 13:41:35 -0700446 injectTapOnDisplay(x, y, ui::LogicalDisplayId::DEFAULT);
Vishnu Nair16a938f2021-09-24 07:14:54 -0700447}
448
Linnan Li13bf76a2024-05-05 19:18:02 +0800449void injectKeyOnDisplay(uint32_t keycode, ui::LogicalDisplayId displayId) {
Vishnu Nair16a938f2021-09-24 07:14:54 -0700450 char *buf1, *bufDisplayId;
451 asprintf(&buf1, "%d", keycode);
Linnan Li13bf76a2024-05-05 19:18:02 +0800452 asprintf(&bufDisplayId, "%d", displayId.val());
Vishnu Nair16a938f2021-09-24 07:14:54 -0700453 if (fork() == 0) {
454 execlp("input", "input", "-d", bufDisplayId, "keyevent", buf1, NULL);
Robert Carr1c4c5592018-09-24 13:18:43 -0700455 }
456}
457
Vishnu Naira066d902021-09-13 18:40:17 -0700458void injectKey(uint32_t keycode) {
Siarhei Vishniakoucfbee532024-05-10 13:41:35 -0700459 injectKeyOnDisplay(keycode, ui::LogicalDisplayId::INVALID);
Vishnu Naira066d902021-09-13 18:40:17 -0700460}
461
Robert Carr1c4c5592018-09-24 13:18:43 -0700462TEST_F(InputSurfacesTest, can_receive_input) {
463 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
464 surface->showAt(100, 100);
465
466 injectTap(101, 101);
467
Siarhei Vishniakou1d038d42024-10-29 11:25:58 -0700468 surface->expectTap(1, 1);
Robert Carr1c4c5592018-09-24 13:18:43 -0700469}
470
Siarhei Vishniakouf1035d42019-09-20 16:32:01 +0100471/**
472 * Set up two surfaces side-by-side. Tap each surface.
473 * Next, swap the positions of the two surfaces. Inject tap into the two
474 * original locations. Ensure that the tap is received by the surfaces in the
475 * reverse order.
476 */
Robert Carr1c4c5592018-09-24 13:18:43 -0700477TEST_F(InputSurfacesTest, input_respects_positioning) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000478 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Left Surface");
Robert Carr1c4c5592018-09-24 13:18:43 -0700479 surface->showAt(100, 100);
480
Arpit Singha9ec7d42024-12-04 14:34:05 +0000481 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100, "Right Surface");
Robert Carr1c4c5592018-09-24 13:18:43 -0700482 surface2->showAt(200, 200);
483
484 injectTap(201, 201);
485 surface2->expectTap(1, 1);
486
487 injectTap(101, 101);
488 surface->expectTap(1, 1);
489
Linnan Li13bf76a2024-05-05 19:18:02 +0800490 surface2->doTransaction([](auto& t, auto& sc) { t.setPosition(sc, 100, 100); });
491 surface->doTransaction([](auto& t, auto& sc) { t.setPosition(sc, 200, 200); });
Robert Carr1c4c5592018-09-24 13:18:43 -0700492
493 injectTap(101, 101);
494 surface2->expectTap(1, 1);
495
496 injectTap(201, 201);
497 surface->expectTap(1, 1);
498}
499
500TEST_F(InputSurfacesTest, input_respects_layering) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000501 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface 1");
502 std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100, "Test Surface 2");
Robert Carr1c4c5592018-09-24 13:18:43 -0700503
504 surface->showAt(10, 10);
505 surface2->showAt(10, 10);
506
Linnan Li13bf76a2024-05-05 19:18:02 +0800507 surface->doTransaction([](auto& t, auto& sc) { t.setLayer(sc, LAYER_BASE + 1); });
Robert Carr1c4c5592018-09-24 13:18:43 -0700508
509 injectTap(11, 11);
510 surface->expectTap(1, 1);
511
Linnan Li13bf76a2024-05-05 19:18:02 +0800512 surface2->doTransaction([](auto& t, auto& sc) { t.setLayer(sc, LAYER_BASE + 1); });
Robert Carr1c4c5592018-09-24 13:18:43 -0700513
514 injectTap(11, 11);
515 surface2->expectTap(1, 1);
516
Linnan Li13bf76a2024-05-05 19:18:02 +0800517 surface2->doTransaction([](auto& t, auto& sc) { t.hide(sc); });
Robert Carr1c4c5592018-09-24 13:18:43 -0700518
519 injectTap(11, 11);
520 surface->expectTap(1, 1);
521}
522
Vishnu Nairde19f852018-12-18 16:11:53 -0800523// Surface Insets are set to offset the client content and draw a border around the client surface
524// (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
525// of the client content.
526TEST_F(InputSurfacesTest, input_respects_surface_insets) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000527 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
528 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Vishnu Nairde19f852018-12-18 16:11:53 -0800529 bgSurface->showAt(100, 100);
530
Patrick Williams87602162024-11-05 10:13:19 -0600531 fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
Vishnu Nairde19f852018-12-18 16:11:53 -0800532 fgSurface->showAt(100, 100);
533
534 injectTap(106, 106);
535 fgSurface->expectTap(1, 1);
536
537 injectTap(101, 101);
538 bgSurface->expectTap(1, 1);
539}
540
Vishnu Nairfed7c122023-03-18 01:54:43 +0000541TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableRegionWithCrop) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000542 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
543 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Vishnu Nairfed7c122023-03-18 01:54:43 +0000544 bgSurface->showAt(100, 100);
545
Patrick Williams87602162024-11-05 10:13:19 -0600546 fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
547 fgSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
Vishnu Nairfed7c122023-03-18 01:54:43 +0000548 fgSurface->showAt(100, 100);
549
550 injectTap(106, 106);
551 fgSurface->expectTap(1, 1);
552
553 injectTap(101, 101);
554 bgSurface->expectTap(1, 1);
555}
556
Vishnu Nairde19f852018-12-18 16:11:53 -0800557// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
558TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000559 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
560 std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100, "Child Surface");
Vishnu Nairde19f852018-12-18 16:11:53 -0800561 parentSurface->showAt(100, 100);
562
Patrick Williams87602162024-11-05 10:13:19 -0600563 childSurface->mInputInfo->editInfo()->surfaceInset = 10;
Vishnu Nairde19f852018-12-18 16:11:53 -0800564 childSurface->showAt(100, 100);
565
Linnan Li13bf76a2024-05-05 19:18:02 +0800566 childSurface->doTransaction([&](auto& t, auto& sc) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800567 t.setPosition(sc, -5, -5);
Pablo Gamito11dcc222020-09-12 15:49:39 +0000568 t.reparent(sc, parentSurface->mSurfaceControl);
Vishnu Nairde19f852018-12-18 16:11:53 -0800569 });
570
571 injectTap(106, 106);
572 childSurface->expectTap(1, 1);
573
574 injectTap(101, 101);
575 parentSurface->expectTap(1, 1);
576}
577
Arthur Hung118b1142019-05-08 21:25:59 +0800578// Ensure a surface whose insets are scaled, handles the touch offset correctly.
579TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000580 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
581 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Arthur Hung118b1142019-05-08 21:25:59 +0800582 bgSurface->showAt(100, 100);
583
Patrick Williams87602162024-11-05 10:13:19 -0600584 fgSurface->mInputInfo->editInfo()->surfaceInset = 5;
Arthur Hung118b1142019-05-08 21:25:59 +0800585 fgSurface->showAt(100, 100);
586
Linnan Li13bf76a2024-05-05 19:18:02 +0800587 fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
Arthur Hung118b1142019-05-08 21:25:59 +0800588
589 // expect = touch / scale - inset
590 injectTap(112, 124);
591 fgSurface->expectTap(1, 1);
592
593 injectTap(101, 101);
594 bgSurface->expectTap(1, 1);
595}
596
Ady Abraham282f1d72019-07-24 18:05:56 -0700597TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets_overflow) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000598 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
599 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700600 bgSurface->showAt(100, 100);
601
Ady Abraham282f1d72019-07-24 18:05:56 -0700602 // In case we pass the very big inset without any checking.
Patrick Williams87602162024-11-05 10:13:19 -0600603 fgSurface->mInputInfo->editInfo()->surfaceInset = INT32_MAX;
Ady Abraham282f1d72019-07-24 18:05:56 -0700604 fgSurface->showAt(100, 100);
605
Linnan Li13bf76a2024-05-05 19:18:02 +0800606 fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
Ady Abraham282f1d72019-07-24 18:05:56 -0700607
608 // expect no crash for overflow, and inset size to be clamped to surface size
Prabir Pradhanc9589c12021-09-22 06:11:43 -0700609 injectTap(112, 124);
610 bgSurface->expectTap(12, 24);
Ady Abraham282f1d72019-07-24 18:05:56 -0700611}
612
Prabir Pradhan33da9462022-06-14 14:55:57 +0000613TEST_F(InputSurfacesTest, touchable_region) {
614 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
615
Patrick Williams87602162024-11-05 10:13:19 -0600616 surface->mInputInfo->editInfo()->touchableRegion.set(Rect{19, 29, 21, 31});
Prabir Pradhan33da9462022-06-14 14:55:57 +0000617
618 surface->showAt(11, 22);
619
620 // A tap within the surface but outside the touchable region should not be sent to the surface.
621 injectTap(20, 30);
Siarhei Vishniakou1d038d42024-10-29 11:25:58 -0700622 surface->assertNoEvent();
Prabir Pradhan33da9462022-06-14 14:55:57 +0000623
624 injectTap(31, 52);
625 surface->expectTap(20, 30);
626}
627
628TEST_F(InputSurfacesTest, input_respects_touchable_region_offset_overflow) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000629 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
630 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Prabir Pradhan33da9462022-06-14 14:55:57 +0000631 bgSurface->showAt(100, 100);
632
633 // Set the touchable region to the values at the limit of its corresponding type.
634 // Since the surface is offset from the origin, the touchable region will be transformed into
635 // display space, which would trigger an overflow or an underflow. Ensure that we are protected
636 // against such a situation.
Patrick Williams87602162024-11-05 10:13:19 -0600637 fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
638 Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
Prabir Pradhan33da9462022-06-14 14:55:57 +0000639
640 fgSurface->showAt(100, 100);
641
642 // Expect no crash for overflow. The overflowed touchable region is ignored, so the background
643 // surface receives touch.
644 injectTap(112, 124);
645 bgSurface->expectTap(12, 24);
646}
647
648TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000649 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
650 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Prabir Pradhan33da9462022-06-14 14:55:57 +0000651 bgSurface->showAt(0, 0);
652
Patrick Williams87602162024-11-05 10:13:19 -0600653 fgSurface->mInputInfo->editInfo()->touchableRegion.orSelf(
654 Rect{INT32_MIN, INT32_MIN, INT32_MAX, INT32_MAX});
Prabir Pradhan33da9462022-06-14 14:55:57 +0000655 fgSurface->showAt(0, 0);
656
Linnan Li13bf76a2024-05-05 19:18:02 +0800657 fgSurface->doTransaction([&](auto& t, auto& sc) { t.setMatrix(sc, 2.0, 0, 0, 2.0); });
Prabir Pradhan33da9462022-06-14 14:55:57 +0000658
659 // Expect no crash for overflow.
660 injectTap(12, 24);
Prabir Pradhana4c59bd2023-04-10 20:54:04 +0000661 bgSurface->expectTap(12, 24);
Prabir Pradhan33da9462022-06-14 14:55:57 +0000662}
663
Vishnu Nairde19f852018-12-18 16:11:53 -0800664// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
665TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
666 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +0800667 surface->doTransaction([](auto& t, auto& sc) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800668 Region transparentRegion(Rect(0, 0, 10, 10));
669 t.setTransparentRegionHint(sc, transparentRegion);
670 });
671 surface->showAt(100, 100);
672 injectTap(101, 101);
673 surface->expectTap(1, 1);
674}
675
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700676// TODO(b/139494112) update tests once we define expected behavior
677// Ensure we still send input to the surface regardless of surface visibility changes due to the
678// first buffer being submitted or alpha changes.
679// Original bug ref: b/120839715
680TEST_F(InputSurfacesTest, input_ignores_buffer_layer_buffer) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800681 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500682 std::unique_ptr<BlastInputSurface> bufferSurface =
683 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800684
685 bgSurface->showAt(10, 10);
686 bufferSurface->showAt(10, 10);
687
688 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700689 bufferSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800690
chaviw39d01472021-04-08 14:26:24 -0500691 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800692 injectTap(11, 11);
693 bufferSurface->expectTap(1, 1);
694}
695
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000696TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
Vishnu Nairde19f852018-12-18 16:11:53 -0800697 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
chaviw39d01472021-04-08 14:26:24 -0500698 std::unique_ptr<BlastInputSurface> bufferSurface =
699 BlastInputSurface::makeBlastInputSurface(mComposerClient, 100, 100);
700 postBuffer(bufferSurface->mSurfaceControl, 100, 100);
Vishnu Nairde19f852018-12-18 16:11:53 -0800701
702 bgSurface->showAt(10, 10);
703 bufferSurface->showAt(10, 10);
704
705 injectTap(11, 11);
706 bufferSurface->expectTap(1, 1);
707
Linnan Li13bf76a2024-05-05 19:18:02 +0800708 bufferSurface->doTransaction([](auto& t, auto& sc) { t.setAlpha(sc, 0.0); });
Vishnu Nairde19f852018-12-18 16:11:53 -0800709
710 injectTap(11, 11);
Arthur Hungfb2ebce2021-10-04 14:08:48 +0000711 bgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800712}
713
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700714TEST_F(InputSurfacesTest, input_ignores_color_layer_alpha) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000715 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100, "Background Surface");
716 std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100, "Foreground Surface");
Vishnu Nairde19f852018-12-18 16:11:53 -0800717
718 bgSurface->showAt(10, 10);
719 fgSurface->showAt(10, 10);
720
721 injectTap(11, 11);
722 fgSurface->expectTap(1, 1);
723
Linnan Li13bf76a2024-05-05 19:18:02 +0800724 fgSurface->doTransaction([](auto& t, auto& sc) { t.setAlpha(sc, 0.0); });
Vishnu Nairde19f852018-12-18 16:11:53 -0800725
726 injectTap(11, 11);
Vishnu Nairf8678ba2019-10-11 18:11:26 -0700727 fgSurface->expectTap(1, 1);
Vishnu Nairde19f852018-12-18 16:11:53 -0800728}
729
730TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
731 std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
732 std::unique_ptr<InputSurface> containerSurface =
733 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
734
735 bgSurface->showAt(10, 10);
736 containerSurface->showAt(10, 10);
737
738 injectTap(11, 11);
739 containerSurface->expectTap(1, 1);
740
Linnan Li13bf76a2024-05-05 19:18:02 +0800741 containerSurface->doTransaction([](auto& t, auto& sc) { t.hide(sc); });
Vishnu Nairde19f852018-12-18 16:11:53 -0800742
743 injectTap(11, 11);
744 bgSurface->expectTap(1, 1);
745}
chaviwfbe5d9c2018-12-26 12:23:37 -0800746
Arthur Hungd20b2702019-01-14 18:16:16 +0800747TEST_F(InputSurfacesTest, input_respects_outscreen) {
748 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
749 surface->showAt(-1, -1);
750
751 injectTap(0, 0);
752 surface->expectTap(1, 1);
753}
arthurhungb4a0f852020-06-16 11:02:50 +0800754
755TEST_F(InputSurfacesTest, input_ignores_cursor_layer) {
756 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
757 std::unique_ptr<InputSurface> cursorSurface =
758 InputSurface::makeCursorInputSurface(mComposerClient, 10, 10);
759
760 surface->showAt(10, 10);
arthurhungb4a0f852020-06-16 11:02:50 +0800761 cursorSurface->showAt(10, 10);
762
763 injectTap(11, 11);
764 surface->expectTap(1, 1);
765}
Vishnu Nair958da932020-08-21 17:12:37 -0700766
767TEST_F(InputSurfacesTest, can_be_focused) {
768 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
769 surface->showAt(100, 100);
770 surface->requestFocus();
771
772 surface->assertFocusChange(true);
Vishnu Naira066d902021-09-13 18:40:17 -0700773
774 injectKey(AKEYCODE_V);
775 surface->expectKey(AKEYCODE_V);
Robert Carr1c4c5592018-09-24 13:18:43 -0700776}
chaviw44a6d2b2020-09-08 17:14:16 -0700777
778TEST_F(InputSurfacesTest, rotate_surface) {
779 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
780 surface->showAt(10, 10);
Linnan Li13bf76a2024-05-05 19:18:02 +0800781 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700782 t.setMatrix(sc, 0, 1, -1, 0); // 90 degrees
783 });
784 injectTap(8, 11);
785 surface->expectTap(1, 2);
786
Linnan Li13bf76a2024-05-05 19:18:02 +0800787 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700788 t.setMatrix(sc, -1, 0, 0, -1); // 180 degrees
789 });
790 injectTap(9, 8);
791 surface->expectTap(1, 2);
792
Linnan Li13bf76a2024-05-05 19:18:02 +0800793 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700794 t.setMatrix(sc, 0, -1, 1, 0); // 270 degrees
795 });
796 injectTap(12, 9);
797 surface->expectTap(1, 2);
798}
799
800TEST_F(InputSurfacesTest, rotate_surface_with_scale) {
801 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
802 surface->showAt(10, 10);
Linnan Li13bf76a2024-05-05 19:18:02 +0800803 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700804 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
805 });
806 injectTap(2, 12);
807 surface->expectTap(1, 2);
808
Linnan Li13bf76a2024-05-05 19:18:02 +0800809 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700810 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
811 });
812 injectTap(8, 2);
813 surface->expectTap(1, 2);
814
Linnan Li13bf76a2024-05-05 19:18:02 +0800815 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700816 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
817 });
818 injectTap(18, 8);
819 surface->expectTap(1, 2);
820}
821
822TEST_F(InputSurfacesTest, rotate_surface_with_scale_and_insets) {
823 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Patrick Williams87602162024-11-05 10:13:19 -0600824 surface->mInputInfo->editInfo()->surfaceInset = 5;
chaviw44a6d2b2020-09-08 17:14:16 -0700825 surface->showAt(100, 100);
826
Linnan Li13bf76a2024-05-05 19:18:02 +0800827 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700828 t.setMatrix(sc, 0, 2, -4, 0); // 90 degrees
829 });
830 injectTap(40, 120);
831 surface->expectTap(5, 10);
832
Linnan Li13bf76a2024-05-05 19:18:02 +0800833 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700834 t.setMatrix(sc, -2, 0, 0, -4); // 180 degrees
835 });
836 injectTap(80, 40);
837 surface->expectTap(5, 10);
838
Linnan Li13bf76a2024-05-05 19:18:02 +0800839 surface->doTransaction([](auto& t, auto& sc) {
chaviw44a6d2b2020-09-08 17:14:16 -0700840 t.setMatrix(sc, 0, -2, 4, 0); // 270 degrees
841 });
842 injectTap(160, 80);
843 surface->expectTap(5, 10);
844}
845
chaviw39cfa2e2020-11-04 14:19:02 -0800846TEST_F(InputSurfacesTest, touch_flag_obscured) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000847 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Touchable Surface");
chaviw39cfa2e2020-11-04 14:19:02 -0800848 surface->showAt(100, 100);
849
850 // Add non touchable window to fully cover touchable window. Window behind gets touch, but
851 // with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED
Arpit Singha9ec7d42024-12-04 14:34:05 +0000852 std::unique_ptr<InputSurface> nonTouchableSurface =
853 makeSurface(100, 100, "Non-Touchable Surface");
Patrick Williams87602162024-11-05 10:13:19 -0600854 nonTouchableSurface->mInputInfo->editInfo()
855 ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
856 nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
Bernardo Rufino602ef712020-12-21 11:02:18 +0000857 // Overriding occlusion mode otherwise the touch would be discarded at InputDispatcher by
858 // the default obscured/untrusted touch filter introduced in S.
Patrick Williams87602162024-11-05 10:13:19 -0600859 nonTouchableSurface->mInputInfo->editInfo()->touchOcclusionMode = TouchOcclusionMode::ALLOW;
chaviw39cfa2e2020-11-04 14:19:02 -0800860 nonTouchableSurface->showAt(100, 100);
861
862 injectTap(190, 199);
863 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
864}
865
866TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000867 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
chaviw39cfa2e2020-11-04 14:19:02 -0800868 surface->showAt(100, 100);
869
870 // Add non touchable window to cover touchable window, but parent is cropped to not cover area
871 // that will be tapped. Window behind gets touch, but with flag
872 // AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED
Arpit Singha9ec7d42024-12-04 14:34:05 +0000873 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
874 std::unique_ptr<InputSurface> nonTouchableSurface =
875 makeSurface(100, 100, "Non-Touchable Surface");
Patrick Williams87602162024-11-05 10:13:19 -0600876 nonTouchableSurface->mInputInfo->editInfo()
877 ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
878 parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
879 true);
880 nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
881 parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
chaviw39cfa2e2020-11-04 14:19:02 -0800882 nonTouchableSurface->showAt(0, 0);
883 parentSurface->showAt(100, 100);
884
Linnan Li13bf76a2024-05-05 19:18:02 +0800885 nonTouchableSurface->doTransaction([&](auto& t, auto& sc) {
chaviw25714502021-02-11 10:01:08 -0800886 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800887 t.reparent(sc, parentSurface->mSurfaceControl);
888 });
889
890 injectTap(190, 199);
891 surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
892}
893
894TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000895 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
chaviw39cfa2e2020-11-04 14:19:02 -0800896 surface->showAt(100, 100);
897
898 // Add non touchable window to cover touchable window, but parent is cropped to avoid covering
899 // the touchable window. Window behind gets touch with no obscured flags.
Arpit Singha9ec7d42024-12-04 14:34:05 +0000900 std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100, "Parent Surface");
901 std::unique_ptr<InputSurface> nonTouchableSurface =
902 makeSurface(100, 100, "Non-Touchable Surface");
Patrick Williams87602162024-11-05 10:13:19 -0600903 nonTouchableSurface->mInputInfo->editInfo()
904 ->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE, true);
905 parentSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
906 true);
907 nonTouchableSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
908 parentSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
chaviw39cfa2e2020-11-04 14:19:02 -0800909 nonTouchableSurface->showAt(0, 0);
910 parentSurface->showAt(50, 50);
911
Linnan Li13bf76a2024-05-05 19:18:02 +0800912 nonTouchableSurface->doTransaction([&](auto& t, auto& sc) {
chaviw25714502021-02-11 10:01:08 -0800913 t.setCrop(parentSurface->mSurfaceControl, Rect(0, 0, 50, 50));
chaviw39cfa2e2020-11-04 14:19:02 -0800914 t.reparent(sc, parentSurface->mSurfaceControl);
915 });
916
917 injectTap(101, 110);
918 surface->expectTap(1, 10);
919}
920
chaviw7e72caf2020-12-02 16:50:43 -0800921TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_bql) {
922 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
923
924 std::unique_ptr<InputSurface> bufferSurface =
925 InputSurface::makeBufferInputSurface(mComposerClient, 0, 0);
Patrick Williams87602162024-11-05 10:13:19 -0600926 bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
927 true);
928 bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
chaviw7e72caf2020-12-02 16:50:43 -0800929
930 surface->showAt(10, 10);
931 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
932
933 injectTap(11, 11);
934 surface->expectTap(1, 1);
935}
936
937TEST_F(InputSurfacesTest, touch_not_obscured_with_zero_sized_blast) {
938 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
939
chaviw39d01472021-04-08 14:26:24 -0500940 std::unique_ptr<BlastInputSurface> bufferSurface =
941 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
Patrick Williams87602162024-11-05 10:13:19 -0600942 bufferSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
943 true);
944 bufferSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
chaviw7e72caf2020-12-02 16:50:43 -0800945
946 surface->showAt(10, 10);
947 bufferSurface->showAt(50, 50, Rect::EMPTY_RECT);
948
949 injectTap(11, 11);
950 surface->expectTap(1, 1);
951}
952
Vishnu Naira066d902021-09-13 18:40:17 -0700953TEST_F(InputSurfacesTest, strict_unobscured_input_unobscured_window) {
954 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
955 surface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +0800956 [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
Vishnu Naira066d902021-09-13 18:40:17 -0700957 surface->showAt(100, 100);
958
959 injectTap(101, 101);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -0700960 surface->expectTap(1, 1);
Vishnu Naira066d902021-09-13 18:40:17 -0700961
962 surface->requestFocus();
963 surface->assertFocusChange(true);
964 injectKey(AKEYCODE_V);
965 surface->expectKey(AKEYCODE_V);
966}
967
968TEST_F(InputSurfacesTest, strict_unobscured_input_scaled_without_crop_window) {
969 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +0800970 surface->doTransaction([&](auto& t, auto& sc) {
Vishnu Naira066d902021-09-13 18:40:17 -0700971 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
972 t.setMatrix(sc, 2.0, 0, 0, 2.0);
973 });
974 surface->showAt(100, 100);
975
976 injectTap(101, 101);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -0700977 surface->expectTap(.5, .5);
Vishnu Naira066d902021-09-13 18:40:17 -0700978
979 surface->requestFocus();
980 surface->assertFocusChange(true);
981 injectKey(AKEYCODE_V);
982 surface->expectKey(AKEYCODE_V);
983}
984
985TEST_F(InputSurfacesTest, strict_unobscured_input_obscured_window) {
Arpit Singha9ec7d42024-12-04 14:34:05 +0000986 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
Patrick Williams87602162024-11-05 10:13:19 -0600987 surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
Vishnu Naira066d902021-09-13 18:40:17 -0700988 surface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +0800989 [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
Vishnu Naira066d902021-09-13 18:40:17 -0700990 surface->showAt(100, 100);
Arpit Singha9ec7d42024-12-04 14:34:05 +0000991 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100, "Obscuring Surface");
Patrick Williams87602162024-11-05 10:13:19 -0600992 obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
993 true);
994 obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
Vishnu Naira066d902021-09-13 18:40:17 -0700995 obscuringSurface->showAt(100, 100);
996 injectTap(101, 101);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -0700997 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -0700998
999 surface->requestFocus();
1000 surface->assertFocusChange(true);
1001 injectKey(AKEYCODE_V);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001002 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001003}
1004
1005TEST_F(InputSurfacesTest, strict_unobscured_input_partially_obscured_window) {
Arpit Singha9ec7d42024-12-04 14:34:05 +00001006 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
Patrick Williams87602162024-11-05 10:13:19 -06001007 surface->mInputInfo->editInfo()->ownerUid = gui::Uid{11111};
Vishnu Naira066d902021-09-13 18:40:17 -07001008 surface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +08001009 [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::OBSCURED); });
Vishnu Naira066d902021-09-13 18:40:17 -07001010 surface->showAt(100, 100);
Arpit Singha9ec7d42024-12-04 14:34:05 +00001011 std::unique_ptr<InputSurface> obscuringSurface = makeSurface(100, 100, "Obscuring Surface");
Patrick Williams87602162024-11-05 10:13:19 -06001012 obscuringSurface->mInputInfo->editInfo()->setInputConfig(WindowInfo::InputConfig::NOT_TOUCHABLE,
1013 true);
1014 obscuringSurface->mInputInfo->editInfo()->ownerUid = gui::Uid{22222};
Vishnu Naira066d902021-09-13 18:40:17 -07001015 obscuringSurface->showAt(190, 190);
1016
1017 injectTap(101, 101);
1018
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001019 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001020
1021 surface->requestFocus();
1022 surface->assertFocusChange(true);
1023 injectKey(AKEYCODE_V);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001024 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001025}
1026
1027TEST_F(InputSurfacesTest, strict_unobscured_input_alpha_window) {
Arpit Singha9ec7d42024-12-04 14:34:05 +00001028 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300, "Parent Surface");
Vishnu Naira066d902021-09-13 18:40:17 -07001029 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
1030
Arpit Singha9ec7d42024-12-04 14:34:05 +00001031 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
Vishnu Naira066d902021-09-13 18:40:17 -07001032 surface->showAt(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +08001033 surface->doTransaction([&](auto& t, auto& sc) {
Vishnu Naira066d902021-09-13 18:40:17 -07001034 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
1035 t.reparent(sc, parentSurface->mSurfaceControl);
1036 t.setAlpha(parentSurface->mSurfaceControl, 0.9f);
1037 });
1038
1039 injectTap(101, 101);
1040
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001041 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001042
1043 surface->requestFocus();
1044 surface->assertFocusChange(true);
1045 injectKey(AKEYCODE_V);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001046 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001047}
1048
1049TEST_F(InputSurfacesTest, strict_unobscured_input_cropped_window) {
Arpit Singha9ec7d42024-12-04 14:34:05 +00001050 std::unique_ptr<InputSurface> parentSurface = makeSurface(300, 300, "Parent Surface");
Vishnu Naira066d902021-09-13 18:40:17 -07001051 parentSurface->showAt(0, 0, Rect(0, 0, 300, 300));
1052
Arpit Singha9ec7d42024-12-04 14:34:05 +00001053 std::unique_ptr<InputSurface> surface = makeSurface(100, 100, "Test Surface");
Linnan Li13bf76a2024-05-05 19:18:02 +08001054 surface->doTransaction([&](auto& t, auto& sc) {
Vishnu Naira066d902021-09-13 18:40:17 -07001055 t.setDropInputMode(sc, gui::DropInputMode::OBSCURED);
1056 t.reparent(sc, parentSurface->mSurfaceControl);
1057 t.setCrop(parentSurface->mSurfaceControl, Rect(10, 10, 100, 100));
1058 });
1059 surface->showAt(100, 100);
1060
1061 injectTap(111, 111);
1062
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001063 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001064
1065 surface->requestFocus();
1066 surface->assertFocusChange(true);
1067 injectKey(AKEYCODE_V);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001068 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001069}
1070
Arthur Hung49d525a2021-11-19 15:11:51 +00001071TEST_F(InputSurfacesTest, ignore_touch_region_with_zero_sized_blast) {
1072 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1073
1074 std::unique_ptr<BlastInputSurface> bufferSurface =
1075 BlastInputSurface::makeBlastInputSurface(mComposerClient, 0, 0);
1076
1077 surface->showAt(100, 100);
Patrick Williams87602162024-11-05 10:13:19 -06001078 bufferSurface->mInputInfo->editInfo()->touchableRegion.orSelf(Rect(0, 0, 200, 200));
Arthur Hung49d525a2021-11-19 15:11:51 +00001079 bufferSurface->showAt(100, 100, Rect::EMPTY_RECT);
1080
1081 injectTap(101, 101);
1082 surface->expectTap(1, 1);
1083}
1084
Vishnu Naira066d902021-09-13 18:40:17 -07001085TEST_F(InputSurfacesTest, drop_input_policy) {
1086 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
1087 surface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +08001088 [&](auto& t, auto& sc) { t.setDropInputMode(sc, gui::DropInputMode::ALL); });
Vishnu Naira066d902021-09-13 18:40:17 -07001089 surface->showAt(100, 100);
1090
1091 injectTap(101, 101);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001092 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001093
1094 surface->requestFocus();
1095 surface->assertFocusChange(true);
1096 injectKey(AKEYCODE_V);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001097 surface->assertNoEvent();
Vishnu Naira066d902021-09-13 18:40:17 -07001098}
Vishnu Nair16a938f2021-09-24 07:14:54 -07001099
Prabir Pradhan8c285982022-01-28 09:19:39 -08001100TEST_F(InputSurfacesTest, layer_with_valid_crop_can_be_focused) {
1101 std::unique_ptr<InputSurface> bufferSurface =
1102 InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
1103
1104 bufferSurface->showAt(50, 50, Rect{0, 0, 100, 100});
1105
1106 bufferSurface->requestFocus();
1107 bufferSurface->assertFocusChange(true);
1108}
1109
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001110/**
1111 * If a cropped layer's touchable region is replaced with a null crop, it should receive input in
1112 * its own crop.
1113 */
1114TEST_F(InputSurfacesTest, cropped_container_replaces_touchable_region_with_null_crop) {
1115 std::unique_ptr<InputSurface> parentContainer =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001116 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1117 "Parent Container Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001118 std::unique_ptr<InputSurface> containerSurface =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001119 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100,
1120 "Test Container Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001121 containerSurface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +08001122 [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
Patrick Williams87602162024-11-05 10:13:19 -06001123 containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1124 containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001125 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1126 containerSurface->showAt(10, 10, Rect(0, 0, 5, 5));
1127
1128 // Receives events inside its own crop
1129 injectTap(21, 21);
1130 containerSurface->expectTap(1, 1); // Event is in layer space
1131
1132 // Does not receive events outside its crop
1133 injectTap(26, 26);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001134 containerSurface->assertNoEvent();
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001135}
1136
1137/**
1138 * If an un-cropped layer's touchable region is replaced with a null crop, it should receive input
1139 * in its parent's touchable region. The input events should be in the layer's coordinate space.
1140 */
1141TEST_F(InputSurfacesTest, uncropped_container_replaces_touchable_region_with_null_crop) {
Prabir Pradhan56d55bc2024-10-28 21:00:30 +00001142 std::unique_ptr<InputSurface> bgContainer =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001143 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1144 "Background Container Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001145 std::unique_ptr<InputSurface> parentContainer =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001146 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0,
1147 "Parent Container Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001148 std::unique_ptr<InputSurface> containerSurface =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001149 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100,
1150 "Test Container Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001151 containerSurface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +08001152 [&](auto& t, auto& sc) { t.reparent(sc, parentContainer->mSurfaceControl); });
Patrick Williams87602162024-11-05 10:13:19 -06001153 containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1154 containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle = nullptr;
Prabir Pradhan56d55bc2024-10-28 21:00:30 +00001155 parentContainer->doTransaction(
1156 [&](auto& t, auto& sc) { t.reparent(sc, bgContainer->mSurfaceControl); });
1157 bgContainer->showAt(0, 0, Rect(0, 0, 100, 100));
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001158 parentContainer->showAt(10, 10, Rect(0, 0, 20, 20));
1159 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1160
1161 // Receives events inside parent bounds
1162 injectTap(21, 21);
1163 containerSurface->expectTap(1, 1); // Event is in layer space
1164
1165 // Does not receive events outside parent bounds
1166 injectTap(31, 31);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001167 containerSurface->assertNoEvent();
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001168}
1169
1170/**
1171 * If a layer's touchable region is replaced with a layer crop, it should receive input in the crop
1172 * layer's bounds. The input events should be in the layer's coordinate space.
1173 */
1174TEST_F(InputSurfacesTest, replace_touchable_region_with_crop) {
1175 std::unique_ptr<InputSurface> cropLayer =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001176 InputSurface::makeContainerInputSurface(mComposerClient, 0, 0, "Crop Layer Surface");
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001177 cropLayer->showAt(50, 50, Rect(0, 0, 20, 20));
1178
1179 std::unique_ptr<InputSurface> containerSurface =
Arpit Singha9ec7d42024-12-04 14:34:05 +00001180 InputSurface::makeContainerInputSurface(mComposerClient, 100, 100, "Container Surface");
Patrick Williams87602162024-11-05 10:13:19 -06001181 containerSurface->mInputInfo->editInfo()->replaceTouchableRegionWithCrop = true;
1182 containerSurface->mInputInfo->editInfo()->touchableRegionCropHandle =
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001183 cropLayer->mSurfaceControl->getHandle();
1184 containerSurface->showAt(10, 10, Rect::INVALID_RECT);
1185
1186 // Receives events inside crop layer bounds
1187 injectTap(51, 51);
1188 containerSurface->expectTap(41, 41); // Event is in layer space
1189
1190 // Does not receive events outside crop layer bounds
1191 injectTap(21, 21);
1192 injectTap(71, 71);
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001193 containerSurface->assertNoEvent();
Prabir Pradhan6fa425a2021-12-16 07:16:04 -08001194}
1195
Linus Tufvessona1858822022-03-04 09:32:07 +00001196TEST_F(InputSurfacesTest, child_container_with_no_input_channel_blocks_parent) {
1197 std::unique_ptr<InputSurface> parent = makeSurface(100, 100);
1198
1199 parent->showAt(100, 100);
1200 injectTap(101, 101);
1201 parent->expectTap(1, 1);
1202
1203 std::unique_ptr<InputSurface> childContainerSurface =
1204 InputSurface::makeContainerInputSurfaceNoInputChannel(mComposerClient, 100, 100);
1205 childContainerSurface->showAt(0, 0);
1206 childContainerSurface->doTransaction(
Linnan Li13bf76a2024-05-05 19:18:02 +08001207 [&](auto& t, auto& sc) { t.reparent(sc, parent->mSurfaceControl); });
Linus Tufvessona1858822022-03-04 09:32:07 +00001208 injectTap(101, 101);
1209
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001210 parent->assertNoEvent();
Linus Tufvessona1858822022-03-04 09:32:07 +00001211}
1212
Vishnu Nair16a938f2021-09-24 07:14:54 -07001213class MultiDisplayTests : public InputSurfacesTest {
1214public:
1215 MultiDisplayTests() : InputSurfacesTest() { ProcessState::self()->startThreadPool(); }
Linnan Li13bf76a2024-05-05 19:18:02 +08001216
Prabir Pradhand0aba782021-12-14 00:44:21 -08001217 void TearDown() override {
Alan Dingd53801c2024-05-08 16:45:29 -07001218 std::for_each(mVirtualDisplays.begin(), mVirtualDisplays.end(),
1219 SurfaceComposerClient::destroyVirtualDisplay);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001220 InputSurfacesTest::TearDown();
1221 }
1222
Prabir Pradhand0aba782021-12-14 00:44:21 -08001223 void createDisplay(int32_t width, int32_t height, bool isSecure, ui::LayerStack layerStack,
1224 bool receivesInput = true, int32_t offsetX = 0, int32_t offsetY = 0) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001225 sp<IGraphicBufferConsumer> consumer;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001226 sp<IGraphicBufferProducer> producer;
1227 BufferQueue::createBufferQueue(&producer, &consumer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001228 consumer->setConsumerName(String8("Virtual disp consumer"));
1229 consumer->setDefaultBufferSize(width, height);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001230 mProducers.push_back(producer);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001231
Prabir Pradhand0aba782021-12-14 00:44:21 -08001232 std::string name = "VirtualDisplay";
1233 name += std::to_string(mVirtualDisplays.size());
Alan Dingd53801c2024-05-08 16:45:29 -07001234 sp<IBinder> token = SurfaceComposerClient::createVirtualDisplay(name, isSecure);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001235 SurfaceComposerClient::Transaction t;
Prabir Pradhand0aba782021-12-14 00:44:21 -08001236 t.setDisplaySurface(token, producer);
1237 t.setDisplayFlags(token, receivesInput ? 0x01 /* DisplayDevice::eReceivesInput */ : 0);
1238 t.setDisplayLayerStack(token, layerStack);
1239 t.setDisplayProjection(token, ui::ROTATION_0, {0, 0, width, height},
1240 {offsetX, offsetY, offsetX + width, offsetY + height});
Prabir Pradhana97fd942024-10-28 21:21:53 +00001241 t.apply(/*synchronously=*/true);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001242
1243 mVirtualDisplays.push_back(token);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001244 }
1245
Prabir Pradhand0aba782021-12-14 00:44:21 -08001246 std::vector<sp<IBinder>> mVirtualDisplays;
1247 std::vector<sp<IGraphicBufferProducer>> mProducers;
Vishnu Nair16a938f2021-09-24 07:14:54 -07001248};
1249
Prabir Pradhanda0f62c2022-07-22 19:53:04 +00001250TEST_F(MultiDisplayTests, drop_touch_if_layer_on_invalid_display) {
Prabir Pradhand0aba782021-12-14 00:44:21 -08001251 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1252 // Do not create a display associated with the LayerStack.
1253 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +08001254 surface->doTransaction([&](auto& t, auto& sc) { t.setLayerStack(sc, layerStack); });
Prabir Pradhand0aba782021-12-14 00:44:21 -08001255 surface->showAt(100, 100);
1256
Prabir Pradhanda0f62c2022-07-22 19:53:04 +00001257 // Touches should be dropped if the layer is on an invalid display.
Linnan Li13bf76a2024-05-05 19:18:02 +08001258 injectTapOnDisplay(101, 101, toDisplayId(layerStack));
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001259 surface->assertNoEvent();
Prabir Pradhanda0f62c2022-07-22 19:53:04 +00001260
1261 // However, we still let the window be focused and receive keys.
Linnan Li13bf76a2024-05-05 19:18:02 +08001262 surface->requestFocus(toDisplayId(layerStack));
Prabir Pradhanda0f62c2022-07-22 19:53:04 +00001263 surface->assertFocusChange(true);
1264
Linnan Li13bf76a2024-05-05 19:18:02 +08001265 injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
Prabir Pradhanda0f62c2022-07-22 19:53:04 +00001266 surface->expectKey(AKEYCODE_V);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001267}
1268
1269TEST_F(MultiDisplayTests, virtual_display_receives_input) {
1270 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1271 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1272 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +08001273 surface->doTransaction([&](auto& t, auto& sc) { t.setLayerStack(sc, layerStack); });
Prabir Pradhand0aba782021-12-14 00:44:21 -08001274 surface->showAt(100, 100);
1275
Linnan Li13bf76a2024-05-05 19:18:02 +08001276 injectTapOnDisplay(101, 101, toDisplayId(layerStack));
Prabir Pradhand0aba782021-12-14 00:44:21 -08001277 surface->expectTap(1, 1);
1278
Linnan Li13bf76a2024-05-05 19:18:02 +08001279 surface->requestFocus(toDisplayId(layerStack));
Prabir Pradhand0aba782021-12-14 00:44:21 -08001280 surface->assertFocusChange(true);
Linnan Li13bf76a2024-05-05 19:18:02 +08001281 injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
Prabir Pradhand0aba782021-12-14 00:44:21 -08001282 surface->expectKey(AKEYCODE_V);
1283}
1284
Vishnu Nair16a938f2021-09-24 07:14:54 -07001285TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
1286 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
1287 createDisplay(1000, 1000, false /*isSecure*/, layerStack);
1288 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +08001289 surface->doTransaction([&](auto& t, auto& sc) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001290 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1291 t.setLayerStack(sc, layerStack);
1292 });
1293 surface->showAt(100, 100);
1294
Linnan Li13bf76a2024-05-05 19:18:02 +08001295 injectTapOnDisplay(101, 101, toDisplayId(layerStack));
Vishnu Nair16a938f2021-09-24 07:14:54 -07001296
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001297 surface->assertNoEvent();
Vishnu Nair16a938f2021-09-24 07:14:54 -07001298
Linnan Li13bf76a2024-05-05 19:18:02 +08001299 surface->requestFocus(toDisplayId(layerStack));
Vishnu Nair16a938f2021-09-24 07:14:54 -07001300 surface->assertFocusChange(true);
Linnan Li13bf76a2024-05-05 19:18:02 +08001301 injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001302 surface->assertNoEvent();
Vishnu Nair16a938f2021-09-24 07:14:54 -07001303}
1304
1305TEST_F(MultiDisplayTests, dont_drop_input_for_secure_layer_on_secure_display) {
1306 ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001307
1308 // Create the secure display as system, because only certain users can create secure displays.
1309 seteuid(AID_SYSTEM);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001310 createDisplay(1000, 1000, true /*isSecure*/, layerStack);
Prabir Pradhand0aba782021-12-14 00:44:21 -08001311 // Change the uid back to root.
1312 seteuid(AID_ROOT);
1313
Vishnu Nair16a938f2021-09-24 07:14:54 -07001314 std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
Linnan Li13bf76a2024-05-05 19:18:02 +08001315 surface->doTransaction([&](auto& t, auto& sc) {
Vishnu Nair16a938f2021-09-24 07:14:54 -07001316 t.setFlags(sc, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure);
1317 t.setLayerStack(sc, layerStack);
1318 });
1319 surface->showAt(100, 100);
1320
Linnan Li13bf76a2024-05-05 19:18:02 +08001321 injectTapOnDisplay(101, 101, toDisplayId(layerStack));
Siarhei Vishniakou7b3fda32024-03-29 14:27:49 -07001322 surface->expectTap(1, 1);
Vishnu Nair16a938f2021-09-24 07:14:54 -07001323
Linnan Li13bf76a2024-05-05 19:18:02 +08001324 surface->requestFocus(toDisplayId(layerStack));
Vishnu Nair16a938f2021-09-24 07:14:54 -07001325 surface->assertFocusChange(true);
Linnan Li13bf76a2024-05-05 19:18:02 +08001326 injectKeyOnDisplay(AKEYCODE_V, toDisplayId(layerStack));
Vishnu Nair16a938f2021-09-24 07:14:54 -07001327
1328 surface->expectKey(AKEYCODE_V);
1329}
1330
Linnan Li13bf76a2024-05-05 19:18:02 +08001331} // namespace test
1332} // namespace android