blob: ff4b425da378a7f8a978aebe7db3c489f885be0f [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 Vishniakoub581f7f2022-12-07 20:23:06 +000048void TouchedWindow::clearHoveringPointers() {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070049 for (auto& [_, state] : mDeviceStates) {
50 state.hoveringPointerIds.reset();
51 }
52
53 std::erase_if(mDeviceStates, [](const auto& pair) { return !pair.second.hasPointers(); });
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000054}
55
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070056bool TouchedWindow::hasHoveringPointer(DeviceId deviceId, int32_t pointerId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070057 const auto stateIt = mDeviceStates.find(deviceId);
58 if (stateIt == mDeviceStates.end()) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000059 return false;
60 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070061 const DeviceState& state = stateIt->second;
62
63 return state.hoveringPointerIds.test(pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000064}
65
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070066void TouchedWindow::addHoveringPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070067 mDeviceStates[deviceId].hoveringPointerIds.set(pointerId);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +000068}
69
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070070void TouchedWindow::addTouchingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070071 std::bitset<MAX_POINTER_ID + 1> pointers) {
72 mDeviceStates[deviceId].touchingPointerIds |= pointers;
73}
74
75bool TouchedWindow::hasTouchingPointers() const {
76 for (const auto& [_, state] : mDeviceStates) {
77 if (state.touchingPointerIds.any()) {
78 return true;
79 }
80 }
81 return false;
82}
83
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070084bool TouchedWindow::hasTouchingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070085 return getTouchingPointers(deviceId).any();
86}
87
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070088bool TouchedWindow::hasTouchingPointer(DeviceId deviceId, int32_t pointerId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070089 return getTouchingPointers(deviceId).test(pointerId);
90}
91
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -070092std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getTouchingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -070093 const auto stateIt = mDeviceStates.find(deviceId);
94 if (stateIt == mDeviceStates.end()) {
95 return {};
96 }
97 const DeviceState& state = stateIt->second;
98
99 return state.touchingPointerIds;
100}
101
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700102void TouchedWindow::removeTouchingPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700103 std::bitset<MAX_POINTER_ID + 1> pointerIds;
104 pointerIds.set(pointerId, true);
105
106 removeTouchingPointers(deviceId, pointerIds);
107}
108
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700109void TouchedWindow::removeTouchingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700110 std::bitset<MAX_POINTER_ID + 1> pointers) {
111 const auto stateIt = mDeviceStates.find(deviceId);
112 if (stateIt == mDeviceStates.end()) {
113 return;
114 }
115 DeviceState& state = stateIt->second;
116
117 state.touchingPointerIds &= ~pointers;
118 state.pilferingPointerIds &= ~pointers;
119
120 if (!state.hasPointers()) {
121 mDeviceStates.erase(stateIt);
Siarhei Vishniakou6464e462023-02-06 18:57:59 -0800122 }
123}
124
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700125std::set<DeviceId> TouchedWindow::getTouchingDeviceIds() const {
126 std::set<DeviceId> deviceIds;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700127 for (const auto& [deviceId, _] : mDeviceStates) {
128 deviceIds.insert(deviceId);
129 }
130 return deviceIds;
131}
132
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700133std::set<DeviceId> TouchedWindow::getActiveDeviceIds() const {
134 std::set<DeviceId> out;
Siarhei Vishniakou45504fe2023-05-05 16:05:10 -0700135 for (const auto& [deviceId, _] : mDeviceStates) {
136 out.emplace(deviceId);
137 }
138 return out;
139}
140
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700141bool TouchedWindow::hasPilferingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700142 const auto stateIt = mDeviceStates.find(deviceId);
143 if (stateIt == mDeviceStates.end()) {
144 return false;
145 }
146 const DeviceState& state = stateIt->second;
147
148 return state.pilferingPointerIds.any();
149}
150
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700151void TouchedWindow::addPilferingPointers(DeviceId deviceId,
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700152 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
153 mDeviceStates[deviceId].pilferingPointerIds |= pointerIds;
154}
155
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700156void TouchedWindow::addPilferingPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700157 mDeviceStates[deviceId].pilferingPointerIds.set(pointerId);
158}
159
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700160std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getPilferingPointers(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700161 const auto stateIt = mDeviceStates.find(deviceId);
162 if (stateIt == mDeviceStates.end()) {
163 return {};
164 }
165 const DeviceState& state = stateIt->second;
166
167 return state.pilferingPointerIds;
168}
169
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700170std::map<DeviceId, std::bitset<MAX_POINTER_ID + 1>> TouchedWindow::getPilferingPointers() const {
171 std::map<DeviceId, std::bitset<MAX_POINTER_ID + 1>> out;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700172 for (const auto& [deviceId, state] : mDeviceStates) {
173 out.emplace(deviceId, state.pilferingPointerIds);
174 }
175 return out;
176}
177
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700178std::optional<nsecs_t> TouchedWindow::getDownTimeInTarget(DeviceId deviceId) const {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700179 const auto stateIt = mDeviceStates.find(deviceId);
180 if (stateIt == mDeviceStates.end()) {
181 return {};
182 }
183 const DeviceState& state = stateIt->second;
184 return state.downTimeInTarget;
185}
186
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700187void TouchedWindow::trySetDownTimeInTarget(DeviceId deviceId, nsecs_t downTime) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700188 auto [stateIt, _] = mDeviceStates.try_emplace(deviceId);
189 DeviceState& state = stateIt->second;
190
191 if (!state.downTimeInTarget) {
192 state.downTimeInTarget = downTime;
193 }
194}
195
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700196void TouchedWindow::removeAllTouchingPointersForDevice(DeviceId deviceId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700197 const auto stateIt = mDeviceStates.find(deviceId);
198 if (stateIt == mDeviceStates.end()) {
199 return;
200 }
201 DeviceState& state = stateIt->second;
202
203 state.touchingPointerIds.reset();
204 state.pilferingPointerIds.reset();
205 state.downTimeInTarget.reset();
206
207 if (!state.hasPointers()) {
208 mDeviceStates.erase(stateIt);
209 }
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700210}
211
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700212void TouchedWindow::removeHoveringPointer(DeviceId deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700213 const auto stateIt = mDeviceStates.find(deviceId);
214 if (stateIt == mDeviceStates.end()) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000215 return;
216 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700217 DeviceState& state = stateIt->second;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000218
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700219 state.hoveringPointerIds.set(pointerId, false);
220
221 if (!state.hasPointers()) {
222 mDeviceStates.erase(stateIt);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000223 }
224}
225
Siarhei Vishniakoud38a1e02023-07-18 11:55:17 -0700226void TouchedWindow::removeAllHoveringPointersForDevice(DeviceId deviceId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700227 const auto stateIt = mDeviceStates.find(deviceId);
228 if (stateIt == mDeviceStates.end()) {
229 return;
230 }
231 DeviceState& state = stateIt->second;
232
233 state.hoveringPointerIds.reset();
234
235 if (!state.hasPointers()) {
236 mDeviceStates.erase(stateIt);
237 }
238}
239
240std::string TouchedWindow::deviceStateToString(const TouchedWindow::DeviceState& state) {
241 return StringPrintf("[touchingPointerIds=%s, "
242 "downTimeInTarget=%s, hoveringPointerIds=%s, pilferingPointerIds=%s]",
243 bitsetToString(state.touchingPointerIds).c_str(),
244 toString(state.downTimeInTarget).c_str(),
245 bitsetToString(state.hoveringPointerIds).c_str(),
246 bitsetToString(state.pilferingPointerIds).c_str());
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700247}
248
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800249std::string TouchedWindow::dump() const {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000250 std::string out;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700251 std::string deviceStates =
252 dumpMap(mDeviceStates, constToString, TouchedWindow::deviceStateToString);
253 out += StringPrintf("name='%s', targetFlags=%s, mDeviceStates=%s\n",
254 windowHandle->getName().c_str(), targetFlags.string().c_str(),
255 deviceStates.c_str());
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000256 return out;
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800257}
258
Siarhei Vishniakou72945a02023-09-18 18:30:25 -0700259std::ostream& operator<<(std::ostream& out, const TouchedWindow& window) {
260 out << window.dump();
261 return out;
262}
263
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800264} // namespace inputdispatcher
265} // namespace android