Pointer icon refactor for stylus (base)

When PointerChoreographer is enabled, PointerChoreographer can
create multiple StylusPointerControllers for each stylus device.
A StylusPointerController is created when the corresponding stylus
sends the first hover event. It can show and hide a hover pointer
on the associated display.

Test: atest libinputservice_test
Bug: 293587049
Change-Id: I208f09f0e0f73a6396d60f5b2bd0242dddd3c66b
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 246db6c..972e168 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -78,6 +78,10 @@
             controller = std::shared_ptr<PointerController>(
                     new TouchPointerController(policy, looper, spriteController, enabled));
             break;
+        case ControllerType::STYLUS:
+            controller = std::shared_ptr<PointerController>(
+                    new StylusPointerController(policy, looper, spriteController, enabled));
+            break;
         case ControllerType::LEGACY:
         default:
             controller = std::shared_ptr<PointerController>(
@@ -410,4 +414,13 @@
     PointerController::setPresentation(Presentation::SPOT);
 }
 
+// --- StylusPointerController ---
+
+StylusPointerController::StylusPointerController(const sp<PointerControllerPolicyInterface>& policy,
+                                                 const sp<Looper>& looper,
+                                                 SpriteController& spriteController, bool enabled)
+      : PointerController(policy, looper, spriteController, enabled) {
+    PointerController::setPresentation(Presentation::STYLUS_HOVER);
+}
+
 } // namespace android
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 1a8e109..6461abf 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -198,6 +198,24 @@
     void setInactivityTimeout(InactivityTimeout) override {}
 };
 
+class StylusPointerController : public PointerController {
+public:
+    /** A version of PointerController that controls one stylus pointer. */
+    StylusPointerController(const sp<PointerControllerPolicyInterface>& policy,
+                            const sp<Looper>& looper, SpriteController& spriteController,
+                            bool enabled);
+
+    void setPresentation(Presentation) override {
+        LOG_ALWAYS_FATAL("Should not be called");
+    }
+    void setSpots(const PointerCoords*, const uint32_t*, BitSet32, int32_t) override {
+        LOG_ALWAYS_FATAL("Should not be called");
+    }
+    void clearSpots() override {
+        LOG_ALWAYS_FATAL("Should not be called");
+    }
+};
+
 } // namespace android
 
 #endif // _UI_POINTER_CONTROLLER_H
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index c05406a..2182093 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1749,6 +1749,11 @@
 }
 
 void NativeInputManager::setStylusPointerIconEnabled(bool enabled) {
+    if (ENABLE_POINTER_CHOREOGRAPHER) {
+        mInputManager->getChoreographer().setStylusPointerIconEnabled(enabled);
+        return;
+    }
+
     { // acquire lock
         std::scoped_lock _l(mLock);