1# VirtualDeviceManager Demo Apps 2 3#### Page contents 4 5[Overview](#overview) \ 6[Prerequisites](#prerequisites) \ 7[Build & Install](#build-and-install) \ 8[Run](#run) \ 9[Host Options](#host-options) \ 10[Client Options](#client-options) \ 11[Demos](#demos) 12 13## Overview 14 15The VDM Demo Apps allow for showcasing VDM features, rapid prototyping and 16testing of new features. 17 18The VDM Demo contains 3 apps: 19 20* **Host**: installed on the host device, creates and manages a virtual 21 device, which represents the client device and communicates with the 22 physical client device by sending audio and frames of the virtual displays, 23 receiving input and sensor data that is injected into the framework. It can 24 launch apps on the virtual device, which are streamed to the client. 25 26* **Client**: installed on the client device. It receives the audio and frames 27 from the host device, which it renders, and sends back input and sensor 28 data. For best experience with app streaming on multiple displays at the 29 same time, it's best to use a large screen device as a client, like a Pixel 30 Tablet. 31 32* **Demos**: installed on the host, meant to showcase specific VDM features. 33 The demos can be also run natively on the host to illustrate better the 34 difference in the behavior when they are streamed to a virtual device. 35 36## Prerequisites 37 38* An Android device running Android 13 or newer to act as a client device. 39 40* A *rooted* Android device running Android 14 or newer (e.g. a `userdebug` or 41 `eng` build) to act as a host device. Even though VDM is available starting 42 Android 13, the support there is minimal and the Host app is not compatible 43 with Android 13. 44 45* Both devices need to support 46 [Wi-Fi Aware](https://developer.android.com/develop/connectivity/wifi/wifi-aware) 47 48Note: This example app uses an Android device as a client, but there's no such 49general requirement. The client device, its capabilities, the connectivity layer 50and the communication protocol are entirely up to the virtual device owner. 51 52## Build and Install 53 54### Using the script 55 56Simply connect your devices, navigate to the root of your Android checkout and 57run 58 59``` 60./development/samples/VirtualDeviceManager/setup.sh 61``` 62 63The interactive script will prompt you which apps to install to which of the 64available devices, build the APKs and install them. 65 66### Using adevice on the host device 67 681. Track the required modules. 69 70 ```shell 71 adevice track VdmHost 72 adevice track VdmDemos 73 ``` 74 751. Update the device 76 77 ```shell 78 adevice update 79 ``` 80 81### Manually 82 831. Source `build/envsetup.sh` and run `lunch` or set 84 `UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true` if there's no local build because 85 the APKs need to be built against a locally built SDK. 86 871. Build the Host app. 88 89 ```shell 90 m -j VdmHost 91 ``` 92 931. Install the application as a system app on the host device. 94 95 ```shell 96 adb root && adb disable-verity && adb reboot # one time 97 adb root && adb remount 98 adb push $ANDROID_BUILD_TOP/development/samples/VirtualDeviceManager/host/com.example.android.vdmdemo.host.xml /system/etc/permissions/com.example.android.vdmdemo.host.xml 99 adb shell mkdir /system/priv-app/VdmDemoHost 100 adb push $OUT/system/priv-app/VdmHost/VdmHost.apk /system/priv-app/VdmDemoHost/ 101 adb reboot 102 ``` 103 104 **Tip:** Subsequent installs without changes to permissions, etc. do not 105 need all the commands above - you can just run \ 106 \ 107 `adb install -r -d -g $OUT/system/priv-app/VdmHost/VdmHost.apk` 108 1091. Build and install the Demo app on the host device. 110 111 ```shell 112 m -j VdmDemos && adb install -r -d -g $OUT/system/app/VdmDemos/VdmDemos.apk 113 ``` 114 1151. Build and install the Client app on the client device. 116 117 ```shell 118 m -j VdmClient && adb install -r -d -g $OUT/system/app/VdmClient/VdmClient.apk 119 ``` 120 121## Run 122 1231. Start both the Client and the Host apps on each respective device. 124 1251. They should find each other and connect automatically. On the first launch 126 the Host app will ask to create a CDM association: allow it. 127 128 WARNING: If there are other devices in the vicinity with one of these apps 129 running, they might interfere. 130 1311. Check out the different [Host Options](#host-options) and 132 [Client Options](#client-options) that allow for changing the behavior of 133 the streamed apps and the virtual device in general. 134 1351. Check out the [Demo apps](#demos) that are specifically meant to showcase 136 the VDM features. 137 138<!-- LINT.IfChange(host_options) --> 139 140## Host Options 141 142NOTE: Any flag changes require device reboot or "Force stop" of the host app 143because the flag values are cached and evaluated only when the host app is 144starting. Alternatively, run: \ 145\ 146`adb shell am force-stop com.example.android.vdmdemo.host` 147 148### Launcher 149 150Once the connection with the client device is established, the Host app will 151show a launcher-like list of installed apps on the host device. 152 153- Clicking an app icon will create a new virtual display, launch the app there 154 and start streaming the display contents to the client. The client will show 155 the surface of that display and render its contents. 156 157- Long pressing on an app icon will open a dialog to select an existing 158 display to launch the app on instead of creating a new one. 159 160- The Host app has a **CREATE HOME DISPLAY** button, clicking it will create a 161 new virtual display, launch the secondary home activity there and start 162 streaming the display contents to the client. The display on the Client app 163 will have a home button, clicking it will navigate the streaming experience 164 back to the home activity. Run the commands below to enable this 165 functionality. 166 167 ```shell 168 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_home true 169 adb shell am force-stop com.example.android.vdmdemo.host 170 ``` 171 172- The Host app has a **CREATE MIRROR DISPLAY** button, clicking it will create 173 a new virtual display, mirror the default host display there and start 174 streaming the display contents to the client. 175 176### Settings 177 178#### Input 179 180The input menu button enables several different mechanisms for injecting input 181from the host device into the focused display on the client device. The focused 182display is indicated by the frame around its header whenever there are more than 183one displays. The display focus is based on user interaction. 184 185Each input screen has a "Back", "Home" and "Forward" buttons. 186 187- **Touchpad** shows an on-screen touchpad for injecting mouse events into the 188 focused display. 189 190- **Remote** allows the host device to act as a pointer that controls the 191 mouse movement on the focused display. 192 193- **Navigation** shows an on-screen D-Pad, rotary and touchpad for navigating 194 the activity on the focused display. 195 196- **Keyboard** shows the host device's on-screen keyboard and sends any key 197 events to the activity on the focused display. 198 199- **Stylus** allows for injecting simulated stylus events into the focused 200 display. Use together with the stylus demo. Run the commands below to enable 201 this functionality. 202 203 ```shell 204 adb shell device_config put virtual_devices android.companion.virtual.flags.virtual_stylus true 205 adb shell am force-stop com.example.android.vdmdemo.host 206 ``` 207 208#### General 209 210- **Device profile**: Enables device streaming CDM role as opposed to app 211 streaming role, with all differences in policies that this entails. \ 212 *Changing this will recreate the virtual device.* 213 214- **Hide streamed app from recents**: Whether streamed apps should show up in 215 the host device's recent apps. Run the commands below to make this 216 functionality dynamic. \ 217 *This can be changed dynamically starting with Android V.* 218 219 ```shell 220 adb shell device_config put virtual_devices android.companion.virtual.flags.dynamic_policy true 221 adb shell am force-stop com.example.android.vdmdemo.host 222 ``` 223 224- **Enable cross-device clipboard**: Whether to share the clipboard between 225 the host and the virtual device. If disabled, both devices will have their 226 own isolated clipboards. Run the commands below to enable this 227 functionality. \ 228 *This can be changed dynamically.* 229 230 ```shell 231 adb shell device_config put virtual_devices android.companion.virtual.flags.dynamic_policy true 232 adb shell device_config put virtual_devices android.companion.virtual.flags.cross_device_clipboard true 233 adb shell am force-stop com.example.android.vdmdemo.host 234 ``` 235 236- **Enable custom activity policy**: Whether to use custom user notification 237 for activities that are unable to launch on the virtual display and send 238 such activities to the default display, whenever possible. Use together with 239 the activity policy demo. The behavior of the display fallback launch is 240 different depending on whether an activity result is expected by the caller, 241 and on whether the default display keyguard is currently locked. \ 242 *This can be changed dynamically.* 243 244 ```shell 245 adb shell device_config put virtual_devices android.companion.virtual.flags.dynamic_policy true 246 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.activity_control_api true 247 adb shell am force-stop com.example.android.vdmdemo.host 248 ``` 249 250#### Client capabilities 251 252- **Enable client Sensors**: Enables sensor injection from the client device 253 into the host device. Any context that is associated with the virtual device 254 will access the virtual sensors by default. \ 255 *Changing this will recreate the virtual device.* 256 257- **Enable client Camera**: Enables front & back camera injection from the 258 client device into the host device. (WIP: Any context that is associated 259 with the virtual device will the virtual cameras by default). Run the 260 commands below on host device to enable this functionality. \ 261 *Changing this will recreate the virtual device.* 262 263 ```shell 264 adb shell device_config put virtual_devices android.companion.virtual.flags.virtual_camera true 265 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.virtual_camera_service_discovery true 266 adb shell am force-stop com.example.android.vdmdemo.host 267 ``` 268 269- **Enable client Audio**: Enables audio output on the client device. Any 270 context that is associated with the virtual device will play audio on the 271 client by default. \ 272 *This can be changed dynamically.* 273 274#### Displays 275 276- **Display rotation**: Whether orientation change requests from streamed apps 277 should trigger orientation change of the relevant display. The client will 278 automatically rotate the relevant display upon such request. Disabling this 279 simulates a fixed orientation display that cannot physically rotate. Then 280 any streamed apps on that display will be letterboxed/pillarboxed if they 281 request orientation change. \ 282 *This can be changed dynamically but only applies to newly created 283 displays.* 284 285- **Display category**: Whether to specify a custom display category for the 286 virtual displays. This means that only activities that have explicitly set 287 a matching `android:requiredDisplayCategory` activity attribute can be 288 launched on that display. \ 289 *Changing this will recreate the virtual device.* 290 291- **Always unlocked**: Whether the virtual displays should remain unlocked and 292 interactive when the host device is locked. Disabling this will result in a 293 simple lock screen shown on these displays when the host device is locked. \ 294 *Changing this will recreate the virtual device.* 295 296- **Show pointer icon**: Whether pointer icon should be shown for virtual 297 input pointer devices. \ 298 *This can be changed dynamically.* 299 300- **Custom home**: Whether to use a custom activity as home on home displays, 301 or use the device-default secondary home activity. Run the commands below to 302 enable this functionality. \ 303 *Changing this will recreate the virtual device.* 304 305 ```shell 306 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_home true 307 adb shell am force-stop com.example.android.vdmdemo.host 308 ``` 309 310- **Custom status bar**: Whether to add a custom status bar view on the 311 non-mirror virtual displays. Run the commands below to enable this 312 functionality. \ 313 *This can be changed dynamically but only applies to newly created 314 displays.* 315 316 ```shell 317 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.status_bar_and_insets true 318 adb shell am force-stop com.example.android.vdmdemo.host 319 ``` 320 321- **Display timeout**: Whether to keep the displays always awake or to put 322 them to sleep after a timeout. Run the commands below to enable this 323 functionality. \ 324 *Changing this will recreate the virtual device.* 325 326 ```shell 327 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.device_aware_display_power true 328 adb shell am force-stop com.example.android.vdmdemo.host 329 ``` 330 331- **Enable client brightness**: Whether to propagate any brightness changes 332 from the virtual display to the client's display. Run the commands below to 333 enable this functionality. \ 334 *This can be changed dynamically but only applies to newly created 335 displays.* 336 337 ```shell 338 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.device_aware_display_power true 339 adb shell am force-stop com.example.android.vdmdemo.host 340 ``` 341 342#### Audio 343 344- **Use AudioPolicy.updateMixingRules**: Updates the dynamic AudiPolicy mixing rules 345 instead of unregistering and re-registering the AudioPolicy. 346 347#### Input method 348 349Note: The virtual keyboard acts like a physically connected keyboard to the host 350device. If you want the software keyboard to be shown on the virtual displays, 351you likely need to enable this in the host Settings. On a Pixel device: System 352-> Language and input -> Physical keyboard. 353 354- **Display IME policy**: Choose the IME behavior on remote displays. Run the 355 commands below to enable this functionality. \ 356 *This can be changed dynamically.* 357 358 ```shell 359 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_ime true 360 adb shell am force-stop com.example.android.vdmdemo.host 361 ``` 362 363- **Use the native client IME**: Enables the native client IME instead of 364 streaming the host's IME on the virtual displays. Requires the *Display IME 365 Policy* to be set to *Show IME on the remote display*. Run the commands 366 below to enable this functionality. \ 367 *Changing this will recreate the virtual device.* 368 369 ```shell 370 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_ime true 371 adb shell am force-stop com.example.android.vdmdemo.host 372 ``` 373 374#### Debug 375 376- **Record encoder output**: Enables recording the output of the encoder on 377 the host device to a local file on the device. This can be helpful with 378 debugging Encoding related issues. To download and play the file locally: 379 380 ```shell 381 adb pull /sdcard/Download/vdmdemo_encoder_output_<displayId>.h264 382 ffplay -f h264 vdmdemo_encoder_output_<displayId>.h264 383 ``` 384 385<!-- LINT.ThenChange(README.md) --> 386<!-- LINT.IfChange(client_options) --> 387 388## Client Options 389 390### Streamed displays 391 392- Each display on the Client app has a "Back" and "Close" buttons. When a 393 display becomes empty, it's automatically removed. 394 395- Each display on the Client app has a "Rotate" button to switch between 396 portrait and landscape orientation. This simulates the physical rotation of 397 the display of the streamed activity. The "Resize" button can be used to 398 change the display dimensions. 399 400- Each display on the Client app has a "Fullscreen" button which will move the 401 contents of that display to an immersive fullscreen activity. The client's 402 back button/gestures are sent back to the streamed app. Use Volume Down on 403 the client device to exit fullscreen. Volume Up acts as a home key, if the 404 streamed display is a home display. 405 406### Input 407 408The input menu button enables **on-screen D-Pad, rotary and touchpad** for 409navigating the activity on the focused display. The focused display is indicated 410by the frame around its header whenever there are more than one displays. The 411display focus is based on user interaction. 412 413In addition, any input events generated from an **externally connected 414keyboard** are forwarded to the activity streamed on the focused display. 415 416**Externally connected mouse** events are also forwarded to the relevant 417display, if the mouse pointer is currently positioned on a streamed display. 418 419### Power 420 421The power menu button acts as a "virtual power button". It will toggle the state 422of the virtual device and all its displays between ON and OFF. 423Run the commands below on the host device to enable this functionality. 424 425```shell 426adb shell device_config put virtual_devices android.companion.virtual.flags.device_aware_display_power true 427adb shell am force-stop com.example.android.vdmdemo.host 428``` 429 430<!-- LINT.ThenChange(README.md) --> 431<!-- LINT.IfChange(demos) --> 432 433## Demos 434 435- **Activity policy**: An activity showcasing blocking of activity launches on 436 the virtual device - either because the activity has opted out via 437 `android:canDisplayOnRemoteDevices` attribute, or because of the custom 438 activity policy of that device. 439 440- **Sensors**: A simple activity balancing a beam on the screen based on the 441 accelerometer events, which allows for selecting which device's sensor to 442 use. By default, will use the sensors of the device it's shown on. 443 444- **Display Power**: A simple activity showcasing the behavior of proximity 445 locks, screen brightness override and requesting the screen to be kept on 446 or turned on. 447 448- **Rotation**: A simple activity that is in landscape by default and can send 449 orientation change requests on demand. Showcases the display rotation on the 450 client, which will rotate the user-visible surface. 451 452- **Home**: A simple activity with utilities around launching HOME and 453 SECONDARY_HOME Intents, as well as other implicit intents. 454 455- **Secure Window**: A simple activity that declares the Window as secure. 456 This showcases the FLAG_SECURE streaming policies in VDM. 457 458- **Permissions**: A simple activity with buttons to request and revoke 459 runtime permissions. This can help test the permission streaming and 460 device-aware permission features. 461 462- **Latency**: Renders a simple counter view that renders a new frame with an 463 incremented counter every second. Can be useful for debugging latency, 464 encoder, decoder issues in the demo application. 465 466- **Vibration**: A simple activity making vibration requests via different 467 APIs and allows for selecting which device's vibrator to use. By default, 468 will use the vibrator of the device it's shown on. Note that currently there 469 is no vibration support on virtual devices, so vibration requests from 470 streamed activities are ignored. 471 472- **Stylus**: A simple drawing activity that reacts on stylus input events. 473 Use together with the simulated stylus input feature of the host app. 474 475- **Recorder**: A simple activity that can start multiple audio recorders. 476 This helps test audio recording permissions and concurrent recordings. 477 478The demo activity depends on whether the **Display Category** Host preference is 479enabled or not. If enabled, it becomes equivalent to the **Home** demo activity, 480which showcases implicit intent handling. 481 482<!-- LINT.ThenChange(README.md) --> 483 484## SDK Version 485 486### Android 16 / Baklava 487 488- Added support for custom power management. 489 490- Added support for custom system windows (like status bar) and insets. 491 492- Added support for per-display activity policies. 493 494- Added support for custom redirection of blocked activities. 495 496- Added support for hiding the blocked activity dialog. 497 498- Added support for virtual display cutout. 499 500- Added support for virtual display rotation. 501 502- Added support for virtual rotary input. 503 504### Android 15 / Vanilla Ice Cream / SDK level 35 505 506- Added support for virtual camera. 507 508- Added support for virtual stylus input. 509 510- Added support for cross-device clipboard. 511 512- Added support for custom home activities. 513 514- Added support for custom IME component. 515 516- Added support for per-display IME policy. 517 518- Added support for fixed orientation displays (disable display rotation). 519 520- Added support for mirroring the default display on the virtual device. 521 522- Added support for dynamic policy changes, so the device does not need to be 523 recreated. 524 525- Improved support for displays that support home activities. Removed 526 navigation bar and added support for normal home intents. 527 528- Improved handling of vibrating requests originating from virtual devices. 529 530- Improved multi-display mouse support. 531 532- Fixed bugs with hiding streamed apps from the host's recent apps. 533 534### Android 14 / Upside Down Cake / SDK level 34 535 536- Added support for display categories and restricted activities. 537 538- Added support for virtual sensors. 539 540- Added device awareness to contexts. 541 542- Added support for clipboard on the virtual device. 543 544- Added support for hiding streamed apps from the host's recent apps. 545 546- Added `COMPANION_DEVICE_NEARBY_DEVICE_STREAMING` device profile. 547 548- Added support for virtual navigation input: D-Pad and navigation touchpad. 549 550- Added support for display categories and restricted activities. 551 552- Improved support for audio, allowing routing to be based on the origin 553 context. 554 555- Improved support for creation of virtual displays and input devices. 556 557- Improved handling of virtual touch events. 558 559### Android 13 / Tiramisu / SDK level 33 560 561- Added support for virtual audio device. 562 563- Added support for hiding the mouse pointer icon. 564 565- Added support for virtual mouse, keyboard, touchscreen. 566 567- Added support for always unlocked displays. 568 569- Added `COMPANION_DEVICE_APP_STREAMING` device profile. 570 571- Added support for virtual device creation. 572