dumpsys_rs/lib.rs
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
mod error;
use std::{io::Read, thread};
use binder::{binder_impl::IBinderInternal, get_service, SpIBinder};
/// The main entry of this crate
pub struct Dumpsys {
service: SpIBinder,
}
impl Dumpsys {
/// Retrieve an existing service and save it for dump, blocking for a few seconds if it doesn't yet exist.
///
/// For example
///
/// ```sh
/// dumpsys SurfaceFlinger
/// ```
///
/// is equal to
///
/// ```
/// use dumpsys_rs::Dumpsys;
///
/// Dumpsys::new("SurfaceFlinger");
/// ```
pub fn new<S>(service_name: S) -> Option<Self>
where
S: AsRef<str>,
{
let service = get_service(service_name.as_ref())?;
Some(Self { service })
}
/// # Example
///
/// ```
/// use dumpsys_rs::Dumpsys;
///
/// # fn foo() -> Option<()> {
/// let result = Dumpsys::new("SurfaceFlinger")?
/// .dump(&["--latency"])
/// .unwrap();
/// println!("{result}");
/// # Some(())
/// # }
/// ```
pub fn dump(&self, args: &'static [&str]) -> Result<String, error::DumpError> {
let mut buf = String::new();
{
let mut service = self.service.clone();
let (mut read, write) = os_pipe::pipe()?;
let handle = thread::spawn(move || service.dump(&write, args));
let _ = read.read_to_string(&mut buf);
handle.join().unwrap()?;
}
Ok(buf)
}
}