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/include/input/InputDevice.h b/include/input/InputDevice.h
index 57b659d..798f680 100644
--- a/include/input/InputDevice.h
+++ b/include/input/InputDevice.h
@@ -278,7 +278,7 @@
void initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
bool isExternal, bool hasMic, int32_t associatedDisplayId,
- InputDeviceViewBehavior viewBehavior = {{}});
+ InputDeviceViewBehavior viewBehavior = {{}}, bool enabled = true);
inline int32_t getId() const { return mId; }
inline int32_t getControllerNumber() const { return mControllerNumber; }
@@ -347,6 +347,9 @@
inline int32_t getAssociatedDisplayId() const { return mAssociatedDisplayId; }
+ inline void setEnabled(bool enabled) { mEnabled = enabled; }
+ inline bool isEnabled() const { return mEnabled; }
+
private:
int32_t mId;
int32_t mGeneration;
@@ -361,6 +364,7 @@
std::shared_ptr<KeyCharacterMap> mKeyCharacterMap;
std::optional<InputDeviceUsiVersion> mUsiVersion;
int32_t mAssociatedDisplayId;
+ bool mEnabled;
bool mHasVibrator;
bool mHasBattery;
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index c348833..222647d 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -187,6 +187,7 @@
mKeyCharacterMap(other.mKeyCharacterMap),
mUsiVersion(other.mUsiVersion),
mAssociatedDisplayId(other.mAssociatedDisplayId),
+ mEnabled(other.mEnabled),
mHasVibrator(other.mHasVibrator),
mHasBattery(other.mHasBattery),
mHasButtonUnderPad(other.mHasButtonUnderPad),
@@ -202,7 +203,7 @@
void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber,
const InputDeviceIdentifier& identifier, const std::string& alias,
bool isExternal, bool hasMic, int32_t associatedDisplayId,
- InputDeviceViewBehavior viewBehavior) {
+ InputDeviceViewBehavior viewBehavior, bool enabled) {
mId = id;
mGeneration = generation;
mControllerNumber = controllerNumber;
@@ -213,6 +214,7 @@
mSources = 0;
mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
mAssociatedDisplayId = associatedDisplayId;
+ mEnabled = enabled;
mHasVibrator = false;
mHasBattery = false;
mHasButtonUnderPad = false;
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);