cargo_mobile2/android/adb/
device_name.rs

1use super::adb;
2use crate::{
3    android::env::Env,
4    util::cli::{Report, Reportable},
5};
6use once_cell_regex::regex;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum Error {
11    #[error("Failed to run `adb emu avd name`: {0}")]
12    EmuFailed(#[source] super::RunCheckedError),
13    #[error("Failed to run `adb shell dumpsys bluetooth_manager`: {0}")]
14    DumpsysFailed(#[source] super::RunCheckedError),
15    #[error("Name regex didn't match anything.")]
16    NotMatched,
17    #[error(transparent)]
18    Io(#[from] std::io::Error),
19}
20
21impl Reportable for Error {
22    fn report(&self) -> Report {
23        let msg = "Failed to get device name";
24        match self {
25            Self::EmuFailed(err) => err.report("Failed to run `adb emu avd name`"),
26            Self::DumpsysFailed(err) => {
27                err.report("Failed to run `adb shell dumpsys bluetooth_manager`")
28            }
29            Self::NotMatched => Report::error(msg, self),
30            Self::Io(err) => Report::error("IO error", err),
31        }
32    }
33}
34
35pub fn device_name(env: &Env, serial_no: &str) -> Result<String, Error> {
36    if serial_no.starts_with("emulator") {
37        super::check_authorized(
38            adb(env, ["-s", serial_no])
39                .before_spawn(move |cmd| {
40                    cmd.args(["emu", "avd", "name"]);
41                    Ok(())
42                })
43                .stderr_capture()
44                .stdout_capture()
45                .start()?
46                .wait()?,
47        )
48        .map(|stdout| stdout.split('\n').next().unwrap().trim().into())
49        .map_err(Error::EmuFailed)
50    } else {
51        super::check_authorized(
52            adb(env, ["-s", serial_no])
53                .before_spawn(move |cmd| {
54                    cmd.args(["shell", "dumpsys", "bluetooth_manager"]);
55                    Ok(())
56                })
57                .stderr_capture()
58                .stdout_capture()
59                .start()?
60                .wait()?,
61        )
62        .map_err(Error::DumpsysFailed)
63        .and_then(|stdout| {
64            regex!(r"\bname: (?P<name>.*)")
65                .captures(&stdout)
66                .map(|caps| caps["name"].to_owned())
67                .ok_or_else(|| Error::NotMatched)
68        })
69    }
70}