Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const PROBE_DURATION: Duration = Duration::from_secs(5);
#[tokio::main]
async fn main() -> Result<()> {
let selector = std::env::args().nth(1);
let discovery = discover_emulator(selector.as_deref())?;
let discovery = discover_emulator(selector.as_deref()).await?;
let serial = discovery
.properties
.get("port.serial")
Expand All @@ -32,18 +32,20 @@ async fn main() -> Result<()> {
let stop = Arc::new(AtomicBool::new(false));
let stimulus_stop = Arc::clone(&stop);
let stimulus_serial = serial.clone();
let stimulus = std::thread::spawn(move || {
let stimulus = tokio::spawn(async move {
let adb = AdbClient::discover(Some(&stimulus_serial));
let Ok((width, height)) = adb.get_screen_size() else {
let Ok((width, height)) = adb.get_screen_size().await else {
return;
};
while !stimulus_stop.load(Ordering::Relaxed) {
let _ = adb.swipe(
(width as f64 * 0.5, height as f64 * 0.75),
(width as f64 * 0.5, height as f64 * 0.25),
250,
);
std::thread::sleep(Duration::from_millis(150));
let _ = adb
.swipe(
(width as f64 * 0.5, height as f64 * 0.75),
(width as f64 * 0.5, height as f64 * 0.25),
250,
)
.await;
tokio::time::sleep(Duration::from_millis(150)).await;
}
});

Expand All @@ -52,7 +54,7 @@ async fn main() -> Result<()> {
let mmap = probe_mmap(client).await?;
print_report("mmap", &mmap);
stop.store(true, Ordering::Relaxed);
let _ = stimulus.join();
let _ = stimulus.await;
println!("probe passed");
Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const RECOVERY_TIMEOUT: Duration = Duration::from_secs(5);
#[tokio::main]
async fn main() -> Result<()> {
let selector = std::env::args().nth(1);
let discovery = discover_emulator(selector.as_deref())?;
let discovery = discover_emulator(selector.as_deref()).await?;
println!("discovery : {}", discovery.path.display());
println!("endpoint : {}", discovery.endpoint());

Expand Down
24 changes: 14 additions & 10 deletions packages/accessibility-android-sys/examples/screenrecord_probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,29 @@ use anyhow::{Context, Result, bail};
const IDLE_FLUSH: Duration = Duration::from_millis(75);
const PROBE_DURATION: Duration = Duration::from_secs(5);

fn main() -> Result<()> {
#[tokio::main]
async fn main() -> Result<()> {
let serial = std::env::args()
.nth(1)
.unwrap_or_else(|| "emulator-5554".to_string());
let adb = AdbClient::discover(Some(&serial));
adb.check_connection()?;
let (width, height) = adb.get_screen_size()?;
adb.check_connection().await?;
let (width, height) = adb.get_screen_size().await?;
let config = ScreenRecordConfig::for_max_dimension(width, height, Some(1280), 5_000_000);
println!("device : {serial}");
println!("source : {width}x{height}");
println!("encoded : {}x{}", config.width, config.height);

let stimulus = adb.clone();
std::thread::spawn(move || {
std::thread::sleep(Duration::from_secs(1));
let _ = stimulus.swipe(
(width as f64 * 0.5, height as f64 * 0.75),
(width as f64 * 0.5, height as f64 * 0.25),
800,
);
let stimulus = tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(1)).await;
let _ = stimulus
.swipe(
(width as f64 * 0.5, height as f64 * 0.75),
(width as f64 * 0.5, height as f64 * 0.25),
800,
)
.await;
});

let started = Instant::now();
Expand Down Expand Up @@ -67,6 +70,7 @@ fn main() -> Result<()> {
restart.elapsed().as_secs_f64() * 1000.0
);
println!("entry NALs: {:?}", nal_types(&first.data));
let _ = stimulus.await;
println!("probe passed");
Ok(())
}
Expand Down
49 changes: 29 additions & 20 deletions packages/accessibility-android-sys/src/emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub mod raw;
pub mod screenrecord;

pub mod protocol {
#![allow(clippy::result_large_err)]

pub mod controller {
tonic::include_proto!("android.emulation.control");
}
Expand Down Expand Up @@ -38,9 +40,9 @@ pub struct EmulatorDiscovery {
}

impl EmulatorDiscovery {
pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
pub async fn from_file(path: impl AsRef<Path>) -> Result<Self> {
let path = path.as_ref();
let contents = std::fs::read_to_string(path).with_context(|| {
let contents = tokio::fs::read_to_string(path).await.with_context(|| {
format!("failed to read emulator discovery file {}", path.display())
})?;
let properties = parse_properties(&contents);
Expand Down Expand Up @@ -246,17 +248,17 @@ impl EmulatorGrpcClient {
}
}

pub fn discover_emulator(selector: Option<&str>) -> Result<EmulatorDiscovery> {
discover_emulator_in(&discovery_directories(), selector)
pub async fn discover_emulator(selector: Option<&str>) -> Result<EmulatorDiscovery> {
discover_emulator_in(&discovery_directories(), selector).await
}

pub fn discover_emulator_in(
pub async fn discover_emulator_in(
directories: &[PathBuf],
selector: Option<&str>,
) -> Result<EmulatorDiscovery> {
let mut paths = BTreeSet::new();
for directory in directories {
let entries = match std::fs::read_dir(directory) {
let mut entries = match tokio::fs::read_dir(directory).await {
Ok(entries) => entries,
Err(error) if error.kind() == std::io::ErrorKind::NotFound => continue,
Err(error) => {
Expand All @@ -268,8 +270,8 @@ pub fn discover_emulator_in(
});
}
};
for entry in entries {
let path = entry?.path();
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
let Some(name) = path.file_name().and_then(|name| name.to_str()) else {
continue;
};
Expand All @@ -279,10 +281,12 @@ pub fn discover_emulator_in(
}
}

let mut discoveries = paths
.into_iter()
.filter_map(|path| EmulatorDiscovery::from_file(path).ok())
.collect::<Vec<_>>();
let mut discoveries = Vec::new();
for path in paths {
if let Ok(discovery) = EmulatorDiscovery::from_file(path).await {
discoveries.push(discovery);
}
}
if let Some(selector) = selector {
discoveries.retain(|discovery| discovery.matches(selector));
}
Expand Down Expand Up @@ -351,17 +355,17 @@ mod tests {
path
}

#[test]
#[tokio::test]
#[cfg_attr(miri, ignore)]
fn parses_discovery_file() {
async fn parses_discovery_file() {
let directory = test_directory("parse");
let path = directory.join("pid_1234.ini");
std::fs::write(
&path,
"grpc.port = 8554\ngrpc.token = secret\navd.name = Pixel_8\nport.serial = 5554\n",
)
.unwrap();
let discovery = EmulatorDiscovery::from_file(&path).unwrap();
let discovery = EmulatorDiscovery::from_file(&path).await.unwrap();
assert_eq!(discovery.pid, Some(1234));
assert_eq!(discovery.grpc_port, 8554);
assert_eq!(discovery.grpc_token.as_deref(), Some("secret"));
Expand All @@ -370,9 +374,9 @@ mod tests {
std::fs::remove_dir_all(directory).unwrap();
}

#[test]
#[tokio::test]
#[cfg_attr(miri, ignore)]
fn selects_one_emulator() {
async fn selects_one_emulator() {
let directory = test_directory("select");
std::fs::write(
directory.join("pid_1.ini"),
Expand All @@ -384,10 +388,15 @@ mod tests {
"grpc.port=8555\navd.name=tablet\n",
)
.unwrap();
let discovery =
discover_emulator_in(std::slice::from_ref(&directory), Some("tablet")).unwrap();
let discovery = discover_emulator_in(std::slice::from_ref(&directory), Some("tablet"))
.await
.unwrap();
assert_eq!(discovery.grpc_port, 8555);
assert!(discover_emulator_in(std::slice::from_ref(&directory), None).is_err());
assert!(
discover_emulator_in(std::slice::from_ref(&directory), None)
.await
.is_err()
);
std::fs::remove_dir_all(directory).unwrap();
}
}
2 changes: 1 addition & 1 deletion packages/accessibility-android-sys/src/emulator/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl RawFrameStream {
if config.width == 0 || config.height == 0 {
bail!("raw Android capture requires non-zero dimensions");
}
let discovery = discover_emulator(selector)?;
let discovery = discover_emulator(selector).await?;
Self::start_with_discovery(discovery, config).await
}

Expand Down
Loading
Loading