pub struct InputFacade {}
Expand description

Perform Input fidl operations.

Note this object is shared among all threads created by server.

Implementations§

source§

impl InputFacade

source

pub fn new() -> InputFacade

source

pub async fn tap(&self, args: Value) -> Result<ActionResult, Error>

Tap at coordinates (x, y) for a touchscreen with default or custom width, height, duration, and tap event counts

§Arguments
  • value: will be parsed to TapRequest
    • must include:
      • x: X axis coordinate
      • y: Y axis coordinate
    • optionally includes any of:
      • width: Horizontal resolution of the touch panel, defaults to 1000
      • height: Vertical resolution of the touch panel, defaults to 1000
      • tap_event_count: Number of tap events to send (duration is divided over the tap events), defaults to 1
      • duration: Duration of the event(s) in milliseconds, defaults to 300
source

pub async fn multi_finger_tap(&self, args: Value) -> Result<ActionResult, Error>

Multi-Finger Taps for a touchscreen with default or custom width, height, duration, and tap event counts.

§Arguments
  • value: will be parsed by MultiFingerTapRequest
    • must include:
      • fingers: List of FIDL struct Touch defined at sdk/fidl/fuchsia.ui.input/input_reports.fidl.
    • optionally includes any of:
      • width: Horizontal resolution of the touch panel, defaults to 1000
      • height: Vertical resolution of the touch panel, defaults to 1000
      • tap_event_count: Number of multi-finger tap events to send (duration is divided over the events), defaults to 1
      • duration: Duration of the event(s) in milliseconds, defaults to 0

Example: To send a 2-finger triple tap over 3s. multi_finger_tap(MultiFingerTap { tap_event_count: 3, duration: 3000, fingers: [ Touch { finger_id: 1, x: 0, y: 0, width: 0, height: 0 }, Touch { finger_id: 2, x: 20, y: 20, width: 0, height: 0 }, ] });

source

pub async fn swipe(&self, args: Value) -> Result<ActionResult, Error>

Swipe from coordinates (x0, y0) to (x1, y1) for a touchscreen with default or custom width, height, duration, and tap event counts

§Arguments
  • value: will be parsed to SwipeRequest
    • must include:
      • x0: X axis start coordinate
      • y0: Y axis start coordinate
      • x1: X axis end coordinate
      • y1: Y axis end coordinate
    • optionally includes any of:
      • width: Horizontal resolution of the touch panel, defaults to 1000
      • height: Vertical resolution of the touch panel, defaults to 1000
      • tap_event_count: Number of move events to send in between the down and up events of the swipe, defaults to duration / 17 (to emulate a 60 HZ sensor)
      • duration: Duration of the event(s) in milliseconds, default to 300
source

pub async fn multi_finger_swipe( &self, args: Value ) -> Result<ActionResult, Error>

Swipes multiple fingers from start positions to end positions for a touchscreen.

§Arguments
  • value: will be parsed to MultiFingerSwipeRequest
    • must include:
      • fingers: List of FingerSwipes.
        • All x0 and x1 values must be in the range (0, width), regardless of whether the width is defaulted or explicitly specified.
        • All y0 and y1 values must be in the range (0, height), regardless of whether the height is defaulted or explicitly specified.
    • optionally includes any of:
      • width: Horizontal resolution of the touch panel, defaults to 1000
      • height: Vertical resolution of the touch panel, defaults to 1000
      • move_event_count: Number of move events to send in between the down and up events of the swipe.
        • Defaults to duration / 17 (to emulate a 60 HZ sensor).
        • If 0, only the down and up events will be sent.
      • duration: Duration of the event(s) in milliseconds
        • Defaults to 300 milliseconds.
        • Must be large enough to allow for at least one nanosecond per move event.
§Returns
  • Ok(ActionResult::Success) if the arguments were successfully parsed and events successfully injected.
  • Err(Error) otherwise.
§Example

To send a two-finger swipe, with four events over two seconds:

multi_finger_swipe(MultiFingerSwipeRequest {
  fingers: [
    FingerSwipe { x0: 0, y0:   0, x1: 100, y1:   0 },
    FingerSwipe { x0: 0, y0: 100, x1: 100, y1: 100 },
  ],
  move_event_count: 4
  duration: 2000,
});
source

pub async fn text(&self, args: Value) -> Result<ActionResult, Error>

Enters text, as if typed on a keyboard, with key_event_duration between key events.

§Arguments
  • value: will be parsed to TextRequest
    • must include:
      • text: the characters to be input.
        • Must be non-empty.
        • All characters within text must be representable using the current keyboard layout and locale. (At present, it is assumed that the current layout and locale are US-QWERTY and en-US, respectively.)
        • If these constraints are violated, returns an Err.
    • optionally includes:
      • key_event_duration: Duration of each event in milliseconds
        • Serves as a lower bound on the time between key events (actual time may be higher due to system load).
        • Defaults to 0 milliseconds (each event is sent as quickly as possible).
        • The number of events is >= 2 * text.len():
          • To account for both key-down and key-up events for every character.
          • To account for modifier keys (e.g. capital letters require pressing the shift key).
§Returns
  • Ok(ActionResult::Success) if the arguments were successfully parsed and events successfully injected.
  • Err(Error) otherwise.
§Example

To send “hello world”, with 1 millisecond between each key event:

text(TextRequest {
  text: "hello world",
  key_event_duration: 1,
});
source

pub async fn key_press(&self, args: Value) -> Result<ActionResult, Error>

