blob: cd0500c8722af8270cec94e0bf327f101c28a50e [file] [log] [blame]
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -08001/*
2 * Copyright (C) 2022 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 "TouchedWindow.h"
18
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070019#include <android-base/logging.h>
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -080020#include <android-base/stringprintf.h>
21#include <input/PrintTools.h>
22
23using android::base::StringPrintf;
24
25namespace android {
26
27namespace inputdispatcher {
28
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000029bool TouchedWindow::hasHoveringPointers() const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070030 for (const auto& [_, state] : mDeviceStates) {
31 if (state.hoveringPointerIds.any()) {
32 return true;
33 }
34 }
35 return false;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000036}
37
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070038bool TouchedWindow::hasHoveringPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070039 const auto stateIt = mDeviceStates.find(deviceId);
40 if (stateIt == mDeviceStates.end()) {
41 return false;
42 }
43 const DeviceState& state = stateIt->second;
44
45 return state.hoveringPointerIds.any();
Siarhei Vishniakoue0431e42023-01-28 17:01:39 -080046}
47
Siarhei Vishniakou2899c552023-07-10 18:20:46 -070048void TouchedWindow::clearHoveringPointers(DeviceId deviceId) {
49 auto stateIt = mDeviceStates.find(deviceId);
50 if (stateIt == mDeviceStates.end()) {
51 return;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070052 }
Siarhei Vishniakou2899c552023-07-10 18:20:46 -070053 DeviceState& state = stateIt->second;
54 state.hoveringPointerIds.reset();
55 if (!state.hasPointers()) {
56 mDeviceStates.erase(stateIt);
57 }
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000058}
59
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070060bool TouchedWindow::hasHoveringPointer(DeviceId deviceId, int32_t pointerId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070061 const auto stateIt = mDeviceStates.find(deviceId);
62 if (stateIt == mDeviceStates.end()) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000063 return false;
64 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070065 const DeviceState& state = stateIt->second;
66
67 return state.hoveringPointerIds.test(pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000068}
69
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070070void TouchedWindow::addHoveringPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070071 mDeviceStates[deviceId].hoveringPointerIds.set(pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000072}
73
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070074void TouchedWindow::addTouchingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070075 std::bitset<MAX_POINTER_ID + 1> pointers) {
76 mDeviceStates[deviceId].touchingPointerIds |= pointers;
77}
78
79bool TouchedWindow::hasTouchingPointers() const {
80 for (const auto& [_, state] : mDeviceStates) {
81 if (state.touchingPointerIds.any()) {
82 return true;
83 }
84 }
85 return false;
86}
87
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070088bool TouchedWindow::hasTouchingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070089 return getTouchingPointers(deviceId).any();
90}
91
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070092bool TouchedWindow::hasTouchingPointer(DeviceId deviceId, int32_t pointerId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070093 return getTouchingPointers(deviceId).test(pointerId);
94}
95
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070096std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getTouchingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070097 const auto stateIt = mDeviceStates.find(deviceId);
98 if (stateIt == mDeviceStates.end()) {
99 return {};
100 }
101 const DeviceState& state = stateIt->second;
102
103 return state.touchingPointerIds;
104}
105
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700106void TouchedWindow::removeTouchingPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700107 std::bitset<MAX_POINTER_ID + 1> pointerIds;
108 pointerIds.set(pointerId, true);
109
110 removeTouchingPointers(deviceId, pointerIds);
111}
112
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700113void TouchedWindow::removeTouchingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700114 std::bitset<MAX_POINTER_ID + 1> pointers) {
115 const auto stateIt = mDeviceStates.find(deviceId);
116 if (stateIt == mDeviceStates.end()) {
117 return;
118 }
119 DeviceState& state = stateIt->second;
120
121 state.touchingPointerIds &= ~pointers;
122 state.pilferingPointerIds &= ~pointers;
123
124 if (!state.hasPointers()) {
125 mDeviceStates.erase(stateIt);
Siarhei Vishniakou6464e462023-02-06 18:57:59 -0800126 }
127}
128
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700129std::set<DeviceId> TouchedWindow::getTouchingDeviceIds() const {
130 std::set<DeviceId> deviceIds;
Prabir Pradhan9cd9eb62023-11-22 17:58:06 +0000131 for (const auto& [deviceId, deviceState] : mDeviceStates) {
132 if (deviceState.touchingPointerIds.any()) {
133 deviceIds.insert(deviceId);
134 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700135 }
136 return deviceIds;
137}
138
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700139bool TouchedWindow::hasPilferingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700140 const auto stateIt = mDeviceStates.find(deviceId);
141 if (stateIt == mDeviceStates.end()) {
142 return false;
143 }
144 const DeviceState& state = stateIt->second;
145
146 return state.pilferingPointerIds.any();
147}
148
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700149void TouchedWindow::addPilferingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700150 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
151 mDeviceStates[deviceId].pilferingPointerIds |= pointerIds;
152}
153
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700154void TouchedWindow::addPilferingPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700155 mDeviceStates[deviceId].pilferingPointerIds.set(pointerId);
156}
157
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700158std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getPilferingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700159 const auto stateIt = mDeviceStates.find(deviceId);
160 if (stateIt == mDeviceStates.end()) {
161 return {};
162 }
163 const DeviceState& state = stateIt->second;
164
165 return state.pilferingPointerIds;
166}
167
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700168std::map<DeviceId, std::bitset<MAX_POINTER_ID + 1>> TouchedWindow::getPilferingPointers() const {
169 std::map<DeviceId, std::bitset<MAX_POINTER_ID + 1>> out;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700170 for (const auto& [deviceId, state] : mDeviceStates) {
171 out.emplace(deviceId, state.pilferingPointerIds);
172 }
173 return out;
174}
175
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700176std::optional<nsecs_t> TouchedWindow::getDownTimeInTarget(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700177 const auto stateIt = mDeviceStates.find(deviceId);
178 if (stateIt == mDeviceStates.end()) {
179 return {};
180 }
181 const DeviceState& state = stateIt->second;
182 return state.downTimeInTarget;
183}
184
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700185void TouchedWindow::trySetDownTimeInTarget(DeviceId deviceId, nsecs_t downTime) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700186 auto [stateIt, _] = mDeviceStates.try_emplace(deviceId);
187 DeviceState& state = stateIt->second;
188
189 if (!state.downTimeInTarget) {
190 state.downTimeInTarget = downTime;
191 }
192}
193
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700194void TouchedWindow::removeAllTouchingPointersForDevice(DeviceId deviceId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700195 const auto stateIt = mDeviceStates.find(deviceId);
196 if (stateIt == mDeviceStates.end()) {
197 return;
198 }
199 DeviceState& state = stateIt->second;
200
201 state.touchingPointerIds.reset();
202 state.pilferingPointerIds.reset();
203 state.downTimeInTarget.reset();
204
205 if (!state.hasPointers()) {
206 mDeviceStates.erase(stateIt);
207 }
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700208}
209
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700210void TouchedWindow::removeHoveringPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700211 const auto stateIt = mDeviceStates.find(deviceId);
212 if (stateIt == mDeviceStates.end()) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000213 return;
214 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700215 DeviceState& state = stateIt->second;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000216
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700217 state.hoveringPointerIds.set(pointerId, false);
218
219 if (!state.hasPointers()) {
220 mDeviceStates.erase(stateIt);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000221 }
222}
223
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700224void TouchedWindow::removeAllHoveringPointersForDevice(DeviceId deviceId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700225 const auto stateIt = mDeviceStates.find(deviceId);
226 if (stateIt == mDeviceStates.end()) {
227 return;
228 }
229 DeviceState& state = stateIt->second;
230
231 state.hoveringPointerIds.reset();
232
233 if (!state.hasPointers()) {
234 mDeviceStates.erase(stateIt);
235 }
236}
237
238std::string TouchedWindow::deviceStateToString(const TouchedWindow::DeviceState& state) {
239 return StringPrintf("[touchingPointerIds=%s, "
240 "downTimeInTarget=%s, hoveringPointerIds=%s, pilferingPointerIds=%s]",
241 bitsetToString(state.touchingPointerIds).c_str(),
242 toString(state.downTimeInTarget).c_str(),
243 bitsetToString(state.hoveringPointerIds).c_str(),
244 bitsetToString(state.pilferingPointerIds).c_str());
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700245}
246
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800247std::string TouchedWindow::dump() const {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000248 std::string out;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700249 std::string deviceStates =
250 dumpMap(mDeviceStates, constToString, TouchedWindow::deviceStateToString);
251 out += StringPrintf("name='%s', targetFlags=%s, mDeviceStates=%s\n",
252 windowHandle->getName().c_str(), targetFlags.string().c_str(),
253 deviceStates.c_str());
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000254 return out;
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800255}
256
Siarhei Vishniakou72945a02023-09-18 18:30:25 -0700257std::ostream& operator<<(std::ostream& out, const TouchedWindow& window) {
258 out << window.dump();
259 return out;
260}
261
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800262} // namespace inputdispatcher
263} // namespace android