use crate::provider::IdeviceProvider;
use crate::services::lockdown::LockdownClient;
use crate::{Idevice, IdeviceError, ReadWrite, obf};
#[cfg(feature = "rsd")]
use crate::RsdService;
#[cfg(feature = "application_listing")]
pub mod application_listing;
#[cfg(feature = "condition_inducer")]
pub mod condition_inducer;
#[cfg(feature = "device_info")]
pub mod device_info;
#[cfg(any(
feature = "energy_monitor",
feature = "graphics",
feature = "rsd",
feature = "sysmontap"
))]
pub mod energy_monitor;
pub mod errors;
#[cfg(feature = "graphics")]
pub mod graphics;
#[cfg(feature = "location_simulation")]
pub mod location_simulation;
pub mod message;
#[cfg(feature = "network_monitor")]
pub mod network_monitor;
pub mod notifications;
pub mod process_control;
pub mod remote_server;
pub mod screenshot;
#[cfg(feature = "sysmontap")]
pub mod sysmontap;
#[cfg(feature = "xctest")]
pub mod xctest;
impl RsdService for remote_server::RemoteServerClient<Box<dyn ReadWrite>> {
fn rsd_service_name() -> std::borrow::Cow<'static, str> {
obf!("com.apple.instruments.dtservicehub")
}
async fn from_stream(stream: Box<dyn ReadWrite>) -> Result<Self, IdeviceError> {
Ok(Self::new(stream))
}
}
impl crate::IdeviceService for remote_server::RemoteServerClient<Box<dyn ReadWrite>> {
fn service_name() -> std::borrow::Cow<'static, str> {
obf!("com.apple.instruments.remoteserver")
}
#[allow(async_fn_in_trait)]
async fn connect(provider: &dyn IdeviceProvider) -> Result<Self, IdeviceError> {
let mut lockdown = LockdownClient::connect(provider).await?;
let legacy = lockdown
.get_value(Some("ProductVersion"), None)
.await
.ok()
.as_ref()
.and_then(|x| x.as_string())
.and_then(|x| x.split(".").next())
.and_then(|x| x.parse::<u8>().ok())
.map(|x| x < 5)
.unwrap_or(false);
lockdown
.start_session(&provider.get_pairing_file().await?)
.await?;
let try_names = [
obf!("com.apple.instruments.remoteserver"),
obf!("com.apple.instruments.remoteserver.DVTSecureSocketProxy"),
];
let mut last_err: Option<IdeviceError> = None;
for name in try_names {
match lockdown.start_service(name).await {
Ok((port, ssl)) => {
let mut idevice = provider.connect(port).await?;
if ssl {
idevice
.start_session(&provider.get_pairing_file().await?, legacy)
.await?;
}
let socket = idevice
.get_socket()
.ok_or(IdeviceError::NoEstablishedConnection)?;
return Ok(remote_server::RemoteServerClient::new(socket));
}
Err(e) => {
last_err = Some(e);
}
}
}
Err(last_err.unwrap_or(IdeviceError::ServiceNotFound))
}
#[allow(async_fn_in_trait)]
async fn from_stream(idevice: Idevice) -> Result<Self, IdeviceError> {
let socket = idevice
.get_socket()
.ok_or(IdeviceError::NoEstablishedConnection)?;
Ok(remote_server::RemoteServerClient::new(socket))
}
}