Loading core/java/android/companion/virtual/camera/VirtualCameraConfig.java +12 −5 Original line number Diff line number Diff line Loading @@ -24,8 +24,10 @@ import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.companion.virtual.VirtualDevice; import android.companion.virtualdevice.flags.Flags; import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraMetadata; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -281,20 +283,25 @@ public final class VirtualCameraConfig implements Parcelable { } /** * Sets the lens facing direction of the virtual camera, can be either * {@link CameraMetadata#LENS_FACING_FRONT} or {@link CameraMetadata#LENS_FACING_BACK}. * Sets the lens facing direction of the virtual camera. * * <p>A {@link VirtualDevice} can have at most one {@link VirtualCamera} with * {@link CameraMetadata#LENS_FACING_FRONT} and at most one {@link VirtualCamera} with * {@link CameraMetadata#LENS_FACING_BACK}. * {@link CameraMetadata#LENS_FACING_BACK}, though it can create multiple cameras with * {@link CameraMetadata#LENS_FACING_EXTERNAL}. * * @param lensFacing The direction that the virtual camera faces relative to the device's * screen. * @see CameraCharacteristics#LENS_FACING */ @NonNull public Builder setLensFacing(int lensFacing) { if (lensFacing != CameraMetadata.LENS_FACING_BACK && lensFacing != CameraMetadata.LENS_FACING_FRONT) { boolean allowLensFacing = lensFacing == CameraMetadata.LENS_FACING_FRONT || lensFacing == CameraMetadata.LENS_FACING_BACK; if (Flags.externalVirtualCameras()) { allowLensFacing |= lensFacing == CameraMetadata.LENS_FACING_EXTERNAL; } if (!allowLensFacing) { throw new IllegalArgumentException("Unsupported lens facing: " + lensFacing); } mLensFacing = lensFacing; Loading services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java +7 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,9 @@ import android.companion.virtual.VirtualDeviceParams.DevicePolicy; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtualcamera.IVirtualCameraService; import android.companion.virtualcamera.VirtualCameraConfiguration; import android.companion.virtualdevice.flags.Flags; import android.content.AttributionSource; import android.hardware.camera2.CameraMetadata; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -197,14 +199,17 @@ public final class VirtualCameraController implements IBinder.DeathRecipient { throw new IllegalArgumentException( "Cannot create virtual camera with DEVICE_POLICY_DEFAULT for " + "POLICY_TYPE_CAMERA"); } else if (isLensFacingAlreadyPresent(config.getLensFacing())) { } else if (isNonExternalLensFacingAlreadyPresent(config.getLensFacing())) { throw new IllegalArgumentException( "Only a single virtual camera can be created with lens facing " + config.getLensFacing()); } } private boolean isLensFacingAlreadyPresent(int lensFacing) { private boolean isNonExternalLensFacingAlreadyPresent(int lensFacing) { if (Flags.externalVirtualCameras() && CameraMetadata.LENS_FACING_EXTERNAL == lensFacing) { return false; } synchronized (mCameras) { for (CameraDescriptor cameraDescriptor : mCameras.values()) { if (cameraDescriptor.mConfig.getLensFacing() == lensFacing) { Loading services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java +47 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.companion.virtual.camera.VirtualCameraConfig.SENSOR_ORIENT import static android.graphics.ImageFormat.YUV_420_888; import static android.graphics.PixelFormat.RGBA_8888; import static android.hardware.camera2.CameraMetadata.LENS_FACING_BACK; import static android.hardware.camera2.CameraMetadata.LENS_FACING_EXTERNAL; import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT; import static com.google.common.truth.Truth.assertThat; Loading @@ -38,11 +39,15 @@ import android.companion.virtual.camera.VirtualCameraCallback; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtualcamera.IVirtualCameraService; import android.companion.virtualcamera.VirtualCameraConfiguration; import android.companion.virtualdevice.flags.Flags; import android.content.AttributionSource; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.TestableLooper; import junitparams.JUnitParamsRunner; Loading @@ -50,12 +55,14 @@ import junitparams.Parameters; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; @Presubmit Loading Loading @@ -89,6 +96,8 @@ public class VirtualCameraControllerTest { private final HandlerExecutor mCallbackHandler = new HandlerExecutor(new Handler(Looper.getMainLooper())); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Loading Loading @@ -168,7 +177,7 @@ public class VirtualCameraControllerTest { CAMERA_LENS_FACING_2); } @Parameters(method = "getAllLensFacingDirections") @Parameters(method = "getSingleCamerasLensFacingDirections") @Test public void registerMultipleSameLensFacingCameras_withCustomCameraPolicy_throwsException( int lensFacing) { Loading @@ -182,6 +191,30 @@ public class VirtualCameraControllerTest { AttributionSource.myAttributionSource())); } @Test @EnableFlags(Flags.FLAG_EXTERNAL_VIRTUAL_CAMERAS) public void registerMultipleExternalCameras_withCustomCameraPolicy_succeeds() { mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_MAX_FPS_1, CAMERA_NAME_1, CAMERA_SENSOR_ORIENTATION_1, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource()); mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT_2, CAMERA_MAX_FPS_2, CAMERA_NAME_2, CAMERA_SENSOR_ORIENTATION_2, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource()); } @Test @DisableFlags(Flags.FLAG_EXTERNAL_VIRTUAL_CAMERAS) public void registerExternalCameras_withCustomCameraPolicy_throwsException_whenNotSupported() { assertThrows(IllegalArgumentException.class, () -> mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_MAX_FPS_1, CAMERA_NAME_1, CAMERA_SENSOR_ORIENTATION_1, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource())); } @Parameters(method = "getAllLensFacingDirections") @Test public void registerCamera_withDefaultCameraPolicy_throwsException(int lensFacing) { Loading Loading @@ -218,10 +251,21 @@ public class VirtualCameraControllerTest { assertThat(configuration.lensFacing).isEqualTo(lensFacing); } private static Integer[] getAllLensFacingDirections() { @SuppressWarnings("unused") // Parameter for parametrized tests private static Integer[] getSingleCamerasLensFacingDirections() { return new Integer[]{ LENS_FACING_BACK, LENS_FACING_FRONT LENS_FACING_FRONT, }; } @SuppressWarnings("unused") // Parameter for parametrized tests private static List<Integer> getAllLensFacingDirections() { List<Integer> lensFacingDirections = new ArrayList<>( List.of(LENS_FACING_BACK, LENS_FACING_FRONT)); if (Flags.externalVirtualCameras()) { lensFacingDirections.add(LENS_FACING_EXTERNAL); } return lensFacingDirections; } } Loading
core/java/android/companion/virtual/camera/VirtualCameraConfig.java +12 −5 Original line number Diff line number Diff line Loading @@ -24,8 +24,10 @@ import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.companion.virtual.VirtualDevice; import android.companion.virtualdevice.flags.Flags; import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraMetadata; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -281,20 +283,25 @@ public final class VirtualCameraConfig implements Parcelable { } /** * Sets the lens facing direction of the virtual camera, can be either * {@link CameraMetadata#LENS_FACING_FRONT} or {@link CameraMetadata#LENS_FACING_BACK}. * Sets the lens facing direction of the virtual camera. * * <p>A {@link VirtualDevice} can have at most one {@link VirtualCamera} with * {@link CameraMetadata#LENS_FACING_FRONT} and at most one {@link VirtualCamera} with * {@link CameraMetadata#LENS_FACING_BACK}. * {@link CameraMetadata#LENS_FACING_BACK}, though it can create multiple cameras with * {@link CameraMetadata#LENS_FACING_EXTERNAL}. * * @param lensFacing The direction that the virtual camera faces relative to the device's * screen. * @see CameraCharacteristics#LENS_FACING */ @NonNull public Builder setLensFacing(int lensFacing) { if (lensFacing != CameraMetadata.LENS_FACING_BACK && lensFacing != CameraMetadata.LENS_FACING_FRONT) { boolean allowLensFacing = lensFacing == CameraMetadata.LENS_FACING_FRONT || lensFacing == CameraMetadata.LENS_FACING_BACK; if (Flags.externalVirtualCameras()) { allowLensFacing |= lensFacing == CameraMetadata.LENS_FACING_EXTERNAL; } if (!allowLensFacing) { throw new IllegalArgumentException("Unsupported lens facing: " + lensFacing); } mLensFacing = lensFacing; Loading
services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraController.java +7 −2 Original line number Diff line number Diff line Loading @@ -26,7 +26,9 @@ import android.companion.virtual.VirtualDeviceParams.DevicePolicy; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtualcamera.IVirtualCameraService; import android.companion.virtualcamera.VirtualCameraConfiguration; import android.companion.virtualdevice.flags.Flags; import android.content.AttributionSource; import android.hardware.camera2.CameraMetadata; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; Loading Loading @@ -197,14 +199,17 @@ public final class VirtualCameraController implements IBinder.DeathRecipient { throw new IllegalArgumentException( "Cannot create virtual camera with DEVICE_POLICY_DEFAULT for " + "POLICY_TYPE_CAMERA"); } else if (isLensFacingAlreadyPresent(config.getLensFacing())) { } else if (isNonExternalLensFacingAlreadyPresent(config.getLensFacing())) { throw new IllegalArgumentException( "Only a single virtual camera can be created with lens facing " + config.getLensFacing()); } } private boolean isLensFacingAlreadyPresent(int lensFacing) { private boolean isNonExternalLensFacingAlreadyPresent(int lensFacing) { if (Flags.externalVirtualCameras() && CameraMetadata.LENS_FACING_EXTERNAL == lensFacing) { return false; } synchronized (mCameras) { for (CameraDescriptor cameraDescriptor : mCameras.values()) { if (cameraDescriptor.mConfig.getLensFacing() == lensFacing) { Loading
services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java +47 −3 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import static android.companion.virtual.camera.VirtualCameraConfig.SENSOR_ORIENT import static android.graphics.ImageFormat.YUV_420_888; import static android.graphics.PixelFormat.RGBA_8888; import static android.hardware.camera2.CameraMetadata.LENS_FACING_BACK; import static android.hardware.camera2.CameraMetadata.LENS_FACING_EXTERNAL; import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT; import static com.google.common.truth.Truth.assertThat; Loading @@ -38,11 +39,15 @@ import android.companion.virtual.camera.VirtualCameraCallback; import android.companion.virtual.camera.VirtualCameraConfig; import android.companion.virtualcamera.IVirtualCameraService; import android.companion.virtualcamera.VirtualCameraConfiguration; import android.companion.virtualdevice.flags.Flags; import android.content.AttributionSource; import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.testing.TestableLooper; import junitparams.JUnitParamsRunner; Loading @@ -50,12 +55,14 @@ import junitparams.Parameters; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; @Presubmit Loading Loading @@ -89,6 +96,8 @@ public class VirtualCameraControllerTest { private final HandlerExecutor mCallbackHandler = new HandlerExecutor(new Handler(Looper.getMainLooper())); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Loading Loading @@ -168,7 +177,7 @@ public class VirtualCameraControllerTest { CAMERA_LENS_FACING_2); } @Parameters(method = "getAllLensFacingDirections") @Parameters(method = "getSingleCamerasLensFacingDirections") @Test public void registerMultipleSameLensFacingCameras_withCustomCameraPolicy_throwsException( int lensFacing) { Loading @@ -182,6 +191,30 @@ public class VirtualCameraControllerTest { AttributionSource.myAttributionSource())); } @Test @EnableFlags(Flags.FLAG_EXTERNAL_VIRTUAL_CAMERAS) public void registerMultipleExternalCameras_withCustomCameraPolicy_succeeds() { mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_MAX_FPS_1, CAMERA_NAME_1, CAMERA_SENSOR_ORIENTATION_1, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource()); mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_2, CAMERA_HEIGHT_2, CAMERA_FORMAT_2, CAMERA_MAX_FPS_2, CAMERA_NAME_2, CAMERA_SENSOR_ORIENTATION_2, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource()); } @Test @DisableFlags(Flags.FLAG_EXTERNAL_VIRTUAL_CAMERAS) public void registerExternalCameras_withCustomCameraPolicy_throwsException_whenNotSupported() { assertThrows(IllegalArgumentException.class, () -> mVirtualCameraController.registerCamera( createVirtualCameraConfig(CAMERA_WIDTH_1, CAMERA_HEIGHT_1, CAMERA_FORMAT_1, CAMERA_MAX_FPS_1, CAMERA_NAME_1, CAMERA_SENSOR_ORIENTATION_1, LENS_FACING_EXTERNAL), AttributionSource.myAttributionSource())); } @Parameters(method = "getAllLensFacingDirections") @Test public void registerCamera_withDefaultCameraPolicy_throwsException(int lensFacing) { Loading Loading @@ -218,10 +251,21 @@ public class VirtualCameraControllerTest { assertThat(configuration.lensFacing).isEqualTo(lensFacing); } private static Integer[] getAllLensFacingDirections() { @SuppressWarnings("unused") // Parameter for parametrized tests private static Integer[] getSingleCamerasLensFacingDirections() { return new Integer[]{ LENS_FACING_BACK, LENS_FACING_FRONT LENS_FACING_FRONT, }; } @SuppressWarnings("unused") // Parameter for parametrized tests private static List<Integer> getAllLensFacingDirections() { List<Integer> lensFacingDirections = new ArrayList<>( List.of(LENS_FACING_BACK, LENS_FACING_FRONT)); if (Flags.externalVirtualCameras()) { lensFacingDirections.add(LENS_FACING_EXTERNAL); } return lensFacingDirections; } }