Add frame rate and sensor orientation for virtual camera
Test: atest CtsVirtualDevicesCameraTestCases
Test: atest virtual_camera_tests
Bug: 310857519
Change-Id: I0dc882f86881f5aaaa6501fdc3fd2f5d64fe2bc0
diff --git a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
index 140ae65..25f6b10 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#include "VirtualCameraDevice.h"
#include "aidl/android/companion/virtualcamera/Format.h"
#include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h"
+#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
#include "aidl/android/hardware/camera/device/CameraMetadata.h"
#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
#include "android/binder_interface_utils.h"
@@ -34,7 +35,9 @@
namespace {
using ::aidl::android::companion::virtualcamera::Format;
+using ::aidl::android::companion::virtualcamera::SensorOrientation;
using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
+using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
using ::aidl::android::hardware::camera::device::CameraMetadata;
using ::aidl::android::hardware::camera::device::Stream;
using ::aidl::android::hardware::camera::device::StreamConfiguration;
@@ -49,6 +52,7 @@
constexpr int kVgaHeight = 480;
constexpr int kHdWidth = 1280;
constexpr int kHdHeight = 720;
+constexpr int kMaxFps = 30;
struct AvailableStreamConfiguration {
const int width;
@@ -96,7 +100,7 @@
}
struct VirtualCameraConfigTestParam {
- std::vector<SupportedStreamConfiguration> inputConfig;
+ VirtualCameraConfiguration inputConfig;
std::vector<AvailableStreamConfiguration> expectedAvailableStreamConfigs;
};
@@ -106,8 +110,8 @@
TEST_P(VirtualCameraDeviceTest, cameraCharacteristicsForInputFormat) {
const VirtualCameraConfigTestParam& param = GetParam();
std::shared_ptr<VirtualCameraDevice> camera =
- ndk::SharedRefBase::make<VirtualCameraDevice>(
- kCameraId, param.inputConfig, /*virtualCameraClientCallback=*/nullptr);
+ ndk::SharedRefBase::make<VirtualCameraDevice>(kCameraId,
+ param.inputConfig);
CameraMetadata metadata;
ASSERT_TRUE(camera->getCameraCharacteristics(&metadata).isOk());
@@ -135,10 +139,15 @@
cameraCharacteristicsForInputFormat, VirtualCameraDeviceTest,
testing::Values(
VirtualCameraConfigTestParam{
- .inputConfig = {SupportedStreamConfiguration{
- .width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = Format::YUV_420_888}},
+ .inputConfig =
+ VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0},
.expectedAvailableStreamConfigs =
{AvailableStreamConfiguration{
.width = kVgaWidth,
@@ -160,14 +169,21 @@
.streamConfiguration =
ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
VirtualCameraConfigTestParam{
- .inputConfig = {SupportedStreamConfiguration{
- .width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = Format::YUV_420_888},
- SupportedStreamConfiguration{
- .width = kHdWidth,
- .height = kHdHeight,
- .pixelFormat = Format::YUV_420_888}},
+ .inputConfig =
+ VirtualCameraConfiguration{
+ .supportedStreamConfigs =
+ {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps},
+ SupportedStreamConfiguration{
+ .width = kHdWidth,
+ .height = kHdHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0},
.expectedAvailableStreamConfigs = {
AvailableStreamConfiguration{
.width = kVgaWidth,
diff --git a/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc b/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
index 615a77c..89e2f14 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,9 @@
namespace {
using ::aidl::android::companion::virtualcamera::Format;
+using ::aidl::android::companion::virtualcamera::SensorOrientation;
using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
+using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::common::TorchModeStatus;
@@ -49,6 +51,7 @@
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
+constexpr int kMaxFps = 30;
constexpr char kVirtualCameraNameRegex[] =
"device@[0-9]+\\.[0-9]+/virtual/[0-9]+";
@@ -79,10 +82,14 @@
std::shared_ptr<VirtualCameraProvider> mCameraProvider;
std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
ndk::SharedRefBase::make<MockCameraProviderCallback>();
- std::vector<SupportedStreamConfiguration> mInputConfigs = {
- SupportedStreamConfiguration{.width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = Format::YUV_420_888}};
+ VirtualCameraConfiguration mInputConfig = VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0};
};
TEST_F(VirtualCameraProviderTest, SetNullCameraCallbackFails) {
@@ -109,7 +116,7 @@
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfigs);
+ mCameraProvider->createCamera(mInputConfig);
EXPECT_THAT(camera, Not(IsNull()));
EXPECT_THAT(camera->getCameraName(), MatchesRegex(kVirtualCameraNameRegex));
@@ -127,7 +134,7 @@
.WillOnce(Return(ndk::ScopedAStatus::ok()));
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfigs);
+ mCameraProvider->createCamera(mInputConfig);
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
// Created camera should be in the list of cameras.
@@ -139,7 +146,7 @@
TEST_F(VirtualCameraProviderTest, RemoveCamera) {
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfigs);
+ mCameraProvider->createCamera(mInputConfig);
EXPECT_CALL(*mMockCameraProviderCallback,
cameraDeviceStatusChange(Eq(camera->getCameraName()),
@@ -156,7 +163,7 @@
TEST_F(VirtualCameraProviderTest, RemoveNonExistingCamera) {
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfigs);
+ mCameraProvider->createCamera(mInputConfig);
// Removing non-existing camera should fail.
const std::string cameraName = "DefinitelyNoTCamera";
diff --git a/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc b/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc
index 38261fb..332b8ef 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
using ::aidl::android::companion::virtualcamera::Format;
+using ::aidl::android::companion::virtualcamera::SensorOrientation;
using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
using ::aidl::android::hardware::camera::common::TorchModeStatus;
@@ -56,16 +57,21 @@
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
+constexpr int kMaxFps = 30;
constexpr char kCreateVirtualDevicePermissions[] =
"android.permission.CREATE_VIRTUAL_DEVICE";
const VirtualCameraConfiguration kEmptyVirtualCameraConfiguration;
-VirtualCameraConfiguration createConfiguration(const int width, const int height,
- const Format format) {
+VirtualCameraConfiguration createConfiguration(
+ const int width, const int height, const Format format, const int maxFps,
+ const SensorOrientation sensorOrientation) {
VirtualCameraConfiguration configuration;
- configuration.supportedStreamConfigs.push_back(
- {.width = width, .height = height, .pixelFormat = format});
+ configuration.supportedStreamConfigs.push_back({.width = width,
+ .height = height,
+ .pixelFormat = format,
+ .maxFps = maxFps});
+ configuration.sensorOrientation = sensorOrientation;
return configuration;
}
@@ -150,7 +156,8 @@
int mDevNullFd;
VirtualCameraConfiguration mVgaYUV420OnlyConfiguration =
- createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888);
+ createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, kMaxFps,
+ SensorOrientation::ORIENTATION_0);
};
TEST_F(VirtualCameraServiceTest, RegisterCameraWithYuvInputSucceeds) {
@@ -173,7 +180,8 @@
bool aidlRet;
VirtualCameraConfiguration config =
- createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888);
+ createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps,
+ SensorOrientation::ORIENTATION_0);
ASSERT_TRUE(mCameraService->registerCamera(ndkToken, config, &aidlRet).isOk());
@@ -208,7 +216,8 @@
bool aidlRet;
VirtualCameraConfiguration config =
- createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN);
+ createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN, kMaxFps,
+ SensorOrientation::ORIENTATION_0);
ASSERT_FALSE(
mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
@@ -219,7 +228,8 @@
TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighResFails) {
bool aidlRet;
VirtualCameraConfiguration config =
- createConfiguration(1000000, 1000000, Format::YUV_420_888);
+ createConfiguration(1000000, 1000000, Format::YUV_420_888, kMaxFps,
+ SensorOrientation::ORIENTATION_0);
ASSERT_FALSE(
mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
@@ -229,8 +239,8 @@
TEST_F(VirtualCameraServiceTest, ConfigurationWithUnalignedResolutionFails) {
bool aidlRet;
- VirtualCameraConfiguration config =
- createConfiguration(641, 481, Format::YUV_420_888);
+ VirtualCameraConfiguration config = createConfiguration(
+ 641, 481, Format::YUV_420_888, kMaxFps, SensorOrientation::ORIENTATION_0);
ASSERT_FALSE(
mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
@@ -241,7 +251,32 @@
TEST_F(VirtualCameraServiceTest, ConfigurationWithNegativeResolutionFails) {
bool aidlRet;
VirtualCameraConfiguration config =
- createConfiguration(-1, kVgaHeight, Format::YUV_420_888);
+ createConfiguration(-1, kVgaHeight, Format::YUV_420_888, kMaxFps,
+ SensorOrientation::ORIENTATION_0);
+
+ ASSERT_FALSE(
+ mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ EXPECT_FALSE(aidlRet);
+ EXPECT_THAT(getCameraIds(), IsEmpty());
+}
+
+TEST_F(VirtualCameraServiceTest, ConfigurationWithTooLowMaxFpsFails) {
+ bool aidlRet;
+ VirtualCameraConfiguration config =
+ createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 0,
+ SensorOrientation::ORIENTATION_0);
+
+ ASSERT_FALSE(
+ mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ EXPECT_FALSE(aidlRet);
+ EXPECT_THAT(getCameraIds(), IsEmpty());
+}
+
+TEST_F(VirtualCameraServiceTest, ConfigurationWithTooHighMaxFpsFails) {
+ bool aidlRet;
+ VirtualCameraConfiguration config =
+ createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 90,
+ SensorOrientation::ORIENTATION_0);
ASSERT_FALSE(
mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
diff --git a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
index 30bd2b6..0c9ea77 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
#include "VirtualCameraSession.h"
#include "aidl/android/companion/virtualcamera/BnVirtualCameraCallback.h"
#include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h"
+#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
#include "aidl/android/hardware/camera/common/Status.h"
#include "aidl/android/hardware/camera/device/BnCameraDeviceCallback.h"
#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
@@ -38,12 +39,15 @@
constexpr int kWidth = 640;
constexpr int kHeight = 480;
+constexpr int kMaxFps = 30;
constexpr int kStreamId = 0;
constexpr int kCameraId = 42;
using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
using ::aidl::android::companion::virtualcamera::Format;
+using ::aidl::android::companion::virtualcamera::SensorOrientation;
using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
+using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
using ::aidl::android::hardware::camera::common::Status;
using ::aidl::android::hardware::camera::device::BnCameraDeviceCallback;
using ::aidl::android::hardware::camera::device::BufferRequest;
@@ -104,12 +108,14 @@
mMockVirtualCameraClientCallback =
ndk::SharedRefBase::make<MockVirtualCameraCallback>();
mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
- kCameraId,
- std::vector<SupportedStreamConfiguration>{
- SupportedStreamConfiguration{.width = kWidth,
- .height = kHeight,
- .pixelFormat = Format::YUV_420_888}},
- mMockVirtualCameraClientCallback);
+ kCameraId, VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kWidth,
+ .height = kHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0});
mVirtualCameraSession = ndk::SharedRefBase::make<VirtualCameraSession>(
mVirtualCameraDevice, mMockCameraDeviceCallback,
mMockVirtualCameraClientCallback);