Skip to main content

EmulatorClient

Struct EmulatorClient 

Source
pub struct EmulatorClient { /* private fields */ }
Expand description

High-level client for controlling an Android Emulator via gRPC

This is a wrapper around the generated EmulatorControllerClient that provides a more convenient API.

Implementations§

Source§

impl EmulatorClient

Source

pub async fn connect_avd(avd: &str) -> Result<Self>

Try to find an emulator running the specified AVD and connect to it

Source

pub async fn connect(endpoint: impl Into<String>) -> Result<Self>

Connect to an emulator at the specified endpoint without authentication

Source

pub async fn connect_with_auth( endpoint: impl Into<String>, provider: AuthProvider, ) -> Result<Self>

Connect to an emulator with JWT authentication

Source

pub fn auth_scheme(&self) -> &AuthScheme

Get the authentication scheme used by this client

Source

pub fn export_token(&self, auds: &[&str], ttl: Duration) -> Result<BearerToken>

Export a bearer token for the given audiences and TTL

This can be used to export a token with specific, limited audience claims in order to grant something limited access to the emulator.

Each audience in auds will be included as an aud claim in the token and should correspond to the gRPC method patterns defined in the allowlist.

This is only applicable when Self::auth_scheme() returns auth::AuthScheme::Jwt.

Source

pub fn endpoint(&self) -> &str

Get the endpoint this client is connected to

Source

pub fn protocol_mut( &mut self, ) -> &mut EmulatorControllerClient<InterceptedService<Channel, AuthProvider>>

Get a mutable reference to the generated gRPC client protobuf binding

Source

pub fn protocol( &self, ) -> &EmulatorControllerClient<InterceptedService<Channel, AuthProvider>>

Get a reference to the generated gRPC client protobuf binding

Source

pub async fn wait_until_booted( &mut self, timeout: Duration, poll_interval: Option<Duration>, ) -> Result<Duration>

Wait until the emulator has fully booted

This method polls the emulator’s boot status until it reports as booted, or until the specified timeout is reached.

§Arguments
  • timeout - Maximum duration to wait for the emulator to boot
  • poll_interval - Duration to wait between boot status checks (defaults to 2 seconds if None)
§Returns

Returns Ok(Duration) with the time elapsed until boot completed, or an error if the timeout is reached or a gRPC error occurs.

§Errors

Returns EmulatorError::ConnectionTimeout if the emulator doesn’t boot within the timeout period. Returns EmulatorError::GrpcStatus if there’s a gRPC communication error.

§Example
use android_emulator::EmulatorClient;
use std::time::Duration;

let mut client = EmulatorClient::connect("http://localhost:8554").await?;

// Wait up to 5 minutes for boot, checking every 2 seconds
let elapsed = client.wait_until_booted(Duration::from_secs(300), None).await?;
println!("Emulator booted in {:.1} seconds", elapsed.as_secs_f64());
Source

pub async fn shutdown(&mut self, timeout: Option<Duration>) -> Result<()>

Request a graceful shutdown of the emulator via the gRPC protocol

This method requests a graceful shutdown by setting the VM state to SHUTDOWN and polls the VM state until it reaches a terminal state or the timeout is reached.

This is a protocol-level operation that does not explicitly kill the emulator process, but a successful shutdown will typically result in the emulator process exiting on its own.

If you spawned the emulator then explicitly calling Emulator::kill() or dropping the Emulator after a shutdown request will kill the process if it hasn’t already exited cleanly.

This is the preferred way to stop an emulator as it allows the guest OS to shut down cleanly, save snapshots, and perform proper cleanup.

§Arguments
  • timeout - Maximum duration to wait for the VM to shut down (defaults to 30 seconds if None)
§Returns

Returns Ok(()) if the shutdown request was successful and the VM shut down, or an error if the operation fails.

§Errors

Returns an error if:

  • Setting the VM state fails
  • The shutdown timeout is exceeded
§Example
use android_emulator::{EmulatorConfig, EmulatorClient};
use std::time::Duration;

let config = EmulatorConfig::new("test");
let instance = config.spawn().await?;
let mut client = instance.connect(Some(Duration::from_secs(30)), true).await?;

// ... use the emulator ...

// Gracefully shutdown via protocol
client.shutdown(None).await?;

// Clean up the process if we spawned it
instance.kill().await?;

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more