blob: 08c7826045e4f21a0eb586b640a57f815933b39b [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) {
Siarhei Vishniakouf47c339e2021-12-30 11:22:26 -0800109 std::erase_if(windows,
110 [&token](const TouchedWindow& w) { return w.windowHandle->getToken() != token; });
Garfield Tane84e6f92019-08-29 17:28:41 -0700111}
112
chaviw98318de2021-05-19 16:45:23 -0500113sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700114 for (size_t i = 0; i < windows.size(); i++) {
115 const TouchedWindow& window = windows[i];
116 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
117 return window.windowHandle;
118 }
119 }
120 return nullptr;
121}
122
123bool TouchState::isSlippery() const {
124 // Must have exactly one foreground window.
125 bool haveSlipperyForegroundWindow = false;
126 for (const TouchedWindow& window : windows) {
127 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
128 if (haveSlipperyForegroundWindow ||
chaviw98318de2021-05-19 16:45:23 -0500129 !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700130 return false;
131 }
132 haveSlipperyForegroundWindow = true;
133 }
134 }
135 return haveSlipperyForegroundWindow;
136}
137
Siarhei Vishniakouca205502021-07-16 21:31:58 +0000138sp<WindowInfoHandle> TouchState::getWallpaperWindow() const {
139 for (size_t i = 0; i < windows.size(); i++) {
140 const TouchedWindow& window = windows[i];
141 if (window.windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
142 return window.windowHandle;
143 }
144 }
145 return nullptr;
146}
147
Prabir Pradhan07e05b62021-11-19 03:57:24 -0800148sp<WindowInfoHandle> TouchState::getWindow(const sp<IBinder>& token) const {
149 for (const TouchedWindow& touchedWindow : windows) {
150 const auto& windowHandle = touchedWindow.windowHandle;
151 if (windowHandle->getToken() == token) {
152 return windowHandle;
153 }
154 }
155 return nullptr;
156}
157
Garfield Tane84e6f92019-08-29 17:28:41 -0700158} // namespace android::inputdispatcher