1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use serde::{Deserialize, Deserializer, Serialize};

use fidl_fuchsia_ui_input::Touch;
use input_synthesis as is;

/// Enum for supported Input commands.
pub enum InputMethod {
    Tap,
    MultiFingerTap,
    Swipe,
    MultiFingerSwipe,
    Text,
    KeyPress,
    /// Arbitrary sequence of key events.
    KeyEvents,
}

impl std::str::FromStr for InputMethod {
    type Err = anyhow::Error;
    fn from_str(method: &str) -> Result<Self, Self::Err> {
        match method {
            "Tap" => Ok(InputMethod::Tap),
            "MultiFingerTap" => Ok(InputMethod::MultiFingerTap),
            "Swipe" => Ok(InputMethod::Swipe),
            "MultiFingerSwipe" => Ok(InputMethod::MultiFingerSwipe),
            "Text" => Ok(InputMethod::Text),
            "KeyPress" => Ok(InputMethod::KeyPress),
            "KeyEvents" => Ok(InputMethod::KeyEvents),
            _ => return Err(format_err!("Invalid Input Facade method: {}", method)),
        }
    }
}

#[derive(Deserialize, Debug)]
pub struct MultiFingerTapRequest {
    pub width: Option<u32>,
    pub height: Option<u32>,
    pub tap_event_count: Option<usize>,
    pub duration: Option<u64>,

    #[serde(default, deserialize_with = "TouchDef::vec")]
    pub fingers: Vec<Touch>,
}

#[derive(Deserialize, Debug)]
pub struct TapRequest {
    pub x: u32,
    pub y: u32,
    pub width: Option<u32>,
    pub height: Option<u32>,
    pub tap_event_count: Option<usize>,
    pub duration: Option<u64>,
}

#[derive(Deserialize, Debug)]
pub struct SwipeRequest {
    pub x0: u32,
    pub y0: u32,
    pub x1: u32,
    pub y1: u32,
    pub width: Option<u32>,
    pub height: Option<u32>,
    pub tap_event_count: Option<usize>,
    pub duration: Option<u64>,
}

#[derive(Deserialize, Debug)]
/// Describes a start and end position for a single finger.
pub struct FingerSwipe {
    pub x0: u32,
    pub y0: u32,
    pub x1: u32,
    pub y1: u32,
}

#[derive(Deserialize, Debug)]
pub struct MultiFingerSwipeRequest {
    pub fingers: Vec<FingerSwipe>,
    pub width: Option<u32>,
    pub height: Option<u32>,
    pub move_event_count: Option<usize>,
    pub duration: Option<u64>,
}

#[derive(Deserialize, Debug)]
pub struct TextRequest {
    pub text: String,
    pub key_event_duration: Option<u64>,
}

#[derive(Deserialize, Debug)]
pub struct KeyPressRequest {
    pub hid_usage_id: u16,
    pub key_press_duration: Option<u64>,
}

#[derive(Deserialize, Debug)]
pub struct KeyEventsRequest {
    #[serde(default, deserialize_with = "is::synthesizer::TimedKeyEvent::vec")]
    pub key_events: Vec<is::synthesizer::TimedKeyEvent>,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum ActionResult {
    Success,
}

/// This matches the FIDL struct `Touch` defined at
/// sdk/fidl/fuchsia.ui.input/input_reports.fidl
/// and is enforced by the build system.
#[derive(Serialize, Deserialize, Debug)]
#[serde(remote = "Touch")]
pub struct TouchDef {
    pub finger_id: u32,
    pub x: i32,
    pub y: i32,
    pub width: u32,
    pub height: u32,
}

/// serde does not work with Vec.
/// This requires us to write our own Deserializer for Vec<Touch>.
/// https://github.com/serde-rs/serde/issues/723#issuecomment-382501277
impl TouchDef {
    fn vec<'de, D>(deserializer: D) -> Result<Vec<Touch>, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        struct Wrapper(#[serde(deserialize_with = "deserialize_element")] Touch);

        fn deserialize_element<'de, D>(deserializer: D) -> Result<Touch, D::Error>
        where
            D: Deserializer<'de>,
        {
            TouchDef::deserialize(deserializer)
        }

        let v = Vec::deserialize(deserializer)?;
        Ok(v.into_iter().map(|Wrapper(a)| a).collect())
    }
}