blob: 759b3e7097ceee6dfbf1bcf51875bbc16134ea0d [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
108void TouchState::filterNonMonitors() {
109 windows.clear();
Garfield Tane84e6f92019-08-29 17:28:41 -0700110}
111
chaviw98318de2021-05-19 16:45:23 -0500112sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700113 for (size_t i = 0; i < windows.size(); i++) {
114 const TouchedWindow& window = windows[i];
115 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
116 return window.windowHandle;
117 }
118 }
119 return nullptr;
120}
121
122bool TouchState::isSlippery() const {
123 // Must have exactly one foreground window.
124 bool haveSlipperyForegroundWindow = false;
125 for (const TouchedWindow& window : windows) {
126 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
127 if (haveSlipperyForegroundWindow ||
chaviw98318de2021-05-19 16:45:23 -0500128 !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700129 return false;
130 }
131 haveSlipperyForegroundWindow = true;
132 }
133 }
134 return haveSlipperyForegroundWindow;
135}
136
Siarhei Vishniakouca205502021-07-16 21:31:58 +0000137sp<WindowInfoHandle> TouchState::getWallpaperWindow() const {
138 for (size_t i = 0; i < windows.size(); i++) {
139 const TouchedWindow& window = windows[i];
140 if (window.windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
141 return window.windowHandle;
142 }
143 }
144 return nullptr;
145}
146
Garfield Tane84e6f92019-08-29 17:28:41 -0700147} // namespace android::inputdispatcher