blob: 6ab97f8ea50c9f8174eb8084c78e7aab9a8292ec [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 Vishniakoue0431e42023-01-28 17:01:39 -080038bool TouchedWindow::hasHoveringPointers(int32_t 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
56bool TouchedWindow::hasHoveringPointer(int32_t 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
66void TouchedWindow::addHoveringPointer(int32_t 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 Vishniakou0836a302023-05-03 13:54:30 -070070void TouchedWindow::addTouchingPointer(int32_t deviceId, int32_t pointerId) {
71 mDeviceStates[deviceId].touchingPointerIds.set(pointerId);
72}
73
74void TouchedWindow::addTouchingPointers(int32_t deviceId,
75 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
88bool TouchedWindow::hasTouchingPointers(int32_t deviceId) const {
89 return getTouchingPointers(deviceId).any();
90}
91
92bool TouchedWindow::hasTouchingPointer(int32_t deviceId, int32_t pointerId) const {
93 return getTouchingPointers(deviceId).test(pointerId);
94}
95
96std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getTouchingPointers(int32_t deviceId) const {
97 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
106void TouchedWindow::removeTouchingPointer(int32_t deviceId, int32_t pointerId) {
107 std::bitset<MAX_POINTER_ID + 1> pointerIds;
108 pointerIds.set(pointerId, true);
109
110 removeTouchingPointers(deviceId, pointerIds);
111}
112
113void TouchedWindow::removeTouchingPointers(int32_t deviceId,
114 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 Vishniakou0836a302023-05-03 13:54:30 -0700129std::set<int32_t> TouchedWindow::getTouchingDeviceIds() const {
130 std::set<int32_t> deviceIds;
131 for (const auto& [deviceId, _] : mDeviceStates) {
132 deviceIds.insert(deviceId);
133 }
134 return deviceIds;
135}
136
137bool TouchedWindow::hasPilferingPointers(int32_t deviceId) const {
138 const auto stateIt = mDeviceStates.find(deviceId);
139 if (stateIt == mDeviceStates.end()) {
140 return false;
141 }
142 const DeviceState& state = stateIt->second;
143
144 return state.pilferingPointerIds.any();
145}
146
147void TouchedWindow::addPilferingPointers(int32_t deviceId,
148 std::bitset<MAX_POINTER_ID + 1> pointerIds) {
149 mDeviceStates[deviceId].pilferingPointerIds |= pointerIds;
150}
151
152void TouchedWindow::addPilferingPointer(int32_t deviceId, int32_t pointerId) {
153 mDeviceStates[deviceId].pilferingPointerIds.set(pointerId);
154}
155
156std::bitset<MAX_POINTER_ID + 1> TouchedWindow::getPilferingPointers(int32_t deviceId) const {
157 const auto stateIt = mDeviceStates.find(deviceId);
158 if (stateIt == mDeviceStates.end()) {
159 return {};
160 }
161 const DeviceState& state = stateIt->second;
162
163 return state.pilferingPointerIds;
164}
165
166std::map<int32_t, std::bitset<MAX_POINTER_ID + 1>> TouchedWindow::getPilferingPointers() const {
167 std::map<int32_t, std::bitset<MAX_POINTER_ID + 1>> out;
168 for (const auto& [deviceId, state] : mDeviceStates) {
169 out.emplace(deviceId, state.pilferingPointerIds);
170 }
171 return out;
172}
173
174std::optional<nsecs_t> TouchedWindow::getDownTimeInTarget(int32_t deviceId) const {
175 const auto stateIt = mDeviceStates.find(deviceId);
176 if (stateIt == mDeviceStates.end()) {
177 return {};
178 }
179 const DeviceState& state = stateIt->second;
180 return state.downTimeInTarget;
181}
182
183void TouchedWindow::trySetDownTimeInTarget(int32_t deviceId, nsecs_t downTime) {
184 auto [stateIt, _] = mDeviceStates.try_emplace(deviceId);
185 DeviceState& state = stateIt->second;
186
187 if (!state.downTimeInTarget) {
188 state.downTimeInTarget = downTime;
189 }
190}
191
192void TouchedWindow::removeAllTouchingPointersForDevice(int32_t deviceId) {
193 const auto stateIt = mDeviceStates.find(deviceId);
194 if (stateIt == mDeviceStates.end()) {
195 return;
196 }
197 DeviceState& state = stateIt->second;
198
199 state.touchingPointerIds.reset();
200 state.pilferingPointerIds.reset();
201 state.downTimeInTarget.reset();
202
203 if (!state.hasPointers()) {
204 mDeviceStates.erase(stateIt);
205 }
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700206}
207
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000208void TouchedWindow::removeHoveringPointer(int32_t deviceId, int32_t pointerId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700209 const auto stateIt = mDeviceStates.find(deviceId);
210 if (stateIt == mDeviceStates.end()) {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000211 return;
212 }
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700213 DeviceState& state = stateIt->second;
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000214
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700215 state.hoveringPointerIds.set(pointerId, false);
216
217 if (!state.hasPointers()) {
218 mDeviceStates.erase(stateIt);
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000219 }
220}
221
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700222void TouchedWindow::removeAllHoveringPointersForDevice(int32_t deviceId) {
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700223 const auto stateIt = mDeviceStates.find(deviceId);
224 if (stateIt == mDeviceStates.end()) {
225 return;
226 }
227 DeviceState& state = stateIt->second;
228
229 state.hoveringPointerIds.reset();
230
231 if (!state.hasPointers()) {
232 mDeviceStates.erase(stateIt);
233 }
234}
235
236std::string TouchedWindow::deviceStateToString(const TouchedWindow::DeviceState& state) {
237 return StringPrintf("[touchingPointerIds=%s, "
238 "downTimeInTarget=%s, hoveringPointerIds=%s, pilferingPointerIds=%s]",
239 bitsetToString(state.touchingPointerIds).c_str(),
240 toString(state.downTimeInTarget).c_str(),
241 bitsetToString(state.hoveringPointerIds).c_str(),
242 bitsetToString(state.pilferingPointerIds).c_str());
Siarhei Vishniakou0686f0c2023-05-02 11:56:15 -0700243}
244
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800245std::string TouchedWindow::dump() const {
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000246 std::string out;
Siarhei Vishniakou0836a302023-05-03 13:54:30 -0700247 std::string deviceStates =
248 dumpMap(mDeviceStates, constToString, TouchedWindow::deviceStateToString);
249 out += StringPrintf("name='%s', targetFlags=%s, mDeviceStates=%s\n",
250 windowHandle->getName().c_str(), targetFlags.string().c_str(),
251 deviceStates.c_str());
Siarhei Vishniakoub581f7f2022-12-07 20:23:06 +0000252 return out;
Siarhei Vishniakou6e1e9872022-11-08 17:51:35 -0800253}
254
255} // namespace inputdispatcher
256} // namespace android