Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8201568: zForce touchscreen input device fails when closed and immediately reopened #258

Closed
wants to merge 2 commits into from

Conversation

jgneff
Copy link
Member

@jgneff jgneff commented Jun 27, 2020

Fixes JDK-8201568.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8201568: zForce touchscreen input device fails when closed and immediately reopened

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jfx pull/258/head:pull/258
$ git checkout pull/258

@bridgekeeper
Copy link

bridgekeeper bot commented Jun 27, 2020

👋 Welcome back jgneff! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request.

@openjdk openjdk bot added the rfr Ready for review label Jun 27, 2020
@mlbridge
Copy link

mlbridge bot commented Jun 27, 2020

Webrevs

@jgneff
Copy link
Member Author

jgneff commented Jun 27, 2020

I thought I could avoid fixing this bug simply by waiting a few years, but the old devices from 2012 and 2013 where the problem occurs are still supported and still even being sold (refurbished) by the manufacturer. The Monocle EPD platform has a work-around for the bug in the method EPDInputDeviceRegistry.createDevice.

The problem does not occur on newer 2015 and 2018 devices that I tested.

Background

The Neonode zForce touchscreen input device almost always fails when it is opened immediately after being closed. Once it fails, no input events are received. The device driver logs the following messages to the kernel ring buffer:

[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-145] command Activate (0) ...
[zForce_ir_touch_recv_data-154] command Resolution (0) ...
[zForce_ir_touch_recv_data-179] command Frequency (0) ...
[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-142] command Deactivate ...
[zForce_ir_touch_recv_data-198] command overrun (8) ...

This pull request reorders the initialization sequence to be "open, open, close" instead of "open, close, open" so that the input device is never actually closed. With this change, the file reference count remains above zero so the call to close it is ignored, and the device driver logs the following messages to the ring buffer:

[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-145] command Activate (0) ...
[zForce_ir_touch_recv_data-154] command Resolution (0) ...
[zForce_ir_touch_recv_data-179] command Frequency (0) ...

In both cases, when the program exits or is canceled with Ctrl-C, the input device is closed normally:

