blob: f1faf69758cecc59da6e77a34ae5ea5dd1ebd6d7 [file] [log] [blame]
Prabir Pradhanb56e92c2023-06-09 23:40:37 +00001/*
2 * Copyright 2023 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#define LOG_TAG "PointerChoreographer"
18
Byoungho Jungda10dd32023-10-06 17:03:45 +090019#include <android-base/logging.h>
20#include <input/PrintTools.h>
21
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000022#include "PointerChoreographer.h"
23
Byoungho Jungda10dd32023-10-06 17:03:45 +090024#define INDENT " "
25
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000026namespace android {
27
Byoungho Jungda10dd32023-10-06 17:03:45 +090028namespace {
29bool isFromMouse(const NotifyMotionArgs& args) {
30 return isFromSource(args.source, AINPUT_SOURCE_MOUSE) &&
31 args.pointerProperties[0].toolType == ToolType::MOUSE;
32}
33
Byoungho Jungee6268f2023-10-30 17:27:26 +090034bool isFromTouchpad(const NotifyMotionArgs& args) {
35 return isFromSource(args.source, AINPUT_SOURCE_MOUSE) &&
36 args.pointerProperties[0].toolType == ToolType::FINGER;
37}
38
Byoungho Jungd6fe27b2023-10-27 20:49:38 +090039bool isHoverAction(int32_t action) {
40 return action == AMOTION_EVENT_ACTION_HOVER_ENTER ||
41 action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT;
42}
43
44bool isStylusHoverEvent(const NotifyMotionArgs& args) {
45 return isStylusEvent(args.source, args.pointerProperties) && isHoverAction(args.action);
46}
Byoungho Jungda10dd32023-10-06 17:03:45 +090047} // namespace
48
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000049// --- PointerChoreographer ---
50
51PointerChoreographer::PointerChoreographer(InputListenerInterface& listener,
52 PointerChoreographerPolicyInterface& policy)
Prabir Pradhan16788792023-11-08 21:07:21 +000053 : mTouchControllerConstructor([this]() REQUIRES(mLock) {
54 return mPolicy.createPointerController(
55 PointerControllerInterface::ControllerType::TOUCH);
56 }),
57 mNextListener(listener),
Byoungho Jungda10dd32023-10-06 17:03:45 +090058 mPolicy(policy),
59 mDefaultMouseDisplayId(ADISPLAY_ID_DEFAULT),
Byoungho Jung6f5b16b2023-10-27 18:22:07 +090060 mNotifiedPointerDisplayId(ADISPLAY_ID_NONE),
Byoungho Jungd6fe27b2023-10-27 20:49:38 +090061 mShowTouchesEnabled(false),
62 mStylusPointerIconEnabled(false) {}
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000063
64void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +090065 std::scoped_lock _l(mLock);
66
67 mInputDeviceInfos = args.inputDeviceInfos;
68 updatePointerControllersLocked();
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000069 mNextListener.notify(args);
70}
71
72void PointerChoreographer::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
73 mNextListener.notify(args);
74}
75
76void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
77 mNextListener.notify(args);
78}
79
80void PointerChoreographer::notifyMotion(const NotifyMotionArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +090081 NotifyMotionArgs newArgs = processMotion(args);
82
83 mNextListener.notify(newArgs);
84}
85
86NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& args) {
87 std::scoped_lock _l(mLock);
88
89 if (isFromMouse(args)) {
90 return processMouseEventLocked(args);
Byoungho Jungee6268f2023-10-30 17:27:26 +090091 } else if (isFromTouchpad(args)) {
92 return processTouchpadEventLocked(args);
Byoungho Jungd6fe27b2023-10-27 20:49:38 +090093 } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) {
94 processStylusHoverEventLocked(args);
Byoungho Jungda10dd32023-10-06 17:03:45 +090095 } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) {
Byoungho Jung6f5b16b2023-10-27 18:22:07 +090096 processTouchscreenAndStylusEventLocked(args);
Byoungho Jungda10dd32023-10-06 17:03:45 +090097 }
98 return args;
99}
100
101NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotionArgs& args) {
102 if (args.getPointerCount() != 1) {
Prabir Pradhan19767602023-11-03 16:53:31 +0000103 LOG(FATAL) << "Only mouse events with a single pointer are currently supported: "
104 << args.dump();
Byoungho Jungda10dd32023-10-06 17:03:45 +0900105 }
106
Byoungho Jungee6268f2023-10-30 17:27:26 +0900107 auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId);
Byoungho Jungda10dd32023-10-06 17:03:45 +0900108
109 const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
110 const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
111 pc.move(deltaX, deltaY);
112 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
113
114 const auto [x, y] = pc.getPosition();
115 NotifyMotionArgs newArgs(args);
116 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
117 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
118 newArgs.xCursorPosition = x;
119 newArgs.yCursorPosition = y;
120 newArgs.displayId = displayId;
121 return newArgs;
122}
123
Byoungho Jungee6268f2023-10-30 17:27:26 +0900124NotifyMotionArgs PointerChoreographer::processTouchpadEventLocked(const NotifyMotionArgs& args) {
125 auto [displayId, pc] = getDisplayIdAndMouseControllerLocked(args.displayId);
126
127 NotifyMotionArgs newArgs(args);
128 newArgs.displayId = displayId;
129 if (args.getPointerCount() == 1 && args.classification == MotionClassification::NONE) {
130 // This is a movement of the mouse pointer.
131 const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
132 const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
133 pc.move(deltaX, deltaY);
134 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
135
136 const auto [x, y] = pc.getPosition();
137 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
138 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
139 newArgs.xCursorPosition = x;
140 newArgs.yCursorPosition = y;
141 } else {
142 // This is a trackpad gesture with fake finger(s) that should not move the mouse pointer.
143 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
144
145 const auto [x, y] = pc.getPosition();
146 for (uint32_t i = 0; i < newArgs.getPointerCount(); i++) {
147 newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X,
148 args.pointerCoords[i].getX() + x);
149 newArgs.pointerCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y,
150 args.pointerCoords[i].getY() + y);
151 }
152 newArgs.xCursorPosition = x;
153 newArgs.yCursorPosition = y;
154 }
155 return newArgs;
156}
157
Byoungho Jungda10dd32023-10-06 17:03:45 +0900158/**
159 * When screen is touched, fade the mouse pointer on that display. We only call fade for
160 * ACTION_DOWN events.This would allow both mouse and touch to be used at the same time if the
161 * mouse device keeps moving and unfades the cursor.
162 * For touch events, we do not need to populate the cursor position.
163 */
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900164void PointerChoreographer::processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) {
165 if (args.displayId == ADISPLAY_ID_NONE) {
166 return;
167 }
168
Byoungho Jungda10dd32023-10-06 17:03:45 +0900169 if (const auto it = mMousePointersByDisplay.find(args.displayId);
170 it != mMousePointersByDisplay.end() && args.action == AMOTION_EVENT_ACTION_DOWN) {
171 it->second->fade(PointerControllerInterface::Transition::GRADUAL);
172 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900173
174 if (!mShowTouchesEnabled) {
175 return;
176 }
177
178 // Get the touch pointer controller for the device, or create one if it doesn't exist.
Prabir Pradhan16788792023-11-08 21:07:21 +0000179 auto [it, _] = mTouchPointersByDevice.try_emplace(args.deviceId, mTouchControllerConstructor);
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900180
181 PointerControllerInterface& pc = *it->second;
182
183 const PointerCoords* coords = args.pointerCoords.data();
184 const int32_t maskedAction = MotionEvent::getActionMasked(args.action);
185 const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
186 std::array<uint32_t, MAX_POINTER_ID + 1> idToIndex;
187 BitSet32 idBits;
188 if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL) {
189 for (size_t i = 0; i < args.getPointerCount(); i++) {
190 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP && actionIndex == i) {
191 continue;
192 }
193 uint32_t id = args.pointerProperties[i].id;
194 idToIndex[id] = i;
195 idBits.markBit(id);
196 }
197 }
198 // The PointerController already handles setting spots per-display, so
199 // we do not need to manually manage display changes for touch spots for now.
200 pc.setSpots(coords, idToIndex.cbegin(), idBits, args.displayId);
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000201}
202
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900203void PointerChoreographer::processStylusHoverEventLocked(const NotifyMotionArgs& args) {
204 if (args.displayId == ADISPLAY_ID_NONE) {
205 return;
206 }
207
208 if (args.getPointerCount() != 1) {
209 LOG(WARNING) << "Only stylus hover events with a single pointer are currently supported: "
210 << args.dump();
211 }
212
213 // Get the stylus pointer controller for the device, or create one if it doesn't exist.
214 auto [it, _] =
215 mStylusPointersByDevice.try_emplace(args.deviceId,
216 getStylusControllerConstructor(args.displayId));
217
218 PointerControllerInterface& pc = *it->second;
219
220 const float x = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
221 const float y = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
222 pc.setPosition(x, y);
223 if (args.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
224 pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
225 } else {
226 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
227 }
228}
229
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000230void PointerChoreographer::notifySwitch(const NotifySwitchArgs& args) {
231 mNextListener.notify(args);
232}
233
234void PointerChoreographer::notifySensor(const NotifySensorArgs& args) {
235 mNextListener.notify(args);
236}
237
238void PointerChoreographer::notifyVibratorState(const NotifyVibratorStateArgs& args) {
239 mNextListener.notify(args);
240}
241
242void PointerChoreographer::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900243 processDeviceReset(args);
244
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000245 mNextListener.notify(args);
246}
247
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900248void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) {
249 std::scoped_lock _l(mLock);
Prabir Pradhan16788792023-11-08 21:07:21 +0000250 mTouchPointersByDevice.erase(args.deviceId);
251 mStylusPointersByDevice.erase(args.deviceId);
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900252}
253
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000254void PointerChoreographer::notifyPointerCaptureChanged(
255 const NotifyPointerCaptureChangedArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900256 if (args.request.enable) {
257 std::scoped_lock _l(mLock);
258 for (const auto& [_, mousePointerController] : mMousePointersByDisplay) {
259 mousePointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
260 }
261 }
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000262 mNextListener.notify(args);
263}
264
265void PointerChoreographer::dump(std::string& dump) {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900266 std::scoped_lock _l(mLock);
267
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000268 dump += "PointerChoreographer:\n";
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900269 dump += StringPrintf("show touches: %s\n", mShowTouchesEnabled ? "true" : "false");
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900270 dump += StringPrintf("stylus pointer icon enabled: %s\n",
271 mStylusPointerIconEnabled ? "true" : "false");
Byoungho Jungda10dd32023-10-06 17:03:45 +0900272
273 dump += INDENT "MousePointerControllers:\n";
274 for (const auto& [displayId, mousePointerController] : mMousePointersByDisplay) {
275 std::string pointerControllerDump = addLinePrefix(mousePointerController->dump(), INDENT);
276 dump += INDENT + std::to_string(displayId) + " : " + pointerControllerDump;
277 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900278 dump += INDENT "TouchPointerControllers:\n";
279 for (const auto& [deviceId, touchPointerController] : mTouchPointersByDevice) {
280 std::string pointerControllerDump = addLinePrefix(touchPointerController->dump(), INDENT);
281 dump += INDENT + std::to_string(deviceId) + " : " + pointerControllerDump;
282 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900283 dump += INDENT "StylusPointerControllers:\n";
284 for (const auto& [deviceId, stylusPointerController] : mStylusPointersByDevice) {
285 std::string pointerControllerDump = addLinePrefix(stylusPointerController->dump(), INDENT);
286 dump += INDENT + std::to_string(deviceId) + " : " + pointerControllerDump;
287 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900288 dump += "\n";
289}
290
291const DisplayViewport* PointerChoreographer::findViewportByIdLocked(int32_t displayId) const {
292 for (auto& viewport : mViewports) {
293 if (viewport.displayId == displayId) {
294 return &viewport;
295 }
296 }
297 return nullptr;
298}
299
300int32_t PointerChoreographer::getTargetMouseDisplayLocked(int32_t associatedDisplayId) const {
301 return associatedDisplayId == ADISPLAY_ID_NONE ? mDefaultMouseDisplayId : associatedDisplayId;
302}
303
Byoungho Jungee6268f2023-10-30 17:27:26 +0900304std::pair<int32_t, PointerControllerInterface&>
305PointerChoreographer::getDisplayIdAndMouseControllerLocked(int32_t associatedDisplayId) {
306 const int32_t displayId = getTargetMouseDisplayLocked(associatedDisplayId);
307
308 // Get the mouse pointer controller for the display, or create one if it doesn't exist.
309 auto [it, emplaced] =
310 mMousePointersByDisplay.try_emplace(displayId,
311 getMouseControllerConstructor(displayId));
312 if (emplaced) {
313 notifyPointerDisplayIdChangedLocked();
314 }
315
316 return {displayId, *it->second};
317}
318
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900319InputDeviceInfo* PointerChoreographer::findInputDeviceLocked(DeviceId deviceId) {
Prabir Pradhan16788792023-11-08 21:07:21 +0000320 auto it = std::find_if(mInputDeviceInfos.begin(), mInputDeviceInfos.end(),
321 [deviceId](const auto& info) { return info.getId() == deviceId; });
322 return it != mInputDeviceInfos.end() ? &(*it) : nullptr;
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900323}
324
Byoungho Jungda10dd32023-10-06 17:03:45 +0900325void PointerChoreographer::updatePointerControllersLocked() {
326 std::set<int32_t /*displayId*/> mouseDisplaysToKeep;
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900327 std::set<DeviceId> touchDevicesToKeep;
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900328 std::set<DeviceId> stylusDevicesToKeep;
Byoungho Jungda10dd32023-10-06 17:03:45 +0900329
330 // Mark the displayIds or deviceIds of PointerControllers currently needed.
331 for (const auto& info : mInputDeviceInfos) {
332 const uint32_t sources = info.getSources();
333 if (isFromSource(sources, AINPUT_SOURCE_MOUSE) ||
334 isFromSource(sources, AINPUT_SOURCE_MOUSE_RELATIVE)) {
335 const int32_t resolvedDisplayId =
336 getTargetMouseDisplayLocked(info.getAssociatedDisplayId());
337 mouseDisplaysToKeep.insert(resolvedDisplayId);
338 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900339 if (isFromSource(sources, AINPUT_SOURCE_TOUCHSCREEN) && mShowTouchesEnabled &&
340 info.getAssociatedDisplayId() != ADISPLAY_ID_NONE) {
341 touchDevicesToKeep.insert(info.getId());
342 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900343 if (isFromSource(sources, AINPUT_SOURCE_STYLUS) && mStylusPointerIconEnabled &&
344 info.getAssociatedDisplayId() != ADISPLAY_ID_NONE) {
345 stylusDevicesToKeep.insert(info.getId());
346 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900347 }
348
349 // Remove PointerControllers no longer needed.
Prabir Pradhan19767602023-11-03 16:53:31 +0000350 std::erase_if(mMousePointersByDisplay, [&mouseDisplaysToKeep](const auto& pair) {
Prabir Pradhan16788792023-11-08 21:07:21 +0000351 return mouseDisplaysToKeep.find(pair.first) == mouseDisplaysToKeep.end();
Byoungho Jungda10dd32023-10-06 17:03:45 +0900352 });
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900353 std::erase_if(mTouchPointersByDevice, [&touchDevicesToKeep](const auto& pair) {
Prabir Pradhan16788792023-11-08 21:07:21 +0000354 return touchDevicesToKeep.find(pair.first) == touchDevicesToKeep.end();
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900355 });
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900356 std::erase_if(mStylusPointersByDevice, [&stylusDevicesToKeep](const auto& pair) {
Prabir Pradhan16788792023-11-08 21:07:21 +0000357 return stylusDevicesToKeep.find(pair.first) == stylusDevicesToKeep.end();
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900358 });
Byoungho Jungda10dd32023-10-06 17:03:45 +0900359
360 // Notify the policy if there's a change on the pointer display ID.
361 notifyPointerDisplayIdChangedLocked();
362}
363
364void PointerChoreographer::notifyPointerDisplayIdChangedLocked() {
365 int32_t displayIdToNotify = ADISPLAY_ID_NONE;
366 FloatPoint cursorPosition = {0, 0};
367 if (const auto it = mMousePointersByDisplay.find(mDefaultMouseDisplayId);
368 it != mMousePointersByDisplay.end()) {
Prabir Pradhan19767602023-11-03 16:53:31 +0000369 const auto& pointerController = it->second;
370 // Use the displayId from the pointerController, because it accurately reflects whether
371 // the viewport has been added for that display. Otherwise, we would have to check if
372 // the viewport exists separately.
373 displayIdToNotify = pointerController->getDisplayId();
374 cursorPosition = pointerController->getPosition();
Byoungho Jungda10dd32023-10-06 17:03:45 +0900375 }
376
377 if (mNotifiedPointerDisplayId == displayIdToNotify) {
378 return;
379 }
380 mPolicy.notifyPointerDisplayIdChanged(displayIdToNotify, cursorPosition);
381 mNotifiedPointerDisplayId = displayIdToNotify;
382}
383
384void PointerChoreographer::setDefaultMouseDisplayId(int32_t displayId) {
385 std::scoped_lock _l(mLock);
386
387 mDefaultMouseDisplayId = displayId;
388 updatePointerControllersLocked();
389}
390
391void PointerChoreographer::setDisplayViewports(const std::vector<DisplayViewport>& viewports) {
392 std::scoped_lock _l(mLock);
393 for (const auto& viewport : viewports) {
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900394 const int32_t displayId = viewport.displayId;
395 if (const auto it = mMousePointersByDisplay.find(displayId);
Byoungho Jungda10dd32023-10-06 17:03:45 +0900396 it != mMousePointersByDisplay.end()) {
397 it->second->setDisplayViewport(viewport);
398 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900399 for (const auto& [deviceId, stylusPointerController] : mStylusPointersByDevice) {
400 const InputDeviceInfo* info = findInputDeviceLocked(deviceId);
401 if (info && info->getAssociatedDisplayId() == displayId) {
402 stylusPointerController->setDisplayViewport(viewport);
403 }
404 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900405 }
406 mViewports = viewports;
407 notifyPointerDisplayIdChangedLocked();
408}
409
410std::optional<DisplayViewport> PointerChoreographer::getViewportForPointerDevice(
411 int32_t associatedDisplayId) {
412 std::scoped_lock _l(mLock);
413 const int32_t resolvedDisplayId = getTargetMouseDisplayLocked(associatedDisplayId);
414 if (const auto viewport = findViewportByIdLocked(resolvedDisplayId); viewport) {
415 return *viewport;
416 }
417 return std::nullopt;
418}
419
420FloatPoint PointerChoreographer::getMouseCursorPosition(int32_t displayId) {
421 std::scoped_lock _l(mLock);
422 const int32_t resolvedDisplayId = getTargetMouseDisplayLocked(displayId);
423 if (auto it = mMousePointersByDisplay.find(resolvedDisplayId);
424 it != mMousePointersByDisplay.end()) {
425 return it->second->getPosition();
426 }
427 return {AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION};
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000428}
429
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900430void PointerChoreographer::setShowTouchesEnabled(bool enabled) {
431 std::scoped_lock _l(mLock);
432 if (mShowTouchesEnabled == enabled) {
433 return;
434 }
435 mShowTouchesEnabled = enabled;
436 updatePointerControllersLocked();
437}
438
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900439void PointerChoreographer::setStylusPointerIconEnabled(bool enabled) {
440 std::scoped_lock _l(mLock);
441 if (mStylusPointerIconEnabled == enabled) {
442 return;
443 }
444 mStylusPointerIconEnabled = enabled;
445 updatePointerControllersLocked();
446}
447
Prabir Pradhan19767602023-11-03 16:53:31 +0000448PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
449 int32_t displayId) {
450 std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
451 [this, displayId]() REQUIRES(mLock) {
452 auto pc = mPolicy.createPointerController(
453 PointerControllerInterface::ControllerType::MOUSE);
454 if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
455 pc->setDisplayViewport(*viewport);
456 }
457 return pc;
458 };
459 return ConstructorDelegate(std::move(ctor));
460}
461
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900462PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusControllerConstructor(
463 int32_t displayId) {
464 std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
465 [this, displayId]() REQUIRES(mLock) {
466 auto pc = mPolicy.createPointerController(
467 PointerControllerInterface::ControllerType::STYLUS);
468 if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
469 pc->setDisplayViewport(*viewport);
470 }
471 return pc;
472 };
473 return ConstructorDelegate(std::move(ctor));
474}
475
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000476} // namespace android