blob: 3aabfc7e14e430944da51d915918e3bc2ed33805 [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
17#include <input/InputWindow.h>
18
19#include "InputTarget.h"
20
21#include "TouchState.h"
22
23using android::InputWindowHandle;
24
25namespace android::inputdispatcher {
26
27TouchState::TouchState()
28 : down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {}
29
30TouchState::~TouchState() {}
31
32void TouchState::reset() {
33 down = false;
34 split = false;
35 deviceId = -1;
36 source = 0;
37 displayId = ADISPLAY_ID_NONE;
38 windows.clear();
Garfield Tane84e6f92019-08-29 17:28:41 -070039 gestureMonitors.clear();
40}
41
42void TouchState::copyFrom(const TouchState& other) {
43 down = other.down;
44 split = other.split;
45 deviceId = other.deviceId;
46 source = other.source;
47 displayId = other.displayId;
48 windows = other.windows;
Garfield Tane84e6f92019-08-29 17:28:41 -070049 gestureMonitors = other.gestureMonitors;
50}
51
52void TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
53 BitSet32 pointerIds) {
54 if (targetFlags & InputTarget::FLAG_SPLIT) {
55 split = true;
56 }
57
58 for (size_t i = 0; i < windows.size(); i++) {
59 TouchedWindow& touchedWindow = windows[i];
60 if (touchedWindow.windowHandle == windowHandle) {
61 touchedWindow.targetFlags |= targetFlags;
62 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
63 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
64 }
65 touchedWindow.pointerIds.value |= pointerIds.value;
66 return;
67 }
68 }
69
70 TouchedWindow touchedWindow;
71 touchedWindow.windowHandle = windowHandle;
72 touchedWindow.targetFlags = targetFlags;
73 touchedWindow.pointerIds = pointerIds;
74 windows.push_back(touchedWindow);
75}
76
Garfield Tane84e6f92019-08-29 17:28:41 -070077void TouchState::addGestureMonitors(const std::vector<TouchedMonitor>& newMonitors) {
78 const size_t newSize = gestureMonitors.size() + newMonitors.size();
79 gestureMonitors.reserve(newSize);
80 gestureMonitors.insert(std::end(gestureMonitors), std::begin(newMonitors),
81 std::end(newMonitors));
82}
83
Garfield Tane84e6f92019-08-29 17:28:41 -070084void TouchState::removeWindowByToken(const sp<IBinder>& token) {
85 for (size_t i = 0; i < windows.size(); i++) {
86 if (windows[i].windowHandle->getToken() == token) {
87 windows.erase(windows.begin() + i);
88 return;
89 }
90 }
91}
92
93void TouchState::filterNonAsIsTouchWindows() {
94 for (size_t i = 0; i < windows.size();) {
95 TouchedWindow& window = windows[i];
96 if (window.targetFlags &
97 (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
98 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
99 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
100 i += 1;
101 } else {
102 windows.erase(windows.begin() + i);
103 }
104 }
105}
106
107void TouchState::filterNonMonitors() {
108 windows.clear();
Garfield Tane84e6f92019-08-29 17:28:41 -0700109}
110
111sp<InputWindowHandle> TouchState::getFirstForegroundWindowHandle() const {
112 for (size_t i = 0; i < windows.size(); i++) {
113 const TouchedWindow& window = windows[i];
114 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
115 return window.windowHandle;
116 }
117 }
118 return nullptr;
119}
120
121bool TouchState::isSlippery() const {
122 // Must have exactly one foreground window.
123 bool haveSlipperyForegroundWindow = false;
124 for (const TouchedWindow& window : windows) {
125 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
126 if (haveSlipperyForegroundWindow ||
Michael Wright44753b12020-07-08 13:48:11 +0100127 !window.windowHandle->getInfo()->flags.test(InputWindowInfo::Flag::SLIPPERY)) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700128 return false;
129 }
130 haveSlipperyForegroundWindow = true;
131 }
132 }
133 return haveSlipperyForegroundWindow;
134}
135
136} // namespace android::inputdispatcher