blob: 841d95bbfe56bb85487914afff701fa3b9456a90 [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 Jungd6fe27b2023-10-27 20:49:38 +090034bool isHoverAction(int32_t action) {
35 return action == AMOTION_EVENT_ACTION_HOVER_ENTER ||
36 action == AMOTION_EVENT_ACTION_HOVER_MOVE || action == AMOTION_EVENT_ACTION_HOVER_EXIT;
37}
38
39bool isStylusHoverEvent(const NotifyMotionArgs& args) {
40 return isStylusEvent(args.source, args.pointerProperties) && isHoverAction(args.action);
41}
Byoungho Jungda10dd32023-10-06 17:03:45 +090042} // namespace
43
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000044// --- PointerChoreographer ---
45
46PointerChoreographer::PointerChoreographer(InputListenerInterface& listener,
47 PointerChoreographerPolicyInterface& policy)
Byoungho Jungda10dd32023-10-06 17:03:45 +090048 : mNextListener(listener),
49 mPolicy(policy),
50 mDefaultMouseDisplayId(ADISPLAY_ID_DEFAULT),
Byoungho Jung6f5b16b2023-10-27 18:22:07 +090051 mNotifiedPointerDisplayId(ADISPLAY_ID_NONE),
Byoungho Jungd6fe27b2023-10-27 20:49:38 +090052 mShowTouchesEnabled(false),
53 mStylusPointerIconEnabled(false) {}
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000054
55void PointerChoreographer::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +090056 std::scoped_lock _l(mLock);
57
58 mInputDeviceInfos = args.inputDeviceInfos;
59 updatePointerControllersLocked();
Prabir Pradhanb56e92c2023-06-09 23:40:37 +000060 mNextListener.notify(args);
61}
62
63void PointerChoreographer::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
64 mNextListener.notify(args);
65}
66
67void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
68 mNextListener.notify(args);
69}
70
71void PointerChoreographer::notifyMotion(const NotifyMotionArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +090072 NotifyMotionArgs newArgs = processMotion(args);
73
74 mNextListener.notify(newArgs);
75}
76
77NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& args) {
78 std::scoped_lock _l(mLock);
79
80 if (isFromMouse(args)) {
81 return processMouseEventLocked(args);
Byoungho Jungd6fe27b2023-10-27 20:49:38 +090082 } else if (mStylusPointerIconEnabled && isStylusHoverEvent(args)) {
83 processStylusHoverEventLocked(args);
Byoungho Jungda10dd32023-10-06 17:03:45 +090084 } else if (isFromSource(args.source, AINPUT_SOURCE_TOUCHSCREEN)) {
Byoungho Jung6f5b16b2023-10-27 18:22:07 +090085 processTouchscreenAndStylusEventLocked(args);
Byoungho Jungda10dd32023-10-06 17:03:45 +090086 }
87 return args;
88}
89
90NotifyMotionArgs PointerChoreographer::processMouseEventLocked(const NotifyMotionArgs& args) {
91 if (args.getPointerCount() != 1) {
Prabir Pradhan19767602023-11-03 16:53:31 +000092 LOG(FATAL) << "Only mouse events with a single pointer are currently supported: "
93 << args.dump();
Byoungho Jungda10dd32023-10-06 17:03:45 +090094 }
95
96 const int32_t displayId = getTargetMouseDisplayLocked(args.displayId);
Prabir Pradhan19767602023-11-03 16:53:31 +000097
98 // Get the mouse pointer controller for the display, or create one if it doesn't exist.
99 auto [it, emplaced] =
100 mMousePointersByDisplay.try_emplace(displayId,
101 getMouseControllerConstructor(displayId));
102 if (emplaced) {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900103 notifyPointerDisplayIdChangedLocked();
104 }
105
106 PointerControllerInterface& pc = *it->second;
107
108 const float deltaX = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
109 const float deltaY = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
110 pc.move(deltaX, deltaY);
111 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
112
113 const auto [x, y] = pc.getPosition();
114 NotifyMotionArgs newArgs(args);
115 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
116 newArgs.pointerCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
117 newArgs.xCursorPosition = x;
118 newArgs.yCursorPosition = y;
119 newArgs.displayId = displayId;
120 return newArgs;
121}
122
123/**
124 * When screen is touched, fade the mouse pointer on that display. We only call fade for
125 * ACTION_DOWN events.This would allow both mouse and touch to be used at the same time if the
126 * mouse device keeps moving and unfades the cursor.
127 * For touch events, we do not need to populate the cursor position.
128 */
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900129void PointerChoreographer::processTouchscreenAndStylusEventLocked(const NotifyMotionArgs& args) {
130 if (args.displayId == ADISPLAY_ID_NONE) {
131 return;
132 }
133
Byoungho Jungda10dd32023-10-06 17:03:45 +0900134 if (const auto it = mMousePointersByDisplay.find(args.displayId);
135 it != mMousePointersByDisplay.end() && args.action == AMOTION_EVENT_ACTION_DOWN) {
136 it->second->fade(PointerControllerInterface::Transition::GRADUAL);
137 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900138
139 if (!mShowTouchesEnabled) {
140 return;
141 }
142
143 // Get the touch pointer controller for the device, or create one if it doesn't exist.
144 auto [it, _] =
145 mTouchPointersByDevice.try_emplace(args.deviceId, getTouchControllerConstructor());
146
147 PointerControllerInterface& pc = *it->second;
148
149 const PointerCoords* coords = args.pointerCoords.data();
150 const int32_t maskedAction = MotionEvent::getActionMasked(args.action);
151 const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
152 std::array<uint32_t, MAX_POINTER_ID + 1> idToIndex;
153 BitSet32 idBits;
154 if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL) {
155 for (size_t i = 0; i < args.getPointerCount(); i++) {
156 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP && actionIndex == i) {
157 continue;
158 }
159 uint32_t id = args.pointerProperties[i].id;
160 idToIndex[id] = i;
161 idBits.markBit(id);
162 }
163 }
164 // The PointerController already handles setting spots per-display, so
165 // we do not need to manually manage display changes for touch spots for now.
166 pc.setSpots(coords, idToIndex.cbegin(), idBits, args.displayId);
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000167}
168
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900169void PointerChoreographer::processStylusHoverEventLocked(const NotifyMotionArgs& args) {
170 if (args.displayId == ADISPLAY_ID_NONE) {
171 return;
172 }
173
174 if (args.getPointerCount() != 1) {
175 LOG(WARNING) << "Only stylus hover events with a single pointer are currently supported: "
176 << args.dump();
177 }
178
179 // Get the stylus pointer controller for the device, or create one if it doesn't exist.
180 auto [it, _] =
181 mStylusPointersByDevice.try_emplace(args.deviceId,
182 getStylusControllerConstructor(args.displayId));
183
184 PointerControllerInterface& pc = *it->second;
185
186 const float x = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
187 const float y = args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
188 pc.setPosition(x, y);
189 if (args.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
190 pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
191 } else {
192 pc.unfade(PointerControllerInterface::Transition::IMMEDIATE);
193 }
194}
195
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000196void PointerChoreographer::notifySwitch(const NotifySwitchArgs& args) {
197 mNextListener.notify(args);
198}
199
200void PointerChoreographer::notifySensor(const NotifySensorArgs& args) {
201 mNextListener.notify(args);
202}
203
204void PointerChoreographer::notifyVibratorState(const NotifyVibratorStateArgs& args) {
205 mNextListener.notify(args);
206}
207
208void PointerChoreographer::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900209 processDeviceReset(args);
210
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000211 mNextListener.notify(args);
212}
213
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900214void PointerChoreographer::processDeviceReset(const NotifyDeviceResetArgs& args) {
215 std::scoped_lock _l(mLock);
216
217 const InputDeviceInfo* info = findInputDeviceLocked(args.deviceId);
218 if (info == nullptr) {
219 return;
220 }
221
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900222 const uint32_t sources = info->getSources();
223 const int32_t displayId = info->getAssociatedDisplayId();
224 if (isFromSource(sources, AINPUT_SOURCE_TOUCHSCREEN) && mShowTouchesEnabled &&
225 displayId != ADISPLAY_ID_NONE) {
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900226 if (const auto it = mTouchPointersByDevice.find(args.deviceId);
227 it != mTouchPointersByDevice.end()) {
228 it->second->clearSpots();
229 }
230 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900231 if (isFromSource(info->getSources(), AINPUT_SOURCE_STYLUS) && mStylusPointerIconEnabled &&
232 displayId != ADISPLAY_ID_NONE) {
233 if (const auto it = mStylusPointersByDevice.find(args.deviceId);
234 it != mStylusPointersByDevice.end()) {
235 it->second->fade(PointerControllerInterface::Transition::IMMEDIATE);
236 }
237 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900238}
239
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000240void PointerChoreographer::notifyPointerCaptureChanged(
241 const NotifyPointerCaptureChangedArgs& args) {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900242 if (args.request.enable) {
243 std::scoped_lock _l(mLock);
244 for (const auto& [_, mousePointerController] : mMousePointersByDisplay) {
245 mousePointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
246 }
247 }
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000248 mNextListener.notify(args);
249}
250
251void PointerChoreographer::dump(std::string& dump) {
Byoungho Jungda10dd32023-10-06 17:03:45 +0900252 std::scoped_lock _l(mLock);
253
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000254 dump += "PointerChoreographer:\n";
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900255 dump += StringPrintf("show touches: %s\n", mShowTouchesEnabled ? "true" : "false");
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900256 dump += StringPrintf("stylus pointer icon enabled: %s\n",
257 mStylusPointerIconEnabled ? "true" : "false");
Byoungho Jungda10dd32023-10-06 17:03:45 +0900258
259 dump += INDENT "MousePointerControllers:\n";
260 for (const auto& [displayId, mousePointerController] : mMousePointersByDisplay) {
261 std::string pointerControllerDump = addLinePrefix(mousePointerController->dump(), INDENT);
262 dump += INDENT + std::to_string(displayId) + " : " + pointerControllerDump;
263 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900264 dump += INDENT "TouchPointerControllers:\n";
265 for (const auto& [deviceId, touchPointerController] : mTouchPointersByDevice) {
266 std::string pointerControllerDump = addLinePrefix(touchPointerController->dump(), INDENT);
267 dump += INDENT + std::to_string(deviceId) + " : " + pointerControllerDump;
268 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900269 dump += INDENT "StylusPointerControllers:\n";
270 for (const auto& [deviceId, stylusPointerController] : mStylusPointersByDevice) {
271 std::string pointerControllerDump = addLinePrefix(stylusPointerController->dump(), INDENT);
272 dump += INDENT + std::to_string(deviceId) + " : " + pointerControllerDump;
273 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900274 dump += "\n";
275}
276
277const DisplayViewport* PointerChoreographer::findViewportByIdLocked(int32_t displayId) const {
278 for (auto& viewport : mViewports) {
279 if (viewport.displayId == displayId) {
280 return &viewport;
281 }
282 }
283 return nullptr;
284}
285
286int32_t PointerChoreographer::getTargetMouseDisplayLocked(int32_t associatedDisplayId) const {
287 return associatedDisplayId == ADISPLAY_ID_NONE ? mDefaultMouseDisplayId : associatedDisplayId;
288}
289
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900290InputDeviceInfo* PointerChoreographer::findInputDeviceLocked(DeviceId deviceId) {
291 for (auto& info : mInputDeviceInfos) {
292 if (info.getId() == deviceId) {
293 return &info;
294 }
295 }
296 return nullptr;
297}
298
Byoungho Jungda10dd32023-10-06 17:03:45 +0900299void PointerChoreographer::updatePointerControllersLocked() {
300 std::set<int32_t /*displayId*/> mouseDisplaysToKeep;
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900301 std::set<DeviceId> touchDevicesToKeep;
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900302 std::set<DeviceId> stylusDevicesToKeep;
Byoungho Jungda10dd32023-10-06 17:03:45 +0900303
304 // Mark the displayIds or deviceIds of PointerControllers currently needed.
305 for (const auto& info : mInputDeviceInfos) {
306 const uint32_t sources = info.getSources();
307 if (isFromSource(sources, AINPUT_SOURCE_MOUSE) ||
308 isFromSource(sources, AINPUT_SOURCE_MOUSE_RELATIVE)) {
309 const int32_t resolvedDisplayId =
310 getTargetMouseDisplayLocked(info.getAssociatedDisplayId());
311 mouseDisplaysToKeep.insert(resolvedDisplayId);
312 }
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900313 if (isFromSource(sources, AINPUT_SOURCE_TOUCHSCREEN) && mShowTouchesEnabled &&
314 info.getAssociatedDisplayId() != ADISPLAY_ID_NONE) {
315 touchDevicesToKeep.insert(info.getId());
316 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900317 if (isFromSource(sources, AINPUT_SOURCE_STYLUS) && mStylusPointerIconEnabled &&
318 info.getAssociatedDisplayId() != ADISPLAY_ID_NONE) {
319 stylusDevicesToKeep.insert(info.getId());
320 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900321 }
322
323 // Remove PointerControllers no longer needed.
324 // This has the side-effect of fading pointers or clearing spots before removal.
Prabir Pradhan19767602023-11-03 16:53:31 +0000325 std::erase_if(mMousePointersByDisplay, [&mouseDisplaysToKeep](const auto& pair) {
326 auto& [displayId, controller] = pair;
327 if (mouseDisplaysToKeep.find(displayId) == mouseDisplaysToKeep.end()) {
328 controller->fade(PointerControllerInterface::Transition::IMMEDIATE);
Byoungho Jungda10dd32023-10-06 17:03:45 +0900329 return true;
330 }
331 return false;
332 });
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900333 std::erase_if(mTouchPointersByDevice, [&touchDevicesToKeep](const auto& pair) {
334 auto& [deviceId, controller] = pair;
335 if (touchDevicesToKeep.find(deviceId) == touchDevicesToKeep.end()) {
336 controller->clearSpots();
337 return true;
338 }
339 return false;
340 });
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900341 std::erase_if(mStylusPointersByDevice, [&stylusDevicesToKeep](const auto& pair) {
342 auto& [deviceId, controller] = pair;
343 if (stylusDevicesToKeep.find(deviceId) == stylusDevicesToKeep.end()) {
344 controller->fade(PointerControllerInterface::Transition::IMMEDIATE);
345 return true;
346 }
347 return false;
348 });
Byoungho Jungda10dd32023-10-06 17:03:45 +0900349
350 // Notify the policy if there's a change on the pointer display ID.
351 notifyPointerDisplayIdChangedLocked();
352}
353
354void PointerChoreographer::notifyPointerDisplayIdChangedLocked() {
355 int32_t displayIdToNotify = ADISPLAY_ID_NONE;
356 FloatPoint cursorPosition = {0, 0};
357 if (const auto it = mMousePointersByDisplay.find(mDefaultMouseDisplayId);
358 it != mMousePointersByDisplay.end()) {
Prabir Pradhan19767602023-11-03 16:53:31 +0000359 const auto& pointerController = it->second;
360 // Use the displayId from the pointerController, because it accurately reflects whether
361 // the viewport has been added for that display. Otherwise, we would have to check if
362 // the viewport exists separately.
363 displayIdToNotify = pointerController->getDisplayId();
364 cursorPosition = pointerController->getPosition();
Byoungho Jungda10dd32023-10-06 17:03:45 +0900365 }
366
367 if (mNotifiedPointerDisplayId == displayIdToNotify) {
368 return;
369 }
370 mPolicy.notifyPointerDisplayIdChanged(displayIdToNotify, cursorPosition);
371 mNotifiedPointerDisplayId = displayIdToNotify;
372}
373
374void PointerChoreographer::setDefaultMouseDisplayId(int32_t displayId) {
375 std::scoped_lock _l(mLock);
376
377 mDefaultMouseDisplayId = displayId;
378 updatePointerControllersLocked();
379}
380
381void PointerChoreographer::setDisplayViewports(const std::vector<DisplayViewport>& viewports) {
382 std::scoped_lock _l(mLock);
383 for (const auto& viewport : viewports) {
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900384 const int32_t displayId = viewport.displayId;
385 if (const auto it = mMousePointersByDisplay.find(displayId);
Byoungho Jungda10dd32023-10-06 17:03:45 +0900386 it != mMousePointersByDisplay.end()) {
387 it->second->setDisplayViewport(viewport);
388 }
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900389 for (const auto& [deviceId, stylusPointerController] : mStylusPointersByDevice) {
390 const InputDeviceInfo* info = findInputDeviceLocked(deviceId);
391 if (info && info->getAssociatedDisplayId() == displayId) {
392 stylusPointerController->setDisplayViewport(viewport);
393 }
394 }
Byoungho Jungda10dd32023-10-06 17:03:45 +0900395 }
396 mViewports = viewports;
397 notifyPointerDisplayIdChangedLocked();
398}
399
400std::optional<DisplayViewport> PointerChoreographer::getViewportForPointerDevice(
401 int32_t associatedDisplayId) {
402 std::scoped_lock _l(mLock);
403 const int32_t resolvedDisplayId = getTargetMouseDisplayLocked(associatedDisplayId);
404 if (const auto viewport = findViewportByIdLocked(resolvedDisplayId); viewport) {
405 return *viewport;
406 }
407 return std::nullopt;
408}
409
410FloatPoint PointerChoreographer::getMouseCursorPosition(int32_t displayId) {
411 std::scoped_lock _l(mLock);
412 const int32_t resolvedDisplayId = getTargetMouseDisplayLocked(displayId);
413 if (auto it = mMousePointersByDisplay.find(resolvedDisplayId);
414 it != mMousePointersByDisplay.end()) {
415 return it->second->getPosition();
416 }
417 return {AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION};
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000418}
419
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900420void PointerChoreographer::setShowTouchesEnabled(bool enabled) {
421 std::scoped_lock _l(mLock);
422 if (mShowTouchesEnabled == enabled) {
423 return;
424 }
425 mShowTouchesEnabled = enabled;
426 updatePointerControllersLocked();
427}
428
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900429void PointerChoreographer::setStylusPointerIconEnabled(bool enabled) {
430 std::scoped_lock _l(mLock);
431 if (mStylusPointerIconEnabled == enabled) {
432 return;
433 }
434 mStylusPointerIconEnabled = enabled;
435 updatePointerControllersLocked();
436}
437
Prabir Pradhan19767602023-11-03 16:53:31 +0000438PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
439 int32_t displayId) {
440 std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
441 [this, displayId]() REQUIRES(mLock) {
442 auto pc = mPolicy.createPointerController(
443 PointerControllerInterface::ControllerType::MOUSE);
444 if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
445 pc->setDisplayViewport(*viewport);
446 }
447 return pc;
448 };
449 return ConstructorDelegate(std::move(ctor));
450}
451
Byoungho Jung6f5b16b2023-10-27 18:22:07 +0900452PointerChoreographer::ControllerConstructor PointerChoreographer::getTouchControllerConstructor() {
453 std::function<std::shared_ptr<PointerControllerInterface>()> ctor = [this]() REQUIRES(mLock) {
454 return mPolicy.createPointerController(PointerControllerInterface::ControllerType::TOUCH);
455 };
456 return ConstructorDelegate(std::move(ctor));
457}
458
Byoungho Jungd6fe27b2023-10-27 20:49:38 +0900459PointerChoreographer::ControllerConstructor PointerChoreographer::getStylusControllerConstructor(
460 int32_t displayId) {
461 std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
462 [this, displayId]() REQUIRES(mLock) {
463 auto pc = mPolicy.createPointerController(
464 PointerControllerInterface::ControllerType::STYLUS);
465 if (const auto viewport = findViewportByIdLocked(displayId); viewport) {
466 pc->setDisplayViewport(*viewport);
467 }
468 return pc;
469 };
470 return ConstructorDelegate(std::move(ctor));
471}
472
Prabir Pradhanb56e92c2023-06-09 23:40:37 +0000473} // namespace android