Loading core/java/android/companion/virtual/IVirtualDevice.aidl +81 −27 Original line number Diff line number Diff line Loading @@ -39,21 +39,22 @@ import android.hardware.input.VirtualNavigationTouchpadConfig; import android.os.ResultReceiver; /** * Interface for a virtual device. * Interface for a virtual device for communication between the system server and the process of * the owner of the virtual device. * * @hide */ interface IVirtualDevice { /** * Returns the association ID for this virtual device. * Returns the CDM association ID of this virtual device. * * @see AssociationInfo#getId() */ int getAssociationId(); /** * Returns the unique device ID for this virtual device. * Returns the unique ID of this virtual device. */ int getDeviceId(); Loading @@ -64,55 +65,99 @@ interface IVirtualDevice { void close(); /** * Notifies of an audio session being started. * Notifies that an audio session being started. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void onAudioSessionStarting( int displayId, IAudioRoutingCallback routingCallback, void onAudioSessionStarting(int displayId, IAudioRoutingCallback routingCallback, IAudioConfigChangedCallback configChangedCallback); /** * Notifies that an audio session has ended. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void onAudioSessionEnded(); /** * Creates a new dpad and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualDpad( in VirtualDpadConfig config, IBinder token); void createVirtualDpad(in VirtualDpadConfig config, IBinder token); /** * Creates a new keyboard and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualKeyboard( in VirtualKeyboardConfig config, IBinder token); void createVirtualKeyboard(in VirtualKeyboardConfig config, IBinder token); /** * Creates a new mouse and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualMouse( in VirtualMouseConfig config, IBinder token); void createVirtualMouse(in VirtualMouseConfig config, IBinder token); /** * Creates a new touchscreen and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualTouchscreen( in VirtualTouchscreenConfig config, IBinder token); void createVirtualTouchscreen(in VirtualTouchscreenConfig config, IBinder token); /** * Creates a new navigation touchpad and registers it with the input framework with the given * token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualNavigationTouchpad( in VirtualNavigationTouchpadConfig config, IBinder token); void createVirtualNavigationTouchpad(in VirtualNavigationTouchpadConfig config, IBinder token); /** * Removes the input device corresponding to the given token from the framework. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterInputDevice(IBinder token); /** * Returns the ID of the device corresponding to the given token, as registered with the input * framework. */ int getInputDeviceId(IBinder token); /** * Injects a key event to the virtual dpad corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event); /** * Injects a key event to the virtual keyboard corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event); /** * Injects a button event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event); /** * Injects a relative event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendRelativeEvent(IBinder token, in VirtualMouseRelativeEvent event); /** * Injects a scroll event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendScrollEvent(IBinder token, in VirtualMouseScrollEvent event); /** * Injects a touch event to the virtual touch input device corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event); /** * Returns all virtual sensors for this device. * Returns all virtual sensors created for this device. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") List<VirtualSensor> getVirtualSensorList(); Loading @@ -126,8 +171,13 @@ interface IVirtualDevice { /** * Launches a pending intent on the given display that is owned by this virtual device. */ void launchPendingIntent( int displayId, in PendingIntent pendingIntent, in ResultReceiver resultReceiver); void launchPendingIntent(int displayId, in PendingIntent pendingIntent, in ResultReceiver resultReceiver); /** * Returns the current cursor position of the mouse corresponding to the given token, in x and y * coordinates. */ PointF getCursorPosition(IBinder token); /** Sets whether to show or hide the cursor while this virtual device is active. */ Loading @@ -140,8 +190,12 @@ interface IVirtualDevice { * intent. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void registerIntentInterceptor( in IVirtualDeviceIntentInterceptor intentInterceptor, in IntentFilter filter); void registerIntentInterceptor(in IVirtualDeviceIntentInterceptor intentInterceptor, in IntentFilter filter); /** * Unregisters a previously registered intent interceptor. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterIntentInterceptor(in IVirtualDeviceIntentInterceptor intentInterceptor); } core/java/android/companion/virtual/VirtualDevice.java +5 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,11 @@ import java.util.Objects; /** * Details of a particular virtual device. * * <p>Read-only device representation exposing the properties of an existing virtual device. * * <p class="note">Not to be confused with {@link VirtualDeviceManager.VirtualDevice}, which is used * by the virtual device creator and allows them to manage the device. */ public final class VirtualDevice implements Parcelable { Loading core/java/android/companion/virtual/VirtualDeviceManager.java +82 −64 Original line number Diff line number Diff line Loading @@ -68,7 +68,13 @@ import java.util.concurrent.Executor; import java.util.function.IntConsumer; /** * System level service for managing virtual devices. * System level service for creation and management of virtual devices. * * <p>VirtualDeviceManager enables interactive sharing of capabilities between the host Android * device and a remote device. * * <p class="note">Not to be confused with the Android Studio's Virtual Device Manager, which allows * for device emulation. */ @SystemService(Context.VIRTUAL_DEVICE_SERVICE) public final class VirtualDeviceManager { Loading Loading @@ -174,6 +180,9 @@ public final class VirtualDeviceManager { /** * Returns the details of all available virtual devices. * * <p>The returned objects are read-only representations that expose the properties of all * existing virtual devices. */ @NonNull public List<android.companion.virtual.VirtualDevice> getVirtualDevices() { Loading Loading @@ -252,11 +261,12 @@ public final class VirtualDeviceManager { * * @param deviceId - id of the virtual audio device * @return Device specific session id to be used for audio playback (see * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. * {@link AudioManager#generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. Otherwise * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned. * * @hide */ public int getAudioPlaybackSessionId(int deviceId) { Loading @@ -275,11 +285,12 @@ public final class VirtualDeviceManager { * * @param deviceId - id of the virtual audio device * @return Device specific session id to be used for audio recording (see * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. * {@link AudioManager#generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. Otherwise * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned. * * @hide */ public int getAudioRecordingSessionId(int deviceId) { Loading @@ -296,10 +307,11 @@ public final class VirtualDeviceManager { /** * Requests sound effect to be played on virtual device. * * @see android.media.AudioManager#playSoundEffect(int) * @see AudioManager#playSoundEffect(int) * * @param deviceId - id of the virtual audio device * @param effectType the type of sound effect * * @hide */ public void playSoundEffect(int deviceId, @AudioManager.SystemSoundEffect int effectType) { Loading @@ -315,11 +327,18 @@ public final class VirtualDeviceManager { } /** * A virtual device has its own virtual display, audio output, microphone, sensors, etc. The * creator of a virtual device can take the output from the virtual display and stream it over * to another device, and inject input events that are received from the remote device. * A representation of a virtual device. * * TODO(b/204081582): Consider using a builder pattern for the input APIs. * <p>A virtual device can have its own virtual displays, audio input/output, sensors, etc. * The creator of a virtual device can take the output from the virtual display and stream it * over to another device, and inject input and sensor events that are received from the remote * device. * * <p>This object is only used by the virtual device creator and allows them to manage the * device's behavior, peripherals, and the user interaction with that device. * * <p class="note">Not to be confused with {@link android.companion.virtual.VirtualDevice}, * which is a read-only representation exposing the properties of an existing virtual device. * * @hide */ Loading @@ -346,8 +365,10 @@ public final class VirtualDeviceManager { } /** * @return A new Context bound to this device. This is a convenience method equivalent to * calling {@link Context#createDeviceContext(int)} with the device id of this device. * Returns a new context bound to this device. * * <p>This is a convenience method equivalent to calling * {@link Context#createDeviceContext(int)} with the id of this device. */ public @NonNull Context createContext() { return mVirtualDeviceInternal.createContext(); Loading Loading @@ -400,17 +421,16 @@ public final class VirtualDeviceManager { * @param height The height of the virtual display in pixels, must be greater than 0. * @param densityDpi The density of the virtual display in dpi, must be greater than 0. * @param surface The surface to which the content of the virtual display should * be rendered, or null if there is none initially. The surface can also be set later using * {@link VirtualDisplay#setSurface(Surface)}. * be rendered, or null if there is none initially. The surface can also be set later * using {@link VirtualDisplay#setSurface(Surface)}. * @param flags A combination of virtual display flags accepted by * {@link DisplayManager#createVirtualDisplay}. In addition, the following flags are * automatically set for all virtual devices: * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC VIRTUAL_DISPLAY_FLAG_PUBLIC} and * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY * VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC} and * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. * @param executor The executor on which {@code callback} will be invoked. This is ignored * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must * not be null. * if {@code callback} is {@code null}. If {@code callback} is specified, this executor * must not be null. * @param callback Callback to call when the state of the {@link VirtualDisplay} changes * @return The newly created virtual display, or {@code null} if the application could * not create the virtual display. Loading Loading @@ -450,8 +470,8 @@ public final class VirtualDeviceManager { * * @param config The configuration of the display. * @param executor The executor on which {@code callback} will be invoked. This is ignored * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must * not be null. * if {@code callback} is {@code null}. If {@code callback} is specified, this executor * must not be null. * @param callback Callback to call when the state of the {@link VirtualDisplay} changes * @return The newly created virtual display, or {@code null} if the application could * not create the virtual display. Loading @@ -478,7 +498,7 @@ public final class VirtualDeviceManager { /** * Creates a virtual dpad. * * @param config the configurations of the virtual Dpad. * @param config the configurations of the virtual dpad. */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull Loading @@ -500,11 +520,10 @@ public final class VirtualDeviceManager { /** * Creates a virtual keyboard. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this keyboard device. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualKeyboard(VirtualKeyboardConfig config) * @deprecated Use {@link #createVirtualKeyboard(VirtualKeyboardConfig config)} instead */ Loading Loading @@ -537,14 +556,12 @@ public final class VirtualDeviceManager { /** * Creates a virtual mouse. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this mouse. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualMouse(VirtualMouseConfig config) * @deprecated Use {@link #createVirtualMouse(VirtualMouseConfig config)} instead * * */ @Deprecated @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) Loading Loading @@ -576,11 +593,10 @@ public final class VirtualDeviceManager { /** * Creates a virtual touchscreen. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this touchscreen device. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualTouchscreen(VirtualTouchscreenConfig config) * @deprecated Use {@link #createVirtualTouchscreen(VirtualTouchscreenConfig config)} * instead Loading @@ -605,11 +621,13 @@ public final class VirtualDeviceManager { /** * Creates a virtual touchpad in navigation mode. * * A touchpad in navigation mode means that its events are interpreted as navigation events * (up, down, etc) instead of using them to update a cursor's absolute position. If the * events are not consumed they are converted to DPAD events. * <p>A touchpad in navigation mode means that its events are interpreted as navigation * events (up, down, etc) instead of using them to update a cursor's absolute position. If * the events are not consumed they are converted to DPAD events and delivered to the target * again. * * @param config the configurations of the virtual navigation touchpad. * @see android.view.InputDevice#SOURCE_TOUCH_NAVIGATION */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull Loading @@ -629,8 +647,8 @@ public final class VirtualDeviceManager { * * @param display The target virtual display to capture from and inject into. * @param executor The {@link Executor} object for the thread on which to execute * the callback. If <code>null</code>, the {@link Executor} associated with * the main {@link Looper} will be used. * the callback. If <code>null</code>, the {@link Executor} associated with the main * {@link Looper} will be used. * @param callback Interface to be notified when playback or recording configuration of * applications running on virtual display is changed. * @return A {@link VirtualAudioDevice} instance. Loading Loading @@ -670,8 +688,7 @@ public final class VirtualDeviceManager { } /** * Removes an activity listener previously added with * {@link #addActivityListener}. * Removes an activity listener previously added with {@link #addActivityListener}. * * @param listener The listener to remove. * @see #addActivityListener(Executor, ActivityListener) Loading @@ -693,10 +710,10 @@ public final class VirtualDeviceManager { } /** * Removes a sound effect listener previously added with {@link #addActivityListener}. * Removes a sound effect listener previously added with {@link #addSoundEffectListener}. * * @param soundEffectListener The listener to remove. * @see #addActivityListener(Executor, ActivityListener) * @see #addSoundEffectListener(Executor, SoundEffectListener) */ public void removeSoundEffectListener(@NonNull SoundEffectListener soundEffectListener) { mVirtualDeviceInternal.removeSoundEffectListener(soundEffectListener); Loading @@ -723,7 +740,7 @@ public final class VirtualDeviceManager { } /** * Unregisters the intent interceptorCallback previously registered with * Unregisters the intent interceptor previously registered with * {@link #registerIntentInterceptor}. */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) Loading Loading @@ -800,6 +817,7 @@ public final class VirtualDeviceManager { /** * Listener for system sound effect playback on virtual device. * * @hide */ @SystemApi Loading @@ -808,8 +826,8 @@ public final class VirtualDeviceManager { /** * Called when there's a system sound effect to be played on virtual device. * * @param effectType - system sound effect type, see * {@code android.media.AudioManager.SystemSoundEffect} * @param effectType - system sound effect type * @see android.media.AudioManager.SystemSoundEffect */ void onPlaySoundEffect(@AudioManager.SystemSoundEffect int effectType); } Loading core/java/android/companion/virtual/VirtualDeviceParams.java +8 −7 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.companion.virtual.sensor.VirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorDirectChannelCallback; import android.content.ComponentName; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.os.SharedMemory; Loading Loading @@ -847,11 +848,11 @@ public final class VirtualDeviceParams implements Parcelable { * <p>Requires {@link #DEVICE_POLICY_CUSTOM} to be set for {@link #POLICY_TYPE_AUDIO}, * otherwise {@link #build()} method will throw {@link IllegalArgumentException} if * the playback session id is set to value other than * {@link android.media.AudioManager.AUDIO_SESSION_ID_GENERATE}. * {@link android.media.AudioManager#AUDIO_SESSION_ID_GENERATE}. * * @param playbackSessionId requested device-specific audio session id for playback * @see android.media.AudioManager.generateAudioSessionId() * @see android.media.AudioTrack.Builder.setContext(Context) * @see android.media.AudioManager#generateAudioSessionId() * @see android.media.AudioTrack.Builder#setContext(Context) */ @NonNull public Builder setAudioPlaybackSessionId(int playbackSessionId) { Loading @@ -871,11 +872,11 @@ public final class VirtualDeviceParams implements Parcelable { * <p>Requires {@link #DEVICE_POLICY_CUSTOM} to be set for {@link #POLICY_TYPE_AUDIO}, * otherwise {@link #build()} method will throw {@link IllegalArgumentException} if * the recording session id is set to value other than * {@link android.media.AudioManager.AUDIO_SESSION_ID_GENERATE}. * {@link android.media.AudioManager#AUDIO_SESSION_ID_GENERATE}. * * @param recordingSessionId requested device-specific audio session id for playback * @see android.media.AudioManager.generateAudioSessionId() * @see android.media.AudioRecord.Builder.setContext(Context) * @see android.media.AudioManager#generateAudioSessionId() * @see android.media.AudioRecord.Builder#setContext(Context) */ @NonNull public Builder setAudioRecordingSessionId(int recordingSessionId) { Loading core/java/android/companion/virtual/audio/AudioCapture.java +5 −5 Original line number Diff line number Diff line Loading @@ -56,12 +56,12 @@ public final class AudioCapture { /** * Sets the {@link AudioRecord} to handle audio capturing. * Callers may call this multiple times with different audio records to change * the underlying {@link AudioRecord} without stopping and re-starting recording. * * @param audioRecord The underlying {@link AudioRecord} to use for capture, * or null if no audio (i.e. silence) should be captured while still keeping the * record in a recording state. * <p>Callers may call this multiple times with different audio records to change the underlying * {@link AudioRecord} without stopping and re-starting recording. * * @param audioRecord The underlying {@link AudioRecord} to use for capture, or null if no audio * (i.e. silence) should be captured while still keeping the record in a recording state. */ void setAudioRecord(@Nullable AudioRecord audioRecord) { Log.d(TAG, "set AudioRecord with " + audioRecord); Loading Loading
core/java/android/companion/virtual/IVirtualDevice.aidl +81 −27 Original line number Diff line number Diff line Loading @@ -39,21 +39,22 @@ import android.hardware.input.VirtualNavigationTouchpadConfig; import android.os.ResultReceiver; /** * Interface for a virtual device. * Interface for a virtual device for communication between the system server and the process of * the owner of the virtual device. * * @hide */ interface IVirtualDevice { /** * Returns the association ID for this virtual device. * Returns the CDM association ID of this virtual device. * * @see AssociationInfo#getId() */ int getAssociationId(); /** * Returns the unique device ID for this virtual device. * Returns the unique ID of this virtual device. */ int getDeviceId(); Loading @@ -64,55 +65,99 @@ interface IVirtualDevice { void close(); /** * Notifies of an audio session being started. * Notifies that an audio session being started. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void onAudioSessionStarting( int displayId, IAudioRoutingCallback routingCallback, void onAudioSessionStarting(int displayId, IAudioRoutingCallback routingCallback, IAudioConfigChangedCallback configChangedCallback); /** * Notifies that an audio session has ended. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void onAudioSessionEnded(); /** * Creates a new dpad and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualDpad( in VirtualDpadConfig config, IBinder token); void createVirtualDpad(in VirtualDpadConfig config, IBinder token); /** * Creates a new keyboard and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualKeyboard( in VirtualKeyboardConfig config, IBinder token); void createVirtualKeyboard(in VirtualKeyboardConfig config, IBinder token); /** * Creates a new mouse and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualMouse( in VirtualMouseConfig config, IBinder token); void createVirtualMouse(in VirtualMouseConfig config, IBinder token); /** * Creates a new touchscreen and registers it with the input framework with the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualTouchscreen( in VirtualTouchscreenConfig config, IBinder token); void createVirtualTouchscreen(in VirtualTouchscreenConfig config, IBinder token); /** * Creates a new navigation touchpad and registers it with the input framework with the given * token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualNavigationTouchpad( in VirtualNavigationTouchpadConfig config, IBinder token); void createVirtualNavigationTouchpad(in VirtualNavigationTouchpadConfig config, IBinder token); /** * Removes the input device corresponding to the given token from the framework. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterInputDevice(IBinder token); /** * Returns the ID of the device corresponding to the given token, as registered with the input * framework. */ int getInputDeviceId(IBinder token); /** * Injects a key event to the virtual dpad corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendDpadKeyEvent(IBinder token, in VirtualKeyEvent event); /** * Injects a key event to the virtual keyboard corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendKeyEvent(IBinder token, in VirtualKeyEvent event); /** * Injects a button event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendButtonEvent(IBinder token, in VirtualMouseButtonEvent event); /** * Injects a relative event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendRelativeEvent(IBinder token, in VirtualMouseRelativeEvent event); /** * Injects a scroll event to the virtual mouse corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendScrollEvent(IBinder token, in VirtualMouseScrollEvent event); /** * Injects a touch event to the virtual touch input device corresponding to the given token. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event); /** * Returns all virtual sensors for this device. * Returns all virtual sensors created for this device. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") List<VirtualSensor> getVirtualSensorList(); Loading @@ -126,8 +171,13 @@ interface IVirtualDevice { /** * Launches a pending intent on the given display that is owned by this virtual device. */ void launchPendingIntent( int displayId, in PendingIntent pendingIntent, in ResultReceiver resultReceiver); void launchPendingIntent(int displayId, in PendingIntent pendingIntent, in ResultReceiver resultReceiver); /** * Returns the current cursor position of the mouse corresponding to the given token, in x and y * coordinates. */ PointF getCursorPosition(IBinder token); /** Sets whether to show or hide the cursor while this virtual device is active. */ Loading @@ -140,8 +190,12 @@ interface IVirtualDevice { * intent. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void registerIntentInterceptor( in IVirtualDeviceIntentInterceptor intentInterceptor, in IntentFilter filter); void registerIntentInterceptor(in IVirtualDeviceIntentInterceptor intentInterceptor, in IntentFilter filter); /** * Unregisters a previously registered intent interceptor. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterIntentInterceptor(in IVirtualDeviceIntentInterceptor intentInterceptor); }
core/java/android/companion/virtual/VirtualDevice.java +5 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,11 @@ import java.util.Objects; /** * Details of a particular virtual device. * * <p>Read-only device representation exposing the properties of an existing virtual device. * * <p class="note">Not to be confused with {@link VirtualDeviceManager.VirtualDevice}, which is used * by the virtual device creator and allows them to manage the device. */ public final class VirtualDevice implements Parcelable { Loading
core/java/android/companion/virtual/VirtualDeviceManager.java +82 −64 Original line number Diff line number Diff line Loading @@ -68,7 +68,13 @@ import java.util.concurrent.Executor; import java.util.function.IntConsumer; /** * System level service for managing virtual devices. * System level service for creation and management of virtual devices. * * <p>VirtualDeviceManager enables interactive sharing of capabilities between the host Android * device and a remote device. * * <p class="note">Not to be confused with the Android Studio's Virtual Device Manager, which allows * for device emulation. */ @SystemService(Context.VIRTUAL_DEVICE_SERVICE) public final class VirtualDeviceManager { Loading Loading @@ -174,6 +180,9 @@ public final class VirtualDeviceManager { /** * Returns the details of all available virtual devices. * * <p>The returned objects are read-only representations that expose the properties of all * existing virtual devices. */ @NonNull public List<android.companion.virtual.VirtualDevice> getVirtualDevices() { Loading Loading @@ -252,11 +261,12 @@ public final class VirtualDeviceManager { * * @param deviceId - id of the virtual audio device * @return Device specific session id to be used for audio playback (see * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. * {@link AudioManager#generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. Otherwise * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned. * * @hide */ public int getAudioPlaybackSessionId(int deviceId) { Loading @@ -275,11 +285,12 @@ public final class VirtualDeviceManager { * * @param deviceId - id of the virtual audio device * @return Device specific session id to be used for audio recording (see * {@link android.media.AudioManager.generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams.POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams.DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. * Otherwise {@link AUDIO_SESSION_ID_GENERATE} constant is returned. * {@link AudioManager#generateAudioSessionId}) if virtual device has * {@link VirtualDeviceParams#POLICY_TYPE_AUDIO} set to * {@link VirtualDeviceParams#DEVICE_POLICY_CUSTOM} and Virtual Audio Device * is configured in context-aware mode. Otherwise * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} constant is returned. * * @hide */ public int getAudioRecordingSessionId(int deviceId) { Loading @@ -296,10 +307,11 @@ public final class VirtualDeviceManager { /** * Requests sound effect to be played on virtual device. * * @see android.media.AudioManager#playSoundEffect(int) * @see AudioManager#playSoundEffect(int) * * @param deviceId - id of the virtual audio device * @param effectType the type of sound effect * * @hide */ public void playSoundEffect(int deviceId, @AudioManager.SystemSoundEffect int effectType) { Loading @@ -315,11 +327,18 @@ public final class VirtualDeviceManager { } /** * A virtual device has its own virtual display, audio output, microphone, sensors, etc. The * creator of a virtual device can take the output from the virtual display and stream it over * to another device, and inject input events that are received from the remote device. * A representation of a virtual device. * * TODO(b/204081582): Consider using a builder pattern for the input APIs. * <p>A virtual device can have its own virtual displays, audio input/output, sensors, etc. * The creator of a virtual device can take the output from the virtual display and stream it * over to another device, and inject input and sensor events that are received from the remote * device. * * <p>This object is only used by the virtual device creator and allows them to manage the * device's behavior, peripherals, and the user interaction with that device. * * <p class="note">Not to be confused with {@link android.companion.virtual.VirtualDevice}, * which is a read-only representation exposing the properties of an existing virtual device. * * @hide */ Loading @@ -346,8 +365,10 @@ public final class VirtualDeviceManager { } /** * @return A new Context bound to this device. This is a convenience method equivalent to * calling {@link Context#createDeviceContext(int)} with the device id of this device. * Returns a new context bound to this device. * * <p>This is a convenience method equivalent to calling * {@link Context#createDeviceContext(int)} with the id of this device. */ public @NonNull Context createContext() { return mVirtualDeviceInternal.createContext(); Loading Loading @@ -400,17 +421,16 @@ public final class VirtualDeviceManager { * @param height The height of the virtual display in pixels, must be greater than 0. * @param densityDpi The density of the virtual display in dpi, must be greater than 0. * @param surface The surface to which the content of the virtual display should * be rendered, or null if there is none initially. The surface can also be set later using * {@link VirtualDisplay#setSurface(Surface)}. * be rendered, or null if there is none initially. The surface can also be set later * using {@link VirtualDisplay#setSurface(Surface)}. * @param flags A combination of virtual display flags accepted by * {@link DisplayManager#createVirtualDisplay}. In addition, the following flags are * automatically set for all virtual devices: * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC VIRTUAL_DISPLAY_FLAG_PUBLIC} and * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY * VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_PUBLIC} and * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}. * @param executor The executor on which {@code callback} will be invoked. This is ignored * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must * not be null. * if {@code callback} is {@code null}. If {@code callback} is specified, this executor * must not be null. * @param callback Callback to call when the state of the {@link VirtualDisplay} changes * @return The newly created virtual display, or {@code null} if the application could * not create the virtual display. Loading Loading @@ -450,8 +470,8 @@ public final class VirtualDeviceManager { * * @param config The configuration of the display. * @param executor The executor on which {@code callback} will be invoked. This is ignored * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must * not be null. * if {@code callback} is {@code null}. If {@code callback} is specified, this executor * must not be null. * @param callback Callback to call when the state of the {@link VirtualDisplay} changes * @return The newly created virtual display, or {@code null} if the application could * not create the virtual display. Loading @@ -478,7 +498,7 @@ public final class VirtualDeviceManager { /** * Creates a virtual dpad. * * @param config the configurations of the virtual Dpad. * @param config the configurations of the virtual dpad. */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull Loading @@ -500,11 +520,10 @@ public final class VirtualDeviceManager { /** * Creates a virtual keyboard. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this keyboard device. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualKeyboard(VirtualKeyboardConfig config) * @deprecated Use {@link #createVirtualKeyboard(VirtualKeyboardConfig config)} instead */ Loading Loading @@ -537,14 +556,12 @@ public final class VirtualDeviceManager { /** * Creates a virtual mouse. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this mouse. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualMouse(VirtualMouseConfig config) * @deprecated Use {@link #createVirtualMouse(VirtualMouseConfig config)} instead * * */ @Deprecated @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) Loading Loading @@ -576,11 +593,10 @@ public final class VirtualDeviceManager { /** * Creates a virtual touchscreen. * * @param display the display that the events inputted through this device should * target * @param inputDeviceName the name to call this input device * @param vendorId the PCI vendor id * @param productId the product id, as defined by the vendor * @param display the display that the events inputted through this device should target. * @param inputDeviceName the name of this touchscreen device. * @param vendorId the PCI vendor id. * @param productId the product id, as defined by the vendor. * @see #createVirtualTouchscreen(VirtualTouchscreenConfig config) * @deprecated Use {@link #createVirtualTouchscreen(VirtualTouchscreenConfig config)} * instead Loading @@ -605,11 +621,13 @@ public final class VirtualDeviceManager { /** * Creates a virtual touchpad in navigation mode. * * A touchpad in navigation mode means that its events are interpreted as navigation events * (up, down, etc) instead of using them to update a cursor's absolute position. If the * events are not consumed they are converted to DPAD events. * <p>A touchpad in navigation mode means that its events are interpreted as navigation * events (up, down, etc) instead of using them to update a cursor's absolute position. If * the events are not consumed they are converted to DPAD events and delivered to the target * again. * * @param config the configurations of the virtual navigation touchpad. * @see android.view.InputDevice#SOURCE_TOUCH_NAVIGATION */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull Loading @@ -629,8 +647,8 @@ public final class VirtualDeviceManager { * * @param display The target virtual display to capture from and inject into. * @param executor The {@link Executor} object for the thread on which to execute * the callback. If <code>null</code>, the {@link Executor} associated with * the main {@link Looper} will be used. * the callback. If <code>null</code>, the {@link Executor} associated with the main * {@link Looper} will be used. * @param callback Interface to be notified when playback or recording configuration of * applications running on virtual display is changed. * @return A {@link VirtualAudioDevice} instance. Loading Loading @@ -670,8 +688,7 @@ public final class VirtualDeviceManager { } /** * Removes an activity listener previously added with * {@link #addActivityListener}. * Removes an activity listener previously added with {@link #addActivityListener}. * * @param listener The listener to remove. * @see #addActivityListener(Executor, ActivityListener) Loading @@ -693,10 +710,10 @@ public final class VirtualDeviceManager { } /** * Removes a sound effect listener previously added with {@link #addActivityListener}. * Removes a sound effect listener previously added with {@link #addSoundEffectListener}. * * @param soundEffectListener The listener to remove. * @see #addActivityListener(Executor, ActivityListener) * @see #addSoundEffectListener(Executor, SoundEffectListener) */ public void removeSoundEffectListener(@NonNull SoundEffectListener soundEffectListener) { mVirtualDeviceInternal.removeSoundEffectListener(soundEffectListener); Loading @@ -723,7 +740,7 @@ public final class VirtualDeviceManager { } /** * Unregisters the intent interceptorCallback previously registered with * Unregisters the intent interceptor previously registered with * {@link #registerIntentInterceptor}. */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) Loading Loading @@ -800,6 +817,7 @@ public final class VirtualDeviceManager { /** * Listener for system sound effect playback on virtual device. * * @hide */ @SystemApi Loading @@ -808,8 +826,8 @@ public final class VirtualDeviceManager { /** * Called when there's a system sound effect to be played on virtual device. * * @param effectType - system sound effect type, see * {@code android.media.AudioManager.SystemSoundEffect} * @param effectType - system sound effect type * @see android.media.AudioManager.SystemSoundEffect */ void onPlaySoundEffect(@AudioManager.SystemSoundEffect int effectType); } Loading
core/java/android/companion/virtual/VirtualDeviceParams.java +8 −7 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.companion.virtual.sensor.VirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorDirectChannelCallback; import android.content.ComponentName; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; import android.os.SharedMemory; Loading Loading @@ -847,11 +848,11 @@ public final class VirtualDeviceParams implements Parcelable { * <p>Requires {@link #DEVICE_POLICY_CUSTOM} to be set for {@link #POLICY_TYPE_AUDIO}, * otherwise {@link #build()} method will throw {@link IllegalArgumentException} if * the playback session id is set to value other than * {@link android.media.AudioManager.AUDIO_SESSION_ID_GENERATE}. * {@link android.media.AudioManager#AUDIO_SESSION_ID_GENERATE}. * * @param playbackSessionId requested device-specific audio session id for playback * @see android.media.AudioManager.generateAudioSessionId() * @see android.media.AudioTrack.Builder.setContext(Context) * @see android.media.AudioManager#generateAudioSessionId() * @see android.media.AudioTrack.Builder#setContext(Context) */ @NonNull public Builder setAudioPlaybackSessionId(int playbackSessionId) { Loading @@ -871,11 +872,11 @@ public final class VirtualDeviceParams implements Parcelable { * <p>Requires {@link #DEVICE_POLICY_CUSTOM} to be set for {@link #POLICY_TYPE_AUDIO}, * otherwise {@link #build()} method will throw {@link IllegalArgumentException} if * the recording session id is set to value other than * {@link android.media.AudioManager.AUDIO_SESSION_ID_GENERATE}. * {@link android.media.AudioManager#AUDIO_SESSION_ID_GENERATE}. * * @param recordingSessionId requested device-specific audio session id for playback * @see android.media.AudioManager.generateAudioSessionId() * @see android.media.AudioRecord.Builder.setContext(Context) * @see android.media.AudioManager#generateAudioSessionId() * @see android.media.AudioRecord.Builder#setContext(Context) */ @NonNull public Builder setAudioRecordingSessionId(int recordingSessionId) { Loading
core/java/android/companion/virtual/audio/AudioCapture.java +5 −5 Original line number Diff line number Diff line Loading @@ -56,12 +56,12 @@ public final class AudioCapture { /** * Sets the {@link AudioRecord} to handle audio capturing. * Callers may call this multiple times with different audio records to change * the underlying {@link AudioRecord} without stopping and re-starting recording. * * @param audioRecord The underlying {@link AudioRecord} to use for capture, * or null if no audio (i.e. silence) should be captured while still keeping the * record in a recording state. * <p>Callers may call this multiple times with different audio records to change the underlying * {@link AudioRecord} without stopping and re-starting recording. * * @param audioRecord The underlying {@link AudioRecord} to use for capture, or null if no audio * (i.e. silence) should be captured while still keeping the record in a recording state. */ void setAudioRecord(@Nullable AudioRecord audioRecord) { Log.d(TAG, "set AudioRecord with " + audioRecord); Loading