• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.companion.virtual;
18 
19 import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE;
20 
21 import android.annotation.CallbackExecutor;
22 import android.annotation.FlaggedApi;
23 import android.annotation.IntDef;
24 import android.annotation.IntRange;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.annotation.RequiresPermission;
28 import android.annotation.SdkConstant;
29 import android.annotation.SuppressLint;
30 import android.annotation.SystemApi;
31 import android.annotation.SystemService;
32 import android.annotation.TestApi;
33 import android.annotation.UserIdInt;
34 import android.app.PendingIntent;
35 import android.companion.AssociationInfo;
36 import android.companion.virtual.audio.VirtualAudioDevice;
37 import android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback;
38 import android.companion.virtual.camera.VirtualCamera;
39 import android.companion.virtual.camera.VirtualCameraConfig;
40 import android.companion.virtual.sensor.VirtualSensor;
41 import android.companion.virtualdevice.flags.Flags;
42 import android.content.ComponentName;
43 import android.content.Context;
44 import android.content.Intent;
45 import android.content.IntentFilter;
46 import android.content.IntentSender;
47 import android.graphics.Point;
48 import android.hardware.display.DisplayManager;
49 import android.hardware.display.DisplayManager.VirtualDisplayFlag;
50 import android.hardware.display.VirtualDisplay;
51 import android.hardware.display.VirtualDisplayConfig;
52 import android.hardware.input.VirtualDpad;
53 import android.hardware.input.VirtualDpadConfig;
54 import android.hardware.input.VirtualKeyboard;
55 import android.hardware.input.VirtualKeyboardConfig;
56 import android.hardware.input.VirtualMouse;
57 import android.hardware.input.VirtualMouseConfig;
58 import android.hardware.input.VirtualNavigationTouchpad;
59 import android.hardware.input.VirtualNavigationTouchpadConfig;
60 import android.hardware.input.VirtualRotaryEncoder;
61 import android.hardware.input.VirtualRotaryEncoderConfig;
62 import android.hardware.input.VirtualStylus;
63 import android.hardware.input.VirtualStylusConfig;
64 import android.hardware.input.VirtualTouchscreen;
65 import android.hardware.input.VirtualTouchscreenConfig;
66 import android.media.AudioManager;
67 import android.os.Binder;
68 import android.os.Looper;
69 import android.os.RemoteException;
70 import android.os.UserHandle;
71 import android.util.ArraySet;
72 import android.util.Log;
73 import android.view.Display;
74 import android.view.Surface;
75 import android.view.WindowManager;
76 
77 import com.android.internal.annotations.GuardedBy;
78 
79 import java.lang.annotation.ElementType;
80 import java.lang.annotation.Retention;
81 import java.lang.annotation.RetentionPolicy;
82 import java.lang.annotation.Target;
83 import java.util.ArrayList;
84 import java.util.Collections;
85 import java.util.Iterator;
86 import java.util.List;
87 import java.util.Objects;
88 import java.util.Set;
89 import java.util.concurrent.Executor;
90 import java.util.function.IntConsumer;
91 
92 /**
93  * System level service for creation and management of virtual devices.
94  *
95  * <p>VirtualDeviceManager enables interactive sharing of capabilities between the host Android
96  * device and a remote device.
97  *
98  * <p class="note">Not to be confused with the Android Studio's Virtual Device Manager, which allows
99  * for device emulation.
100  */
101 @SystemService(Context.VIRTUAL_DEVICE_SERVICE)
102 public final class VirtualDeviceManager {
103 
104     private static final String TAG = "VirtualDeviceManager";
105 
106     /**
107      * Broadcast Action: A Virtual Device was removed.
108      *
109      * <p class="note">This is a protected intent that can only be sent by the system.</p>
110      *
111      * @hide
112      */
113     @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
114     public static final String ACTION_VIRTUAL_DEVICE_REMOVED =
115             "android.companion.virtual.action.VIRTUAL_DEVICE_REMOVED";
116 
117     /**
118      * Int intent extra to be used with {@link #ACTION_VIRTUAL_DEVICE_REMOVED}.
119      * Contains the identifier of the virtual device, which was removed.
120      *
121      * @hide
122      */
123     public static final String EXTRA_VIRTUAL_DEVICE_ID =
124             "android.companion.virtual.extra.VIRTUAL_DEVICE_ID";
125 
126     /** @hide */
127     @Retention(RetentionPolicy.SOURCE)
128     @IntDef(
129             prefix = "LAUNCH_",
130             value = {
131                     LAUNCH_SUCCESS,
132                     LAUNCH_FAILURE_PENDING_INTENT_CANCELED,
133                     LAUNCH_FAILURE_NO_ACTIVITY})
134     @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
135     public @interface PendingIntentLaunchStatus {}
136 
137     /**
138      * Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch was
139      * successful.
140      *
141      * @hide
142      */
143     @SystemApi
144     public static final int LAUNCH_SUCCESS = 0;
145 
146     /**
147      * Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch failed
148      * because the pending intent was canceled.
149      *
150      * @hide
151      */
152     @SystemApi
153     public static final int LAUNCH_FAILURE_PENDING_INTENT_CANCELED = 1;
154 
155     /**
156      * Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch failed
157      * because no activity starts were detected as a result of calling the pending intent.
158      *
159      * @hide
160      */
161     @SystemApi
162     public static final int LAUNCH_FAILURE_NO_ACTIVITY = 2;
163 
164     /**
165      * Persistent device identifier corresponding to the default device.
166      *
167      * @see Context#DEVICE_ID_DEFAULT
168      * @see VirtualDevice#getPersistentDeviceId()
169      *
170      * @hide
171      */
172     @SystemApi
173     public static final String PERSISTENT_DEVICE_ID_DEFAULT =
174             "default:" + Context.DEVICE_ID_DEFAULT;
175 
176     private final IVirtualDeviceManager mService;
177     private final Context mContext;
178 
179     @GuardedBy("mVirtualDeviceListeners")
180     private final List<VirtualDeviceListenerDelegate> mVirtualDeviceListeners = new ArrayList<>();
181 
182     /** @hide */
VirtualDeviceManager( @ullable IVirtualDeviceManager service, @NonNull Context context)183     public VirtualDeviceManager(
184             @Nullable IVirtualDeviceManager service, @NonNull Context context) {
185         mService = service;
186         mContext = context;
187     }
188 
189     /**
190      * Creates a virtual device where applications can launch and receive input events injected by
191      * the creator.
192      *
193      * <p>The {@link android.Manifest.permission#CREATE_VIRTUAL_DEVICE} permission is required to
194      * create virtual devices, which is only available to system apps holding specific roles.
195      *
196      * @param associationId The association ID as returned by {@link AssociationInfo#getId()} from
197      *   Companion Device Manager. Virtual devices must have a corresponding association with CDM in
198      *   order to be created.
199      * @param params The parameters for creating virtual devices. See {@link VirtualDeviceParams}
200      *   for the available options.
201      * @return The created virtual device.
202      *
203      * @hide
204      */
205     @SystemApi
206     @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
207     @NonNull
createVirtualDevice( int associationId, @NonNull VirtualDeviceParams params)208     public VirtualDevice createVirtualDevice(
209             int associationId,
210             @NonNull VirtualDeviceParams params) {
211         Objects.requireNonNull(params, "params must not be null");
212         try {
213             return new VirtualDevice(mService, mContext, associationId, params);
214         } catch (RemoteException e) {
215             throw e.rethrowFromSystemServer();
216         }
217     }
218 
219     /**
220      * Returns the details of all available virtual devices.
221      *
222      * <p>The returned objects are read-only representations that expose the properties of all
223      * existing virtual devices.</p>
224      *
225      * <p>Note that if a virtual device is closed and becomes invalid, the returned objects will
226      * not be updated and may contain stale values. Use a {@link VirtualDeviceListener} for real
227      * time updates of the availability  of virtual devices.</p>
228      */
229     @NonNull
getVirtualDevices()230     public List<android.companion.virtual.VirtualDevice> getVirtualDevices() {
231         if (mService == null) {
232             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
233             return new ArrayList<>();
234         }
235         try {
236             return mService.getVirtualDevices();
237         } catch (RemoteException e) {
238             throw e.rethrowFromSystemServer();
239         }
240     }
241 
242     /**
243      * Returns the details of the virtual device with the given ID, if any.
244      *
245      * <p>The returned object is a read-only representation of the virtual device that expose its
246      * properties.</p>
247      *
248      * <p>Note that if the virtual device is closed and becomes invalid, the returned object will
249      * not be updated and may contain stale values. Use a {@link VirtualDeviceListener} for real
250      * time updates of the availability of virtual devices.</p>
251      *
252      * @return the virtual device with the requested ID, or {@code null} if no such device exists or
253      *   it has already been closed.
254      */
255     @Nullable
getVirtualDevice(int deviceId)256     public android.companion.virtual.VirtualDevice getVirtualDevice(int deviceId) {
257         if (mService == null) {
258             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
259             return null;
260         }
261         if (deviceId == Context.DEVICE_ID_INVALID || deviceId == Context.DEVICE_ID_DEFAULT) {
262             return null;  // Don't even bother making a Binder call.
263         }
264         try {
265             return mService.getVirtualDevice(deviceId);
266         } catch (RemoteException e) {
267             throw e.rethrowFromSystemServer();
268         }
269     }
270 
271     /**
272      * Registers a virtual device listener to receive notifications when virtual devices are created
273      * or closed.
274      *
275      * @param executor The executor where the listener is executed on.
276      * @param listener The listener to add.
277      * @see #unregisterVirtualDeviceListener
278      */
registerVirtualDeviceListener( @onNull @allbackExecutor Executor executor, @NonNull VirtualDeviceListener listener)279     public void registerVirtualDeviceListener(
280             @NonNull @CallbackExecutor Executor executor,
281             @NonNull VirtualDeviceListener listener) {
282         if (mService == null) {
283             Log.w(TAG, "Failed to register listener; no virtual device manager service.");
284             return;
285         }
286         final VirtualDeviceListenerDelegate delegate =
287                 new VirtualDeviceListenerDelegate(Objects.requireNonNull(executor),
288                         Objects.requireNonNull(listener));
289         synchronized (mVirtualDeviceListeners) {
290             try {
291                 mService.registerVirtualDeviceListener(delegate);
292             } catch (RemoteException e) {
293                 throw e.rethrowFromSystemServer();
294             }
295             mVirtualDeviceListeners.add(delegate);
296         }
297     }
298 
299     /**
300      * Unregisters a virtual device listener previously registered with
301      * {@link #registerVirtualDeviceListener}.
302      *
303      * @param listener The listener to unregister.
304      * @see #registerVirtualDeviceListener
305      */
unregisterVirtualDeviceListener(@onNull VirtualDeviceListener listener)306     public void unregisterVirtualDeviceListener(@NonNull VirtualDeviceListener listener) {
307         if (mService == null) {
308             Log.w(TAG, "Failed to unregister listener; no virtual device manager service.");
309             return;
310         }
311         Objects.requireNonNull(listener);
312         synchronized (mVirtualDeviceListeners) {
313             final Iterator<VirtualDeviceListenerDelegate> it = mVirtualDeviceListeners.iterator();
314             while (it.hasNext()) {
315                 final VirtualDeviceListenerDelegate delegate = it.next();
316                 if (delegate.mListener == listener) {
317                     try {
318                         mService.unregisterVirtualDeviceListener(delegate);
319                     } catch (RemoteException e) {
320                         throw e.rethrowFromSystemServer();
321                     }
322                     it.remove();
323                 }
324             }
325         }
326     }
327 
328     /**
329      * Returns the device policy for the given virtual device and policy type.
330      *
331      * <p>In case the virtual device identifier is not valid, or there's no explicitly specified
332      * policy for that device and policy type, then
333      * {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT} is returned.
334      *
335      * @hide
336      */
337     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
338     @TestApi
getDevicePolicy( int deviceId, @VirtualDeviceParams.PolicyType int policyType)339     public @VirtualDeviceParams.DevicePolicy int getDevicePolicy(
340             int deviceId, @VirtualDeviceParams.PolicyType int policyType) {
341         if (deviceId == Context.DEVICE_ID_DEFAULT) {
342             // Avoid unnecessary binder call, for default device, policy will be always default.
343             return VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
344         }
345         if (mService == null) {
346             Log.w(TAG, "Failed to retrieve device policy; no virtual device manager service.");
347             return VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
348         }
349         try {
350             return mService.getDevicePolicy(deviceId, policyType);
351         } catch (RemoteException e) {
352             throw e.rethrowFromSystemServer();
353         }
354     }
355 
356     /**
357      * Returns the ID of the device which owns the display with the given ID.
358      *
359      * @hide
360      */
361     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
362     @TestApi
getDeviceIdForDisplayId(int displayId)363     public int getDeviceIdForDisplayId(int displayId) {
364         if (displayId == Display.DEFAULT_DISPLAY || displayId == Display.INVALID_DISPLAY) {
365             // Avoid unnecessary binder call for default / invalid display id.
366             return Context.DEVICE_ID_DEFAULT;
367         }
368         if (mService == null) {
369             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
370             return Context.DEVICE_ID_DEFAULT;
371         }
372         try {
373             return mService.getDeviceIdForDisplayId(displayId);
374         } catch (RemoteException e) {
375             throw e.rethrowFromSystemServer();
376         }
377     }
378 
379     /**
380      * Get the display name for a given persistent device ID.
381      *
382      * <p>This will work even if currently there is no valid virtual device with the given
383      * persistent ID, as long as such a device has been created or can be created.</p>
384      *
385      * @return the display name associated with the given persistent device ID, or {@code null} if
386      *     the persistent ID is invalid or does not correspond to a virtual device.
387      *
388      * @see VirtualDevice#getPersistentDeviceId()
389      * @hide
390      */
391     @SystemApi
392     @Nullable
getDisplayNameForPersistentDeviceId(@onNull String persistentDeviceId)393     public CharSequence getDisplayNameForPersistentDeviceId(@NonNull String persistentDeviceId) {
394         if (mService == null) {
395             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
396             return null;
397         }
398         try {
399             return mService.getDisplayNameForPersistentDeviceId(
400                     Objects.requireNonNull(persistentDeviceId));
401         } catch (RemoteException e) {
402             throw e.rethrowFromSystemServer();
403         }
404     }
405 
406     /**
407      * Returns all current persistent device IDs, including the ones for which no virtual device
408      * exists, as long as one may have existed or can be created.
409      *
410      * @see VirtualDevice#getPersistentDeviceId()
411      * @hide
412      */
413     @SystemApi
414     @NonNull
getAllPersistentDeviceIds()415     public Set<String> getAllPersistentDeviceIds() {
416         if (mService == null) {
417             Log.w(TAG, "Failed to retrieve persistent ids; no virtual device manager service.");
418             return Collections.emptySet();
419         }
420         try {
421             return new ArraySet<>(mService.getAllPersistentDeviceIds());
422         } catch (RemoteException e) {
423             throw e.rethrowFromSystemServer();
424         }
425     }
426 
427     /**
428      * Checks whether the passed {@code deviceId} is a valid virtual device ID or not.
429      * {@link Context#DEVICE_ID_DEFAULT} is not valid as it is the ID of the default
430      * device which is not a virtual device. {@code deviceId} must correspond to a virtual device
431      * created by {@link VirtualDeviceManager#createVirtualDevice(int, VirtualDeviceParams)}.
432      *
433      * @hide
434      */
isValidVirtualDeviceId(int deviceId)435     public boolean isValidVirtualDeviceId(int deviceId) {
436         if (mService == null) {
437             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
438             return false;
439         }
440         try {
441             return mService.isValidVirtualDeviceId(deviceId);
442         } catch (RemoteException e) {
443             throw e.rethrowFromSystemServer();
444         }
445     }
446 
447     /**
448      * Returns device-specific audio session id for audio playback.
449      *
450      * @param deviceId - id of the virtual audio device
451      * @return Device specific session id to be used for audio playback (see
452      *   {@link AudioManager#generateAudioSessionId}) if virtual device has
453      *   {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to
454      *   {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device
455      *   is configured in context-aware mode. Otherwise
456      *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned.
457      *
458      * @hide
459      */
460     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
461     @TestApi
getAudioPlaybackSessionId(int deviceId)462     public int getAudioPlaybackSessionId(int deviceId) {
463         if (mService == null) {
464             return AUDIO_SESSION_ID_GENERATE;
465         }
466         try {
467             return mService.getAudioPlaybackSessionId(deviceId);
468         } catch (RemoteException e) {
469             throw e.rethrowFromSystemServer();
470         }
471     }
472 
473     /**
474      * Returns device-specific audio session id for audio recording.
475      *
476      * @param deviceId - id of the virtual audio device
477      * @return Device specific session id to be used for audio recording (see
478      *   {@link AudioManager#generateAudioSessionId}) if virtual device has
479      *   {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to
480      *   {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device
481      *   is configured in context-aware mode. Otherwise
482      *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned.
483      *
484      * @hide
485      */
486     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
487     @TestApi
getAudioRecordingSessionId(int deviceId)488     public int getAudioRecordingSessionId(int deviceId) {
489         if (mService == null) {
490             return AUDIO_SESSION_ID_GENERATE;
491         }
492         try {
493             return mService.getAudioRecordingSessionId(deviceId);
494         } catch (RemoteException e) {
495             throw e.rethrowFromSystemServer();
496         }
497     }
498 
499     /**
500      * Requests sound effect to be played on virtual device.
501      *
502      * @see AudioManager#playSoundEffect(int)
503      *
504      * @param deviceId - id of the virtual audio device
505      * @param effectType the type of sound effect
506      *
507      * @hide
508      */
509     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
510     @TestApi
playSoundEffect(int deviceId, @AudioManager.SystemSoundEffect int effectType)511     public void playSoundEffect(int deviceId, @AudioManager.SystemSoundEffect int effectType) {
512         if (mService == null) {
513             Log.w(TAG, "Failed to dispatch sound effect; no virtual device manager service.");
514             return;
515         }
516         try {
517             mService.playSoundEffect(deviceId, effectType);
518         } catch (RemoteException e) {
519             throw e.rethrowFromSystemServer();
520         }
521     }
522 
523     /**
524      * Returns whether the given display is an auto-mirror display owned by a virtual device.
525      *
526      * @hide
527      */
528     @TestApi
isVirtualDeviceOwnedMirrorDisplay(int displayId)529     public boolean isVirtualDeviceOwnedMirrorDisplay(int displayId) {
530         if (mService == null) {
531             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
532             return false;
533         }
534         try {
535             return mService.isVirtualDeviceOwnedMirrorDisplay(displayId);
536         } catch (RemoteException e) {
537             throw e.rethrowFromSystemServer();
538         }
539     }
540 
541     /**
542      * A representation of a virtual device.
543      *
544      * <p>A virtual device can have its own virtual displays, audio input/output, sensors, etc.
545      * The creator of a virtual device can take the output from the virtual display and stream it
546      * over to another device, and inject input and sensor events that are received from the remote
547      * device.
548      *
549      * <p>This object is only used by the virtual device creator and allows them to manage the
550      * device's behavior, peripherals, and the user interaction with that device.
551      *
552      * <p class="note">Not to be confused with {@link android.companion.virtual.VirtualDevice},
553      * which is a read-only representation exposing the properties of an existing virtual device.
554      *
555      * @hide
556      */
557     @SystemApi
558     public static class VirtualDevice implements AutoCloseable {
559 
560         private final VirtualDeviceInternal mVirtualDeviceInternal;
561 
562         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
VirtualDevice( IVirtualDeviceManager service, Context context, int associationId, VirtualDeviceParams params)563         private VirtualDevice(
564                 IVirtualDeviceManager service,
565                 Context context,
566                 int associationId,
567                 VirtualDeviceParams params) throws RemoteException {
568             mVirtualDeviceInternal =
569                     new VirtualDeviceInternal(service, context, associationId, params);
570         }
571 
572         /** @hide */
VirtualDevice(Context context, IVirtualDevice virtualDevice)573         public VirtualDevice(Context context, IVirtualDevice virtualDevice) {
574             mVirtualDeviceInternal = new VirtualDeviceInternal(context, virtualDevice);
575         }
576 
577         /**
578          * Returns the unique ID of this virtual device.
579          */
getDeviceId()580         public int getDeviceId() {
581             return mVirtualDeviceInternal.getDeviceId();
582         }
583 
584         /**
585          * Returns the persistent ID of this virtual device.
586          */
getPersistentDeviceId()587         public @Nullable String getPersistentDeviceId() {
588             return mVirtualDeviceInternal.getPersistentDeviceId();
589         }
590 
591         /**
592          * Returns a new context bound to this device.
593          *
594          * <p>This is a convenience method equivalent to calling
595          * {@link Context#createDeviceContext(int)} with the id of this device.
596          */
createContext()597         public @NonNull Context createContext() {
598             return mVirtualDeviceInternal.createContext();
599         }
600 
601         /**
602          * Returns this device's sensors.
603          *
604          * @see VirtualDeviceParams.Builder#addVirtualSensorConfig
605          *
606          * @return A list of all sensors for this device, or an empty list if no sensors exist.
607          */
608         @NonNull
getVirtualSensorList()609         public List<VirtualSensor> getVirtualSensorList() {
610             return mVirtualDeviceInternal.getVirtualSensorList();
611         }
612 
613         /**
614          * Forces all trusted non-mirror displays of the virtual device to turn off.
615          *
616          * <p>After this action, if all displays across all devices, including the default one, are
617          * off, then the physical device will be put to sleep. If the displays of this virtual
618          * device are already off, then nothing will happen.</p>
619          *
620          * <p>Overrides all the wake locks that are held. This is equivalent to pressing a "virtual
621          * power key" to turn off the screen.</p>
622          *
623          * @see #wakeUp()
624          * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
625          * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
626          */
627         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
goToSleep()628         public void goToSleep() {
629             mVirtualDeviceInternal.goToSleep();
630         }
631 
632         /**
633          * Forces all trusted non-mirror displays of the virtual device to turn on.
634          *
635          * <p>If the displays of this virtual device are turned off, then they will be turned on.
636          * Additionally, if the device is asleep it will be awoken. If the displays of this virtual
637          * device are already on, then nothing will happen.</p>
638          *
639          * <p>This is equivalent to pressing a "virtual power key" to turn on the screen.</p>
640          *
641          * @see #goToSleep()
642          * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
643          * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
644          */
645         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
wakeUp()646         public void wakeUp() {
647             mVirtualDeviceInternal.wakeUp();
648         }
649 
650         /**
651          * Launches a given pending intent on the give display ID.
652          *
653          * @param displayId The display to launch the pending intent on. This display must be
654          *   created from this virtual device.
655          * @param pendingIntent The pending intent to be launched. If the intent is an activity
656          *   intent, the activity will be started on the virtual display using
657          *   {@link android.app.ActivityOptions#setLaunchDisplayId}. If the intent is a service or
658          *   broadcast intent, an attempt will be made to catch activities started as a result of
659          *   sending the pending intent and move them to the given display. When it completes,
660          *   {@code listener} will be called with the status of whether the launch attempt is
661          *   successful or not.
662          * @param executor The executor to run {@code launchCallback} on.
663          * @param listener Listener that is called when the pending intent launching is complete.
664          *   The argument is {@link #LAUNCH_SUCCESS} if the launch successfully started an activity
665          *   on the virtual display, or one of the {@code LAUNCH_FAILED} status explaining why it
666          *   failed.
667          */
launchPendingIntent( int displayId, @NonNull PendingIntent pendingIntent, @NonNull Executor executor, @NonNull IntConsumer listener)668         public void launchPendingIntent(
669                 int displayId,
670                 @NonNull PendingIntent pendingIntent,
671                 @NonNull Executor executor,
672                 @NonNull IntConsumer listener) {
673             Objects.requireNonNull(pendingIntent, "pendingIntent must not be null");
674             Objects.requireNonNull(executor, "executor must not be null");
675             Objects.requireNonNull(listener, "listener must not be null");
676             mVirtualDeviceInternal.launchPendingIntent(
677                     displayId, pendingIntent, executor, listener);
678         }
679 
680         /**
681          * Creates a virtual display for this virtual device. All displays created on the same
682          * device belongs to the same display group.
683          *
684          * @param width The width of the virtual display in pixels, must be greater than 0.
685          * @param height The height of the virtual display in pixels, must be greater than 0.
686          * @param densityDpi The density of the virtual display in dpi, must be greater than 0.
687          * @param surface The surface to which the content of the virtual display should
688          *   be rendered, or null if there is none initially. The surface can also be set later
689          *   using {@link VirtualDisplay#setSurface(Surface)}.
690          * @param flags A combination of virtual display flags accepted by
691          *   {@link DisplayManager#createVirtualDisplay}. In addition, the following flags are
692          *   automatically set for all virtual devices:
693          *   {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC} and
694          *   {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
695          * @param executor The executor on which {@code callback} will be invoked. This is ignored
696          *   if {@code callback} is {@code null}. If {@code callback} is specified, this executor
697          *   must not be null.
698          * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
699          * @return The newly created virtual display, or {@code null} if the application could
700          *   not create the virtual display.
701          *
702          * @see DisplayManager#createVirtualDisplay
703          *
704          * @deprecated use {@link #createVirtualDisplay(VirtualDisplayConfig, Executor,
705          * VirtualDisplay.Callback)}
706          */
707         @Deprecated
708         @Nullable
createVirtualDisplay( @ntRangefrom = 1) int width, @IntRange(from = 1) int height, @IntRange(from = 1) int densityDpi, @Nullable Surface surface, @VirtualDisplayFlag int flags, @Nullable @CallbackExecutor Executor executor, @Nullable VirtualDisplay.Callback callback)709         public VirtualDisplay createVirtualDisplay(
710                 @IntRange(from = 1) int width,
711                 @IntRange(from = 1) int height,
712                 @IntRange(from = 1) int densityDpi,
713                 @Nullable Surface surface,
714                 @VirtualDisplayFlag int flags,
715                 @Nullable @CallbackExecutor Executor executor,
716                 @Nullable VirtualDisplay.Callback callback) {
717             // Currently this just uses the device ID, which means all of the virtual displays
718             // created using the same virtual device will have the same name if they use this
719             // deprecated API. The name should only be used for informational purposes, and not for
720             // identifying the display in code.
721             String virtualDisplayName =  "VirtualDevice_" + getDeviceId();
722             VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
723                     virtualDisplayName, width, height, densityDpi)
724                     .setFlags(flags);
725             if (surface != null) {
726                 builder.setSurface(surface);
727             }
728             return mVirtualDeviceInternal.createVirtualDisplay(builder.build(), executor, callback);
729         }
730 
731         /**
732          * Creates a virtual display for this virtual device. All displays created on the same
733          * device belongs to the same display group.
734          *
735          * @param config The configuration of the display.
736          * @param executor The executor on which {@code callback} will be invoked. This is ignored
737          *   if {@code callback} is {@code null}. If {@code callback} is specified, this executor
738          *   must not be null.
739          * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
740          * @return The newly created virtual display, or {@code null} if the application could
741          *   not create the virtual display.
742          *
743          * @see DisplayManager#createVirtualDisplay
744          */
745         @Nullable
createVirtualDisplay( @onNull VirtualDisplayConfig config, @Nullable @CallbackExecutor Executor executor, @Nullable VirtualDisplay.Callback callback)746         public VirtualDisplay createVirtualDisplay(
747                 @NonNull VirtualDisplayConfig config,
748                 @Nullable @CallbackExecutor Executor executor,
749                 @Nullable VirtualDisplay.Callback callback) {
750             Objects.requireNonNull(config, "config must not be null");
751             return mVirtualDeviceInternal.createVirtualDisplay(config, executor, callback);
752         }
753 
754         /**
755          * Closes the virtual device, stopping and tearing down any virtual displays, associated
756          * virtual audio device, and event injection that's currently in progress.
757          */
close()758         public void close() {
759             mVirtualDeviceInternal.close();
760         }
761 
762         /**
763          * Specifies a policy for this virtual device.
764          *
765          * <p>Policies define the system behavior that may be specific for this virtual device. The
766          * given policy must be able to be changed dynamically during the lifetime of the device.
767          *
768          * @param policyType the type of policy, i.e. which behavior to specify a policy for.
769          * @param devicePolicy the value of the policy, i.e. how to interpret the device behavior.
770          * @throws IllegalArgumentException if the policy cannot be changed at runtime.
771          *
772          * @see VirtualDeviceParams#POLICY_TYPE_RECENTS
773          * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
774          */
setDevicePolicy(@irtualDeviceParams.DynamicPolicyType int policyType, @VirtualDeviceParams.DevicePolicy int devicePolicy)775         public void setDevicePolicy(@VirtualDeviceParams.DynamicPolicyType int policyType,
776                 @VirtualDeviceParams.DevicePolicy int devicePolicy) {
777             mVirtualDeviceInternal.setDevicePolicy(policyType, devicePolicy);
778         }
779 
780         /**
781          * Specifies a component name to be exempt from the current activity launch policy.
782          *
783          * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
784          * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
785          * then the specified component will be blocked from launching.
786          * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
787          * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
788          * specified component will be allowed to launch.</p>
789          *
790          * <p>Note that changing the activity launch policy will clear current set of exempt
791          * components.</p>
792          *
793          * @see #removeActivityPolicyExemption(ComponentName)
794          * @see #setDevicePolicy
795          */
addActivityPolicyExemption(@onNull ComponentName componentName)796         public void addActivityPolicyExemption(@NonNull ComponentName componentName) {
797             addActivityPolicyExemption(new ActivityPolicyExemption.Builder()
798                     .setComponentName(componentName)
799                     .build());
800         }
801 
802         /**
803          * Makes the specified component name to adhere to the default activity launch policy.
804          *
805          * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
806          * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
807          * then the specified component will be allowed to launch.
808          * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
809          * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then the
810          * specified component will be blocked from launching.</p>
811          *
812          * <p>Note that changing the activity launch policy will clear current set of exempt
813          * components.</p>
814          *
815          * @see #addActivityPolicyExemption(ComponentName)
816          * @see #setDevicePolicy
817          */
removeActivityPolicyExemption(@onNull ComponentName componentName)818         public void removeActivityPolicyExemption(@NonNull ComponentName componentName) {
819             removeActivityPolicyExemption(new ActivityPolicyExemption.Builder()
820                     .setComponentName(componentName)
821                     .build());
822         }
823 
824         /**
825          * Specifies an exemption from the current activity launch policy.
826          *
827          * <p>If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} allows activity
828          * launches by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_DEFAULT}),
829          * then all exempt activities be blocked from launching.
830          * If the current {@link VirtualDeviceParams#POLICY_TYPE_ACTIVITY} blocks activity launches
831          * by default, (i.e. it is {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM}), then all
832          * exempt activities will be allowed to launch.</p>
833          *
834          * <p>Note that changing the activity launch policy will clear current set of exempt
835          * packages.</p>
836          * <p>Any change to the exemptions will only be applied for new activity launches.</p>
837          *
838          * @see #removeActivityPolicyExemption(ActivityPolicyExemption)
839          * @see #setDevicePolicy
840          */
841         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
addActivityPolicyExemption(@onNull ActivityPolicyExemption exemption)842         public void addActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
843             mVirtualDeviceInternal.addActivityPolicyExemption(Objects.requireNonNull(exemption));
844         }
845 
846         /**
847          * Removes an exemption from the current activity launch policy.
848          *
849          * <p>Note that changing the activity launch policy will clear current set of exempt
850          * packages.</p>
851          * <p>Any change to the exemptions will only be applied for new activity launches.</p>
852          *
853          * @see #addActivityPolicyExemption(ActivityPolicyExemption)
854          * @see #setDevicePolicy
855          */
856         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
removeActivityPolicyExemption(@onNull ActivityPolicyExemption exemption)857         public void removeActivityPolicyExemption(@NonNull ActivityPolicyExemption exemption) {
858             mVirtualDeviceInternal.removeActivityPolicyExemption(Objects.requireNonNull(exemption));
859         }
860 
861         /**
862          * Specifies a policy for this virtual device to be applied on the given virtual display.
863          * <p>
864          * Any policy specified for a particular display takes precedence over the policy specified
865          * for the device itself.
866          * </p>
867          *
868          * @param policyType the type of policy, i.e. which behavior to specify a policy for.
869          * @param devicePolicy the value of the policy, i.e. how to interpret the device behavior.
870          * @param displayId the ID of the display, for which to apply the policy.
871          * @throws IllegalArgumentException if the specified policy cannot be changed per
872          *   display or if the specified display does not belong to the virtual device.
873          *
874          * @see #setDevicePolicy(int, int)
875          * @see VirtualDeviceParams#POLICY_TYPE_RECENTS
876          * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
877          */
878         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
setDevicePolicy( @irtualDeviceParams.DynamicDisplayPolicyType int policyType, @VirtualDeviceParams.DevicePolicy int devicePolicy, int displayId)879         public void setDevicePolicy(
880                 @VirtualDeviceParams.DynamicDisplayPolicyType int policyType,
881                 @VirtualDeviceParams.DevicePolicy int devicePolicy,
882                 int displayId) {
883             mVirtualDeviceInternal.setDevicePolicyForDisplay(displayId, policyType, devicePolicy);
884         }
885 
886         /**
887          * Creates a virtual dpad.
888          *
889          * @param config the configurations of the virtual dpad.
890          */
891         @NonNull
createVirtualDpad(@onNull VirtualDpadConfig config)892         public VirtualDpad createVirtualDpad(@NonNull VirtualDpadConfig config) {
893             Objects.requireNonNull(config, "config must not be null");
894             return mVirtualDeviceInternal.createVirtualDpad(config);
895         }
896 
897         /**
898          * Creates a virtual keyboard.
899          *
900          * @param config the configurations of the virtual keyboard.
901          */
902         @NonNull
createVirtualKeyboard(@onNull VirtualKeyboardConfig config)903         public VirtualKeyboard createVirtualKeyboard(@NonNull VirtualKeyboardConfig config) {
904             Objects.requireNonNull(config, "config must not be null");
905             return mVirtualDeviceInternal.createVirtualKeyboard(config);
906         }
907 
908         /**
909          * Creates a virtual keyboard.
910          *
911          * @param display the display that the events inputted through this device should target.
912          * @param inputDeviceName the name of this keyboard device.
913          * @param vendorId the PCI vendor id.
914          * @param productId the product id, as defined by the vendor.
915          * @see #createVirtualKeyboard(VirtualKeyboardConfig config)
916          * @deprecated Use {@link #createVirtualKeyboard(VirtualKeyboardConfig config)} instead
917          */
918         @Deprecated
919         @NonNull
createVirtualKeyboard(@onNull VirtualDisplay display, @NonNull String inputDeviceName, int vendorId, int productId)920         public VirtualKeyboard createVirtualKeyboard(@NonNull VirtualDisplay display,
921                 @NonNull String inputDeviceName, int vendorId, int productId) {
922             VirtualKeyboardConfig keyboardConfig =
923                     new VirtualKeyboardConfig.Builder()
924                             .setVendorId(vendorId)
925                             .setProductId(productId)
926                             .setInputDeviceName(inputDeviceName)
927                             .setAssociatedDisplayId(display.getDisplay().getDisplayId())
928                             .build();
929             return mVirtualDeviceInternal.createVirtualKeyboard(keyboardConfig);
930         }
931 
932         /**
933          * Creates a virtual mouse.
934          *
935          * @param config the configurations of the virtual mouse.
936          */
937         @NonNull
createVirtualMouse(@onNull VirtualMouseConfig config)938         public VirtualMouse createVirtualMouse(@NonNull VirtualMouseConfig config) {
939             Objects.requireNonNull(config, "config must not be null");
940             return mVirtualDeviceInternal.createVirtualMouse(config);
941         }
942 
943         /**
944          * Creates a virtual mouse.
945          *
946          * @param display the display that the events inputted through this device should target.
947          * @param inputDeviceName the name of this mouse.
948          * @param vendorId the PCI vendor id.
949          * @param productId the product id, as defined by the vendor.
950          * @see #createVirtualMouse(VirtualMouseConfig config)
951          * @deprecated Use {@link #createVirtualMouse(VirtualMouseConfig config)} instead
952          */
953         @Deprecated
954         @NonNull
createVirtualMouse(@onNull VirtualDisplay display, @NonNull String inputDeviceName, int vendorId, int productId)955         public VirtualMouse createVirtualMouse(@NonNull VirtualDisplay display,
956                 @NonNull String inputDeviceName, int vendorId, int productId) {
957             VirtualMouseConfig mouseConfig =
958                     new VirtualMouseConfig.Builder()
959                             .setVendorId(vendorId)
960                             .setProductId(productId)
961                             .setInputDeviceName(inputDeviceName)
962                             .setAssociatedDisplayId(display.getDisplay().getDisplayId())
963                             .build();
964             return mVirtualDeviceInternal.createVirtualMouse(mouseConfig);
965         }
966 
967         /**
968          * Creates a virtual touchscreen.
969          *
970          * @param config the configurations of the virtual touchscreen.
971          */
972         @NonNull
createVirtualTouchscreen( @onNull VirtualTouchscreenConfig config)973         public VirtualTouchscreen createVirtualTouchscreen(
974                 @NonNull VirtualTouchscreenConfig config) {
975             Objects.requireNonNull(config, "config must not be null");
976             return mVirtualDeviceInternal.createVirtualTouchscreen(config);
977         }
978 
979         /**
980          * Creates a virtual touchscreen.
981          *
982          * @param display the display that the events inputted through this device should target.
983          * @param inputDeviceName the name of this touchscreen device.
984          * @param vendorId the PCI vendor id.
985          * @param productId the product id, as defined by the vendor.
986          * @see #createVirtualTouchscreen(VirtualTouchscreenConfig config)
987          * @deprecated Use {@link #createVirtualTouchscreen(VirtualTouchscreenConfig config)}
988          * instead
989          */
990         @Deprecated
991         @NonNull
createVirtualTouchscreen(@onNull VirtualDisplay display, @NonNull String inputDeviceName, int vendorId, int productId)992         public VirtualTouchscreen createVirtualTouchscreen(@NonNull VirtualDisplay display,
993                 @NonNull String inputDeviceName, int vendorId, int productId) {
994             final Point size = new Point();
995             display.getDisplay().getSize(size);
996             VirtualTouchscreenConfig touchscreenConfig =
997                     new VirtualTouchscreenConfig.Builder(size.x, size.y)
998                             .setVendorId(vendorId)
999                             .setProductId(productId)
1000                             .setInputDeviceName(inputDeviceName)
1001                             .setAssociatedDisplayId(display.getDisplay().getDisplayId())
1002                             .build();
1003             return mVirtualDeviceInternal.createVirtualTouchscreen(touchscreenConfig);
1004         }
1005 
1006         /**
1007          * Creates a virtual touchpad in navigation mode.
1008          *
1009          * <p>A touchpad in navigation mode means that its events are interpreted as navigation
1010          * events (up, down, etc) instead of using them to update a cursor's absolute position. If
1011          * the events are not consumed they are converted to DPAD events and delivered to the target
1012          * again.
1013          *
1014          * @param config the configurations of the virtual navigation touchpad.
1015          * @see android.view.InputDevice#SOURCE_TOUCH_NAVIGATION
1016          */
1017         @NonNull
createVirtualNavigationTouchpad( @onNull VirtualNavigationTouchpadConfig config)1018         public VirtualNavigationTouchpad createVirtualNavigationTouchpad(
1019                 @NonNull VirtualNavigationTouchpadConfig config) {
1020             return mVirtualDeviceInternal.createVirtualNavigationTouchpad(config);
1021         }
1022 
1023         /**
1024          * Creates a virtual stylus.
1025          *
1026          * @param config the touchscreen configurations for the virtual stylus.
1027          */
1028         @NonNull
createVirtualStylus(@onNull VirtualStylusConfig config)1029         public VirtualStylus createVirtualStylus(@NonNull VirtualStylusConfig config) {
1030             return mVirtualDeviceInternal.createVirtualStylus(config);
1031         }
1032 
1033         /**
1034          * Creates a virtual rotary encoder.
1035          *
1036          * @param config the configuration for the virtual rotary encoder.
1037          * @see android.view.InputDevice#SOURCE_ROTARY_ENCODER
1038          */
1039         @NonNull
1040         @FlaggedApi(Flags.FLAG_VIRTUAL_ROTARY)
createVirtualRotaryEncoder( @onNull VirtualRotaryEncoderConfig config)1041         public VirtualRotaryEncoder createVirtualRotaryEncoder(
1042                 @NonNull VirtualRotaryEncoderConfig config) {
1043             if (!Flags.virtualRotary()) {
1044                 throw new UnsupportedOperationException("Virtual rotary support not enabled");
1045             }
1046             return mVirtualDeviceInternal.createVirtualRotaryEncoder(config);
1047         }
1048 
1049         /**
1050          * Creates a VirtualAudioDevice, capable of recording audio emanating from this device,
1051          * or injecting audio from another device.
1052          *
1053          * <p>Note: One {@link VirtualDevice} can only create one {@link VirtualAudioDevice}, so
1054          * calling this method multiple times will return the same instance. When
1055          * {@link VirtualDevice#close()} is called, the associated {@link VirtualAudioDevice} will
1056          * also be closed automatically.
1057          *
1058          * @param display The target virtual display to capture from and inject into.
1059          * @param executor The {@link Executor} object for the thread on which to execute
1060          *   the callback. If <code>null</code>, the {@link Executor} associated with the main
1061          *   {@link Looper} will be used.
1062          * @param callback Interface to be notified when playback or recording configuration of
1063          *   applications running on virtual display is changed.
1064          * @return A {@link VirtualAudioDevice} instance.
1065          */
1066         @NonNull
createVirtualAudioDevice( @onNull VirtualDisplay display, @Nullable Executor executor, @Nullable AudioConfigurationChangeCallback callback)1067         public VirtualAudioDevice createVirtualAudioDevice(
1068                 @NonNull VirtualDisplay display,
1069                 @Nullable Executor executor,
1070                 @Nullable AudioConfigurationChangeCallback callback) {
1071             Objects.requireNonNull(display, "display must not be null");
1072             return mVirtualDeviceInternal.createVirtualAudioDevice(display, executor, callback);
1073         }
1074 
1075         /**
1076          * Creates a new virtual camera with the given {@link VirtualCameraConfig}. A virtual device
1077          * can create a virtual camera only if it has
1078          * {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} as its
1079          * {@link VirtualDeviceParams#POLICY_TYPE_CAMERA}.
1080          *
1081          * @param config camera configuration.
1082          * @return newly created camera.
1083          * @throws UnsupportedOperationException if virtual camera isn't supported on this device.
1084          * @see VirtualDeviceParams#POLICY_TYPE_CAMERA
1085          */
1086         @NonNull
createVirtualCamera(@onNull VirtualCameraConfig config)1087         public VirtualCamera createVirtualCamera(@NonNull VirtualCameraConfig config) {
1088             return mVirtualDeviceInternal.createVirtualCamera(Objects.requireNonNull(config));
1089         }
1090 
1091         /**
1092          * Sets the visibility of the pointer icon for this VirtualDevice's associated displays.
1093          *
1094          * <p>Only applicable to trusted displays.</p>
1095          *
1096          * @param showPointerIcon True if the pointer should be shown; false otherwise. The default
1097          *   visibility is true.
1098          * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED
1099          */
setShowPointerIcon(boolean showPointerIcon)1100         public void setShowPointerIcon(boolean showPointerIcon) {
1101             mVirtualDeviceInternal.setShowPointerIcon(showPointerIcon);
1102         }
1103 
1104         /**
1105          * Specifies the IME behavior on the given display. By default, all displays created by
1106          * virtual devices have {@link WindowManager#DISPLAY_IME_POLICY_LOCAL}.
1107          *
1108          * @param displayId the ID of the display to change the IME policy for. It must be owned by
1109          *                  this virtual device.
1110          * @param policy the IME policy to use on that display
1111          * @throws SecurityException if the display is not owned by this device or is not
1112          *                           {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_TRUSTED trusted}
1113          */
setDisplayImePolicy(int displayId, @WindowManager.DisplayImePolicy int policy)1114         public void setDisplayImePolicy(int displayId, @WindowManager.DisplayImePolicy int policy) {
1115             mVirtualDeviceInternal.setDisplayImePolicy(displayId, policy);
1116         }
1117 
1118         /**
1119          * Adds an activity listener to listen for events such as top activity change or virtual
1120          * display task stack became empty.
1121          *
1122          * @param executor The executor where the listener is executed on.
1123          * @param listener The listener to add.
1124          * @see #removeActivityListener(ActivityListener)
1125          */
addActivityListener( @allbackExecutor @onNull Executor executor, @NonNull ActivityListener listener)1126         public void addActivityListener(
1127                 @CallbackExecutor @NonNull Executor executor, @NonNull ActivityListener listener) {
1128             mVirtualDeviceInternal.addActivityListener(executor, listener);
1129         }
1130 
1131         /**
1132          * Removes an activity listener previously added with {@link #addActivityListener}.
1133          *
1134          * @param listener The listener to remove.
1135          * @see #addActivityListener(Executor, ActivityListener)
1136          */
removeActivityListener(@onNull ActivityListener listener)1137         public void removeActivityListener(@NonNull ActivityListener listener) {
1138             mVirtualDeviceInternal.removeActivityListener(listener);
1139         }
1140 
1141         /**
1142          * Adds a sound effect listener.
1143          *
1144          * @param executor The executor where the listener is executed on.
1145          * @param soundEffectListener The listener to add.
1146          * @see #removeSoundEffectListener(SoundEffectListener)
1147          */
addSoundEffectListener(@allbackExecutor @onNull Executor executor, @NonNull SoundEffectListener soundEffectListener)1148         public void addSoundEffectListener(@CallbackExecutor @NonNull Executor executor,
1149                 @NonNull SoundEffectListener soundEffectListener) {
1150             mVirtualDeviceInternal.addSoundEffectListener(executor, soundEffectListener);
1151         }
1152 
1153         /**
1154          * Removes a sound effect listener previously added with {@link #addSoundEffectListener}.
1155          *
1156          * @param soundEffectListener The listener to remove.
1157          * @see #addSoundEffectListener(Executor, SoundEffectListener)
1158          */
removeSoundEffectListener(@onNull SoundEffectListener soundEffectListener)1159         public void removeSoundEffectListener(@NonNull SoundEffectListener soundEffectListener) {
1160             mVirtualDeviceInternal.removeSoundEffectListener(soundEffectListener);
1161         }
1162 
1163         /**
1164          * Registers an intent interceptor that will intercept an intent attempting to launch
1165          * when matching the provided IntentFilter and calls the callback with the intercepted
1166          * intent.
1167          *
1168          * @param interceptorFilter The filter to match intents intended for interception.
1169          * @param executor The executor where the interceptor is executed on.
1170          * @param interceptorCallback The callback called when an intent matching interceptorFilter
1171          * is intercepted.
1172          * @see #unregisterIntentInterceptor(IntentInterceptorCallback)
1173          */
registerIntentInterceptor( @onNull IntentFilter interceptorFilter, @CallbackExecutor @NonNull Executor executor, @NonNull IntentInterceptorCallback interceptorCallback)1174         public void registerIntentInterceptor(
1175                 @NonNull IntentFilter interceptorFilter,
1176                 @CallbackExecutor @NonNull Executor executor,
1177                 @NonNull IntentInterceptorCallback interceptorCallback) {
1178             mVirtualDeviceInternal.registerIntentInterceptor(
1179                     interceptorFilter, executor, interceptorCallback);
1180         }
1181 
1182         /**
1183          * Unregisters the intent interceptor previously registered with
1184          * {@link #registerIntentInterceptor}.
1185          */
unregisterIntentInterceptor( @onNull IntentInterceptorCallback interceptorCallback)1186         public void unregisterIntentInterceptor(
1187                     @NonNull IntentInterceptorCallback interceptorCallback) {
1188             mVirtualDeviceInternal.unregisterIntentInterceptor(interceptorCallback);
1189         }
1190     }
1191 
1192     /**
1193      * Listener for activity changes and other activity events on a virtual device.
1194      *
1195      * @hide
1196      */
1197     @SystemApi
1198     public interface ActivityListener {
1199 
1200         /**
1201          * Called when the top activity is changed.
1202          *
1203          * <p>Note: When there are no activities running on the virtual display, the
1204          * {@link #onDisplayEmpty(int)} will be called. If the value topActivity is cached, it
1205          * should be cleared when {@link #onDisplayEmpty(int)} is called.
1206          *
1207          * @param displayId The display ID on which the activity change happened.
1208          * @param topActivity The component name of the top activity.
1209          * @deprecated Use {@link #onTopActivityChanged(int, ComponentName, int)} instead
1210          */
onTopActivityChanged(int displayId, @NonNull ComponentName topActivity)1211         void onTopActivityChanged(int displayId, @NonNull ComponentName topActivity);
1212 
1213         /**
1214          * Called when the top activity is changed.
1215          *
1216          * <p>Note: When there are no activities running on the virtual display, the
1217          * {@link #onDisplayEmpty(int)} will be called. If the value topActivity is cached, it
1218          * should be cleared when {@link #onDisplayEmpty(int)} is called.
1219          *
1220          * @param displayId The display ID on which the activity change happened.
1221          * @param topActivity The component name of the top activity.
1222          * @param userId The user ID associated with the top activity.
1223          */
onTopActivityChanged(int displayId, @NonNull ComponentName topActivity, @UserIdInt int userId)1224         default void onTopActivityChanged(int displayId, @NonNull ComponentName topActivity,
1225                 @UserIdInt int userId) {}
1226 
1227         /**
1228          * Called when the display becomes empty (e.g. if the user hits back on the last
1229          * activity of the root task).
1230          *
1231          * @param displayId The display ID that became empty.
1232          */
onDisplayEmpty(int displayId)1233         void onDisplayEmpty(int displayId);
1234 
1235         /**
1236          * Called when an activity launch was blocked due to a policy violation.
1237          *
1238          * @param displayId The display ID on which the activity tried to launch.
1239          * @param componentName The component name of the blocked activity.
1240          * @param user The user associated with the blocked activity.
1241          * @param intentSender The original sender of the intent. May be {@code null} if the sender
1242          *   expects an activity result to be reported. In that case
1243          *   {@link android.app.Activity#RESULT_CANCELED} was already reported back because the
1244          *   launch was blocked. This {@link IntentSender} can be used to relaunch the blocked
1245          *   activity to a different display.
1246          *
1247          * @see VirtualDeviceParams#POLICY_TYPE_ACTIVITY
1248          * @see VirtualDevice#addActivityPolicyExemption(ActivityPolicyExemption)
1249          */
1250         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName, @NonNull UserHandle user, @Nullable IntentSender intentSender)1251         default void onActivityLaunchBlocked(int displayId, @NonNull ComponentName componentName,
1252                 @NonNull UserHandle user, @Nullable IntentSender intentSender) {}
1253 
1254         /**
1255          * Called when a window with a secure surface is shown on the device.
1256          *
1257          * <p>Note that this is called only when the window is associated with an activity.</p>
1258          *
1259          * @param displayId The display ID on which the window was shown.
1260          * @param componentName The component name of the activity that showed the window.
1261          * @param user The user associated with the activity.
1262          *
1263          * @see Display#FLAG_SECURE
1264          * @see WindowManager.LayoutParams#FLAG_SECURE
1265          */
1266         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
onSecureWindowShown(int displayId, @NonNull ComponentName componentName, @NonNull UserHandle user)1267         default void onSecureWindowShown(int displayId, @NonNull ComponentName componentName,
1268                 @NonNull UserHandle user) {}
1269 
1270         /**
1271          * Called when there is no longer any window with a secure surface shown on the device.
1272          *
1273          * <p>This is only called once there are no more secure windows shown on the device. If
1274          * there are multiple secure windows shown on the device, this callback will be called only
1275          * once all of them are hidden.</p>
1276          *
1277          * @param displayId The display ID on which the window was shown before.
1278          *
1279          * @see Display#FLAG_SECURE
1280          * @see WindowManager.LayoutParams#FLAG_SECURE
1281          */
1282         @FlaggedApi(Flags.FLAG_ACTIVITY_CONTROL_API)
onSecureWindowHidden(int displayId)1283         default void onSecureWindowHidden(int displayId) {}
1284     }
1285 
1286     /**
1287      * Interceptor interface to be called when an intent matches the IntentFilter passed into {@link
1288      * VirtualDevice#registerIntentInterceptor}. When the interceptor is called after matching the
1289      * IntentFilter, the intended activity launch will be aborted and alternatively replaced by
1290      * the interceptor's receiver.
1291      *
1292      * @hide
1293      */
1294     @SystemApi
1295     public interface IntentInterceptorCallback {
1296 
1297         /**
1298          * Called when an intent that matches the IntentFilter registered in {@link
1299          * VirtualDevice#registerIntentInterceptor} is intercepted for the virtual device to
1300          * handle.
1301          *
1302          * @param intent The intent that has been intercepted by the interceptor.
1303          */
onIntentIntercepted(@onNull Intent intent)1304         void onIntentIntercepted(@NonNull Intent intent);
1305     }
1306 
1307     /**
1308      * Listener for system sound effect playback on virtual device.
1309      *
1310      * @hide
1311      */
1312     @SystemApi
1313     public interface SoundEffectListener {
1314 
1315         /**
1316          * Called when there's a system sound effect to be played on virtual device.
1317          *
1318          * @param effectType - system sound effect type
1319          * @see android.media.AudioManager.SystemSoundEffect
1320          */
onPlaySoundEffect(@udioManager.SystemSoundEffect int effectType)1321         void onPlaySoundEffect(@AudioManager.SystemSoundEffect int effectType);
1322     }
1323 
1324     /**
1325      * Listener for changes in the available virtual devices.
1326      *
1327      * @see #registerVirtualDeviceListener
1328      */
1329     public interface VirtualDeviceListener {
1330         /**
1331          * Called whenever a new virtual device has been added to the system.
1332          * Use {@link VirtualDeviceManager#getVirtualDevice(int)} to get more information about
1333          * the device.
1334          *
1335          * @param deviceId The id of the virtual device that was added.
1336          */
onVirtualDeviceCreated(int deviceId)1337         default void onVirtualDeviceCreated(int deviceId) {}
1338 
1339         /**
1340          * Called whenever a virtual device has been removed from the system.
1341          *
1342          * @param deviceId The id of the virtual device that was removed.
1343          */
onVirtualDeviceClosed(int deviceId)1344         default void onVirtualDeviceClosed(int deviceId) {}
1345     }
1346 
1347     /**
1348      * A wrapper for {@link VirtualDeviceListener} that executes callbacks on the given executor.
1349      */
1350     private static class VirtualDeviceListenerDelegate extends IVirtualDeviceListener.Stub {
1351         private final VirtualDeviceListener mListener;
1352         private final Executor mExecutor;
1353 
VirtualDeviceListenerDelegate(Executor executor, VirtualDeviceListener listener)1354         private VirtualDeviceListenerDelegate(Executor executor, VirtualDeviceListener listener) {
1355             mExecutor = executor;
1356             mListener = listener;
1357         }
1358 
1359         @Override
onVirtualDeviceCreated(int deviceId)1360         public void onVirtualDeviceCreated(int deviceId) {
1361             final long token = Binder.clearCallingIdentity();
1362             try {
1363                 mExecutor.execute(() -> mListener.onVirtualDeviceCreated(deviceId));
1364             } finally {
1365                 Binder.restoreCallingIdentity(token);
1366             }
1367         }
1368 
1369         @Override
onVirtualDeviceClosed(int deviceId)1370         public void onVirtualDeviceClosed(int deviceId) {
1371             final long token = Binder.clearCallingIdentity();
1372             try {
1373                 mExecutor.execute(() -> mListener.onVirtualDeviceClosed(deviceId));
1374             } finally {
1375                 Binder.restoreCallingIdentity(token);
1376             }
1377         }
1378     }
1379 }
1380