• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
142### Launcher
143
144Once the connection with the client device is established, the Host app will
145show a launcher-like list of installed apps on the host device.
146
147-   Clicking an app icon will create a new virtual display, launch the app there
148    and start streaming the display contents to the client. The client will show
149    the surface of that display and render its contents.
150
151-   Long pressing on an app icon will open a dialog to select an existing
152    display to launch the app on instead of creating a new one.
153
154-   The Host app has a **CREATE HOME DISPLAY** button, clicking it will create a
155    new virtual display, launch the secondary home activity there and start
156    streaming the display contents to the client. The display on the Client app
157    will have a home button, clicking it will navigate the streaming experience
158    back to the home activity.
159
160-   The Host app has a **CREATE MIRROR DISPLAY** button, clicking it will create
161    a new virtual display, mirror the default host display there and start
162    streaming the display contents to the client.
163
164### Settings
165
166#### Input
167
168The input menu button enables several different mechanisms for injecting input
169from the host device into the focused display on the client device. The focused
170display is indicated by the frame around its header whenever there are more than
171one displays. The display focus is based on user interaction.
172
173Each input screen has a "Back", "Home" and "Forward" buttons.
174
175-   **Touchpad** shows an on-screen touchpad for injecting mouse events into the
176    focused display.
177
178-   **Remote** allows the host device to act as a pointer that controls the
179    mouse movement on the focused display.
180
181-   **Navigation** shows an on-screen D-Pad, rotary and touchpad for navigating
182    the activity on the focused display.
183
184-   **Keyboard** shows the host device's on-screen keyboard and sends any key
185    events to the activity on the focused display.
186
187-   **Stylus** allows for injecting simulated stylus events into the focused
188    display. Use together with the stylus demo.
189
190#### General
191
192-   **Device profile**: Enables device streaming CDM role as opposed to app
193    streaming role, with all differences in policies that this entails. \
194    *Changing this will recreate the virtual device.*
195
196-   **Hide streamed app from recents**: Whether streamed apps should show up in
197    the host device's recent apps. \
198    *This can be changed dynamically starting with Android V.*
199
200-   **Enable cross-device clipboard**: Whether to share the clipboard between
201    the host and the virtual device. If disabled, both devices will have their
202    own isolated clipboards. \
203    *This can be changed dynamically.*
204
205-   **Enable custom activity policy**: Whether to use custom user notification
206    for activities that are unable to launch on the virtual display and send
207    such activities to the default display, whenever possible. Use together with
208    the activity policy demo. The behavior of the display fallback launch is
209    different depending on whether an activity result is expected by the caller,
210    and on whether the default display keyguard is currently locked. \
211    *This can be changed dynamically.*
212
213    ```shell
214    adb shell aflags enable android.companion.virtual.flags.activity_control_api && adb reboot
215    ```
216
217#### Client capabilities
218
219-   **Enable client Sensors**: Enables sensor injection from the client device
220    into the host device. Any context that is associated with the virtual device
221    will access the virtual sensors by default. \
222    *Changing this will recreate the virtual device.*
223
224-   **Enable client Camera**: Enables front & back camera injection from the
225    client device into the host device. (WIP: Any context that is associated
226    with the virtual device will the virtual cameras by default). \
227    *Changing this will recreate the virtual device.*
228
229-   **Enable client Audio**: Enables audio output on the client device. Any
230    context that is associated with the virtual device will play audio on the
231    client by default. \
232    *This can be changed dynamically.*
233
234#### Displays
235
236-   **Display rotation**: Whether orientation change requests from streamed apps
237    should trigger orientation change of the relevant display. The client will
238    automatically rotate the relevant display upon such request. Disabling this
239    simulates a fixed orientation display that cannot physically rotate. Then
240    any streamed apps on that display will be letterboxed/pillarboxed if they
241    request orientation change. \
242    *This can be changed dynamically but only applies to newly created
243    displays.*
244
245-   **Display category**: Whether to specify a custom display category for the
246    virtual displays. This means that only activities that have explicitly set
247    a matching `android:requiredDisplayCategory` activity attribute can be
248    launched on that display. \
249    *Changing this will recreate the virtual device.*
250
251-   **Always unlocked**: Whether the virtual displays should remain unlocked and
252    interactive when the host device is locked. Disabling this will result in a
253    simple lock screen shown on these displays when the host device is locked. \
254    *Changing this will recreate the virtual device.*
255
256-   **Show pointer icon**: Whether pointer icon should be shown for virtual
257    input pointer devices. \
258    *This can be changed dynamically.*
259
260-   **Custom home**: Whether to use a custom activity as home on home displays,
261    or use the device-default secondary home activity. \
262    *Changing this will recreate the virtual device.*
263
264-   **Custom status bar**: Whether to add a custom status bar view on the
265    non-mirror virtual displays. Run the commands below to enable this
266    functionality. \
267    *This can be changed dynamically but only applies to newly created
268    displays.*
269
270    ```shell
271    adb shell aflags enable android.companion.virtual.flags.status_bar_and_insets && adb reboot
272    ```
273
274-   **Display timeout**: Whether to keep the displays always awake or to put
275    them to sleep after a timeout. Run the commands below to enable this
276    functionality. \
277    *Changing this will recreate the virtual device.*
278
279    ```shell
280    adb shell aflags enable android.companion.virtual.flags.device_aware_display_power && adb reboot
281    ```
282
283-   **Enable client brightness**: Whether to propagate any brightness changes
284    from the virtual display to the client's display. Run the commands below to
285    enable this functionality. \
286    *This can be changed dynamically but only applies to newly created
287    displays.*
288
289    ```shell
290    adb shell aflags enable android.companion.virtual.flags.device_aware_display_power && adb reboot
291    ```
292
293#### Audio
294
295-   **Use AudioPolicy.updateMixingRules**: Updates the dynamic AudiPolicy mixing rules
296    instead of unregistering and re-registering the AudioPolicy.
297
298#### Input method
299
300Note: The virtual keyboard acts like a physically connected keyboard to the host
301device. If you want the software keyboard to be shown on the virtual displays,
302you likely need to enable this in the host Settings. On a Pixel device: System
303-> Language and input -> Physical keyboard.
304
305-   **Display IME policy**: Choose the IME behavior on remote displays. \
306    *This can be changed dynamically.*
307
308-   **Use the native client IME**: Enables the native client IME instead of
309    streaming the host's IME on the virtual displays. Requires the *Display IME
310    Policy* to be set to *Show IME on the remote display*. \
311    *Changing this will recreate the virtual device.*
312
313#### Debug
314
315-   **Single device demo**: Does not require a connection to a client device.
316    The contents of the virtual displays are rendered locally in a separate
317    activity.
318
319- **Record encoder output**: Enables recording the output of the encoder on
320    the host device to a local file on the device. This can be helpful with
321    debugging Encoding related issues. To download and play the file locally:
322
323    ```shell
324    adb pull /sdcard/Download/vdmdemo_encoder_output_<displayId>.h264
325    ffplay -f h264 vdmdemo_encoder_output_<displayId>.h264
326    ```
327
328-   **Network channel**: Select different communication channel between the
329    client and the host to avoid collisions with other demo setups nearby.
330    The selected channel on the host must match the selected channel on the
331    client.
332
333<!-- LINT.ThenChange(README.md) -->
334<!-- LINT.IfChange(client_options) -->
335
336## Client Options
337
338### Streamed displays
339
340-   Each display on the Client app has a "Back" and "Close" buttons. When a
341    display becomes empty, it's automatically removed.
342
343-   Each display on the Client app has a "Rotate" button to switch between
344    portrait and landscape orientation. This simulates the physical rotation of
345    the display of the streamed activity. The "Resize" button can be used to
346    change the display dimensions.
347
348-   Each display on the Client app has a "Fullscreen" button which will move the
349    contents of that display to an immersive fullscreen activity. The client's
350    back button/gestures are sent back to the streamed app. Use Volume Down on
351    the client device to exit fullscreen. Volume Up acts as a home key, if the
352    streamed display is a home display.
353
354### Input
355
356The input menu button enables **on-screen D-Pad, rotary and touchpad** for
357navigating the activity on the focused display. The focused display is indicated
358by the frame around its header whenever there are more than one displays. The
359display focus is based on user interaction.
360
361In addition, any input events generated from an **externally connected
362keyboard** are forwarded to the activity streamed on the focused display.
363
364**Externally connected mouse** events are also forwarded to the relevant
365display, if the mouse pointer is currently positioned on a streamed display.
366
367### Power
368
369The power menu button acts as a "virtual power button". It will toggle the state
370of the virtual device and all its displays between ON and OFF.
371Run the commands below on the host device to enable this functionality.
372
373```shell
374adb shell aflags enable android.companion.virtual.flags.device_aware_display_power && adb reboot
375```
376
377### Settings
378
379#### Debug
380
381-   **Network channel**: Select different communication channel between the
382    client and the host to avoid collisions with other demo setups nearby.
383    The selected channel on the host must match the selected channel on the
384    client.
385
386<!-- LINT.ThenChange(README.md) -->
387<!-- LINT.IfChange(demos) -->
388
389## Demos
390
391-   **Activity policy**: An activity showcasing blocking of activity launches on
392    the virtual device - either because the activity has opted out via
393    `android:canDisplayOnRemoteDevices` attribute, or because of the custom
394    activity policy of that device.
395
396-   **Sensors**: A simple activity balancing a beam on the screen based on the
397    accelerometer events, which allows for selecting which device's sensor to
398    use. By default, will use the sensors of the device it's shown on.
399
400-   **Display Power**: A simple activity showcasing the behavior of proximity
401    locks, screen brightness override and requesting the screen to be kept on
402    or turned on.
403
404-   **Rotation**: A simple activity that is in landscape by default and can send
405    orientation change requests on demand. Showcases the display rotation on the
406    client, which will rotate the user-visible surface.
407
408-   **Home**: A simple activity with utilities around launching HOME and
409    SECONDARY_HOME Intents, as well as other implicit intents.
410
411-   **Secure Window**: A simple activity that declares the Window as secure.
412    This showcases the FLAG_SECURE streaming policies in VDM.
413
414-   **Permissions**: A simple activity with buttons to request and revoke
415    runtime permissions. This can help test the permission streaming and
416    device-aware permission features.
417
418-   **Latency**: Renders a simple counter view that renders a new frame with an
419    incremented counter every second. Can be useful for debugging latency,
420    encoder, decoder issues in the demo application.
421
422-   **Vibration**: A simple activity making vibration requests via different
423    APIs and allows for selecting which device's vibrator to use. By default,
424    will use the vibrator of the device it's shown on. Note that currently there
425    is no vibration support on virtual devices, so vibration requests from
426    streamed activities are ignored.
427
428-   **Stylus**: A simple drawing activity that reacts on stylus input events.
429    Use together with the simulated stylus input feature of the host app.
430
431-   **Recorder**: A simple activity that can start multiple audio recorders.
432    This helps test audio recording permissions and concurrent recordings.
433
434The demo activity depends on whether the **Display Category** Host preference is
435enabled or not. If enabled, it becomes equivalent to the **Home** demo activity,
436which showcases implicit intent handling.
437
438<!-- LINT.ThenChange(README.md) -->
439
440## SDK Version
441
442### Beyond Android 16
443
444-   Added support for virtual sensor additional info.
445
446### Android 16 / Baklava / SDK level 36
447
448-   Added `COMPANION_DEVICE_VIRTUAL_DEVICE` device profile.
449
450-   Added support for custom power management.
451
452-   Added support for custom system windows (like status bar) and insets.
453
454-   Added support for per-display activity policies.
455
456-   Added support for custom redirection of blocked activities.
457
458-   Added support for hiding the blocked activity dialog.
459
460-   Added support for virtual display cutout.
461
462-   Added support for virtual display rotation.
463
464-   Added support for virtual rotary input.
465
466### Android 15 / Vanilla Ice Cream / SDK level 35
467
468-   Added support for virtual camera.
469
470-   Added support for virtual stylus input.
471
472-   Added support for cross-device clipboard.
473
474-   Added support for custom home activities.
475
476-   Added support for custom IME component.
477
478-   Added support for per-display IME policy.
479
480-   Added support for fixed orientation displays (disable display rotation).
481
482-   Added support for mirroring the default display on the virtual device.
483
484-   Added support for dynamic policy changes, so the device does not need to be
485    recreated.
486
487-   Improved support for displays that support home activities. Removed
488    navigation bar and added support for normal home intents.
489
490-   Improved handling of vibrating requests originating from virtual devices.
491
492-   Improved multi-display mouse support.
493
494-   Fixed bugs with hiding streamed apps from the host's recent apps.
495
496### Android 14 / Upside Down Cake / SDK level 34
497
498-   Added support for display categories and restricted activities.
499
500-   Added support for virtual sensors.
501
502-   Added device awareness to contexts.
503
504-   Added support for clipboard on the virtual device.
505
506-   Added support for hiding streamed apps from the host's recent apps.
507
508-   Added `COMPANION_DEVICE_NEARBY_DEVICE_STREAMING` device profile.
509
510-   Added support for virtual navigation input: D-Pad and navigation touchpad.
511
512-   Added support for display categories and restricted activities.
513
514-   Improved support for audio, allowing routing to be based on the origin
515    context.
516
517-   Improved support for creation of virtual displays and input devices.
518
519-   Improved handling of virtual touch events.
520
521### Android 13 / Tiramisu / SDK level 33
522
523-   Added support for virtual audio device.
524
525-   Added support for hiding the mouse pointer icon.
526
527-   Added support for virtual mouse, keyboard, touchscreen.
528
529-   Added support for always unlocked displays.
530
531-   Added `COMPANION_DEVICE_APP_STREAMING` device profile.
532
533-   Added support for virtual device creation.
534