Thanks to Erwin Jansen for these samples and this readme. (I just formatted this and threw it in a gist to make it more shareable and readable)
Samples can be downloaded here: https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-grpc/docs/grpc-samples
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
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:
- Create the grpc bindings using protoc
- Place the generated bindings in the right location.
- Configure the EmulatorService, (i.e. set port, authentication etc.)
- Make calls to the emulator.
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.
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
First you need to install ProtocolBuffers 3.0.0-beta-3 or later. The installation depends on your OS.
Your best bet is to use homebrew and use the following
$ brew install protobuf
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
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 https://android.googlesource.com/platform/external/qemu/+/refs/heads/emu-master-dev/android/android-grpc/android/emulation/control/api_config.yaml
-
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.
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 viewEmulatorPngView
-> 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 usegRPC-web to make it all possible.
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.
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
In the python directory you will find an example that aks the emulator about the vm configuration after which it will send a series of key events with a 2ms delay.
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 run the sample as follows:
$ make deps && make run
Hi,
Seems that the above aosp link are not existed, could you please update it?