Pointer icon refactor for mouse (base)

When PointerChoreographer is enabled, CursorInputMapper no longer
depends on the legacy PointerController. PointerChoreographer is
responsible for accumulating movements, fading/unfading pointers,
and deciding display/coordinates.

Test: atest libinputservice_test
Bug: 293587049

Change-Id: Ie35b385a99623bbcb2e47b394b7cf2c0f7c5bc0e
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index abd9284..576ebc1 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -24,6 +24,7 @@
 #include <SkColor.h>
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
+#include <com_android_input_flags.h>
 #include <ftl/enum.h>
 
 #include <mutex>
@@ -34,6 +35,8 @@
 #define INDENT2 "    "
 #define INDENT3 "      "
 
+namespace input_flags = com::android::input::flags;
+
 namespace android {
 
 namespace {
@@ -63,10 +66,20 @@
 
 std::shared_ptr<PointerController> PointerController::create(
         const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
-        SpriteController& spriteController, bool enabled) {
+        SpriteController& spriteController, bool enabled, ControllerType type) {
     // using 'new' to access non-public constructor
-    std::shared_ptr<PointerController> controller = std::shared_ptr<PointerController>(
-            new PointerController(policy, looper, spriteController, enabled));
+    std::shared_ptr<PointerController> controller;
+    switch (type) {
+        case ControllerType::MOUSE:
+            controller = std::shared_ptr<PointerController>(
+                    new MousePointerController(policy, looper, spriteController, enabled));
+            break;
+        case ControllerType::LEGACY:
+        default:
+            controller = std::shared_ptr<PointerController>(
+                    new PointerController(policy, looper, spriteController, enabled));
+            break;
+    }
 
     /*
      * Now we need to hook up the constructed PointerController object to its callbacks.
@@ -375,4 +388,13 @@
     return dump;
 }
 
+// --- MousePointerController ---
+
+MousePointerController::MousePointerController(const sp<PointerControllerPolicyInterface>& policy,
+                                               const sp<Looper>& looper,
+                                               SpriteController& spriteController, bool enabled)
+      : PointerController(policy, looper, spriteController, enabled) {
+    PointerController::setPresentation(Presentation::POINTER);
+}
+
 } // namespace android
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index aa7ca3c..08e19a0 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -47,7 +47,8 @@
 public:
     static std::shared_ptr<PointerController> create(
             const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
-            SpriteController& spriteController, bool enabled);
+            SpriteController& spriteController, bool enabled,
+            ControllerType type = ControllerType::LEGACY);
 
     ~PointerController() override;
 
@@ -75,7 +76,7 @@
     void onDisplayInfosChangedLocked(const std::vector<gui::DisplayInfo>& displayInfos)
             REQUIRES(getLock());
 
-    std::string dump();
+    std::string dump() override;
 
 protected:
     using WindowListenerConsumer =
@@ -87,10 +88,10 @@
                       WindowListenerConsumer registerListener,
                       WindowListenerConsumer unregisterListener);
 
-private:
     PointerController(const sp<PointerControllerPolicyInterface>& policy, const sp<Looper>& looper,
                       SpriteController& spriteController, bool enabled);
 
+private:
     friend PointerControllerContext::LooperCallback;
     friend PointerControllerContext::MessageHandler;
 
@@ -135,6 +136,24 @@
     void clearSpotsLocked() REQUIRES(getLock());
 };
 
+class MousePointerController : public PointerController {
+public:
+    /** A version of PointerController that controls one mouse pointer. */
+    MousePointerController(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 176bc283..5767c49 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -86,6 +86,8 @@
 
 namespace android {
 
+static const bool ENABLE_POINTER_CHOREOGRAPHER = input_flags::enable_pointer_choreographer();
+
 // The exponent used to calculate the pointer speed scaling factor.
 // The scaling factor is calculated as 2 ^ (speed * exponent),
 // where the speed ranges from -7 to + 7 and is supplied by the user.
@@ -327,6 +329,8 @@
     TouchAffineTransformation getTouchAffineTransformation(JNIEnv* env, jfloatArray matrixArr);
     void notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) override;
     bool isInputMethodConnectionActive() override;
+    std::optional<DisplayViewport> getViewportForPointerDevice(
+            int32_t associatedDisplayId) override;
 
     /* --- InputDispatcherPolicyInterface implementation --- */
 
@@ -374,8 +378,10 @@
     virtual PointerIconStyle getCustomPointerIconId();
     virtual void onPointerDisplayIdChanged(int32_t displayId, const FloatPoint& position);
 
-    /* --- PointerControllerPolicyInterface implementation --- */
-    std::shared_ptr<PointerControllerInterface> createPointerController() override;
+    /* --- PointerChoreographerPolicyInterface implementation --- */
+    std::shared_ptr<PointerControllerInterface> createPointerController(
+            PointerControllerInterface::ControllerType type) override;
+    void notifyPointerDisplayIdChanged(int32_t displayId, const FloatPoint& position) override;
 
 private:
     sp<InputManagerInterface> mInputManager;
@@ -492,7 +498,9 @@
         dump += StringPrintf(INDENT "Pointer Capture: %s, seq=%" PRIu32 "\n",
                              mLocked.pointerCaptureRequest.enable ? "Enabled" : "Disabled",
                              mLocked.pointerCaptureRequest.seq);
-        forEachPointerControllerLocked([&dump](PointerController& pc) { dump += pc.dump(); });
+        if (auto pc = mLocked.legacyPointerController.lock(); pc) {
+            dump += pc->dump();
+        }
     } // release lock
     dump += "\n";
 
@@ -537,6 +545,9 @@
                 [&viewports](PointerController& pc) { pc.onDisplayViewportsUpdated(viewports); });
     } // release lock
 
+    if (ENABLE_POINTER_CHOREOGRAPHER) {
+        mInputManager->getChoreographer().setDisplayViewports(viewports);
+    }
     mInputManager->getReader().requestRefreshConfiguration(
             InputReaderConfiguration::Change::DISPLAY_INFO);
 }
