xref: /aosp_15_r20/development/samples/VirtualDeviceManager/README.md (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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