blob: ab86196af4b697db4ca1aebc59508ac28b4da314 [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}
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}
50
chaviw98318de2021-05-19 16:45:23 -050051void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
Garfield Tane84e6f92019-08-29 17:28:41 -070052 BitSet32 pointerIds) {
53 if (targetFlags & InputTarget::FLAG_SPLIT) {
54 split = true;
55 }
56
57 for (size_t i = 0; i < windows.size(); i++) {
58 TouchedWindow& touchedWindow = windows[i];
59 if (touchedWindow.windowHandle == windowHandle) {
60 touchedWindow.targetFlags |= targetFlags;
61 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
62 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
63 }
64 touchedWindow.pointerIds.value |= pointerIds.value;
65 return;
66 }
67 }
68
69 TouchedWindow touchedWindow;
70 touchedWindow.windowHandle = windowHandle;
71 touchedWindow.targetFlags = targetFlags;
72 touchedWindow.pointerIds = pointerIds;
73 windows.push_back(touchedWindow);
74}
75
Garfield Tane84e6f92019-08-29 17:28:41 -070076void TouchState::removeWindowByToken(const sp<IBinder>& token) {
77 for (size_t i = 0; i < windows.size(); i++) {
78 if (windows[i].windowHandle->getToken() == token) {
79 windows.erase(windows.begin() + i);
80 return;
81 }
82 }
83}
84
85void TouchState::filterNonAsIsTouchWindows() {
86 for (size_t i = 0; i < windows.size();) {
87 TouchedWindow& window = windows[i];
88 if (window.targetFlags &
89 (InputTarget::FLAG_DISPATCH_AS_IS | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
90 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
91 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
92 i += 1;
93 } else {
94 windows.erase(windows.begin() + i);
95 }
96 }
97}
98
Prabir Pradhan07e05b62021-11-19 03:57:24 -080099void TouchState::filterWindowsExcept(const sp<IBinder>& token) {
Siarhei Vishniakouf47c339e2021-12-30 11:22:26 -0800100 std::erase_if(windows,
101 [&token](const TouchedWindow& w) { return w.windowHandle->getToken() != token; });
Garfield Tane84e6f92019-08-29 17:28:41 -0700102}
103
chaviw98318de2021-05-19 16:45:23 -0500104sp<WindowInfoHandle> TouchState::getFirstForegroundWindowHandle() const {
Garfield Tane84e6f92019-08-29 17:28:41 -0700105 for (size_t i = 0; i < windows.size(); i++) {
106 const TouchedWindow& window = windows[i];
107 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
108 return window.windowHandle;
109 }
110 }
111 return nullptr;
112}
113
114bool TouchState::isSlippery() const {
115 // Must have exactly one foreground window.
116 bool haveSlipperyForegroundWindow = false;
117 for (const TouchedWindow& window : windows) {
118 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
119 if (haveSlipperyForegroundWindow ||
chaviw98318de2021-05-19 16:45:23 -0500120 !window.windowHandle->getInfo()->flags.test(WindowInfo::Flag::SLIPPERY)) {
Garfield Tane84e6f92019-08-29 17:28:41 -0700121 return false;
122 }
123 haveSlipperyForegroundWindow = true;
124 }
125 }
126 return haveSlipperyForegroundWindow;
127}
128
Siarhei Vishniakouca205502021-07-16 21:31:58 +0000129sp<WindowInfoHandle> TouchState::getWallpaperWindow() const {
130 for (size_t i = 0; i < windows.size(); i++) {
131 const TouchedWindow& window = windows[i];
132 if (window.windowHandle->getInfo()->type == WindowInfo::Type::WALLPAPER) {
133 return window.windowHandle;
134 }
135 }
136 return nullptr;
137}
138
Prabir Pradhan07e05b62021-11-19 03:57:24 -0800139sp<WindowInfoHandle> TouchState::getWindow(const sp<IBinder>& token) const {
140 for (const TouchedWindow& touchedWindow : windows) {
141 const auto& windowHandle = touchedWindow.windowHandle;
142 if (windowHandle->getToken() == token) {
143 return windowHandle;
144 }
145 }
146 return nullptr;
147}
148
Garfield Tane84e6f92019-08-29 17:28:41 -0700149} // namespace android::inputdispatcher