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
use std::{fmt::Display, process::Command};

use crate::{ADBCommand, ADBResult};

/// Reboot the device, defaults to system image
pub struct ADBReboot {
    shell: Command,
}

impl ADBReboot {
    pub fn new() -> Self {
        let mut cmd = Command::new("adb");
        cmd.arg("reboot");

        ADBReboot { shell: cmd }
    }

    /// Reboot the device to this point
    pub fn to(mut self, method: RebootMethod) -> Self {
        self.shell.arg(method.to_string());
        self
    }
}

impl Default for ADBReboot {
    fn default() -> Self {
        Self::new()
    }
}

impl ADBCommand for ADBReboot {
    fn build(&mut self) -> Result<&mut Command, String> {
        Ok(&mut self.shell)
    }

    fn process_output(&self, output: ADBResult) -> ADBResult {
        output
    }
}

pub enum RebootMethod {
    Bootloader,
    Recovery,
    Sideload,
    SideloadAutoReboot,
}

impl Display for RebootMethod {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                RebootMethod::Bootloader => "bootloader",
                RebootMethod::Recovery => "recovery",
                RebootMethod::Sideload => "sideload",
                RebootMethod::SideloadAutoReboot => "sideload-auto-reboot",
            }
        )
    }
}

/// Options for the ADB daemon
pub struct ADBDaemon {
    shell: Command,
}

impl ADBDaemon {
    /// Restart adbd with root permissions
    pub fn root() -> Self {
        let mut cmd = Command::new("adb");
        cmd.arg("root");

        ADBDaemon { shell: cmd }
    }

    /// Restart adbd without root permissions
    pub fn unroot() -> Self {
        let mut cmd = Command::new("adb");
        cmd.arg("unroot");

        ADBDaemon { shell: cmd }
    }

    /// Restart adbd listening on USB
    pub fn usb() -> Self {
        let mut cmd = Command::new("adb");
        cmd.arg("usb");

        ADBDaemon { shell: cmd }
    }

    /// Restart adbd listening on TCP on port
    pub fn tcpip(port: u32) -> Self {
        let mut cmd = Command::new("adb");
        cmd.arg("tcp").arg(port.to_string());

        ADBDaemon { shell: cmd }
    }
}

impl ADBCommand for ADBDaemon {
    fn build(&mut self) -> Result<&mut Command, String> {
        Ok(&mut self.shell)
    }

    fn process_output(&self, output: ADBResult) -> ADBResult {
        output
    }
}