[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[zForce_ir_touch_recv_data-142] command Deactivate ...

Summary

I decided to go ahead and submit this pull request for the following reasons:

  1. we know of at least one input device where the code causes problems, so there could be others;
  2. this makes progress towards removing 48 lines of work-around code from EPDInputDeviceRegistry; and
  3. opening and closing an input device is expensive enough that we probably shouldn't close it when we know we're going to open it again only two statements later.

Copy link
Collaborator

@johanvos johanvos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rationale makes sense (open/open/close) instead of (open/close/open)

@openjdk
Copy link

openjdk bot commented Jun 29, 2020

@jgneff This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8201568: zForce touchscreen input device fails when closed and immediately reopened

Reviewed-by: jvos

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 57 new commits pushed to the master branch:

  • 97d655f: 8256012: Fix build of Monocle for Linux
  • e1adfa9: 8257758: Allow building of JavaFX native libs for Apple Silicon
  • 1a8652a: 8257719: JFXPanel scene fails to render correctly on HiDPI after fix for JDK-8199592
  • 7fa02fe: 8257897: Fix webkit build for XCode 12
  • 794ffc0: 8231372: JFXPanel fails to render if setScene called on Swing thread
  • e7dbdfc: 8233678: [macos 10.15] System menu bar does not work initially on macOS Catalina
  • ca0d3d0: 8256821: TreeViewSkin/Behavior: misbehavior on switching skin
  • 00a8646: 8247576: Labeled/SkinBase: misbehavior on switching skin
  • c8d9c94: 8254049: Update WebView to public suffix list 2020-04-24
  • bd51089: 8256978: GitHub actions: build fails on Linux due to missing package
  • ... and 47 more: https://git.openjdk.java.net/jfx/compare/d10f948ee7380ac73bc4e2d5bff1caba50fe00a8...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@johanvos) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk openjdk bot added the ready Ready to be integrated label Jun 29, 2020
@jgneff
Copy link
Member Author

jgneff commented Jun 29, 2020

Based on my notes below, I believe this change is safe for any Linux input device driver because the driver shouldn't receive the intermediate open and close calls at all.

Nonetheless, it would be reassuring if someone could try this change just once on a mainstream device, such as the Raspberry Pi with a touchscreen LCD panel. I only have six obscure ARM devices and a headless QEMU ARM virtual machine for testing. @johanvos or @dellgreen - Is that something you could test? If you think it's overkill and not worth it, that's fine, too.

Notes

The Linux kernel documentation about opening and closing input devices states:

Note that input core keeps track of number of users for the device and makes sure that dev->open() is called only when the first user connects to the device and that dev->close() is called when the very last user disconnects. Calls to both callbacks are serialized.

Also, the Linux Programmer's Manual for the close system call (man 2 close) states:

If fd is the last file descriptor referring to the underlying open file description (see open(2)), the resources associated with the open file description are freed.

Running a JavaFX program with strace -f -e trace=open,close -o strace.log shows the one open for the event0 keyboard, and the open, open, close for the event1 touchscreen:

5847  open("/dev/input/event0", O_RDONLY) = 11
...
5847  open("/dev/input/event1", O_RDONLY) = 12
5847  open("/dev/input/event1", O_RDONLY) = 13
5847  close(13)                         = 0

Both devices are actually closed by the kernel when the JavaFX program ends.

@johanvos
Copy link
Collaborator

johanvos commented Jul 1, 2020

I don't have access to a Pi right now, so I can't test this (I'll be able to test in about 10 days from now though)

@jgneff
Copy link
Member Author

jgneff commented Jul 9, 2020

I don't have access to a Pi right now, so I can't test this (I'll be able to test in about 10 days from now though)

Thank you, Johan. If you have the time, that would be great. Otherwise, merging this for early-access builds of JavaFX 16 should provide enough time to find any regression errors on other devices.

By the way, do you know whether I would be able to use a PinePhone instead of a Raspberry Pi for testing the Monocle Linux platform (monocle.platform=Linux)? The PinePhone has a quad-core ARM Cortex A53 processor instead of the quad-core ARM Cortex-A72 on the Raspberry Pi 4, but it also has the advantage of a built-in LCD touchscreen.

@Torbuntu
Copy link
Contributor

Torbuntu commented Jul 27, 2020

By the way, do you know whether I would be able to use a PinePhone

I have been trying to run JavaFX on the PinePhone ever since I got it. The OS I'm using is Fedora and it is aarch64, which means I had to add that arch to build.gradle to compile it. As is the touchscreen doesn't respond correctly at all. Every touch reports as a mouse_entered, mouse_exited event.

Though this is due to using the Desktop JavaFX. Is there somewhere I can find an embedded aarch64 version? Since desktop javafx/OpenJFX only runs monocle in headless according to this: https://wiki.openjdk.java.net/display/OpenJFX/Monocle

@jgneff
Copy link
Member Author

jgneff commented Jul 27, 2020

Is there somewhere I can find an embedded aarch64 version?

If I had a PinePhone, I would try to get the 32-bit armhf build of JavaFX working. That's the one you build with gradle -PCOMPILE_TARGETS=armv6hf sdk jmod. You may need to switch operating systems. See the Ask Ubuntu question "Can I run an ARM32 bit App on an ARM64bit platform which is running Ubuntu 16.04?"

@Torbuntu
Copy link
Contributor

I do not know of a currently supported 32-bit armhf OS for the PinePhone.
This issue affects Desktop JavaFX linux touch as well, so I suppose I'll need to dig into adding that in, which was mentioned on this older issue: javafxports/openjdk-jfx#329 (comment)

Thanks for the quick reply!

@jgneff
Copy link
Member Author

jgneff commented Sep 21, 2020

Nonetheless, it would be reassuring if someone could try this change just once on a mainstream device, such as the Raspberry Pi with a touchscreen LCD panel.

I just placed an order for a Raspberry Pi 2 Model B -- the older model with the 32-bit ARMv7-A architecture. It's the oldest, slowest, and coolest-running Raspberry Pi supported by Ubuntu, and it's also the closest match to the processors found in devices with e-paper displays. The Raspberry Pi should finally let me test changes like this to the Linux Monocle platform on which the EPD platform is based. I may eventually add a touchscreen, but I'm hoping to get by with just the mouse for now.

@openjdk openjdk bot removed the ready Ready to be integrated label Sep 25, 2020
@jgneff
Copy link
Member Author

jgneff commented Sep 29, 2020

@johanvos, would you mind approving this pull request again? It looks as if the ready label was removed when I merged the master branch. All of the tests I ran this week worked as expected and are described below.

Tests

I ran additional tests on the following devices after merging the master branch:

  • Kobo Touch Model N905C,
  • Kobo Glo HD Model N437, and
  • Raspberry Pi 2 Model B.

I ran the tests:

  • without this fix and without the workaround,
  • with this fix but without the workaround,
  • with this fix and with the workaround (representing this pull request).

The workaround is the code in EPDInputDeviceRegistry.createDevice that lets the current JavaFX 15 release avoid the problem even without this fix. The goal of this pull request is to be able eventually to remove the EPDInputDeviceRegistry subclass entirely.

The test results are shown below. The system call trace was captured with the following command using the epd-javafx application.

$ sudo strace -f -e trace=open,openat,close -o strace.log \
    bin/run.sh --pattern=3 --loops=1

Note: In the messages below from the kernel ring buffer, the final two lines with zforce_i2c_close and Deactivate are printed when the program terminates. That call made by the kernel on behalf of the program is not recorded in the program's system call trace.

Kobo Touch Model N905C

This device has the "command overrun" bug.

Without fix, without workaround

The system call trace shows:

3576  open("/dev/input/event1", O_RDONLY) = 12
3576  close(12)                         = 0
3576  open("/dev/input/event1", O_RDONLY) = 12

The error occurs, and the touchscreen is disabled:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-145] command Activate (0) ...
[zForce_ir_touch_recv_data-154] command Resolution (0) ...
[zForce_ir_touch_recv_data-179] command Frequency (0) ...
[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-142] command Deactivate ...
[zForce_ir_touch_recv_data-198] command overrun (8) ...
[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[zForce_ir_touch_recv_data-142] command Deactivate ...

With fix, without workaround

The system call trace shows:

3997  open("/dev/input/event1", O_RDONLY) = 12
3997  open("/dev/input/event1", O_RDONLY) = 13
3997  close(13)                         = 0

The error does not occur, and the touchscreen works as expected:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-145] command Activate (0) ...
[zForce_ir_touch_recv_data-154] command Resolution (0) ...
[zForce_ir_touch_recv_data-179] command Frequency (0) ...
[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[zForce_ir_touch_recv_data-142] command Deactivate ...

With fix, with workaround

The system call trace shows the additional open call due to the workaround:

4123  open("/dev/input/event1", O_RDONLY) = 13
4123  open("/dev/input/event1", O_RDONLY) = 14
4123  open("/dev/input/event1", O_RDONLY) = 15
4123  close(15)                         = 0

The error does not occur, and the touchscreen works as expected:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-425] zforce_i2c_open()
[zForce_ir_touch_recv_data-145] command Activate (0) ...
[zForce_ir_touch_recv_data-154] command Resolution (0) ...
[zForce_ir_touch_recv_data-179] command Frequency (0) ...
[drivers/input/touchscreen/zforce_i2c.c-440] zforce_i2c_close()
[zForce_ir_touch_recv_data-142] command Deactivate ...

Kobo Glo HD Model N437

This device does not have the "command overrun" bug.

Without fix, without workaround

The system call trace shows:

3396  open("/dev/input/event1", O_RDONLY) = 11
3396  close(11)                         = 0
3396  open("/dev/input/event1", O_RDONLY) = 11

The error does not occur, and the touchscreen works as expected:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-740] zforce_i2c_open()
[zForce_ir_touch_recv_data-233] command Activate (0) ...
...
[zForce_ir_touch_recv_data-250] command Resolution (0) ...
[zForce_ir_touch_recv_data-278] command Frequency (0) ...
[zForce_ir_touch_recv_data-260] command Configuration ...
[drivers/input/touchscreen/zforce_i2c.c-756] zforce_i2c_close()
[zForce_ir_touch_recv_data-230] command Deactivate ...

With fix, without workaround

The system call trace shows:

3620  open("/dev/input/event1", O_RDONLY) = 15
3620  open("/dev/input/event1", O_RDONLY) = 16
3620  close(16)                         = 0

The error does not occur, and the touchscreen works as expected:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-740] zforce_i2c_open()
[zForce_ir_touch_recv_data-233] command Activate (0) ...
...
[zForce_ir_touch_recv_data-250] command Resolution (0) ...
[zForce_ir_touch_recv_data-278] command Frequency (0) ...
[zForce_ir_touch_recv_data-260] command Configuration ...
[drivers/input/touchscreen/zforce_i2c.c-756] zforce_i2c_close()
[zForce_ir_touch_recv_data-230] command Deactivate ...

