Do not show pointer for disabled device

We currently display the pointer for all devices that support displaying
it, but there are actually some devices that are disabled and shouldn't
actually have it displayed for them, here's an implementation for that.

This is done by adding an enabled state to the InputDeviceInfo to
determine its disabled status.

Bug: 335795596
Test: atest inputflinger_tests

Signed-off-by: Linnan Li <lilinnan@xiaomi.corp-partner.google.com>
(cherry picked from https://partner-android-review.googlesource.com/q/commit:d7c5c6d376f5eae7cbb7cce5ea12f2ba420d87ab)
Merged-In: Ibdad9f8424a29d83412866eace0ef96026fb270a
Change-Id: Ibdad9f8424a29d83412866eace0ef96026fb270a
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 10efea5..4dc2737 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -434,6 +434,11 @@
     // Mark the displayIds or deviceIds of PointerControllers currently needed, and create
     // new PointerControllers if necessary.
     for (const auto& info : mInputDeviceInfos) {
+        if (!info.isEnabled()) {
+            // If device is disabled, we should not keep it, and should not show pointer for
+            // disabled mouse device.
+            continue;
+        }
         const uint32_t sources = info.getSources();
         const bool isKnownMouse = mMouseDevices.count(info.getId()) != 0;
 
diff --git a/services/inputflinger/reader/InputDevice.cpp b/services/inputflinger/reader/InputDevice.cpp
index 782c84a..af1ab4a 100644
--- a/services/inputflinger/reader/InputDevice.cpp
+++ b/services/inputflinger/reader/InputDevice.cpp
@@ -409,7 +409,7 @@
     InputDeviceInfo outDeviceInfo;
     outDeviceInfo.initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias, mIsExternal,
                              mHasMic, getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE),
-                             {mShouldSmoothScroll});
+                             {mShouldSmoothScroll}, isEnabled());
 
     for_each_mapper(
             [&outDeviceInfo](InputMapper& mapper) { mapper.populateDeviceInfo(outDeviceInfo); });
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 7d1b23c..11c6b7e 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -42,6 +42,7 @@
 
 constexpr int32_t DEVICE_ID = 3;
 constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1;
+constexpr int32_t THIRD_DEVICE_ID = SECOND_DEVICE_ID + 1;
 constexpr int32_t DISPLAY_ID = 5;
 constexpr int32_t ANOTHER_DISPLAY_ID = 10;
 constexpr int32_t DISPLAY_WIDTH = 480;
@@ -537,7 +538,8 @@
     mChoreographer.notifyInputDevicesChanged(
             {/*id=*/0,
              {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE),
-              generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
+              generateTestDeviceInfo(SECOND_DEVICE_ID,
+                                     AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
                                      DISPLAY_ID)}});
 
     ASSERT_FALSE(pc->isPointerShown());
@@ -548,6 +550,73 @@
     ASSERT_FALSE(pc->isPointerShown());
 }
 
+TEST_F(PointerChoreographerTest, DisabledMouseConnected) {
+    mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
+    mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID);
+    InputDeviceInfo mouseDeviceInfo =
+            generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE);
+    // Disable this mouse device.
+    mouseDeviceInfo.setEnabled(false);
+    mChoreographer.notifyInputDevicesChanged({/*id=*/0, {mouseDeviceInfo}});
+
+    // Disabled mouse device should not create PointerController
+    assertPointerControllerNotCreated();
+}
+
+TEST_F(PointerChoreographerTest, MouseDeviceDisableLater) {
+    mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
+    mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID);
+    InputDeviceInfo mouseDeviceInfo =
+            generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE);
+
+    mChoreographer.notifyInputDevicesChanged({/*id=*/0, {mouseDeviceInfo}});
+
+    auto pc = assertPointerControllerCreated(PointerControllerInterface::ControllerType::MOUSE);
+    ASSERT_TRUE(pc->isPointerShown());
+
+    // Now we disable this mouse device
+    mouseDeviceInfo.setEnabled(false);
+    mChoreographer.notifyInputDevicesChanged({/*id=*/0, {mouseDeviceInfo}});
+
+    // Because the mouse device disabled, the PointerController should be removed.
+    assertPointerControllerRemoved(pc);
+}
+
+TEST_F(PointerChoreographerTest, MultipleEnabledAndDisabledMiceConnectionAndRemoval) {
+    mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
+    mChoreographer.setDefaultMouseDisplayId(DISPLAY_ID);
+    InputDeviceInfo disabledMouseDeviceInfo =
+            generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE);
+    disabledMouseDeviceInfo.setEnabled(false);
+
+    InputDeviceInfo enabledMouseDeviceInfo =
+            generateTestDeviceInfo(SECOND_DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE);
+
+    InputDeviceInfo anotherEnabledMouseDeviceInfo =
+            generateTestDeviceInfo(THIRD_DEVICE_ID, AINPUT_SOURCE_MOUSE, ADISPLAY_ID_NONE);
+
+    mChoreographer.notifyInputDevicesChanged(
+            {/*id=*/0,
+             {disabledMouseDeviceInfo, enabledMouseDeviceInfo, anotherEnabledMouseDeviceInfo}});
+
+    // Mouse should show, because we have two enabled mice device.
+    auto pc = assertPointerControllerCreated(PointerControllerInterface::ControllerType::MOUSE);
+    ASSERT_TRUE(pc->isPointerShown());
+
+    // Now we remove one of enabled mice device.
+    mChoreographer.notifyInputDevicesChanged(
+            {/*id=*/0, {disabledMouseDeviceInfo, enabledMouseDeviceInfo}});
+
+    // Because we still have an enabled mouse device, pointer should still show.
+    ASSERT_TRUE(pc->isPointerShown());
+
+    // We finally remove last enabled mouse device.
+    mChoreographer.notifyInputDevicesChanged({/*id=*/0, {disabledMouseDeviceInfo}});
+
+    // The PointerController should be removed, because there is no enabled mouse device.
+    assertPointerControllerRemoved(pc);
+}
+
 TEST_F(PointerChoreographerTest, WhenShowTouchesEnabledAndDisabledDoesNotCreatePointerController) {
     // Disable show touches and add a touch device.
     mChoreographer.setShowTouchesEnabled(false);