blob: d624e99acfd7588d232e214b311806a5f881e31f [file] [log] [blame]
Garfield Tane84e6f92019-08-29 17:28:41 -07001/*
2 * Copyright (C) 2019 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
chaviw98318de2021-05-19 16:45:23 -050017#include <gui/WindowInfo.h>
Garfield Tane84e6f92019-08-29 17:28:41 -070018
19#include "InputTarget.h"
20
21#include "TouchState.h"
22
chaviw98318de2021-05-19 16:45:23 -050023using android::gui::WindowInfo;
24using android::gui::WindowInfoHandle;
Garfield Tane84e6f92019-08-29 17:28:41 -070025
26namespace android::inputdispatcher {
27
28TouchState::TouchState()
29 : down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {}
30
31TouchState::~TouchState() {}
32
33void TouchState::reset() {
34 down = false;
35 split = false;
36 deviceId = -1;
37 source = 0;
38 displayId = ADISPLAY_ID_NONE;
39 windows.clear();
Garfield Tane84e6f92019-08-29 17:28:41 -070040 gestureMonitors.clear();
41}
42
43void TouchState::copyFrom(const TouchState& other) {
44 down = other.down;
45 split = other.split;
46 deviceId = other.deviceId;
47 source = other.source;
48 displayId = other.displayId;
49 windows = other.windows;
Garfield Tane84e6f92019-08-29 17:28:41 -070050 gestureMonitors = other.gestureMonitors;
51}
52
chaviw98318de2021-05-19 16:45:23 -050053void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
Garfield Tane84e6f92019-08-29 17:28:41 -070054 BitSet32 pointerIds) {
55 if (targetFlags & InputTarget::FLAG_SPLIT) {
56 split = true;
57 }
58
59 for (size_t i = 0; i < windows.size(); i++) {
60 TouchedWindow& touchedWindow = windows[i];
61 if (touchedWindow.windowHandle == windowHandle) {
62 touchedWindow.targetFlags |= targetFlags;
63 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
64 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
65 }
66 touchedWindow.pointerIds.value |= pointerIds.value;
67 return;
68 }
69 }
70
71 TouchedWindow touchedWindow;
72 touchedWindow.windowHandle = windowHandle;
73 touchedWindow.targetFlags = targetFlags;
74 touchedWindow.pointerIds = pointerIds;
75 windows.push_back(touchedWindow);
76}
77
Prabir Pradhan0a99c922021-09-03 08:27:53 -070078void TouchState::addGestureMonitors(const std::vector<Monitor>& newMonitors) {
Garfield Tane84e6f92019-08-29 17:28:41 -070079 const size_t newSize = gestureMonitors.size() + newMonitors.size();
80 gestureMonitors.reserve(newSize);
81 gestureMonitors.insert(std::end(gestureMonitors), std::begin(newMonitors),
82 std::end(newMonitors));
83}
84
Garfield Tane84e6f92019-08-29 17:28:41 -070085void TouchState::removeWindowByToken(const sp<IBinder>& token) {
86 for (size_t i = 0; i < windows.size(); i++) {
87 if (windows[i].windowHandle->getToken() == token) {
88 windows.erase(windows.begin() + i);
89 return;
90 }
91 }
92}
93
94void TouchState::filterNonAsIsTouchWindows() {
95 for (size_t i = 0; i < windows.size();) {
96 TouchedWindow& window = windows[i];
97 if (window.targetFlags &
98 (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
99 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
100 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
101 i += 1;
102 } else {
103 windows.erase(windows.begin() + i);
104 }
105 }
106}
107
Prabir Pradhan07e05b62021-11-19 03:57:24 -0800108void TouchState::filterWindowsExcept(const sp<IBinder>& token) {
109 auto it = std::remove_if(windows.begin(), windows.end(), [&token](const TouchedWindow& w) {
110 return w.windowHandle->getToken() != token;
111 });
112 windows.erase(it, windows.end());
Garfield Tane84e6f92019-08-29 17:28:41 -0700113}
114
chaviw98318de2021-05-19 16:45:23 -0500115sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700116 for (size_t i = 0; i < windows.size(); i++) {
117 const TouchedWindow& window = windows[i];
118 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
119 return window.windowHandle;
120 }
121 }
122 return nullptr;
123}
124
125bool TouchState::isSlippery() const {
126 // Must have exactly one foreground window.
127 bool haveSlipperyForegroundWindow = false;
128 for (const TouchedWindow& window : windows) {
129 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
130 if (haveSlipperyForegroundWindow ||
chaviw98318de2021-05-19 16:45:23 -0500131 !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700132 return false;
133 }
134 haveSlipperyForegroundWindow = true;
135 }
136 }
137 return haveSlipperyForegroundWindow;
138}
139
Siarhei Vishniakouca205502021-07-16 21:31:58 +0000140sp<WindowInfoHandle> TouchState::getWallpaperWindow() const {
141 for (size_t i = 0; i < windows.size(); i++) {
142 const TouchedWindow& window = windows[i];
143 if (window.windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
144 return window.windowHandle;
145 }
146 }
147 return nullptr;
148}
149
Prabir Pradhan07e05b62021-11-19 03:57:24 -0800150sp<WindowInfoHandle> TouchState::getWindow(const sp<IBinder>& token) const {
151 for (const TouchedWindow& touchedWindow : windows) {
152 const auto& windowHandle = touchedWindow.windowHandle;
153 if (windowHandle->getToken() == token) {
154 return windowHandle;
155 }
156 }
157 return nullptr;
158}
159
Garfield Tane84e6f92019-08-29 17:28:41 -0700160} // namespace android::inputdispatcher