README.md
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### Manually
67
681. Source `build/envsetup.sh` and run `lunch` or set
69 `UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true` if there's no local build because
70 the APKs need to be built against a locally built SDK.
71
721. Build the Host app.
73
74 ```shell
75 m -j VdmHost
76 ```
77
781. Install the application as a system app on the host device.
79
80 ```shell
81 adb root && adb disable-verity && adb reboot # one time
82 adb root && adb remount
83 adb push $ANDROID_BUILD_TOP/development/samples/VirtualDeviceManager/host/com.example.android.vdmdemo.host.xml /system/etc/permissions/com.example.android.vdmdemo.host.xml
84 adb shell mkdir /system/priv-app/VdmDemoHost
85 adb push $OUT/system/priv-app/VdmHost/VdmHost.apk /system/priv-app/VdmDemoHost/
86 adb reboot
87 ```
88
89 **Tip:** Subsequent installs without changes to permissions, etc. do not
90 need all the commands above - you can just run \
91 \
92 `adb install -r -d -g $OUT/system/priv-app/VdmHost/VdmHost.apk`
93
941. Build and install the Demo app on the host device.
95
96 ```shell
97 m -j VdmDemos && adb install -r -d -g $OUT/system/app/VdmDemos/VdmDemos.apk
98 ```
99
1001. Build and install the Client app on the client device.
101
102 ```shell
103 m -j VdmClient && adb install -r -d -g $OUT/system/app/VdmClient/VdmClient.apk
104 ```
105
106## Run
107
1081. Start both the Client and the Host apps on each respective device.
109
1101. They should find each other and connect automatically. On the first launch
111 the Host app will ask to create a CDM association: allow it.
112
113 WARNING: If there are other devices in the vicinity with one of these apps
114 running, they might interfere.
115
1161. Check out the different [Host Options](#host-options) and
117 [Client Options](#client-options) that allow for changing the behavior of
118 the streamed apps and the virtual device in general.
119
1201. Check out the [Demo apps](#demos) that are specifically meant to showcase
121 the VDM features.
122
123<!-- LINT.IfChange(host_options) -->
124
125## Host Options
126
127NOTE: Any flag changes require device reboot or "Force stop" of the host app
128because the flag values are cached and evaluated only when the host app is
129starting. Alternatively, run: \
130\
131`adb shell am force-stop com.example.android.vdmdemo.host`
132
133### Launcher
134
135Once the connection with the client device is established, the Host app will
136show a launcher-like list of installed apps on the host device.
137
138- Clicking an app icon will create a new virtual display, launch the app there
139 and start streaming the display contents to the client. The client will show
140 the surface of that display and render its contents.
141
142- Long pressing on an app icon will open a dialog to select an existing
143 display to launch the app on instead of creating a new one.
144
145- The Host app has a **CREATE HOME DISPLAY** button, clicking it will create a
146 new virtual display, launch the secondary home activity there and start
147 streaming the display contents to the client. The display on the Client app
148 will have a home button, clicking it will navigate the streaming experience
149 back to the home activity. Run the commands below to enable this
150 functionality.
151
152 ```shell
153 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_home true
154 adb shell am force-stop com.example.android.vdmdemo.host
155 ```
156
157- The Host app has a **CREATE MIRROR DISPLAY** button, clicking it will create
158 a new virtual display, mirror the default host display there and start
159 streaming the display contents to the client. Run the commands below to
160 enable this functionality.
161
162 ```shell
163 adb shell device_config put virtual_devices android.companion.virtual.flags.consistent_display_flags true
164 adb shell device_config put virtual_devices android.companion.virtual.flags.interactive_screen_mirror true
165 adb shell am force-stop com.example.android.vdmdemo.host
166 ```
167
168### Settings
169
170#### Input
171
172The input menu button enables several different mechanisms for injecting input
173from the host device into the focused display on the client device. The focused
174display is indicated by the frame around its header whenever there are more than
175one displays. The display focus is based on user interaction.
176
177Each input screen has a "Back", "Home" and "Forward" buttons.
178
179- **Touchpad** shows an on-screen touchpad for injecting mouse events into the
180 focused display.
181
182- **Remote** allows the host device to act as a pointer that controls the
183 mouse movement on the focused display.
184
185- **Navigation** shows an on-screen D-Pad and touchpad for navigating the
186 activity on the focused display.
187
188- **Keyboard** shows the host device's on-screen keyboard and sends any key
189 events to the activity on the focused display.
190
191- **Stylus** allows for injecting simulated stylus events into the focused
192 display. Use together with the stylus demo. Run the commands below to enable
193 this functionality.
194
195 ```shell
196 adb shell device_config put virtual_devices android.companion.virtual.flags.virtual_stylus true
197 adb shell am force-stop com.example.android.vdmdemo.host
198 ```
199
200#### General
201
202- **Device profile**: Enables device streaming CDM role as opposed to app
203 streaming role, with all differences in policies that this entails. \
204 *Changing this will recreate the virtual device.*
205
206- **Hide streamed app from recents**: Whether streamed apps should show up in
207 the host device's recent apps. Run the commands below to make this
208 functionality dynamic. \
209 *This can be changed dynamically starting with Android V.*
210
211 ```shell
212 adb shell device_config put virtual_devices android.companion.virtual.flags.dynamic_policy true
213 adb shell am force-stop com.example.android.vdmdemo.host
214 ```
215
216- **Enable cross-device clipboard**: Whether to share the clipboard between
217 the host and the virtual device. If disabled, both devices will have their
218 own isolated clipboards. Run the commands below to enable this
219 functionality. \
220 *This can be changed dynamically.*
221
222 ```shell
223 adb shell device_config put virtual_devices android.companion.virtual.flags.dynamic_policy true
224 adb shell device_config put virtual_devices android.companion.virtual.flags.cross_device_clipboard true
225 adb shell am force-stop com.example.android.vdmdemo.host
226 ```
227
228#### Client capabilities
229
230- **Enable client Sensors**: Enables sensor injection from the client device
231 into the host device. Any context that is associated with the virtual device
232 will access the virtual sensors by default. \
233 *Changing this will recreate the virtual device.*
234
235- **Enable client Camera**: Enables front & back camera injection from the client device
236 into the host device. (WIP: Any context that is associated with the virtual device
237 will the virtual cameras by default). Run the commands below on host device \
238 to enable this functionality.
239 *Changing this will recreate the virtual device.*
240
241 ```shell
242 adb shell device_config put virtual_devices android.companion.virtual.flags.virtual_camera true
243 adb shell device_config put virtual_devices android.companion.virtualdevice.flags.virtual_camera_service_discovery true
244 adb shell am force-stop com.example.android.vdmdemo.host
245 ```
246
247- **Enable client Audio**: Enables audio output on the client device. Any
248 context that is associated with the virtual device will play audio on the
249 client by default. \
250 *This can be changed dynamically.*
251
252#### Displays
253
254- **Display rotation**: Whether orientation change requests from streamed apps
255 should trigger orientation change of the relevant display. The client will
256 automatically rotate the relevant display upon such request. Disabling this
257 simulates a fixed orientation display that cannot physically rotate. Then
258 any streamed apps on that display will be letterboxed/pillarboxed if they
259 request orientation change. Run the commands below to enable this
260 functionality. \
261 *This can be changed dynamically but only applies to newly created
262 displays.*
263
264 ```shell
265 adb shell device_config put virtual_devices android.companion.virtual.flags.consistent_display_flags true
266 adb shell am force-stop com.example.android.vdmdemo.host
267 ```
268
269- **Always unlocked**: Whether the virtual displays should remain unlocked and
270 interactive when the host device is locked. Disabling this will result in a
271 simple lock screen shown on these displays when the host device is locked. \
272 *Changing this will recreate the virtual device.*
273
274- **Show pointer icon**: Whether pointer icon should be shown for virtual
275 input pointer devices. \
276 *This can be changed dynamically.*
277
278- **Custom home**: Whether to use a custom activity as home on home displays,
279 or use the device-default secondary home activity. Run the commands below to
280 enable this functionality. \
281 *Changing this will recreate the virtual device.*
282
283 ```shell
284 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_home true
285 adb shell am force-stop com.example.android.vdmdemo.host
286 ```
287
288#### Input method
289
290Note: The virtual keyboard acts like a physically connected keyboard to the
291host device. If you want the software keyboard to be shown on the virtual
292displays, you likely need to enable this in the host Settings. On a Pixel
293device: System -> Language and input -> Physical keyboard.
294
295- **Display IME policy**: Choose the IME behavior on remote displays. Run the
296 commands below to enable this functionality. \
297 *This can be changed dynamically.*
298
299 ```shell
300 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_ime true
301 adb shell am force-stop com.example.android.vdmdemo.host
302 ```
303
304- **Use the native client IME**: Enables the native client IME instead of
305 streaming the host's IME on the virtual displays. Requires the *Display IME
306 Policy* to be set to *Show IME on the remote display*. Run the commands
307 below to enable this functionality. \
308 *Changing this will recreate the virtual device.*
309
310 ```shell
311 adb shell device_config put virtual_devices android.companion.virtual.flags.vdm_custom_ime true
312 adb shell am force-stop com.example.android.vdmdemo.host
313 ```
314
315#### Debug
316
317- **Record encoder output**: Enables recording the output of the encoder on
318 the host device to a local file on the device. This can be helpful with
319 debugging Encoding related issues. To download and play the file locally:
320
321 ```shell
322 adb pull /sdcard/Download/vdmdemo_encoder_output_<displayId>.h264
323 ffplay -f h264 vdmdemo_encoder_output_<displayId>.h264
324 ```
325
326<!-- LINT.ThenChange(README.md) -->
327<!-- LINT.IfChange(client_options) -->
328
329## Client Options
330
331### Streamed displays
332
333- Each display on the Client app has a "Back" and "Close" buttons. When a
334 display becomes empty, it's automatically removed.
335
336- Each display on the Client app has a "Rotate" button to switch between
337 portrait and landscape orientation. This simulates the physical rotation of
338 the display of the streamed activity. The "Resize" button can be used to
339 change the display dimensions.
340
341- Each display on the Client app has a "Fullscreen" button which will move the
342 contents of that display to an immersive fullscreen activity. The client's
343 back button/gestures are sent back to the streamed app. Use Volume Down on
344 the client device to exit fullscreen. Volume Up acts as a home key, if the
345 streamed display is a home display.
346
347### Input
348
349The input menu button enables **on-screen D-Pad and touchpad** for navigating
350the activity on the focused display. The focused display is indicated by the
351frame around its header whenever there are more than one displays. The display
352focus is based on user interaction.
353
354In addition, any input events generated from an **externally connected
355keyboard** are forwarded to the activity streamed on the focused display.
356
357**Externally connected mouse** events are also forwarded to the relevant
358display, if the mouse pointer is currently positioned on a streamed display.
359
360<!-- LINT.ThenChange(README.md) -->
361<!-- LINT.IfChange(demos) -->
362
363## Demos
364
365- **Sensors**: A simple activity balancing a beam on the screen based on the
366 accelerometer events, which allows for selecting which device's sensor to
367 use. By default, will use the sensors of the device it's shown on.
368
369- **Rotation**: A simple activity that is in landscape by default and can send
370 orientation change requests on demand. Showcases the display rotation on the
371 client, which will rotate the user-visible surface.
372
373- **Home**: A simple activity with utilities around launching HOME and
374 SECONDARY_HOME Intents.
375
376- **Secure Window**: A simple activity that declares the Window as secure.
377 This showcases the FLAG_SECURE streaming policies in VDM.
378
379- **Permissions**: A simple activity with buttons to request and revoke
380 runtime permissions. This can help test the permission streaming and
381 device-aware permission features.
382
383- **Latency**: Renders a simple counter view that renders a new frame with an
384 incremented counter every second. Can be useful for debugging latency,
385 encoder, decoder issues in the demo application.
386
387- **Vibration**: A simple activity making vibration requests via different
388 APIs and allows for selecting which device's vibrator to use. By default,
389 will use the vibrator of the device it's shown on. Note that currently there
390 is no vibration support on virtual devices, so vibration requests from
391 streamed activities are ignored.
392
393- **Stylus**: A simple drawing activity that reacts on stylus input events.
394 Use together with the simulated stylus input feature of the host app.
395
396<!-- LINT.ThenChange(README.md) -->
397
398## SDK Version
399
400### Android 15 / Vanilla Ice Cream / SDK level 35
401
402- Added support for cross-device clipboard.
403
404- Added support for custom home activities.
405
406- Added support for custom IME component.
407
408- Added support for per-display IME policy.
409
410- Added support for fixed orientation displays (disable display rotation).
411
412- Added support for mirroring the default display on the virtual device.
413
414- Added support for dynamic policy changes, so the device does not need to be
415 recreated.
416
417- Improved support for displays that support home activities. Removed
418 navigation bar and added support for normal home intents.
419
420- Improved handling of vibrating requests originating from virtual devices.
421
422- Improved multi-display mouse support.
423
424- Fixed bugs with hiding streamed apps from the host's recent apps.
425
426### Android 14 / Upside Down Cake / SDK level 34
427
428- Added support for virtual sensors.
429
430- Added device awareness to contexts.
431
432- Added support for clipboard on the virtual device.
433
434- Added support for hiding streamed apps from the host's recent apps.
435
436- Added `COMPANION_DEVICE_NEARBY_DEVICE_STREAMING` device profile.
437
438- Added support for virtual navigation input: D-Pad and navigation touchpad.
439
440- Improved support for audio, allowing routing to be based on the origin
441 context.
442
443- Improved support for creation of virtual displays and input devices.
444
445- Improved handling of virtual touch events.
446
447### Android 13 / Tiramisu / SDK level 33
448
449- Added support for virtual audio device.
450
451- Added support for hiding the mouse pointer icon.
452
453- Added support for virtual mouse, keyboard, touchscreen.
454
455- Added support for always unlocked displays.
456
457- Added `COMPANION_DEVICE_APP_STREAMING` device profile.
458
459- Added support for virtual device creation.
460