summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arthur Hung <arthurhung@google.com> 2019-09-02 16:16:58 +0800
committer Arthur Hung <arthurhung@google.com> 2019-09-12 13:48:59 +0800
commit9da14733afb5da5cb362f3c865d85d303cc62b15 (patch)
tree3e72f04923bfb4095e660cb6e31d8e25cf71bdb3
parentbfd9c00879b16bf782f08e7691d5490c611120e2 (diff)
Fix touch can't work after enabled the associated viewport
If a device has associated port but there is no viewport found, it would be expeced to be disabled. But for some devices, such as touch screen or joystick, they have to read the axis ranges info in InputMapper at first time configuration changed. So we have to defer disabling the device after info has been read when the device plugged. Bug: 140205788 Test: atest inputflinger_tests Change-Id: I9dd55e0016b6a020aab211dada45880195aec8dd
-rw-r--r--services/inputflinger/InputReader.cpp13
-rw-r--r--services/inputflinger/tests/InputReader_test.cpp33
2 files changed, 44 insertions, 2 deletions
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 1cbf78eb43..d59f274ab0 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -1141,13 +1141,24 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config
}
}
- setEnabled(enabled, when);
+ if (changes) {
+ // For first-time configuration, only allow device to be disabled after mappers have
+ // finished configuring. This is because we need to read some of the properties from
+ // the device's open fd.
+ setEnabled(enabled, when);
+ }
}
for (InputMapper* mapper : mMappers) {
mapper->configure(when, config, changes);
mSources |= mapper->getSources();
}
+
+ // If a device is just plugged but it might be disabled, we need to update some info like
+ // axis range of touch from each InputMapper first, then disable it.
+ if (!changes) {
+ setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when);
+ }
}
}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 348a12bf3a..09df2a70c7 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -527,7 +527,7 @@ private:
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
RawAbsoluteAxisInfo* outAxisInfo) const {
Device* device = getDevice(deviceId);
- if (device) {
+ if (device && device->enabled) {
ssize_t index = device->absoluteAxes.indexOfKey(axis);
if (index >= 0) {
*outAxisInfo = device->absoluteAxes.valueAt(index);
@@ -6554,4 +6554,35 @@ TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreRotated) {
ASSERT_EQ(frames, motionArgs.videoFrames);
}
+/**
+ * If we had defined port associations, but the viewport is not ready, the touch device would be
+ * expected to be disabled, and it should be enabled after the viewport has found.
+ */
+TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ constexpr uint8_t hdmi2 = 1;
+ const std::string secondaryUniqueId = "uniqueId2";
+ constexpr ViewportType type = ViewportType::VIEWPORT_EXTERNAL;
+
+ mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
+
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ ASSERT_EQ(mDevice->isEnabled(), false);
+
+ // Add display on hdmi2, the device should be enabled and can receive touch event.
+ prepareSecondaryDisplay(type, hdmi2);
+ ASSERT_EQ(mDevice->isEnabled(), true);
+
+ // Send a touch event.
+ processPosition(mapper, 100, 100);
+ processSync(mapper);
+
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
+}
+
} // namespace android