Android Emulator Container Scripts

repository·master·Indexed 24 days ago

https://github.com/google/android-emulator-container-scripts

A collection of scripts and tools for running Android Emulators within containers (such as Docker) for cloud or remote use. It supports GPU acceleration, WebRTC-based web streaming, and includes cloud-init configurations for provisioning on AWS, Azure, and Google Cloud (GCE). The repository also provides the android-emulator-webrtc React library for displaying and interacting with remote emulators in a browser, including components for video/audio streaming, hardware key simulation, and mock location updates.

Tokens
13.9K
Snippets
38
Records
85
Agent score
84%

What's inside android-emulator-container-scripts

  1. Provision Android Emulator in the Cloud using cloud-init

    master

    This directory provides cloud-init configurations to automatically provision a cloud VM instance and run the Android Emulator inside a container. The configuration installs a systemd service named aemu.service which pulls a specified Docker image and launches the emulator instances.

    Requirements

    The VM host must run a Linux OS with KVM acceleration available:

    • AWS: Use EC2 Bare Metal instances or instances supporting KVM.
    • Azure: Select VM sizes supporting nested virtualization (e.g., Dv3 or Ev3 family).
    • Google Cloud (GCE): Enable nested virtualization.
    NOTE

    Standard Google Cloud Container-Optimized OS (COS) images do not expose /dev/kvm by default. You must build a custom COS image with KVM enabled to use it.

  2. Handle User Input via WebRTC Data Channels

    master

    To support user interaction (mouse, keyboard, touch, wheels), the WebRTC Peer Connection must establish a data channel labeled "input".

    Message Routing Logic:

    1. The client serializes input events into binary protobuf format using the emulator_controller.InputEvent wrapper.
    2. The client sends these binary bytes over the "input" data channel.
    3. The gateway server must receive these binary messages and forward them directly to the emulator's gRPC streaming method: EmulatorController.streamInputEvent.

    Note: Because the WebRTC data channel format is identical to the gRPC protobuf payload, the gateway can forward the raw binary bytes directly to the emulator without decoding them.

  3. Implement WebRTC JSEP Signaling via WebSocket

    master

    The gateway must implement a WebSocket signaling flow to bridge the browser and the emulator. The connection follows this sequence:

    1. Connection: Client connects to ws://<host>/api/v1/emulator/ws-jsep (or wss://).
    2. Start Signal (Server -> Client): Server sends ICE Servers configuration.
    3. SDP Offer (Server -> Client): Server sends the WebRTC SDP Offer.
    4. SDP Answer (Client -> Server): Client responds with the WebRTC SDP Answer.
    5. Trickle ICE (Bidirectional): Server and Client exchange ICE candidates.
    6. Teardown: Either side sends a bye message before closing.
  4. End-to-End Architecture for Emulator WebRTC Streaming

    master

    The WebRTC streaming architecture consists of three main components that facilitate real-time interaction with an Android Emulator:

    1. React Web Frontend: A client application (running on localhost:5173) that communicates with the Gateway via HTTP REST and WebSocket signaling.
    2. Python Gateway Server: A bridge (running on localhost:8080) that translates HTTP REST and WebSocket JSEP signaling into the emulator's native rtc2 gRPC protocol.
    3. Android Emulator: The target device that receives gRPC commands and streams WebRTC Data & Media via UDP/SRTP back to the client.

    Data Flow:

    • Signaling: Frontend $\rightarrow$ (HTTP/WS) $\rightarrow$ Gateway $\rightarrow$ (gRPC) $\rightarrow$ Emulator.
    • Media/Data: Frontend $\leftarrow$ (WebRTC UDP/SRTP) $\leftarrow$ Emulator.
  5. Signaling API (WebSocket) Flow and Formats

    master

    WebRTC JSEP signaling is performed over a WebSocket connection at ws://<host>/api/v1/emulator/ws-jsep (or wss://). The signaling flow follows these steps:

    1. Connection: Client connects to the WebSocket.
    2. Start Signal (Server -> Client): Server sends ICE Servers configuration.
    3. SDP Offer (Server -> Client): Server sends the WebRTC SDP Offer.
    4. SDP Answer (Client -> Server): Client responds with the WebRTC SDP Answer.
    5. Trickle ICE (Bidirectional): Server and Client exchange ICE candidates.
    6. Teardown: Either side sends a bye message before closing.

    All messages are JSON objects with a single root key indicating the message type.

  6. Run with NVIDIA GPU Acceleration

    master

    To use NVIDIA GPU acceleration, you must have the NVIDIA Container Toolkit installed. If running headless, ensure an X server like Xvfb is running.

    1. Build with GPU support: emu-docker create stable U --gpu (where U is the API level).
    2. Launch: Use the ./run-with-gpu.sh helper script.
    # Build
    emu-docker create stable U --gpu
    
    # Launch
    ./run-with-gpu.sh <docker-image-id> <additional-emulator-params>
  7. Run Docker images with performance optimizations

    master

    You can run images using the provided ./run.sh helper or via direct docker run commands.

    To improve disk performance, mount the /data partition in tmpfs using the --mount flag.

    # Using helper script
    ./run.sh <docker-image-id> <additional-emulator-params>
    
    # Direct run with tmpfs for /data performance
    docker run -e ADBKEY="$(cat ~/.android/adbkey)" \
      --device /dev/kvm \
      --mount type=tmpfs,destination=/data \
      --publish 8554:8554/tcp \
      --publish 5555:5555/tcp <docker-image-id>
  8. Requirements for running Android Emulator containers

    master

    To run the Android Emulator Docker images, you must meet the following requirements:

    • OS: Linux only. Windows and MacOS are not supported.
    • KVM Access: KVM (Kernel-based Virtual Machine) must be available. This can be achieved via:
      • Bare Metal: Running on physical hardware.
      • Nested Virtualization: Running on a virtual machine that supports nested virtualization (e.g., AWS bare metal instances, specific Azure VM sizes, or GCE instances with nested virtualization enabled).

    Note: Using nested virtualization may result in reduced performance.

  9. Set up WebRTC Web Streaming

    master

    The project provides a WebRTC architecture to view and control the emulator in a browser. The stack consists of a Python Gateway Server (translating HTTP/WS to gRPC) and a React WebRTC App (rendering the stream).

    Quick Start Demo

    1. Locate Discovery File: Find your active emulator discovery .ini file (e.g., ~/.android/avd/running/pid_<PID>.ini on Linux).
    2. Launch Gateway:
      cd gateway
      ./launch_video_demo.sh --discovery_file /path/to/pid_<PID>.ini
    3. Launch React App:
      cd js/example
      npm install
      npm run dev
    4. Access: Open http://localhost:5173 and connect to localhost:8080.
    # 1. Launch Gateway
    cd gateway
    ./launch_video_demo.sh --discovery_file /path/to/pid_<PID>.ini
    
    # 2. Launch React App
    cd js/example
    npm install
    npm run dev