Add setPointerIcon for PointerChoreographer

To set pointer icon for mouse or stylus, we are going to use
setPointerIcon with more parameters which will be useful for
multi-device experience and security.

Test: atest inputflinger_tests
Bug: 293587049
Change-Id: Ie0250928ed28c6dc238faa8dcae8ad154ed053fe
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index f1faf69..78ece3b 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -445,6 +445,57 @@
     updatePointerControllersLocked();
 }
 
+bool PointerChoreographer::setPointerIcon(
+        std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon, int32_t displayId,
+        DeviceId deviceId) {
+    std::scoped_lock _l(mLock);
+    if (deviceId < 0) {
+        ALOGW("Invalid device id %d. Cannot set pointer icon.", deviceId);
+        return false;
+    }
+    const InputDeviceInfo* info = findInputDeviceLocked(deviceId);
+    if (!info) {
+        ALOGW("No input device info found for id %d. Cannot set pointer icon.", deviceId);
+        return false;
+    }
+    const uint32_t sources = info->getSources();
+    const auto stylusPointerIt = mStylusPointersByDevice.find(deviceId);
+
+    if (isFromSource(sources, AINPUT_SOURCE_STYLUS) &&
+        stylusPointerIt != mStylusPointersByDevice.end()) {
+        if (std::holds_alternative<std::unique_ptr<SpriteIcon>>(icon)) {
+            if (std::get<std::unique_ptr<SpriteIcon>>(icon) == nullptr) {
+                LOG(FATAL) << "SpriteIcon should not be null";
+            }
+            stylusPointerIt->second->setCustomPointerIcon(
+                    *std::get<std::unique_ptr<SpriteIcon>>(icon));
+        } else {
+            stylusPointerIt->second->updatePointerIcon(std::get<PointerIconStyle>(icon));
+        }
+    } else if (isFromSource(sources, AINPUT_SOURCE_MOUSE)) {
+        if (const auto mousePointerIt = mMousePointersByDisplay.find(displayId);
+            mousePointerIt != mMousePointersByDisplay.end()) {
+            if (std::holds_alternative<std::unique_ptr<SpriteIcon>>(icon)) {
+                if (std::get<std::unique_ptr<SpriteIcon>>(icon) == nullptr) {
+                    LOG(FATAL) << "SpriteIcon should not be null";
+                }
+                mousePointerIt->second->setCustomPointerIcon(
+                        *std::get<std::unique_ptr<SpriteIcon>>(icon));
+            } else {
+                mousePointerIt->second->updatePointerIcon(std::get<PointerIconStyle>(icon));
+            }
+        } else {
+            ALOGW("No mouse pointer controller found for display %d, device %d.", displayId,
+                  deviceId);
+            return false;
+        }
+    } else {
+        ALOGW("Cannot set pointer icon for display %d, device %d.", displayId, deviceId);
+        return false;
+    }
+    return true;
+}
+
 PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
         int32_t displayId) {
     std::function<std::shared_ptr<PointerControllerInterface>()> ctor =