The default WebRTC browser interface for Cuttlefish includes a control panel that enables more ways to interact with the virtual device.
The control panel features default buttons to simulate common physical device actions such as power button or volume buttons, as well as device rotation.
Custom actions
You can customize the control panel to add more buttons that allow your virtual device to more closely emulate your physical device. This is useful for testing features unique to your device, such as a hardware button or special gesture that triggers a unique action in the OS. You can also use custom buttons to enable testing more QA-focused features such as the behavior of your OS when the device is low battery.
The default Cuttlefish control panel includes support to "plug in" custom actions without needing to modify the main Cuttlefish AOSP project. Your virtual device needs to include only a minimal configuration file to start using custom actions. See this example custom action config file.
Create a JSON file that defines your device's custom actions. You can put this file in any directory you own. The structure of this file is described in the ADB shell and Action server sections.
Create a
prebuilt_etc_host
module for your JSON config. Ensure that thesub_dir
is equal tocvd_custom_action_config
.prebuilt_etc_host { // Use any name you choose. name: "my_custom_action_config.json", src: "my_custom_action_config.json", // Always use this sub_dir. sub_dir: "cvd_custom_action_config", }
Set Soong config build variables in your device's product makefile to configure the virtual device host package to include your custom action config file.
# Set these variables exactly as shown here to enable the host package to see # your custom config module name. SOONG_CONFIG_NAMESPACES += cvd SOONG_CONFIG_cvd += custom_action_config # Set this value to the name of your JSON module. SOONG_CONFIG_cvd_custom_action_config := my_custom_action_config.json
There are two supported methods to implement a custom action:
- ADB shell command
- Action server
Your JSON config file can define multiple instances of each type of implementation.
ADB shell command
You can define a single button that is implemented by executing a single adb
shell
command. For example, the following JSON snippet defines a single button
that launches a web page:
{
"shell_command":"am start -a android.intent.action.VIEW -d https://www.android.com/",
"button":{
"command":"web",
"title":"Web Page",
"icon_name":"language"
}
}
The fields are:
shell_command
: The command to execute inadb shell
when the button is pressedbutton
: A single button object with the following subfields:command
: A unique name for this buttontitle
: An alt-text title for this buttonicon_name
: The name of an icon from https://material.io/resources/icons
Action server
Action servers allow more control over the behavior of your actions. An action server is a host binary that listens for button press events from WebRTC using a socket pair. WebRTC forwards the events to the action server, and then the action server decides how to implement the action.
Action servers allow more powerful control, such as maintaining state (such as for a toggleable event) or even running "meta-actions" such as killing the current device, launching more devices, or starting a screen-recording browser extension. The possibilities are limited only by what you decide to implement inside the host binary.
The following JSON snippet defines an action server that listens for events on two buttons:
{
"server":"cuttlefish_example_action_server",
"buttons":[
{
"command":"settings",
"title":"Quick Settings",
"icon_name":"settings"
},
{
"command":"alert",
"title":"Do Not Disturb",
"icon_name":"notifications_paused"
}
]
}
The fields are:
server
: The name of your host binary modulebuttons
: An array of buttons, with the same subfields as above
After updating the JSON config, append the name of the action server module to
the Soong config build variable cvd_custom_action_servers
. For example:
# Append to this variable exactly as shown here.
SOONG_CONFIG_cvd += custom_action_servers
# Append the name of your action server(s) to this variable.
SOONG_CONFIG_cvd_custom_action_servers += cuttlefish_example_action_server
Each action server host binary should perform the following steps:
Accept a socket file descriptor number as the first and only program argument.
This socket is created by
launch_cvd
usingsocketpair
with domainAF_LOCAL
, typeSOCK_STREAM
, and protocol 0.In a loop, attempt to read 128 bytes from the socket. These bytes contain button press events sent by the WebRTC client in the format
command:state
.command
is as provided in the JSON config, andstate
is the button press state (down
orup
).Act on the incoming events to simulate the custom action.