This document describes how the input system works inside Mozart.
Zircon provides access to devices through the file system under
/dev/class/input. Those are HID devices and there are associated ioctls to retrieve the description report and simple reads on those devices will return the event reports.
When launching an application through the sysmgr process,
src/root_presenter is launched as a singleton to create the root of the
Presentation. When starting, root_presenter starts
src/input_reader which will monitor the
/dev/class/input directory for new devices and discover existing devices if they are already present.
Any time a device is detected (or discovered the first time)
InputReader reads the HID description report and converts it into a DeviceDescriptor.
That device is then registered through the
InputDeviceRegistry which is implemented by the root presenter
App then notifies any existing
Presentation of the new device. It also creates a channel for that device in the form of an
InputReader can keep a reference to, to forward events.
Presentation creates a
DeviceState (found under
lib/input) which will be used later in the process.
During the initialization of the device,
InputReader will add the handle corresponding to that device to the list of handles to monitor for activity in its message loop. Whenever activity is detected, it reads the packet and the
InputInterpreter associated to this device, will convert the report into an
InputReport is forwarded through the
InputDevice channel created during the registration process to the root presenter
App which dispatches it to the different
DeviceState held by a
Presentation will convert the
InputReport into an
InputEvent has been generated by a
DeviceState, it's forwarded to
ViewAssociate dedicated to process input events which implements the
There is one
InputDispatcherImpl per view tree. The view tree is owned by
Presentation. So the
InputEvent is forwarded to each one of them.
InputDispatcherImpl will query the
ViewInspector service to retrieve the input focus chain. It will then dispatch those events through the chain. It starts at the deepest view in that chain and propagates the event until the
View says it has handled the event though the
InputEvent is a touch or mouse down event,
InputDispatcherImpl, using the
ViewInspector, runs the
HitTest on the scene graph. The result contains a tree of nodes that were hit.
ViewInspector to convert this list of nodes into
Views, at which point it requests in parallel the different views whether they are hit or not and which of their children should be considered for the hit. This is done through the
Once all views have responded,
InputDispatcherImpl reconciles the results walking down the tree from the top and using the answer to which subviews should participate to build a tree of interested parties. For each leaf it will then create focus chain, which is the branch that leads from that leaf to the root.
InputDispatcherImpl picks one of the chain but this will be changed in the future. It then tells the
ViewInspector which chain is now in focus.