pub struct EmulatorControllerClient<T> { /* private fields */ }Expand description
An EmulatorController service lets you control the emulator. Note that this is currently an experimental feature, and that the service definition might change without notice. Use at your own risk!
We use the following rough conventions:
streamXXX –> streams values XXX (usually for emulator lifetime). Values are updated as soon as they become available. getXXX –> gets a single value XXX setXXX –> sets a single value XXX, does not returning state, these usually have an observable lasting side effect. sendXXX –> send a single event XXX, possibly returning state information. android usually responds to these events.
Implementations§
Source§impl<T> EmulatorControllerClient<T>where
T: GrpcService<Body>,
T::Error: Into<StdError>,
T::ResponseBody: Body<Data = Bytes> + Send + 'static,
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
impl<T> EmulatorControllerClient<T>where
T: GrpcService<Body>,
T::Error: Into<StdError>,
T::ResponseBody: Body<Data = Bytes> + Send + 'static,
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
pub fn new(inner: T) -> Self
pub fn with_origin(inner: T, origin: Uri) -> Self
pub fn with_interceptor<F>(
inner: T,
interceptor: F,
) -> EmulatorControllerClient<InterceptedService<T, F>>where
F: Interceptor,
T::ResponseBody: Default,
T: Service<Request<Body>, Response = Response<<T as GrpcService<Body>>::ResponseBody>>,
<T as Service<Request<Body>>>::Error: Into<StdError> + Send + Sync,
Sourcepub fn send_compressed(self, encoding: CompressionEncoding) -> Self
pub fn send_compressed(self, encoding: CompressionEncoding) -> Self
Compress requests with the given encoding.
This requires the server to support it otherwise it might respond with an error.
Sourcepub fn accept_compressed(self, encoding: CompressionEncoding) -> Self
pub fn accept_compressed(self, encoding: CompressionEncoding) -> Self
Enable decompressing responses.
Sourcepub fn max_decoding_message_size(self, limit: usize) -> Self
pub fn max_decoding_message_size(self, limit: usize) -> Self
Limits the maximum size of a decoded message.
Default: 4MB
Sourcepub fn max_encoding_message_size(self, limit: usize) -> Self
pub fn max_encoding_message_size(self, limit: usize) -> Self
Limits the maximum size of an encoded message.
Default: usize::MAX
Sourcepub async fn stream_sensor(
&mut self,
request: impl IntoRequest<SensorValue>,
) -> Result<Response<Streaming<SensorValue>>, Status>
pub async fn stream_sensor( &mut self, request: impl IntoRequest<SensorValue>, ) -> Result<Response<Streaming<SensorValue>>, Status>
set/get/stream the sensor data This RPC is not implemented in EmulatorController and will return an unimplemented error.
Sourcepub async fn get_sensor(
&mut self,
request: impl IntoRequest<SensorValue>,
) -> Result<Response<SensorValue>, Status>
pub async fn get_sensor( &mut self, request: impl IntoRequest<SensorValue>, ) -> Result<Response<SensorValue>, Status>
Gets the current value of a specified sensor.
The following gRPC error codes can be returned:
- INTERNAL (code 13) if
getSensorSizefails to retrieve sensor dimensions.
The status field in the SensorValue reply indicates the operational state:
OK(0): Sensor data retrieved successfully.UNKNOWN(2): Unknown sensor type (should not happen if using validSensorType).DISABLED(3): The sensor is disabled.NO_SERVICE(4): Theqemudservice responsible for sensors is not available or initiated.
Sourcepub async fn set_sensor(
&mut self,
request: impl IntoRequest<SensorValue>,
) -> Result<Response<()>, Status>
pub async fn set_sensor( &mut self, request: impl IntoRequest<SensorValue>, ) -> Result<Response<()>, Status>
Sets the override value for a specified sensor. This operation is asynchronous
and executed on the emulator’s main looper. An immediate subsequent getSensor
call might not reflect the newly set value.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
No specific gRPC error codes are returned by this method itself, but underlying
operations might log warnings if the sensor agent is unavailable.
Sourcepub async fn set_physical_model(
&mut self,
request: impl IntoRequest<PhysicalModelValue>,
) -> Result<Response<()>, Status>
pub async fn set_physical_model( &mut self, request: impl IntoRequest<PhysicalModelValue>, ) -> Result<Response<()>, Status>
set/get/stream the physical model, this is likely the one you are looking for when you wish to modify the device state.
This operation is asynchronous and executed on the emulator’s main looper. An immediate subsequent getPhysicalModel
call might not reflect the newly set value. The interpolation field from the request is used to determine the
physical interpolation method, mapped using abs((static_cast<int>(physicalValue.interpolation())) - 1).
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn get_physical_model(
&mut self,
request: impl IntoRequest<PhysicalModelValue>,
) -> Result<Response<PhysicalModelValue>, Status>
pub async fn get_physical_model( &mut self, request: impl IntoRequest<PhysicalModelValue>, ) -> Result<Response<PhysicalModelValue>, Status>
Gets the current value of a specified physical model parameter.
The status field in the PhysicalModelValue reply indicates the operational state:
OK(0): Physical model data retrieved successfully.UNKNOWN(2): Unknown physical type (should not happen if using validPhysicalType).NO_SERVICE(3): Theqemudservice responsible for physical parameters is not available or initiated.
Sourcepub async fn stream_physical_model(
&mut self,
request: impl IntoRequest<PhysicalModelValue>,
) -> Result<Response<Streaming<PhysicalModelValue>>, Status>
pub async fn stream_physical_model( &mut self, request: impl IntoRequest<PhysicalModelValue>, ) -> Result<Response<Streaming<PhysicalModelValue>>, Status>
This RPC is not implemented in EmulatorController and will return an unimplemented error.
Sourcepub async fn set_clipboard(
&mut self,
request: impl IntoRequest<ClipData>,
) -> Result<Response<()>, Status>
pub async fn set_clipboard( &mut self, request: impl IntoRequest<ClipData>, ) -> Result<Response<()>, Status>
Atomically sets the current primary clipboard data. This operation is asynchronous
and executed on the emulator’s main looper. It triggers a ClipboardEvent
to all listeners (except the originating channel) indicating the new content.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn get_clipboard(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<ClipData>, Status>
pub async fn get_clipboard( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<ClipData>, Status>
Retrieves the current primary clipboard data. This is a synchronous operation.
This method returns OK (code 0) and the current ClipData upon success.
Sourcepub async fn stream_clipboard(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<Streaming<ClipData>>, Status>
pub async fn stream_clipboard( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<Streaming<ClipData>>, Status>
Streams real-time updates of the clipboard content. Upon subscription,
it immediately sends the current clipboard state. Subsequent updates are
streamed as new content becomes available from the guest or is set via setClipboard
from a different client. Events originating from the same client that initiated
the stream are filtered out to prevent echoing.
It is possible to miss very rapid clipboard updates. The stream will block awaiting new events after the initial state is sent.
This method returns a server-side streaming reactor.
Sourcepub async fn set_battery(
&mut self,
request: impl IntoRequest<BatteryState>,
) -> Result<Response<()>, Status>
pub async fn set_battery( &mut self, request: impl IntoRequest<BatteryState>, ) -> Result<Response<()>, Status>
Sets the emulator’s battery state to the provided values. This operation is executed asynchronously on the main looper.
This method returns OK (code 0) upon successful asynchronous scheduling
of the operation. No explicit gRPC error codes are returned by this method.
Sourcepub async fn get_battery(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<BatteryState>, Status>
pub async fn get_battery( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<BatteryState>, Status>
Retrieves the current battery state from the emulator. This is a synchronous operation that waits for completion.
This method returns OK (code 0) and populates the BatteryState reply
with the current information upon success. No explicit gRPC error codes
are returned by this method.
Sourcepub async fn set_gps(
&mut self,
request: impl IntoRequest<GpsState>,
) -> Result<Response<()>, Status>
pub async fn set_gps( &mut self, request: impl IntoRequest<GpsState>, ) -> Result<Response<()>, Status>
Sets the state of the GPS in the emulator. This operation is asynchronous and executed on the main looper. It updates the emulator’s GPS location (latitude, longitude, altitude, speed, bearing, and satellites) and sets the timestamp.
Note: Setting the GPS position will not be immediately reflected in the user
interface. Android typically samples GPS at 1 Hz.
This method returns OK (code 0) upon successful asynchronous scheduling
of the operation.
Sourcepub async fn get_gps(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<GpsState>, Status>
pub async fn get_gps( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<GpsState>, Status>
Gets the latest GPS state as reported by the emulator. This includes data
delivered by previous setGps calls or from the location UI if active.
This is a synchronous operation that waits for completion.
Note: The returned GPS state is not necessarily the exact coordinate visible at the time due to Android’s typical 1 Hz GPS sample frequency.
This method returns OK (code 0) and populates the GpsState reply
with the retrieved information upon success. No explicit gRPC error codes
are returned by this method.
Sourcepub async fn send_fingerprint(
&mut self,
request: impl IntoRequest<Fingerprint>,
) -> Result<Response<()>, Status>
pub async fn send_fingerprint( &mut self, request: impl IntoRequest<Fingerprint>, ) -> Result<Response<()>, Status>
Simulates a touch event on the fingerprint sensor. This operation is executed asynchronously on the main looper.
The isTouching field indicates whether the fingerprint sensor is being
touched, and touchId specifies the identifier of the registered
fingerprint. The setTouch agent function is used to apply these values.
This method returns OK (code 0) upon successful asynchronous scheduling
of the operation. No explicit gRPC error codes are returned by this method.
Sourcepub async fn send_key(
&mut self,
request: impl IntoRequest<KeyboardEvent>,
) -> Result<Response<()>, Status>
pub async fn send_key( &mut self, request: impl IntoRequest<KeyboardEvent>, ) -> Result<Response<()>, Status>
Sends a keyboard event to the emulator. This operation is asynchronous and executed on the main looper.
The KeyboardEvent message allows specifying input using keyCode, key (W3C standard string), or text (UTF-8 string).
The KeyEventSender prioritizes key, then keyCode, then text.
- If
keyis a non-printable W3C key string (e.g., “Backspace”, “ArrowUp”), it’s translated to an evdev keycode and sent. - If
keyis a printable Unicode character, it’s converted to a sequence of evdev keydown/keyup events, handling modifiers. - If
keyCodeis provided, it’s translated from itscodeType(Usb, Evdev, XKB, Win, Mac) to an evdev keycode and sent as keydown/keyup pairs. - If
textis provided, each UTF-8 character is converted to evdev keypress (keydown then keyup) events.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn send_touch(
&mut self,
request: impl IntoRequest<TouchEvent>,
) -> Result<Response<()>, Status>
pub async fn send_touch( &mut self, request: impl IntoRequest<TouchEvent>, ) -> Result<Response<()>, Status>
Sends touch events to the emulator. This operation is asynchronous and executed on the main looper.
The TouchEvent contains a list of Touch objects, each with x, y coordinates, identifier, pressure, touch_major, touch_minor, expiration, and orientation.
Coordinates are scaled to the emulator’s display resolution. Each Touch identifier is mapped to an internal Linux multitouch slot.
Expiration handling ensures that inactive touch events are properly “lifted” after 120 seconds.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation. Warnings are logged if no touch slots are available.
Sourcepub async fn send_mouse(
&mut self,
request: impl IntoRequest<MouseEvent>,
) -> Result<Response<()>, Status>
pub async fn send_mouse( &mut self, request: impl IntoRequest<MouseEvent>, ) -> Result<Response<()>, Status>
Sends mouse events to the emulator. This operation is asynchronous and executed on the main looper.
The MouseEvent specifies x, y coordinates, buttons state (bitmask: 1 for left, 2 for right), and display ID.
In certain virtual input configurations (VirtioInput enabled, but VirtioMouse and VirtioTablet disabled), buttons may be masked to only consider the primary button.
The event is sent to the emulator’s user_event_agent.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn inject_wheel(
&mut self,
request: impl IntoStreamingRequest<Message = WheelEvent>,
) -> Result<Response<()>, Status>
pub async fn inject_wheel( &mut self, request: impl IntoStreamingRequest<Message = WheelEvent>, ) -> Result<Response<()>, Status>
Injects a stream of wheel events into the emulator. This is a server-side streaming RPC.
Each WheelEvent contains dx, dy (delta values, dy is pre-multiplied by 120 for scroll clicks), and display ID.
If the emulator’s input device has rotary capabilities (e.g., AVD_WEAR flavor), dy is scaled and sent as a rotary event.
Otherwise, it’s sent as a standard mouse wheel event.
This method returns a server-side streaming reactor.
Sourcepub async fn stream_input_event(
&mut self,
request: impl IntoStreamingRequest<Message = InputEvent>,
) -> Result<Response<()>, Status>
pub async fn stream_input_event( &mut self, request: impl IntoStreamingRequest<Message = InputEvent>, ) -> Result<Response<()>, Status>
Streams a series of generic input events to the emulator. The events are processed in the order they arrive.
This is a server-side streaming RPC that supports various input types encapsulated within InputEvent’s oneof type field.
Supported input types:
key_event(KeyboardEvent): Processed byKeyEventSenderas described insendKey.touch_event(TouchEvent): Processed byTouchEventSenderas described insendTouch.mouse_event(MouseEvent): Processed byMouseEventSenderas described insendMouse.android_event(AndroidEvent): Raw Linux input events (type,code,value) sent directly to the kernel.pen_event(PenEvent): Processed byPenEventSenderfor pen input, including pressure, orientation, and button state.wheel_event(WheelEvent): Processed byWheelEventSenderas described ininjectWheel.xr_command(XrCommand): Executes XR-specific commands (e.g.,RECENTERto recenter the viewport). Unknown actions are logged as warnings.xr_head_rotation_event(RotationRadian): Sends head rotation data in radians. Logs an error if the agent call fails.xr_head_movement_event(Translation): Sends head movement data in meters. Logs an error if the agent call fails.xr_head_angular_velocity_event(AngularVelocity): Sends head angular velocity data in radians per second. Logs an error if the agent call fails.xr_head_velocity_event(Velocity): Sends head velocity data in meters per second. Logs an error if the agent call fails.touchpad_event(TouchpadEvent): Processed byTouchpadEventSenderfor touchpad input, similar to touch events but for a touchpad device.
All underlying input sending operations for XR events are executed asynchronously on the main looper.
Returns INVALID_ARGUMENT (code 3) if an unrecognized input event type is received, indicating a potential out-of-date emulator.
The stream reactor automatically deletes itself upon completion.
Sourcepub async fn send_phone(
&mut self,
request: impl IntoRequest<PhoneCall>,
) -> Result<Response<PhoneResponse>, Status>
pub async fn send_phone( &mut self, request: impl IntoRequest<PhoneCall>, ) -> Result<Response<PhoneResponse>, Status>
Initiates or manipulates a phone call in the emulator. This is a synchronous operation executed on the main looper.
The PhoneCall message specifies the operation (e.g., InitCall, AcceptCall)
and the target phone number. The telephonyCmd agent function handles the
actual call action.
Returns a PhoneResponse indicating the outcome:
OK(0): The operation was successful.BadOperation(1): The providedoperationenum is out of range.BadNumber(2): The providednumberis malformed.InvalidAction(3): The requestedoperationis invalid given the current call state (e.g., disconnecting when no call is active).ActionFailed(4): An internal error occurred, typically if the modem agent is unavailable.RadioOff(5): The emulator’s radio is turned off.
Sourcepub async fn send_sms(
&mut self,
request: impl IntoRequest<SmsMessage>,
) -> Result<Response<PhoneResponse>, Status>
pub async fn send_sms( &mut self, request: impl IntoRequest<SmsMessage>, ) -> Result<Response<PhoneResponse>, Status>
Sends an SMS message to the emulator. This is a synchronous operation.
The SmsMessage contains the srcAddress (source phone number) and the text of the message.
The srcAddress is validated for GSM formatting. The message text is converted into SMS PDUs
(Protocol Data Units) and delivered via the modem agent.
Returns a PhoneResponse indicating the outcome:
OK(0): The SMS message was successfully delivered.BadNumber(2): ThesrcAddressis malformed.ActionFailed(4): An internal error occurred, e.g., if the modem agent is unavailable or PDU creation fails.
Other error cases from PDU creation (e.g., invalid characters in text) also result in ActionFailed.
Sourcepub async fn set_phone_number(
&mut self,
request: impl IntoRequest<PhoneNumber>,
) -> Result<Response<PhoneResponse>, Status>
pub async fn set_phone_number( &mut self, request: impl IntoRequest<PhoneNumber>, ) -> Result<Response<PhoneResponse>, Status>
Sets the emulator’s phone number. This is a synchronous operation.
The PhoneNumber message contains the new number to be set. The modem agent’s
amodem_update_phone_number function is used for this update.
Returns a PhoneResponse indicating the outcome:
OK(0): The phone number was successfully updated.BadNumber(2): The providednumberis invalid for the modem.ActionFailed(4): An internal error occurred, typically if the modem agent is unavailable.
Sourcepub async fn get_status(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<EmulatorStatus>, Status>
pub async fn get_status( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<EmulatorStatus>, Status>
Retrieves the current status of the emulator. This includes comprehensive information about the virtual machine’s configuration and the guest operating system’s state.
The EmulatorStatus reply contains:
version: The emulator version string.uptime: The time the emulator has been active in milliseconds.booted: A boolean indicating if the device has completed booting.vmConfig: DetailedVmConfiguration(hypervisor type, CPU cores, RAM size).hardwareConfig: Key-value pairs describing the emulator’s hardware configuration.heartbeat: A monotonically increasing number indicating guest activity (incremented approximately once per second).guestConfig: A map of key-value pairs with guest-specific configurations, including:- “multidisplay”: “available” or “unavailable” based on display pipe readiness.
- “androidVersion”: The Android version of the guest OS.
- “hypervisorVersion”: The hypervisor version used by the guest.
This method returns OK (code 0) upon successful retrieval of the emulator status.
Sourcepub async fn get_screenshot(
&mut self,
request: impl IntoRequest<ImageFormat>,
) -> Result<Response<Image>, Status>
pub async fn get_screenshot( &mut self, request: impl IntoRequest<ImageFormat>, ) -> Result<Response<Image>, Status>
Retrieves a single screenshot in the desired format.
The image will be scaled to the desiredWidth and desiredHeight specified in ImageFormat, while maintaining
the aspect ratio. If width or height are 0, the device’s current display dimensions are used.
The returned image will never exceed the device’s actual display resolution, but can be smaller.
The display field in ImageFormat specifies the target display; 0 (or omitted) indicates the main display.
For folded Pixel Fold devices, the display ID might be internally remapped, and foldedDisplay information will be populated.
The resulting image is properly oriented based on the device’s coarse-grained orientation, derived from sensor state.
The transport field in ImageFormat can specify MMAP for shared memory delivery, but if the shared memory region
is too small, a FAILED_PRECONDITION error will be returned.
This method returns:
OK(code 0) and anImageobject upon success.INVALID_ARGUMENT(code 3) if the specifieddisplayID is invalid or disabled.CANCELLED(code 1) if the gRPC context is cancelled during the operation (an expensive operation).FAILED_PRECONDITION(code 9) if the guest has not posted a new frame yet (for non-PNG formats when fast path is used).
This method will return an image with width 0 and height 0 if the display is not visible.
Sourcepub async fn stream_screenshot(
&mut self,
request: impl IntoRequest<ImageFormat>,
) -> Result<Response<Streaming<Image>>, Status>
pub async fn stream_screenshot( &mut self, request: impl IntoRequest<ImageFormat>, ) -> Result<Response<Streaming<Image>>, Status>
Streams a series of screenshots in the desired format. This is a server-side streaming RPC.
A new frame is delivered whenever the device produces a new frame or when sensor changes occur. Initial state: The first frame delivered might be an empty image (width 0, height 0) if the display is inactive. Subsequent frames are delivered when new content is available or a sensor event triggers an update. If the display becomes inactive, an empty image will be delivered again. Images resume when the display becomes active.
ImageFormat parameters (format, width, height, display) behave as described in getScreenshot.
The transport field in ImageFormat can specify MMAP for shared memory delivery. If MMAP is used and the
provided shared memory handle is valid and mapped, pixel data will be written directly to it.
The image field in the Image reply will be empty if MMAP transport is used.
Performance considerations:
- Streaming can produce a significant amount of data.
PNGformat is CPU-intensive due to encoding overhead.- Using
MMAPtransport can significantly reduce gRPC overhead for pixel data.
This method returns:
- A server-side streaming reactor.
INVALID_ARGUMENT(code 3) if the specifieddisplayID is invalid or disabled.CANCELLED(code 1) if the gRPC context is cancelled during the operation.
Sourcepub async fn stream_audio(
&mut self,
request: impl IntoRequest<AudioFormat>,
) -> Result<Response<Streaming<AudioPacket>>, Status>
pub async fn stream_audio( &mut self, request: impl IntoRequest<AudioFormat>, ) -> Result<Response<Streaming<AudioPacket>>, Status>
Streams a series of audio packets in the desired format. This is a server-side streaming RPC.
A new frame is delivered approximately every 20-30ms when the emulated device produces audio.
If samplingRate is 0, it defaults to 44100 Hz.
The stream may block indefinitely if the emulator ceases to produce audio.
Packets are allocated with a buffer size calculated based on the audio format and a 30ms frame time.
This method returns OK (code 0) upon successful streaming initiation.
Sourcepub async fn inject_audio(
&mut self,
request: impl IntoStreamingRequest<Message = AudioPacket>,
) -> Result<Response<()>, Status>
pub async fn inject_audio( &mut self, request: impl IntoStreamingRequest<Message = AudioPacket>, ) -> Result<Response<()>, Status>
Injects a series of audio packets into the Android microphone. This is a client-side streaming RPC. Audio packets are processed at a rate determined by the emulator’s request for frames. An internal buffer can hold approximately 300ms of audio.
Notes:
- Only the
AudioFormatfrom the first received packet is honored. SubsequentAudioFormatchanges are ignored. MODE_REAL_TIMEis experimental: incoming data may overwrite existing data if the client does not control timing properly.- The circular buffer attempts to deliver all queued samples upon stream closure by writing silence for up to 300ms.
Returns the following gRPC error codes:
FAILED_PRECONDITION(code 9): If another microphone is already active, or if unable to register the microphone.INVALID_ARGUMENT(code 3): If the desiredsamplingRateexceeds 48kHz, or if anAudioPacketis too large for the internal buffer.
This method returns OK (code 0) upon successful completion of the stream.
Sourcepub async fn get_microphone_state(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<MicrophoneState>, Status>
pub async fn get_microphone_state( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<MicrophoneState>, Status>
Retrieves the current settings for the microphone
Sourcepub async fn set_microphone_state(
&mut self,
request: impl IntoRequest<MicrophoneState>,
) -> Result<Response<()>, Status>
pub async fn set_microphone_state( &mut self, request: impl IntoRequest<MicrophoneState>, ) -> Result<Response<()>, Status>
Sets the state for the microphone
Sourcepub async fn get_logcat(
&mut self,
request: impl IntoRequest<LogMessage>,
) -> Result<Response<LogMessage>, Status>
👎Deprecated
pub async fn get_logcat( &mut self, request: impl IntoRequest<LogMessage>, ) -> Result<Response<LogMessage>, Status>
Deprecated, please use the streamLogcat method instead.
Sourcepub async fn stream_logcat(
&mut self,
request: impl IntoRequest<LogMessage>,
) -> Result<Response<Streaming<LogMessage>>, Status>
pub async fn stream_logcat( &mut self, request: impl IntoRequest<LogMessage>, ) -> Result<Response<Streaming<LogMessage>>, Status>
Streams the logcat output from the emulator in real-time. This is a server-side streaming RPC.
The stream sources its data from the logcat command executed via AdbShellStream in the Android guest.
Log lines are processed individually as they arrive.
The LogMessage.sort field determines the output format:
- If
LogMessage.sortisParsed, each incoming log line is parsed into a structuredLogcatEntryobject, and these entries are returned in theLogMessage.entriesfield. Structured parsing is typically available for Android API Level 23 (Marshmallow) and later. - If
LogMessage.sortisText(or unspecified), the raw log line is returned in theLogMessage.contentsfield.
The stream continues as long as the underlying logcat process is running and the client is connected.
The stream will naturally terminate if the logcat process stops or the connection is lost.
No explicit gRPC error codes are returned by this method during active streaming.
Sourcepub async fn set_vm_state(
&mut self,
request: impl IntoRequest<VmRunState>,
) -> Result<Response<()>, Status>
pub async fn set_vm_state( &mut self, request: impl IntoRequest<VmRunState>, ) -> Result<Response<()>, Status>
Transitions the virtual machine to the desired state. This operation is scheduled asynchronously.
Transition commands:
RUNNINGorSTART: Starts or resumes execution of the virtual machine.PAUSEDorSTOP: Pauses execution of the virtual machine, halting CPU cycles.RESETorRESTART: Performs a warm reset of the virtual machine.SHUTDOWN: Initiates a graceful shutdown of the emulator.TERMINATE: Forcefully terminates the emulator process immediately without cleanup. This can cause data corruption and must be used with caution.
Note that write-only actions (START, STOP, RESET, RESTART) perform the
transition but are not observed as states in getVmState. Purely observable states
(UNKNOWN, RESTORE_VM, SAVE_VM, INTERNAL_ERROR) cannot be set directly.
Returns once the operation has been scheduled.
Note: The call may not return when the state is set to TERMINATE or SHUTDOWN.
Sourcepub async fn get_vm_state(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<VmRunState>, Status>
pub async fn get_vm_state( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<VmRunState>, Status>
Retrieves the current execution state of the virtual machine.
The returned VmRunState represents the current condition of the VM:
RUNNING: The virtual machine is actively executing.PAUSED: Execution is suspended (CPUs are halted).SHUTDOWN: The guest operating system has initiated a shutdown.RESTORE_VM: The virtual machine is paused while restoring its state (e.g., loading a snapshot).SAVE_VM: The virtual machine is paused while saving its state (e.g., taking a snapshot).INTERNAL_ERROR: Execution has stopped due to a guest panic, I/O error, or hypervisor failure.UNKNOWN: The virtual machine is in an unmapped or transient state.
This is a synchronous query operation.
Sourcepub async fn set_display_configurations(
&mut self,
request: impl IntoRequest<DisplayConfigurations>,
) -> Result<Response<DisplayConfigurations>, Status>
pub async fn set_display_configurations( &mut self, request: impl IntoRequest<DisplayConfigurations>, ) -> Result<Response<DisplayConfigurations>, Status>
Atomically changes the current multi-display configuration. This operation applies
the provided DisplayConfigurations, with special handling for secondary displays.
Display ID 0 (the primary display) cannot be modified via this RPC.
Preconditions:
- The
android::featurecontrol::MultiDisplayfeature must be enabled.
Input Validation:
INVALID_ARGUMENT(code 3): If duplicatedisplayIDs are found in the request.INVALID_ARGUMENT(code 3): If anyDisplayConfiguration(width, height, dpi, flags) is outside valid ranges as determined bymultiDisplayParamValidate.INVALID_ARGUMENT(code 3): If anydisplayID is outside the configurable range[1, userConfigurable].
Atomic Update and Rollback:
The system attempts to apply each display configuration. If any update fails
(e.g., after multiple retries for transient pipe errors), a rollback mechanism
is initiated: successfully updated displays are reverted to their previous state,
and newly added displays are deleted. In such cases, an INTERNAL error is returned.
Deletion of Unrequested Displays:
Any displays that were active before this call but are not present in the new
request.displays (and are not display ID 0) will be deleted.
Notifications:
Upon successful completion, notifyDisplayChanges() is called to inform
third-party subscribers.
Returns the following gRPC error codes:
OK(code 0): Upon successful application of all configurations, returning the final activeDisplayConfigurations.FAILED_PRECONDITION(code 9): If the multi-display feature is not available.INTERNAL(code 13): If an internal emulator failure occurs during display modification or rollback.
Sourcepub async fn get_display_configurations(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<DisplayConfigurations>, Status>
pub async fn get_display_configurations( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<DisplayConfigurations>, Status>
Returns all currently valid logical displays configured in the emulator. This is a synchronous operation.
Preconditions:
- The
android::featurecontrol::MultiDisplayfeature must be enabled.
The DisplayConfigurations reply contains:
displays: A repeated field ofDisplayConfigurationobjects, each detailing the width, height, DPI, flags, and ID of an active display. For Pixel Fold devices, only the main display configuration might be relevant.userConfigurable: The maximum number of user-configurable displays (IDs from 1 up to this value).maxDisplays: The total maximum number of displays the emulator supports.
This method returns:
OK(code 0) and the currentDisplayConfigurationsupon success.FAILED_PRECONDITION(code 9): If the AVD does not support the multi-display feature.
Sourcepub async fn stream_notification(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<Streaming<Notification>>, Status>
pub async fn stream_notification( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<Streaming<Notification>>, Status>
Notifies the client of various emulator state changes in real-time. This is a server-side streaming RPC.
Upon subscription, the current states of virtual scene camera, foldable posture, boot completion,
and XR options are immediately sent. The stream then continuously delivers new notifications
when relevant events occur. UniqueEventStreamWriter ensures that only distinct state changes are streamed.
Notifications include:
CameraNotification: Reports virtual scene camera activation/deactivation and associated display.DisplayConfigurationsChangedNotification: Triggered when display configurations are modified via the extended UI. Does not fire for changes made through console or gRPC.Posture: Reports changes in the device’s foldable posture.BootCompletedNotification: Indicates when the emulator has finished booting.BrightnessValue: Reports changes in backlight brightness (LCD, keyboard, or button).TextViewFocus: Sent when a text view gains or loses focus, or immediately on subscription.XrOptions: Reports changes in XR-related settings (environment, passthrough coefficient), or immediately on subscription.MicrophoneState: Reports changes in the microphone state (currently whether host microphone access is allowed)LedIndicator: Reports changes in AI Glasses XR LED light state on subscription.
This method returns a server-side streaming reactor.
Sourcepub async fn rotate_virtual_scene_camera(
&mut self,
request: impl IntoRequest<RotationRadian>,
) -> Result<Response<()>, Status>
pub async fn rotate_virtual_scene_camera( &mut self, request: impl IntoRequest<RotationRadian>, ) -> Result<Response<()>, Status>
Rotates the virtual scene camera relative to its current orientation. This operation is asynchronous and executed on the main looper.
The RotationRadian message specifies angles in radians around the x, y, and z axes. The z component of rotation is currently unused.
The coordinate system is right-handed: x-axis points right, y-axis points up, and z-axis points towards the viewer.
This operation only succeeds if the virtual scene camera is actively connected.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn set_virtual_scene_camera_velocity(
&mut self,
request: impl IntoRequest<Velocity>,
) -> Result<Response<()>, Status>
pub async fn set_virtual_scene_camera_velocity( &mut self, request: impl IntoRequest<Velocity>, ) -> Result<Response<()>, Status>
Sets the absolute velocity of the virtual scene camera. This operation is asynchronous and executed on the main looper.
The Velocity message specifies components in meters per second along the x, y, and z axes.
The coordinate system is right-handed: x-axis points right, y-axis points up, and z-axis points towards the viewer.
The transition to these target velocity values may be smoothed over time by the implementation.
This operation only succeeds if the virtual scene camera is actively connected.
This method returns OK (code 0) upon successful asynchronous scheduling of the operation.
Sourcepub async fn set_posture(
&mut self,
request: impl IntoRequest<Posture>,
) -> Result<Response<()>, Status>
pub async fn set_posture( &mut self, request: impl IntoRequest<Posture>, ) -> Result<Response<()>, Status>
Sets the foldable posture of the device. This operation is asynchronous and executed on the main looper.
The Posture message contains a PostureValue enum, defining the desired
physical configuration of the foldable device.
Returns the following gRPC error codes:
OK(code 0): Upon successful asynchronous scheduling of the operation.FAILED_PRECONDITION(code 9): If the emulator is unable to set the specified posture.
Sourcepub async fn get_brightness(
&mut self,
request: impl IntoRequest<BrightnessValue>,
) -> Result<Response<BrightnessValue>, Status>
pub async fn get_brightness( &mut self, request: impl IntoRequest<BrightnessValue>, ) -> Result<Response<BrightnessValue>, Status>
Retrieves the current backlight brightness for a specified light type. This is a synchronous operation.
The BrightnessValue.target field (e.g., LCD, KEYBOARD, BUTTON) determines which light’s brightness is queried.
Internal mapping converts these to string names like “lcd_backlight”.
Returns the following gRPC error codes:
OK(code 0): Upon successful retrieval, populating theBrightnessValuereply with thetargetand currentvalue.FAILED_PRECONDITION(code 9): If the AVD does not support thehw-controlagent or itsgetBrightnessfunction is unavailable.
Sourcepub async fn set_brightness(
&mut self,
request: impl IntoRequest<BrightnessValue>,
) -> Result<Response<()>, Status>
pub async fn set_brightness( &mut self, request: impl IntoRequest<BrightnessValue>, ) -> Result<Response<()>, Status>
Sets the backlight brightness for a specified light type. This operation is asynchronous and executed on the main looper.
The BrightnessValue.target field (e.g., LCD, KEYBOARD, BUTTON) determines which light’s brightness is set.
The BrightnessValue.value specifies the desired intensity, ranging from 0 to 255.
Internal mapping converts LightType to string names like “lcd_backlight”.
Returns the following gRPC error codes:
OK(code 0): Upon successful asynchronous scheduling of the operation.FAILED_PRECONDITION(code 9): If the AVD does not support thehw-controlagent or itssetBrightnessfunction is unavailable.INVALID_ARGUMENT(code 3): If thebrightnessvalue exceeds the valid range (0-255).
Sourcepub async fn get_display_mode(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<DisplayMode>, Status>
pub async fn get_display_mode( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<DisplayMode>, Status>
Returns the current mode of the primary display of a resizable AVD. This is a synchronous operation.
Preconditions:
- The AVD must be configured to support resizable displays (
resizableEnabled()must be true).
The DisplayMode.value field will be populated with the current DisplayModeValue,
derived from the getResizableActiveConfigId().
Returns the following gRPC error codes:
OK(code 0): Upon successful retrieval of the display mode.FAILED_PRECONDITION(code 9): If the AVD is not resizable.
Sourcepub async fn set_display_mode(
&mut self,
request: impl IntoRequest<DisplayMode>,
) -> Result<Response<()>, Status>
pub async fn set_display_mode( &mut self, request: impl IntoRequest<DisplayMode>, ) -> Result<Response<()>, Status>
Sets the size of the primary display of a resizable AVD to the specified DisplayModeValue. This operation is asynchronous
and executed on the main looper.
Preconditions:
- The AVD must be configured to support resizable displays (
resizableEnabled()must be true). - The emulator’s
changeResizableDisplayagent function must be available.
The DisplayMode.value field specifies the desired display configuration (e.g., PHONE, FOLDABLE, TABLET, DESKTOP).
Returns the following gRPC error codes:
OK(code 0): Upon successful asynchronous scheduling of the operation.FAILED_PRECONDITION(code 9): If the AVD is not resizable.INTERNAL(code 13): If the internal window agent functionchangeResizableDisplayis not available.
Sourcepub async fn set_xr_options(
&mut self,
request: impl IntoRequest<XrOptions>,
) -> Result<Response<()>, Status>
pub async fn set_xr_options( &mut self, request: impl IntoRequest<XrOptions>, ) -> Result<Response<()>, Status>
Changes the XR-related settings of the emulator. This operation is asynchronous and executed on the main looper.
The XrOptions message specifies the environment (e.g., LIVING_ROOM_DAY, LIVING_ROOM_NIGHT)
and passthrough_coefficient (a float between 0.0 and 1.0 for real/artificial environment visibility).
Values for passthrough_coefficient outside [0.0, 1.0] are ignored.
Returns the following gRPC error codes:
OK(code 0): Upon successful asynchronous scheduling of the operation.FAILED_PRECONDITION(code 9): If thesetXrOptionsagent function fails (e.g., if XR is not supported).
Sourcepub async fn get_xr_options(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<XrOptions>, Status>
pub async fn get_xr_options( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<XrOptions>, Status>
Retrieves the current state of XR-related settings from the emulator. This is a synchronous operation.
Preconditions:
- XR mode must be supported in the current AVD (
isXrGuestOs()must be true). (Note: Current implementation ofisXrGuestOs()always returns true).
The XrOptions reply contains the current environment and passthrough_coefficient.
Returns the following gRPC error codes:
OK(code 0): Upon successful retrieval of the XR options.FAILED_PRECONDITION(code 9): If XR mode is not supported in the current AVD or if thegetXrOptionsagent function fails.
Sourcepub async fn set_environment(
&mut self,
request: impl IntoRequest<Environment>,
) -> Result<Response<()>, Status>
pub async fn set_environment( &mut self, request: impl IntoRequest<Environment>, ) -> Result<Response<()>, Status>
Sets the environment background for AI glasses.
Sourcepub async fn get_environment(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<Environment>, Status>
pub async fn get_environment( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<Environment>, Status>
Gets the current environment configuration for AI glasses. Values that are not set in environment.ini will be set to default values.
Sourcepub async fn get_host_cameras(
&mut self,
request: impl IntoRequest<()>,
) -> Result<Response<CameraList>, Status>
pub async fn get_host_cameras( &mut self, request: impl IntoRequest<()>, ) -> Result<Response<CameraList>, Status>
Returns the list of video cameras connected to the host machine.
Trait Implementations§
Source§impl<T: Clone> Clone for EmulatorControllerClient<T>
impl<T: Clone> Clone for EmulatorControllerClient<T>
Auto Trait Implementations§
impl<T> !Freeze for EmulatorControllerClient<T>
impl<T> RefUnwindSafe for EmulatorControllerClient<T>where
Grpc<T>: RefUnwindSafe,
impl<T> Send for EmulatorControllerClient<T>
impl<T> Sync for EmulatorControllerClient<T>
impl<T> Unpin for EmulatorControllerClient<T>
impl<T> UnsafeUnpin for EmulatorControllerClient<T>where
Grpc<T>: UnsafeUnpin,
impl<T> UnwindSafe for EmulatorControllerClient<T>where
Grpc<T>: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request