@@ -721,6 +732,7 @@
             continue;
         }
         apply(*pc);
+        it++;
     }
 }
 
@@ -735,9 +747,6 @@
     if (controller == nullptr) {
         ensureSpriteControllerLocked();
 
-        static const bool ENABLE_POINTER_CHOREOGRAPHER =
-                input_flags::enable_pointer_choreographer();
-
         // Disable the functionality of the legacy PointerController if PointerChoreographer is
         // enabled.
         controller = PointerController::create(this, mLooper, *mLocked.spriteController,
@@ -749,17 +758,43 @@
     return controller;
 }
 
-std::shared_ptr<PointerControllerInterface> NativeInputManager::createPointerController() {
+std::shared_ptr<PointerControllerInterface> NativeInputManager::createPointerController(
+        PointerControllerInterface::ControllerType type) {
     std::scoped_lock _l(mLock);
     ensureSpriteControllerLocked();
     std::shared_ptr<PointerController> pc =
-            PointerController::create(this, mLooper, *mLocked.spriteController, /*enabled=*/true);
+            PointerController::create(this, mLooper, *mLocked.spriteController, /*enabled=*/true,
+                                      type);
     mLocked.pointerControllers.emplace_back(pc);
     return pc;
 }
 
 void NativeInputManager::onPointerDisplayIdChanged(int32_t pointerDisplayId,
                                                    const FloatPoint& position) {
+    if (ENABLE_POINTER_CHOREOGRAPHER) {
+        return;
+    }
+    JNIEnv* env = jniEnv();
+    env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDisplayIdChanged, pointerDisplayId,
+                        position.x, position.y);
+    checkAndClearExceptionFromCallback(env, "onPointerDisplayIdChanged");
+}
+
+void NativeInputManager::notifyPointerDisplayIdChanged(int32_t pointerDisplayId,
+                                                       const FloatPoint& position) {
+    // Notify the Reader so that devices can be reconfigured.
+    { // acquire lock
+        std::scoped_lock _l(mLock);
+        if (mLocked.pointerDisplayId == pointerDisplayId) {
+            return;
+        }
+        mLocked.pointerDisplayId = pointerDisplayId;
+        ALOGI("%s: pointer displayId set to: %d", __func__, pointerDisplayId);
+    } // release lock
+    mInputManager->getReader().requestRefreshConfiguration(
+            InputReaderConfiguration::Change::DISPLAY_INFO);
+
+    // Notify the system.
     JNIEnv* env = jniEnv();
     env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDisplayIdChanged, pointerDisplayId,
                         position.x, position.y);
@@ -1118,19 +1153,23 @@
 }
 
 void NativeInputManager::setPointerDisplayId(int32_t displayId) {
-    { // acquire lock
-        std::scoped_lock _l(mLock);
+    if (ENABLE_POINTER_CHOREOGRAPHER) {
+        mInputManager->getChoreographer().setDefaultMouseDisplayId(displayId);
+    } else {
+        { // acquire lock
+            std::scoped_lock _l(mLock);
 
-        if (mLocked.pointerDisplayId == displayId) {
-            return;
-        }
+            if (mLocked.pointerDisplayId == displayId) {
+                return;
+            }
 
-        ALOGI("Setting pointer display id to %d.", displayId);
-        mLocked.pointerDisplayId = displayId;
-    } // release lock
+            ALOGI("Setting pointer display id to %d.", displayId);
+            mLocked.pointerDisplayId = displayId;
+        } // release lock
 
-    mInputManager->getReader().requestRefreshConfiguration(
-            InputReaderConfiguration::Change::DISPLAY_INFO);
+        mInputManager->getReader().requestRefreshConfiguration(
+                InputReaderConfiguration::Change::DISPLAY_INFO);
+    }
 }
 
 void NativeInputManager::setPointerSpeed(int32_t speed) {
@@ -1356,6 +1395,11 @@
     return result;
 }
 
+std::optional<DisplayViewport> NativeInputManager::getViewportForPointerDevice(
+        int32_t associatedDisplayId) {
+    return mInputManager->getChoreographer().getViewportForPointerDevice(associatedDisplayId);
+}
+
 bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) {
     ATRACE_CALL();
     JNIEnv* env = jniEnv();
@@ -1689,6 +1733,9 @@
 }
 
 FloatPoint NativeInputManager::getMouseCursorPosition() {
+    if (ENABLE_POINTER_CHOREOGRAPHER) {
+        return mInputManager->getChoreographer().getMouseCursorPosition(ADISPLAY_ID_NONE);
+    }
     std::scoped_lock _l(mLock);
     const auto pc = mLocked.legacyPointerController.lock();
     if (!pc) return {AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION};