tree: 43e4e9b489b2608db94a70c518542745cddbb666 [path history] [tgz]
  1. go/
  2. js/
  3. python/
  4. README.MD
android/android-grpc/docs/grpc-samples/README.MD

Emulator over gRPC Examples

Caveats: Experimental feature!!

This is currently an experimental feature, and as such there are some things lacking that might be important if you want to use this in production:

  • There is no authentication/authorization. The gRPC server does not do any authentication nor authorization. Anyone who has access to the gRPC control port can control your emulator
  • No TLS support. Currently the gRPC service inside the emulato has not turned on TLS.
  • Not all emulator control functions have been enabled. This likely means that the .proto file describing the interface will evolve.

In other words, make sure you keep this port private on your network and be ready to recompile your code when changes happen.

DO NOT RUN THIS AS IS IN A PRODUCTION ENVIRONMENT

Introduction

This document describes how you can control the emulator over the gRPC interface. To learn more about gRPC you can visit the website.

We describe several sample cases.

  • One where we will use the GO language to create a webserver that allows you to control the emulator over http.

  • An example demonstrates how you can use Javascript & React to control the emulator.

  • An example that uses the python bindings.

Note that this is still under active development, so more functionality might be added in the future.

In general all the approaches work in a similar fashion:

  1. Create the grpc bindings using protoc
  2. Place the generated bindings in the right location.
  3. Configure the EmulatorService, (i.e. set port, authentication etc.)
  4. Make calls to the emulator.

Enabling gRPC in the build

You must enable gRPC in the build, either by editing CMakeLists.txt and setting GRPC to TRUE or by building as follows:

   ./android/rebuild --cmake_option GRPC=TRUE

This will compile in the gRPC feature.

Controlling the emulator with http.

In this example we will construct an intermediate server that acts as a webserver. The webserver will enable an API that is forwarded to the emulator.

In order to run this sample you will need to have a working Go environment. You can find a Go distribution and learn more about Go here

Note: The example requires you to have the ports 5556 & 8080 available

Installation

First you need to install ProtocolBuffers 3.0.0-beta-3 or later. The installation depends on your OS.

I'm using homebrew (Mac/Linux)

Your best bet is to use homebrew and use the following

  $ brew install protobuf

I'm using linux

You must make sure you have a recent version of protobuf available:

$ mkdir tmp && cd tmp
$ git clone https://github.com/google/protobuf && cd protobuf
$ ./autogen.sh && ./configure
$ make  check
$ sudo make install

Launch the emulator and webserver

Before we can access the emulator we must launch it with the gRPC server enabled.

  $ emulator @my_avd -grpc 5556 [..other options...]

Once the emulator is launched you can build and launch the web service as follows:

  $ cd $AOSP/external/qemu/android/android-grpc/docs/grpc-samples/go && make deps && make run

Now you should be able to access the emulator over http on port 8080. For example: http://localhost:8080/v1/gps will show you the current gps settings.

The following example will send a keycode to the emulator:

curl -H "Accept: application/json" -X POST -d '{"key": "30"}' http://localhost:8080/v1/key

For more details on the endpoints look at $AOSP/android/android-grpc/android/emulation/control/api_config.yaml

Troubleshooting/Known Issues:

  • I see TypeError: ...

    Our Makefiles are very simplisitic and are not detecting changes to the .proto files. You might have to run make clean before trying again.

  • I see the following json:

      {"error":"all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp [::1]:5556: connect: connection refused\"","message":"all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp [::1]:5556: connect: connection refused\"","code":14}
    

    You likely restarted the emulator, restart the httpbridge.

  • Why are screenshots slow in debug builds?

    The emulator enables a lot of checks (address sanitizers, code coverage) that take up a lot of resources. You might be better of using a release build.

Controlling the emulator from JavaScript with React

The javascript example showcases how you can interact with the emulator by displaying the current screeenshot, and sending mouse events to the emulator. The sample consists of two react components:

  • Emulator -> Responsible for sending mouse clicks, and hosting a view
  • EmulatorPngView -> Responsible for displaying a view of the emulator. (Very slow)

In the future we hope to replace the EmulatorPngView with something like an EmulatorWebRTCView that has significantly better performance characteristics.

In order to control the emulator from Javascript we will have to route the calls through an intermediate proxy. We will use gRPC-web to make it all possible.

Requirements

In order to run the demo you will need Node, dep and a protoc plugin to generate the javascript classes.

Your best bet is to use homebrew and use the following

  $ brew install dep npm

or else follow the documentation here: https://golang.github.io/dep/docs/installation.html

If you are planning to modify .proto files you willneed to acquire the proper protoc plugin from here. You can either build it yourself, or install the binary.

Launch the emulator and website

In order to launch this demo you will need the following ports available:

  • 5556 Emulator gRPC port
  • 8080 gRPC JavaScript proxy
  • 3000 npm developer port.

Before we can access the emulator we must launch it with the gRPC server enabled.

  $ emulator @my_avd -grpc 5556 [..other options...]

Once the emulator is launched you can build and launch the web application as follows:

  $ cd $AOSP/external/qemu/android/android-grpc/docs/grpc-samples/js  && make deps && make develop

Note: Make deps is only needed once

A browser should open and you should be able to interact with the emulator.

You can stop all the components by running:

  $ cd $AOSP/external/qemu/android/android-grpc/docs/grpc-samples/js  && make stop

Note: this will just kill npm and the proxy

Launch the emulator in a release like environment with envoy and docker.

The recommended proxy for gRPC on the web is Envoy. Envoy is an L7 proxy and communication bus designed for large modern service oriented architectures. It basically can handle a few things for us:

This gets us closer to what is needed to deploy the emulator with gRPC into a production environment. A sample is added that uses docker to configure a simple production like environment with the following characteristics:

  • An nginx container that will serve production build of the javascript example
  • An envoy gRPC proxy
  • A http -> https redirect
  • A TLS endpoint using self signed certificates.

Do not deploy this in a real production environment without adding some authorization filters, as anyone who can make an https connection will be able to control your emulator.

Controlling the emulator with Python

In the python directory you will find two examples:

  • An example that aks the emulator about the vm configuration after which it will send a series of key events with a 2ms delay. After building you can run this with python -m sample.keystrokes

  • An example that uses the streaming interface to retrieve the logcat. After building you can run this with python -m sample.logcat

Before we can access the emulator we must launch it with the gRPC server enabled.

  $ emulator @my_avd -grpc 5556 [..other options...]

Once the emulator is launched you can build the samples as follows:

  $ make deps