Use uinput touchscreen to inject monkey touch events
Using uinput for injection will ensure that when monkey quits, there's no
possibility of unfinished event streams, because the device used for
injection will be deleted with the process. This will also allow more
complete testing of the entire system rather than just testing the upper
layer, so it will be a closer representation of the user performing actions
on the device.
Previously, it was possible for monkey to leave dangling pointers on
screen. This would conflict with subsequent monkey runs, thus leading to
crashes that are not actually achievable via normal user input.
This CL will help us eventually get rid of the 'injectInputEvent' API.
Later, we can also look into using uinput for other event types, thus
removing the 'injectInputEvent' dependency from monkey completely.
The approach in the CL works as follows:
1. Monkey.java communicates with native code via aidl
2. For the very first time, we need to make a single jni call to create
the service and send it to java as an ibinder.
3. Monkey will create a touchscreen using VirtualInputDevice from
libinput
4. Any time monkey has to inject a touch event, it will send it via the
uinput touchscreen instead.
The VDM infra provides Java APIs, so in theory we could just use that
here, and not require any native code. However, I could not get that
approach to work, because existing Java bindings for virtual input devices
require a valid Context object. We don't currently have a valid Context
object inside monkey code.
Attempts to circumvent this by directly using the binder interface of
IVirtualDeviceManager without context were unsuccessful, because those require
providing a valid VirtualDeviceParams object. However, creating that object
requires the use of its builder, which internally has flag-value checks. The
flag-checking code also requires a valid context, leading to crashes
when accessed from a non-Activity context (http://b/341726919).
I briefly also explored the creation of a context within the monkey binary,
such as by registering a service, but it proved to be complex and would require changes
to build files and the general way the monkey operation is set up. Even if successful,
this approach would likely introduce more complexity than the JNI/AIDL solution.
Therefore, I went with the JNI/AIDL approach here.
Bug: 344695913
Flag: EXEMPT refactor
Test: adb shell monkey 1000 --pct-touch 100
Change-Id: I450110d192726e8904e36fc6c115a49a2ee88b59
6 files changed