Simulates a single key down + up sequence, for the given hid_usage_id.

§Arguments
  • value: will be parsed to KeyPressRequest
    • must include
      • hid_usage_id: desired HID Usage ID, per HID Usages and Descriptions.
        • The Usage ID will be interpreted in the context of “Usage Page” 0x07, which is the “Keyboard/Keypad” page.
        • Because Usage IDs are defined by an external standard, it is impractical to validate this parameter. As such, any value can be injected successfully. However, the interpretation of unrecognized values is subject to the choices of the system under test.
    • optionally includes:
      • key_press_duration: time between the down event and the up event, in milliseconds
        • Serves as a lower bound on the time between the down event and the up event (actual time may be higher due to system load).
        • Defaults to 0 milliseconds (the up event is sent immediately after the down event)
§Returns
  • Ok(ActionResult::Success) if the arguments were successfully parsed and events successfully injected.
  • Err(Error) otherwise.
§Future directions

Per https://fxbug.dev/42142047, this method will be replaced with a method that deals in fuchsia.input.Keys, instead of HID Usage IDs.

§Example

To simulate a press of the ENTER key, with 1 millisecond between the down and up events:

key_press(KeyPressRequest {
  hid_usage_id: 40,
  key_press_duration: 1,
});
source

pub async fn key_events(&self, args: Value) -> Result<ActionResult, Error>

Simulates a sequence of key events (presses and releases) on a keyboard.

Dispatches the supplied events into a keyboard device, honoring the timing sequence that is requested in them, to the extent possible using the current scheduling system.

Since each individual key press is broken down into constituent pieces (presses, releases, pauses), it is possible to dispatch a key event sequence corresponding to multiple keys being pressed and released in an arbitrary sequence. This sequence is usually understood as a timing diagram like this:

          v--- key press   v--- key release
A: _______/^^^^^^^^^^^^^^^^\__________
   |<----->|   <-- duration from start for key press.
   |<--------------------->|   <-- duration from start for key release.

B: ____________/^^^^^^^^^^^^^^^^\_____
               ^--- key press   ^--- key release
   |<--------->|   <-- duration from start for key press.
   |<-------------------------->|   <-- duration for key release.

You would from there convert the desired timing diagram into a sequence of [KeyEvent]s that you would pass into this function. Note that all durations are specified as durations from the start of the key event sequence.

Note that due to the way event timing works, it is in practice impossible to have two key events happen at exactly the same time even if you so specify. Do not rely on simultaneous asynchronous event processing: it does not work in this code, and it is not how reality works either. Instead, design your key event processing so that it is robust against the inherent non-determinism in key event delivery.

§Arguments

The args must be a JSON value that can be parsed as types::KeyEventsRequest.

types::KeyEventsRequest, in turn, has a sequence of key events that need to be injected. Each key event is a triple of:

  • The Fuchsia encoding of the USB HID usage code (see [fuchsia_ui_input::Key]).
  • The duration in milliseconds since the start of the key event sequence when this action must happen.
  • The type of the key event (see [fuchsia_ui_input3::KeyEventType]), encoded as a numeric value.
§Example:

The above diagram would be encoded as the following sequence of events (in pseudocode):

[
  { "A", 10, Pressed  },
  { "B", 10, Pressed  },
  { "A", 50, Released },
  { "B", 60, Released },
]
§Returns
  • Ok(ActionResult::Success) if the arguments were successfully parsed and events successfully injected.
  • Err(Error) otherwise.

Trait Implementations§

source§

impl Debug for InputFacade

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Facade for InputFacade

source§

fn handle_request<'life0, 'async_trait>( &'life0 self, method: String, args: Value ) -> Pin<Box<dyn Future<Output = Result<Value, Error>> + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Asynchronously handle the incoming request for the given method and arguments, returning a future object representing the pending operation.
source§

fn cleanup(&self)

In response to a request to /cleanup, cleanup any cross-request state.
source§

fn print(&self)

In response to a request to /print, log relevant facade state.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> DebugExt for T
where T: Debug,

source§

fn debug(&self) -> String

source§

impl<T> Encode<Ambiguous1> for T

source§

unsafe fn encode( self, _encoder: &mut Encoder<'_>, _offset: usize, _depth: Depth ) -> Result<(), Error>

Encodes the object into the encoder’s buffers. Any handles stored in the object are swapped for Handle::INVALID. Read more
source§

impl<T> Encode<Ambiguous2> for T

source§

unsafe fn encode( self, _encoder: &mut Encoder<'_>, _offset: usize, _depth: Depth ) -> Result<(), Error>

Encodes the object into the encoder’s buffers. Any handles stored in the object are swapped for Handle::INVALID. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoAny for T
where T: 'static + Send + Sync,

§

fn into_any(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Cast the given object into a dyn std::any::Any.
source§

impl<T, U> IntoExt<U> for T
where U: FromExt<T>,

source§

fn into_ext(self) -> U

Performs the conversion.
source§

impl<T> OptionalField for T
where T: ?Sized,

source§

const PRESENT: Presence<Self> = _

source§

const ABSENT: Presence<Self> = _

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T, U> TryIntoExt<U> for T
where U: TryFromExt<T>,

§

type Error = <U as TryFromExt<T>>::Error

source§

fn try_into_ext(self) -> Result<U, <T as TryIntoExt<U>>::Error>

Tries to perform the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
source§

impl<St> WithTag for St

source§

fn tagged<T>(self, tag: T) -> Tagged<T, St>

Produce a new stream from this one which yields item tupled with a constant tag