With fix, with workaround

The system call trace shows the additional open call due to the workaround:

3913  open("/dev/input/event1", O_RDONLY) = 18
3913  open("/dev/input/event1", O_RDONLY) = 19
3913  open("/dev/input/event1", O_RDONLY) = 20
3913  close(20)                         = 0

The error does not occur, and the touchscreen works as expected:

$ dmesg | grep -i zforce
[drivers/input/touchscreen/zforce_i2c.c-740] zforce_i2c_open()
[zForce_ir_touch_recv_data-233] command Activate (0) ...
...
[zForce_ir_touch_recv_data-250] command Resolution (0) ...
[zForce_ir_touch_recv_data-278] command Frequency (0) ...
[zForce_ir_touch_recv_data-260] command Configuration ...
[drivers/input/touchscreen/zforce_i2c.c-756] zforce_i2c_close()
[zForce_ir_touch_recv_data-230] command Deactivate ...

Raspberry Pi 2 Model B

This device has a normal mouse rather than a touchscreen.

Without fix, without workaround

The system call trace shows:

19407 openat(AT_FDCWD, "/dev/input/event0", O_RDONLY) = 18

There is no output to the kernel ring buffer, and the mouse (event0) works as expected.

With fix, without workaround

The system call trace shows:

19548 openat(AT_FDCWD, "/dev/input/event0", O_RDONLY) = 18

