cargo_mobile2/android/adb/
device_name.rs1use 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}