(
udid: &str,
bundle_id: &str,
shm_name: &str,
mirror: &str,
)
| 259 | } |
| 260 | |
| 261 | fn launch_with_injector( |
| 262 | udid: &str, |
| 263 | bundle_id: &str, |
| 264 | shm_name: &str, |
| 265 | mirror: &str, |
| 266 | ) -> Result<(), AppError> { |
| 267 | let dylib = camera_injector_path().map_err(app_internal)?; |
| 268 | let _ = Command::new("/usr/bin/xcrun") |
| 269 | .args(["simctl", "terminate", udid, bundle_id]) |
| 270 | .stdout(Stdio::null()) |
| 271 | .stderr(Stdio::null()) |
| 272 | .status(); |
| 273 | let app_log = camera_app_log_file(udid); |
| 274 | let mut child = Command::new("/usr/bin/xcrun") |
| 275 | .arg("simctl") |
| 276 | .arg("launch") |
| 277 | .arg(format!("--stdout={}", app_log.display())) |
| 278 | .arg(format!("--stderr={}", app_log.display())) |
| 279 | .arg(udid) |
| 280 | .arg(bundle_id) |
| 281 | .env("SIMCTL_CHILD_DYLD_INSERT_LIBRARIES", dylib) |
| 282 | .env("SIMCTL_CHILD_SIMDECK_CAMERA_SHM_NAME", shm_name) |
| 283 | .env("SIMCTL_CHILD_SIMDECK_CAMERA_MIRROR", mirror) |
| 284 | .stdout(Stdio::piped()) |
| 285 | .stderr(Stdio::piped()) |
| 286 | .spawn() |
| 287 | .map_err(|error| AppError::native(format!("Unable to launch camera app. {error}")))?; |
| 288 | let start = Instant::now(); |
| 289 | let output = loop { |
| 290 | match child.try_wait() { |
| 291 | Ok(Some(_)) => break child.wait_with_output().map_err(app_internal)?, |
| 292 | Ok(None) => { |
| 293 | if start.elapsed() > Duration::from_secs(180) { |
| 294 | let _ = child.kill(); |
| 295 | let output = child.wait_with_output().map_err(app_internal)?; |
| 296 | let stderr = String::from_utf8_lossy(&output.stderr).trim().to_owned(); |
| 297 | return Err(AppError::native(if stderr.is_empty() { |
| 298 | "xcrun simctl launch timed out after 180s.".to_owned() |
| 299 | } else { |
| 300 | format!("xcrun simctl launch timed out after 180s. {stderr}") |
| 301 | })); |
| 302 | } |
| 303 | std::thread::sleep(Duration::from_millis(100)); |
| 304 | } |
| 305 | Err(error) => { |
| 306 | return Err(AppError::native(format!( |
| 307 | "Unable to wait for camera app launch. {error}" |
| 308 | ))) |
| 309 | } |
| 310 | } |
| 311 | }; |
| 312 | if output.status.success() { |
| 313 | Ok(()) |
| 314 | } else { |
| 315 | let stderr = String::from_utf8_lossy(&output.stderr).trim().to_owned(); |
| 316 | let stdout = String::from_utf8_lossy(&output.stdout).trim().to_owned(); |
| 317 | Err(AppError::native(if stderr.is_empty() { |
| 318 | stdout |
no test coverage detected