Bug: /dev/input/eventX 事件阻碍kernel suspend flow

Bug: /dev/input/eventX 事件阻碍kernel suspend flow

1.相关模块:

###(1) Android: InputReader

frameworks/native/services/inputflinger/EventHub.cpp
会注册epoll wakeup source,
epoll_ctl(/dev/input/), flag设成了EPOLLWAKEUP

###(2)Kernel: drivers/input/input.c

input_dev_suspend()-> input_dev_release_keys() ->
kernel认为:当前按着的key等resume回来之后不会继续hold住,所以要释放所有的key。(Simulate keyup events for all keys that are marked as pressed.)

2.解决方案:kernel修复自己的bug:

commit a5f5a6880ba2645af793ddba96e95c96cac3194e
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date:   Thu Aug 6 19:15:30 2015 -0700

    Input: do not emit unneeded EV_SYN when suspending

    backport 00159f19a5057cb779146afce1cceede692af346 upstream.

    Do not emit EV_SYN/SYN_REPORT on suspend if there were no keys that are
    still pressed as we are suspending the device (and in all other cases when
    input core is forcibly releasing keys via input_dev_release_keys() call).

    Reviewed-by: Benson Leung <bleung@chromium.org>
    Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

改动如下

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 29ca0bb..087255a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -667,6 +667,7 @@ EXPORT_SYMBOL(input_close_device);
  */
 static void input_dev_release_keys(struct input_dev *dev)
 {
+       bool need_sync = false;
        int code;

        if (is_event_supported(EV_KEY, dev->evbit, EV_MAX)) {
@@ -674,9 +675,11 @@ static void input_dev_release_keys(struct input_dev *dev)
                        if (is_event_supported(code, dev->keybit, KEY_MAX) &&
                            __test_and_clear_bit(code, dev->key)) {
                                input_pass_event(dev, EV_KEY, code, 0);
+                               need_sync = true;
                        }
                }
-               input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+               if (need_sync)
+                       input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
        }
 }