Loading core/api/system-current.txt +9 −5 Original line number Diff line number Diff line Loading @@ -3187,7 +3187,7 @@ package android.companion.virtual { method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig); method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method public int getDeviceId(); method @Nullable public android.companion.virtual.sensor.VirtualSensor getVirtualSensor(int, @NonNull String); method @NonNull public java.util.List<android.companion.virtual.sensor.VirtualSensor> getVirtualSensorList(); method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener); Loading Loading @@ -3242,6 +3242,7 @@ package android.companion.virtual { method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setVirtualSensorCallback(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.sensor.VirtualSensorCallback); } } Loading Loading @@ -3293,14 +3294,18 @@ package android.companion.virtual.audio { package android.companion.virtual.sensor { public class VirtualSensor { public final class VirtualSensor implements android.os.Parcelable { method public int describeContents(); method public int getDeviceId(); method @NonNull public String getName(); method public int getType(); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendEvent(@NonNull android.companion.virtual.sensor.VirtualSensorEvent); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensor> CREATOR; } public static interface VirtualSensor.SensorStateChangeCallback { method public void onStateChanged(boolean, @NonNull java.time.Duration, @NonNull java.time.Duration); public interface VirtualSensorCallback { method public void onConfigurationChanged(@NonNull android.companion.virtual.sensor.VirtualSensor, boolean, @NonNull java.time.Duration, @NonNull java.time.Duration); } public final class VirtualSensorConfig implements android.os.Parcelable { Loading @@ -3315,7 +3320,6 @@ package android.companion.virtual.sensor { public static final class VirtualSensorConfig.Builder { ctor public VirtualSensorConfig.Builder(int, @NonNull String); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig build(); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setStateChangeCallback(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.sensor.VirtualSensor.SensorStateChangeCallback); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setVendor(@Nullable String); } core/java/android/companion/virtual/IVirtualDevice.aidl +3 −9 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.app.PendingIntent; import android.companion.virtual.IVirtualDeviceIntentInterceptor; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; import android.companion.virtual.sensor.IVirtualSensorStateChangeCallback; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorEvent; import android.content.IntentFilter; Loading Loading @@ -112,16 +112,10 @@ interface IVirtualDevice { boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event); /** * Creates a virtual sensor, capable of injecting sensor events into the system. * Returns all virtual sensors for this device. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualSensor(IBinder tokenm, in VirtualSensorConfig config); /** * Removes the sensor corresponding to the given token from the system. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterSensor(IBinder token); List<VirtualSensor> getVirtualSensorList(); /** * Sends an event to the virtual sensor corresponding to the given token. Loading core/java/android/companion/virtual/VirtualDeviceManager.java +9 −39 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChan import android.companion.virtual.camera.VirtualCameraDevice; import android.companion.virtual.camera.VirtualCameraInput; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorConfig; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -428,8 +427,6 @@ public final class VirtualDeviceManager { }; @Nullable private VirtualCameraDevice mVirtualCameraDevice; @NonNull private final List<VirtualSensor> mVirtualSensors = new ArrayList<>(); @Nullable private VirtualAudioDevice mVirtualAudioDevice; Loading @@ -448,10 +445,6 @@ public final class VirtualDeviceManager { params, mActivityListenerBinder, mSoundEffectListener); final List<VirtualSensorConfig> virtualSensorConfigs = params.getVirtualSensorConfigs(); for (int i = 0; i < virtualSensorConfigs.size(); ++i) { mVirtualSensors.add(createVirtualSensor(virtualSensorConfigs.get(i))); } } /** Loading @@ -478,20 +471,19 @@ public final class VirtualDeviceManager { } /** * Returns this device's sensor with the given type and name, if any. * Returns this device's sensors. * * @see VirtualDeviceParams.Builder#addVirtualSensorConfig * * @param type The type of the sensor. * @param name The name of the sensor. * @return The matching sensor if found, {@code null} otherwise. * @return A list of all sensors for this device, or an empty list if no sensors exist. */ @Nullable public VirtualSensor getVirtualSensor(int type, @NonNull String name) { return mVirtualSensors.stream() .filter(sensor -> sensor.getType() == type && sensor.getName().equals(name)) .findAny() .orElse(null); @NonNull public List<VirtualSensor> getVirtualSensorList() { try { return mVirtualDevice.getVirtualSensorList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** Loading Loading @@ -937,28 +929,6 @@ public final class VirtualDeviceManager { } } /** * Creates a virtual sensor, capable of injecting sensor events into the system. Only for * internal use, since device sensors must remain valid for the entire lifetime of the * device. * * @param config The configuration of the sensor. * @hide */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull public VirtualSensor createVirtualSensor(@NonNull VirtualSensorConfig config) { Objects.requireNonNull(config); try { final IBinder token = new Binder( "android.hardware.sensor.VirtualSensor:" + config.getName()); mVirtualDevice.createVirtualSensor(token, config); return new VirtualSensor(config.getType(), config.getName(), mVirtualDevice, token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Adds an activity listener to listen for events such as top activity change or virtual * display task stack became empty. Loading core/java/android/companion/virtual/VirtualDeviceParams.java +83 −7 Original line number Diff line number Diff line Loading @@ -19,11 +19,18 @@ package android.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; import static java.util.concurrent.TimeUnit.MICROSECONDS; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.companion.virtual.sensor.IVirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensorConfig; import android.content.ComponentName; import android.os.Parcel; Loading @@ -37,11 +44,13 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; /** * Params that can be configured when creating virtual devices. Loading Loading @@ -190,6 +199,7 @@ public final class VirtualDeviceParams implements Parcelable { // Mapping of @PolicyType to @DevicePolicy @NonNull private final SparseIntArray mDevicePolicies; @NonNull private final List<VirtualSensorConfig> mVirtualSensorConfigs; @Nullable private final IVirtualSensorCallback mVirtualSensorCallback; @RecentsPolicy private final int mDefaultRecentsPolicy; private final int mAudioPlaybackSessionId; Loading @@ -207,6 +217,7 @@ public final class VirtualDeviceParams implements Parcelable { @Nullable String name, @NonNull SparseIntArray devicePolicies, @NonNull List<VirtualSensorConfig> virtualSensorConfigs, @Nullable IVirtualSensorCallback virtualSensorCallback, @RecentsPolicy int defaultRecentsPolicy, int audioPlaybackSessionId, int audioRecordingSessionId) { Loading @@ -224,6 +235,7 @@ public final class VirtualDeviceParams implements Parcelable { mName = name; mDevicePolicies = Objects.requireNonNull(devicePolicies); mVirtualSensorConfigs = Objects.requireNonNull(virtualSensorConfigs); mVirtualSensorCallback = virtualSensorCallback; mDefaultRecentsPolicy = defaultRecentsPolicy; mAudioPlaybackSessionId = audioPlaybackSessionId; mAudioRecordingSessionId = audioRecordingSessionId; Loading @@ -244,6 +256,8 @@ public final class VirtualDeviceParams implements Parcelable { mDevicePolicies = parcel.readSparseIntArray(); mVirtualSensorConfigs = new ArrayList<>(); parcel.readTypedList(mVirtualSensorConfigs, VirtualSensorConfig.CREATOR); mVirtualSensorCallback = IVirtualSensorCallback.Stub.asInterface(parcel.readStrongBinder()); mDefaultRecentsPolicy = parcel.readInt(); mAudioPlaybackSessionId = parcel.readInt(); mAudioRecordingSessionId = parcel.readInt(); Loading Loading @@ -371,6 +385,15 @@ public final class VirtualDeviceParams implements Parcelable { return mVirtualSensorConfigs; } /** * Returns the callback to get notified about changes in the sensor listeners. * @hide */ @Nullable public IVirtualSensorCallback getVirtualSensorCallback() { return mVirtualSensorCallback; } /** * Returns the policy of how to handle activities in recents. * Loading Loading @@ -417,6 +440,8 @@ public final class VirtualDeviceParams implements Parcelable { dest.writeString8(mName); dest.writeSparseIntArray(mDevicePolicies); dest.writeTypedList(mVirtualSensorConfigs); dest.writeStrongBinder( mVirtualSensorCallback != null ? mVirtualSensorCallback.asBinder() : null); dest.writeInt(mDefaultRecentsPolicy); dest.writeInt(mAudioPlaybackSessionId); dest.writeInt(mAudioRecordingSessionId); Loading Loading @@ -522,11 +547,38 @@ public final class VirtualDeviceParams implements Parcelable { private boolean mDefaultActivityPolicyConfigured = false; @Nullable private String mName; @NonNull private SparseIntArray mDevicePolicies = new SparseIntArray(); @NonNull private List<VirtualSensorConfig> mVirtualSensorConfigs = new ArrayList<>(); private int mDefaultRecentsPolicy; private int mAudioPlaybackSessionId = AUDIO_SESSION_ID_GENERATE; private int mAudioRecordingSessionId = AUDIO_SESSION_ID_GENERATE; @NonNull private List<VirtualSensorConfig> mVirtualSensorConfigs = new ArrayList<>(); @Nullable private IVirtualSensorCallback mVirtualSensorCallback; private static class VirtualSensorCallbackDelegate extends IVirtualSensorCallback.Stub { @NonNull private final Executor mExecutor; @NonNull private final VirtualSensorCallback mCallback; VirtualSensorCallbackDelegate(@NonNull @CallbackExecutor Executor executor, @NonNull VirtualSensorCallback callback) { mCallback = callback; mExecutor = executor; } @Override public void onConfigurationChanged(@NonNull VirtualSensor sensor, boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros) { final Duration samplingPeriod = Duration.ofNanos(MICROSECONDS.toNanos(samplingPeriodMicros)); final Duration batchReportingLatency = Duration.ofNanos(MICROSECONDS.toNanos(batchReportLatencyMicros)); mExecutor.execute(() -> mCallback.onConfigurationChanged( sensor, enabled, samplingPeriod, batchReportingLatency)); } } /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} * is required if this is set to {@link #LOCK_STATE_ALWAYS_UNLOCKED}. Loading Loading @@ -730,6 +782,24 @@ public final class VirtualDeviceParams implements Parcelable { return this; } /** * Sets the callback to get notified about changes in the sensor listeners. * * @param executor The executor where the callback is executed on. * @param callback The callback to get notified when the state of the sensor * listeners has changed, see {@link VirtualSensorCallback} */ @SuppressLint("MissingGetterMatchingBuilder") @NonNull public Builder setVirtualSensorCallback( @NonNull @CallbackExecutor Executor executor, @NonNull VirtualSensorCallback callback) { mVirtualSensorCallback = new VirtualSensorCallbackDelegate( Objects.requireNonNull(executor), Objects.requireNonNull(callback)); return this; } /** * Sets the policy to indicate how activities are handled in recents. * Loading Loading @@ -798,13 +868,18 @@ public final class VirtualDeviceParams implements Parcelable { */ @NonNull public VirtualDeviceParams build() { if (!mVirtualSensorConfigs.isEmpty() && (mDevicePolicies.get(POLICY_TYPE_SENSORS, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_CUSTOM)) { if (!mVirtualSensorConfigs.isEmpty()) { if (mDevicePolicies.get(POLICY_TYPE_SENSORS, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_CUSTOM) { throw new IllegalArgumentException( "DEVICE_POLICY_CUSTOM for POLICY_TYPE_SENSORS is required for creating " + "virtual sensors."); } if (mVirtualSensorCallback == null) { throw new IllegalArgumentException( "VirtualSensorCallback is required for creating virtual sensors."); } } if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE || mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE) Loading Loading @@ -837,6 +912,7 @@ public final class VirtualDeviceParams implements Parcelable { mName, mDevicePolicies, mVirtualSensorConfigs, mVirtualSensorCallback, mDefaultRecentsPolicy, mAudioPlaybackSessionId, mAudioRecordingSessionId); Loading core/java/android/companion/virtual/sensor/IVirtualSensorStateChangeCallback.aidl→core/java/android/companion/virtual/sensor/IVirtualSensorCallback.aidl +8 −4 Original line number Diff line number Diff line Loading @@ -16,20 +16,24 @@ package android.companion.virtual.sensor; import android.companion.virtual.sensor.VirtualSensor; /** * Interface for notification of listener registration changes for a virtual sensor. * Interface for notifying the sensor owner about whether and how sensor events should be injected. * * @hide */ oneway interface IVirtualSensorStateChangeCallback { oneway interface IVirtualSensorCallback { /** * Called when the registered listeners to a virtual sensor have changed. * Called when the requested sensor event injection parameters have changed. * * @param sensor The sensor whose requested injection parameters have changed. * @param enabled Whether the sensor is enabled. * @param samplingPeriodMicros The requested sensor's sampling period in microseconds. * @param batchReportingLatencyMicros The requested maximum time interval in microseconds * between the delivery of two batches of sensor events. */ void onStateChanged(boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros); void onConfigurationChanged(in VirtualSensor sensor, boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros); } Loading
core/api/system-current.txt +9 −5 Original line number Diff line number Diff line Loading @@ -3187,7 +3187,7 @@ package android.companion.virtual { method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.input.VirtualTouchscreenConfig); method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int); method public int getDeviceId(); method @Nullable public android.companion.virtual.sensor.VirtualSensor getVirtualSensor(int, @NonNull String); method @NonNull public java.util.List<android.companion.virtual.sensor.VirtualSensor> getVirtualSensorList(); method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void registerIntentInterceptor(@NonNull android.content.IntentFilter, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.IntentInterceptorCallback); method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener); Loading Loading @@ -3242,6 +3242,7 @@ package android.companion.virtual { method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setName(@NonNull String); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>); method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setVirtualSensorCallback(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.sensor.VirtualSensorCallback); } } Loading Loading @@ -3293,14 +3294,18 @@ package android.companion.virtual.audio { package android.companion.virtual.sensor { public class VirtualSensor { public final class VirtualSensor implements android.os.Parcelable { method public int describeContents(); method public int getDeviceId(); method @NonNull public String getName(); method public int getType(); method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void sendEvent(@NonNull android.companion.virtual.sensor.VirtualSensorEvent); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensor> CREATOR; } public static interface VirtualSensor.SensorStateChangeCallback { method public void onStateChanged(boolean, @NonNull java.time.Duration, @NonNull java.time.Duration); public interface VirtualSensorCallback { method public void onConfigurationChanged(@NonNull android.companion.virtual.sensor.VirtualSensor, boolean, @NonNull java.time.Duration, @NonNull java.time.Duration); } public final class VirtualSensorConfig implements android.os.Parcelable { Loading @@ -3315,7 +3320,6 @@ package android.companion.virtual.sensor { public static final class VirtualSensorConfig.Builder { ctor public VirtualSensorConfig.Builder(int, @NonNull String); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig build(); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setStateChangeCallback(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.sensor.VirtualSensor.SensorStateChangeCallback); method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setVendor(@Nullable String); }
core/java/android/companion/virtual/IVirtualDevice.aidl +3 −9 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ import android.app.PendingIntent; import android.companion.virtual.IVirtualDeviceIntentInterceptor; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; import android.companion.virtual.sensor.IVirtualSensorStateChangeCallback; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorConfig; import android.companion.virtual.sensor.VirtualSensorEvent; import android.content.IntentFilter; Loading Loading @@ -112,16 +112,10 @@ interface IVirtualDevice { boolean sendTouchEvent(IBinder token, in VirtualTouchEvent event); /** * Creates a virtual sensor, capable of injecting sensor events into the system. * Returns all virtual sensors for this device. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void createVirtualSensor(IBinder tokenm, in VirtualSensorConfig config); /** * Removes the sensor corresponding to the given token from the system. */ @EnforcePermission("CREATE_VIRTUAL_DEVICE") void unregisterSensor(IBinder token); List<VirtualSensor> getVirtualSensorList(); /** * Sends an event to the virtual sensor corresponding to the given token. Loading
core/java/android/companion/virtual/VirtualDeviceManager.java +9 −39 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChan import android.companion.virtual.camera.VirtualCameraDevice; import android.companion.virtual.camera.VirtualCameraInput; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorConfig; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -428,8 +427,6 @@ public final class VirtualDeviceManager { }; @Nullable private VirtualCameraDevice mVirtualCameraDevice; @NonNull private final List<VirtualSensor> mVirtualSensors = new ArrayList<>(); @Nullable private VirtualAudioDevice mVirtualAudioDevice; Loading @@ -448,10 +445,6 @@ public final class VirtualDeviceManager { params, mActivityListenerBinder, mSoundEffectListener); final List<VirtualSensorConfig> virtualSensorConfigs = params.getVirtualSensorConfigs(); for (int i = 0; i < virtualSensorConfigs.size(); ++i) { mVirtualSensors.add(createVirtualSensor(virtualSensorConfigs.get(i))); } } /** Loading @@ -478,20 +471,19 @@ public final class VirtualDeviceManager { } /** * Returns this device's sensor with the given type and name, if any. * Returns this device's sensors. * * @see VirtualDeviceParams.Builder#addVirtualSensorConfig * * @param type The type of the sensor. * @param name The name of the sensor. * @return The matching sensor if found, {@code null} otherwise. * @return A list of all sensors for this device, or an empty list if no sensors exist. */ @Nullable public VirtualSensor getVirtualSensor(int type, @NonNull String name) { return mVirtualSensors.stream() .filter(sensor -> sensor.getType() == type && sensor.getName().equals(name)) .findAny() .orElse(null); @NonNull public List<VirtualSensor> getVirtualSensorList() { try { return mVirtualDevice.getVirtualSensorList(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** Loading Loading @@ -937,28 +929,6 @@ public final class VirtualDeviceManager { } } /** * Creates a virtual sensor, capable of injecting sensor events into the system. Only for * internal use, since device sensors must remain valid for the entire lifetime of the * device. * * @param config The configuration of the sensor. * @hide */ @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) @NonNull public VirtualSensor createVirtualSensor(@NonNull VirtualSensorConfig config) { Objects.requireNonNull(config); try { final IBinder token = new Binder( "android.hardware.sensor.VirtualSensor:" + config.getName()); mVirtualDevice.createVirtualSensor(token, config); return new VirtualSensor(config.getType(), config.getName(), mVirtualDevice, token); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Adds an activity listener to listen for events such as top activity change or virtual * display task stack became empty. Loading
core/java/android/companion/virtual/VirtualDeviceParams.java +83 −7 Original line number Diff line number Diff line Loading @@ -19,11 +19,18 @@ package android.companion.virtual; import static android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY; import static android.media.AudioManager.AUDIO_SESSION_ID_GENERATE; import static java.util.concurrent.TimeUnit.MICROSECONDS; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.companion.virtual.sensor.IVirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensorConfig; import android.content.ComponentName; import android.os.Parcel; Loading @@ -37,11 +44,13 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.Executor; /** * Params that can be configured when creating virtual devices. Loading Loading @@ -190,6 +199,7 @@ public final class VirtualDeviceParams implements Parcelable { // Mapping of @PolicyType to @DevicePolicy @NonNull private final SparseIntArray mDevicePolicies; @NonNull private final List<VirtualSensorConfig> mVirtualSensorConfigs; @Nullable private final IVirtualSensorCallback mVirtualSensorCallback; @RecentsPolicy private final int mDefaultRecentsPolicy; private final int mAudioPlaybackSessionId; Loading @@ -207,6 +217,7 @@ public final class VirtualDeviceParams implements Parcelable { @Nullable String name, @NonNull SparseIntArray devicePolicies, @NonNull List<VirtualSensorConfig> virtualSensorConfigs, @Nullable IVirtualSensorCallback virtualSensorCallback, @RecentsPolicy int defaultRecentsPolicy, int audioPlaybackSessionId, int audioRecordingSessionId) { Loading @@ -224,6 +235,7 @@ public final class VirtualDeviceParams implements Parcelable { mName = name; mDevicePolicies = Objects.requireNonNull(devicePolicies); mVirtualSensorConfigs = Objects.requireNonNull(virtualSensorConfigs); mVirtualSensorCallback = virtualSensorCallback; mDefaultRecentsPolicy = defaultRecentsPolicy; mAudioPlaybackSessionId = audioPlaybackSessionId; mAudioRecordingSessionId = audioRecordingSessionId; Loading @@ -244,6 +256,8 @@ public final class VirtualDeviceParams implements Parcelable { mDevicePolicies = parcel.readSparseIntArray(); mVirtualSensorConfigs = new ArrayList<>(); parcel.readTypedList(mVirtualSensorConfigs, VirtualSensorConfig.CREATOR); mVirtualSensorCallback = IVirtualSensorCallback.Stub.asInterface(parcel.readStrongBinder()); mDefaultRecentsPolicy = parcel.readInt(); mAudioPlaybackSessionId = parcel.readInt(); mAudioRecordingSessionId = parcel.readInt(); Loading Loading @@ -371,6 +385,15 @@ public final class VirtualDeviceParams implements Parcelable { return mVirtualSensorConfigs; } /** * Returns the callback to get notified about changes in the sensor listeners. * @hide */ @Nullable public IVirtualSensorCallback getVirtualSensorCallback() { return mVirtualSensorCallback; } /** * Returns the policy of how to handle activities in recents. * Loading Loading @@ -417,6 +440,8 @@ public final class VirtualDeviceParams implements Parcelable { dest.writeString8(mName); dest.writeSparseIntArray(mDevicePolicies); dest.writeTypedList(mVirtualSensorConfigs); dest.writeStrongBinder( mVirtualSensorCallback != null ? mVirtualSensorCallback.asBinder() : null); dest.writeInt(mDefaultRecentsPolicy); dest.writeInt(mAudioPlaybackSessionId); dest.writeInt(mAudioRecordingSessionId); Loading Loading @@ -522,11 +547,38 @@ public final class VirtualDeviceParams implements Parcelable { private boolean mDefaultActivityPolicyConfigured = false; @Nullable private String mName; @NonNull private SparseIntArray mDevicePolicies = new SparseIntArray(); @NonNull private List<VirtualSensorConfig> mVirtualSensorConfigs = new ArrayList<>(); private int mDefaultRecentsPolicy; private int mAudioPlaybackSessionId = AUDIO_SESSION_ID_GENERATE; private int mAudioRecordingSessionId = AUDIO_SESSION_ID_GENERATE; @NonNull private List<VirtualSensorConfig> mVirtualSensorConfigs = new ArrayList<>(); @Nullable private IVirtualSensorCallback mVirtualSensorCallback; private static class VirtualSensorCallbackDelegate extends IVirtualSensorCallback.Stub { @NonNull private final Executor mExecutor; @NonNull private final VirtualSensorCallback mCallback; VirtualSensorCallbackDelegate(@NonNull @CallbackExecutor Executor executor, @NonNull VirtualSensorCallback callback) { mCallback = callback; mExecutor = executor; } @Override public void onConfigurationChanged(@NonNull VirtualSensor sensor, boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros) { final Duration samplingPeriod = Duration.ofNanos(MICROSECONDS.toNanos(samplingPeriodMicros)); final Duration batchReportingLatency = Duration.ofNanos(MICROSECONDS.toNanos(batchReportLatencyMicros)); mExecutor.execute(() -> mCallback.onConfigurationChanged( sensor, enabled, samplingPeriod, batchReportingLatency)); } } /** * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY} * is required if this is set to {@link #LOCK_STATE_ALWAYS_UNLOCKED}. Loading Loading @@ -730,6 +782,24 @@ public final class VirtualDeviceParams implements Parcelable { return this; } /** * Sets the callback to get notified about changes in the sensor listeners. * * @param executor The executor where the callback is executed on. * @param callback The callback to get notified when the state of the sensor * listeners has changed, see {@link VirtualSensorCallback} */ @SuppressLint("MissingGetterMatchingBuilder") @NonNull public Builder setVirtualSensorCallback( @NonNull @CallbackExecutor Executor executor, @NonNull VirtualSensorCallback callback) { mVirtualSensorCallback = new VirtualSensorCallbackDelegate( Objects.requireNonNull(executor), Objects.requireNonNull(callback)); return this; } /** * Sets the policy to indicate how activities are handled in recents. * Loading Loading @@ -798,13 +868,18 @@ public final class VirtualDeviceParams implements Parcelable { */ @NonNull public VirtualDeviceParams build() { if (!mVirtualSensorConfigs.isEmpty() && (mDevicePolicies.get(POLICY_TYPE_SENSORS, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_CUSTOM)) { if (!mVirtualSensorConfigs.isEmpty()) { if (mDevicePolicies.get(POLICY_TYPE_SENSORS, DEVICE_POLICY_DEFAULT) != DEVICE_POLICY_CUSTOM) { throw new IllegalArgumentException( "DEVICE_POLICY_CUSTOM for POLICY_TYPE_SENSORS is required for creating " + "virtual sensors."); } if (mVirtualSensorCallback == null) { throw new IllegalArgumentException( "VirtualSensorCallback is required for creating virtual sensors."); } } if ((mAudioPlaybackSessionId != AUDIO_SESSION_ID_GENERATE || mAudioRecordingSessionId != AUDIO_SESSION_ID_GENERATE) Loading Loading @@ -837,6 +912,7 @@ public final class VirtualDeviceParams implements Parcelable { mName, mDevicePolicies, mVirtualSensorConfigs, mVirtualSensorCallback, mDefaultRecentsPolicy, mAudioPlaybackSessionId, mAudioRecordingSessionId); Loading
core/java/android/companion/virtual/sensor/IVirtualSensorStateChangeCallback.aidl→core/java/android/companion/virtual/sensor/IVirtualSensorCallback.aidl +8 −4 Original line number Diff line number Diff line Loading @@ -16,20 +16,24 @@ package android.companion.virtual.sensor; import android.companion.virtual.sensor.VirtualSensor; /** * Interface for notification of listener registration changes for a virtual sensor. * Interface for notifying the sensor owner about whether and how sensor events should be injected. * * @hide */ oneway interface IVirtualSensorStateChangeCallback { oneway interface IVirtualSensorCallback { /** * Called when the registered listeners to a virtual sensor have changed. * Called when the requested sensor event injection parameters have changed. * * @param sensor The sensor whose requested injection parameters have changed. * @param enabled Whether the sensor is enabled. * @param samplingPeriodMicros The requested sensor's sampling period in microseconds. * @param batchReportingLatencyMicros The requested maximum time interval in microseconds * between the delivery of two batches of sensor events. */ void onStateChanged(boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros); void onConfigurationChanged(in VirtualSensor sensor, boolean enabled, int samplingPeriodMicros, int batchReportLatencyMicros); }