Merge "Pointer Icon Refactor: Integrate setPointerIconVisible" into main
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index fb4943a..c1d5ebf 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1328,8 +1328,7 @@
             mPointerIconDisplayContext = null;
         }
 
-        updateAdditionalDisplayInputProperties(displayId,
-                AdditionalDisplayInputProperties::reset);
+        updateAdditionalDisplayInputProperties(displayId, AdditionalDisplayInputProperties::reset);
 
         // TODO(b/320763728): Rely on WindowInfosListener to determine when a display has been
         //  removed in InputDispatcher instead of this callback.
@@ -1812,8 +1811,6 @@
             mPointerIconType = icon.getType();
             mPointerIcon = mPointerIconType == PointerIcon.TYPE_CUSTOM ? icon : null;
 
-            if (!mCurrentDisplayProperties.pointerIconVisible) return false;
-
             return mNative.setPointerIcon(icon, displayId, deviceId, pointerId, inputToken);
         }
     }
@@ -3509,7 +3506,11 @@
                 properties = new AdditionalDisplayInputProperties();
                 mAdditionalDisplayInputProperties.put(displayId, properties);
             }
+            final boolean oldPointerIconVisible = properties.pointerIconVisible;
             updater.accept(properties);
+            if (oldPointerIconVisible != properties.pointerIconVisible) {
+                mNative.setPointerIconVisibility(displayId, properties.pointerIconVisible);
+            }
             if (properties.allDefaults()) {
                 mAdditionalDisplayInputProperties.remove(displayId);
             }
diff --git a/services/core/java/com/android/server/input/NativeInputManagerService.java b/services/core/java/com/android/server/input/NativeInputManagerService.java
index c3ef80f..706db3d 100644
--- a/services/core/java/com/android/server/input/NativeInputManagerService.java
+++ b/services/core/java/com/android/server/input/NativeInputManagerService.java
@@ -190,6 +190,8 @@
     boolean setPointerIcon(@NonNull PointerIcon icon, int displayId, int deviceId, int pointerId,
             @NonNull IBinder inputToken);
 
+    void setPointerIconVisibility(int displayId, boolean visible);
+
     void requestPointerCapture(IBinder windowToken, boolean enabled);
 
     boolean canDispatchToDisplay(int deviceId, int displayId);
@@ -452,6 +454,9 @@
                 int pointerId, IBinder inputToken);
 
         @Override
+        public native void setPointerIconVisibility(int displayId, boolean visible);
+
+        @Override
         public native void requestPointerCapture(IBinder windowToken, boolean enabled);
 
         @Override
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 1c90e30..ce0efe1 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -304,6 +304,7 @@
     bool setPointerIcon(std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
                         int32_t displayId, DeviceId deviceId, int32_t pointerId,
                         const sp<IBinder>& inputToken);
+    void setPointerIconVisibility(int32_t displayId, bool visible);
     void setMotionClassifierEnabled(bool enabled);
     std::optional<std::string> getBluetoothAddress(int32_t deviceId);
     void setStylusButtonMotionEventsEnabled(bool enabled);
@@ -1397,6 +1398,13 @@
     return mInputManager->getChoreographer().setPointerIcon(std::move(icon), displayId, deviceId);
 }
 
+void NativeInputManager::setPointerIconVisibility(int32_t displayId, bool visible) {
+    if (!ENABLE_POINTER_CHOREOGRAPHER) {
+        return;
+    }
+    mInputManager->getChoreographer().setPointerIconVisibility(displayId, visible);
+}
+
 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
         JNIEnv *env, jfloatArray matrixArr) {
     ATRACE_CALL();
@@ -2550,6 +2558,13 @@
                               ibinderForJavaObject(env, inputTokenObj));
 }
 
+static void nativeSetPointerIconVisibility(JNIEnv* env, jobject nativeImplObj, jint displayId,
+                                           jboolean visible) {
+    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
+
+    im->setPointerIconVisibility(displayId, visible);
+}
+
 static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jobject nativeImplObj, jint deviceId,
                                            jint displayId) {
     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
@@ -2828,6 +2843,7 @@
          (void*)nativeSetCustomPointerIcon},
         {"setPointerIcon", "(Landroid/view/PointerIcon;IIILandroid/os/IBinder;)Z",
          (void*)nativeSetPointerIcon},
+        {"setPointerIconVisibility", "(IZ)V", (void*)nativeSetPointerIconVisibility},
         {"canDispatchToDisplay", "(II)Z", (void*)nativeCanDispatchToDisplay},
         {"notifyPortAssociationsChanged", "()V", (void*)nativeNotifyPortAssociationsChanged},
         {"changeUniqueIdAssociation", "()V", (void*)nativeChangeUniqueIdAssociation},
diff --git a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
index b058631..60a9f0b 100644
--- a/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
+++ b/tests/Input/src/com/android/server/input/InputManagerServiceTests.kt
@@ -292,11 +292,13 @@
         setVirtualMousePointerDisplayIdAndVerify(10)
 
         localService.setPointerIconVisible(false, 10)
+        verify(native).setPointerIconVisibility(10, false)
         verify(native).setPointerIconType(eq(PointerIcon.TYPE_NULL))
         localService.setMousePointerAccelerationEnabled(false, 10)
         verify(native).setMousePointerAccelerationEnabled(eq(false))
 
         service.onDisplayRemoved(10)
+        verify(native).setPointerIconVisibility(10, true)
         verify(native).displayRemoved(eq(10))
         verify(native).setPointerIconType(eq(PointerIcon.TYPE_NOT_SPECIFIED))
         verify(native).setMousePointerAccelerationEnabled(true)
@@ -315,17 +317,20 @@
 
         localService.setPointerIconVisible(false, 10)
         verify(native).setPointerIconType(eq(PointerIcon.TYPE_NULL))
+        verify(native).setPointerIconVisibility(10, false)
         localService.setMousePointerAccelerationEnabled(false, 10)
         verify(native).setMousePointerAccelerationEnabled(eq(false))
 
         localService.setPointerIconVisible(true, 10)
         verify(native).setPointerIconType(eq(PointerIcon.TYPE_NOT_SPECIFIED))
+        verify(native).setPointerIconVisibility(10, true)
         localService.setMousePointerAccelerationEnabled(true, 10)
         verify(native).setMousePointerAccelerationEnabled(eq(true))
 
         // Verify that setting properties on a different display is not propagated until the
         // pointer is moved to that display.
         localService.setPointerIconVisible(false, 20)
+        verify(native).setPointerIconVisibility(20, false)
         localService.setMousePointerAccelerationEnabled(false, 20)
         verifyNoMoreInteractions(native)
 
@@ -341,6 +346,7 @@
         localService.setPointerIconVisible(false, 10)
         localService.setMousePointerAccelerationEnabled(false, 10)
 
+        verify(native).setPointerIconVisibility(10, false)
         verifyNoMoreInteractions(native)
 
         setVirtualMousePointerDisplayIdAndVerify(10)