There is no output to the kernel ring buffer, and the mouse (event0) works as expected.

With fix, with workaround

The system call trace shows:

19802 openat(AT_FDCWD, "/dev/input/event0", O_RDONLY) = 18

There is no output to the kernel ring buffer, and the mouse (event0) works as expected.

@jgneff
Copy link
Member Author

jgneff commented Dec 11, 2020

I'm unsure of the next step for this pull request. GitHub says that it's approved, but the openjdk bot removed the "Ready to be integrated" label when I merged in the master branch back in September. Do I need to wait for its re-approval before integrating it?

@johanvos
Copy link
Collaborator

It seems there was an additional merge commit, which didn't change your code, but it triggered a re-approval request that I missed. I re-approved it, so this should be ready to integrate.

@openjdk openjdk bot added the ready Ready to be integrated label Dec 13, 2020
@jgneff
Copy link
Member Author

jgneff commented Dec 13, 2020

/integrate

@openjdk openjdk bot added the sponsor Ready to sponsor label Dec 13, 2020
@openjdk
Copy link

openjdk bot commented Dec 13, 2020

@jgneff
Your change (at version 68c0523) is now ready to be sponsored by a Committer.

@johanvos
Copy link
Collaborator

/sponsor

@openjdk openjdk bot closed this Dec 14, 2020
@openjdk openjdk bot added the integrated Pull request has been integrated label Dec 14, 2020
@openjdk openjdk bot removed sponsor Ready to sponsor ready Ready to be integrated rfr Ready for review labels Dec 14, 2020
@openjdk
Copy link

openjdk bot commented Dec 14, 2020

@johanvos @jgneff Since your change was applied there have been 57 commits pushed to the master branch:

  • 97d655f: 8256012: Fix build of Monocle for Linux
  • e1adfa9: 8257758: Allow building of JavaFX native libs for Apple Silicon
  • 1a8652a: 8257719: JFXPanel scene fails to render correctly on HiDPI after fix for JDK-8199592
  • 7fa02fe: 8257897: Fix webkit build for XCode 12
  • 794ffc0: 8231372: JFXPanel fails to render if setScene called on Swing thread
  • e7dbdfc: 8233678: [macos 10.15] System menu bar does not work initially on macOS Catalina
  • ca0d3d0: 8256821: TreeViewSkin/Behavior: misbehavior on switching skin
  • 00a8646: 8247576: Labeled/SkinBase: misbehavior on switching skin
  • c8d9c94: 8254049: Update WebView to public suffix list 2020-04-24
  • bd51089: 8256978: GitHub actions: build fails on Linux due to missing package
  • ... and 47 more: https://git.openjdk.java.net/jfx/compare/d10f948ee7380ac73bc4e2d5bff1caba50fe00a8...master

Your commit was automatically rebased without conflicts.

Pushed as commit ebb59e9.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@jgneff jgneff deleted the zforce-command-overrun branch February 23, 2021 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

3 participants