Implement device awareness in camera service
- Modify ICameraServiceListener to pass device id
(i.e., the id of the device owning the camera, for
virtual camera this would be the id of the virtual
device, and for real cameras this would be
Context#DEVICE_ID_DEFAULT) and the mapped camera id
(for virtual devices, the back and front virtual cameras
of that device would have 0 and 1 respectively as their
mapped camera id, and for real cameras this would be
their actual camera id) in the callbacks. Cameraserver
exposes vitual cameras only to callers having context
associated with a custom policy virtual device.
- Modify ICameraService to accept device id and device
policy for binder calls related to camera operations.
Based on these, cameraserver maps the input camera id into
a virtual camera id (if applicable).
- Modify virtual camera HAL service to pass the device id
of virtual cameras using the metadata key ANDROID_INFO_DEVICE_ID.
- This change adds device-awareness to both camera2 and legacy
camera API's.
- This change prevents camera injection, session params injection,
and package name based cameraId-remapping if a virtual camera is
involved.
- This change modifies the NDK implementation to ignore callbacks
for non-default device id's. So virtual cameras are not accessible
using the NDK with this change (if the feature flag for camera
device awareness is enabled). Device awareness for camera NDK will
be added in a future CL.
Test: atest CtsVirtualDevicesCameraTestCases
Bug: 291736219
Change-Id: Iffe2a2e337a9e5801b84495d3ce1e8a1584b4993
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.cc b/services/camera/virtualcamera/VirtualCameraDevice.cc
index a5301e5..852ae2a 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.cc
+++ b/services/camera/virtualcamera/VirtualCameraDevice.cc
@@ -214,7 +214,8 @@
// TODO(b/301023410) - Populate camera characteristics according to camera configuration.
std::optional<CameraMetadata> initCameraCharacteristics(
const std::vector<SupportedStreamConfiguration>& supportedInputConfig,
- const SensorOrientation sensorOrientation, const LensFacing lensFacing) {
+ const SensorOrientation sensorOrientation, const LensFacing lensFacing,
+ const int32_t deviceId) {
if (!std::all_of(supportedInputConfig.begin(), supportedInputConfig.end(),
[](const SupportedStreamConfiguration& config) {
return isFormatSupportedForInput(
@@ -229,6 +230,7 @@
MetadataBuilder()
.setSupportedHardwareLevel(
ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL)
+ .setDeviceId(deviceId)
.setFlashAvailable(false)
.setLensFacing(
static_cast<camera_metadata_enum_android_lens_facing>(lensFacing))
@@ -389,13 +391,14 @@
} // namespace
VirtualCameraDevice::VirtualCameraDevice(
- const uint32_t cameraId, const VirtualCameraConfiguration& configuration)
+ const uint32_t cameraId, const VirtualCameraConfiguration& configuration,
+ int32_t deviceId)
: mCameraId(cameraId),
mVirtualCameraClientCallback(configuration.virtualCameraCallback),
mSupportedInputConfigurations(configuration.supportedStreamConfigs) {
std::optional<CameraMetadata> metadata = initCameraCharacteristics(
mSupportedInputConfigurations, configuration.sensorOrientation,
- configuration.lensFacing);
+ configuration.lensFacing, deviceId);
if (metadata.has_value()) {
mCameraCharacteristics = *metadata;
} else {
diff --git a/services/camera/virtualcamera/VirtualCameraDevice.h b/services/camera/virtualcamera/VirtualCameraDevice.h
index 0aebf6e..cba0674 100644
--- a/services/camera/virtualcamera/VirtualCameraDevice.h
+++ b/services/camera/virtualcamera/VirtualCameraDevice.h
@@ -39,7 +39,8 @@
explicit VirtualCameraDevice(
uint32_t cameraId,
const aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
- configuration);
+ configuration,
+ int32_t deviceId);
virtual ~VirtualCameraDevice() override = default;
diff --git a/services/camera/virtualcamera/VirtualCameraProvider.cc b/services/camera/virtualcamera/VirtualCameraProvider.cc
index eed3e85..67eaec0 100644
--- a/services/camera/virtualcamera/VirtualCameraProvider.cc
+++ b/services/camera/virtualcamera/VirtualCameraProvider.cc
@@ -150,15 +150,16 @@
}
std::shared_ptr<VirtualCameraDevice> VirtualCameraProvider::createCamera(
- const VirtualCameraConfiguration& configuration, const int cameraId) {
+ const VirtualCameraConfiguration& configuration, const int cameraId,
+ const int32_t deviceId) {
if (cameraId < 0) {
ALOGE("%s: Cannot create camera with negative id. cameraId: %d", __func__,
cameraId);
return nullptr;
}
- auto camera =
- ndk::SharedRefBase::make<VirtualCameraDevice>(cameraId, configuration);
+ auto camera = ndk::SharedRefBase::make<VirtualCameraDevice>(
+ cameraId, configuration, deviceId);
std::shared_ptr<ICameraProviderCallback> callback;
{
const std::lock_guard<std::mutex> lock(mLock);
diff --git a/services/camera/virtualcamera/VirtualCameraProvider.h b/services/camera/virtualcamera/VirtualCameraProvider.h
index c1283a0..c536547 100644
--- a/services/camera/virtualcamera/VirtualCameraProvider.h
+++ b/services/camera/virtualcamera/VirtualCameraProvider.h
@@ -77,7 +77,7 @@
std::shared_ptr<VirtualCameraDevice> createCamera(
const aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
configuration,
- int cameraId);
+ int cameraId, int32_t deviceId);
std::shared_ptr<VirtualCameraDevice> getCamera(const std::string& name);
diff --git a/services/camera/virtualcamera/VirtualCameraService.cc b/services/camera/virtualcamera/VirtualCameraService.cc
index 27873e7..5e3a6d9 100644
--- a/services/camera/virtualcamera/VirtualCameraService.cc
+++ b/services/camera/virtualcamera/VirtualCameraService.cc
@@ -62,6 +62,7 @@
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
constexpr int kMaxFps = 60;
+constexpr int kDefaultDeviceId = 0;
constexpr char kEnableTestCameraCmd[] = "enable_test_camera";
constexpr char kDisableTestCameraCmd[] = "disable_test_camera";
constexpr char kHelp[] = "help";
@@ -186,14 +187,15 @@
ndk::ScopedAStatus VirtualCameraService::registerCamera(
const ::ndk::SpAIBinder& token,
- const VirtualCameraConfiguration& configuration, bool* _aidl_return) {
- return registerCamera(token, configuration, sNextId++, _aidl_return);
+ const VirtualCameraConfiguration& configuration, const int32_t deviceId,
+ bool* _aidl_return) {
+ return registerCamera(token, configuration, sNextId++, deviceId, _aidl_return);
}
ndk::ScopedAStatus VirtualCameraService::registerCamera(
const ::ndk::SpAIBinder& token,
const VirtualCameraConfiguration& configuration, const int cameraId,
- bool* _aidl_return) {
+ const int32_t deviceId, bool* _aidl_return) {
if (!mPermissionProxy.checkCallingPermission(kCreateVirtualDevicePermission)) {
ALOGE("%s: caller (pid %d, uid %d) doesn't hold %s permission", __func__,
getpid(), getuid(), kCreateVirtualDevicePermission);
@@ -225,7 +227,7 @@
}
std::shared_ptr<VirtualCameraDevice> camera =
- mVirtualCameraProvider->createCamera(configuration, cameraId);
+ mVirtualCameraProvider->createCamera(configuration, cameraId, deviceId);
if (camera == nullptr) {
ALOGE("Failed to create camera for binder token 0x%" PRIxPTR,
reinterpret_cast<uintptr_t>(token.get()));
@@ -389,7 +391,7 @@
.maxFps = kMaxFps});
configuration.lensFacing = lensFacing.value_or(LensFacing::EXTERNAL);
registerCamera(mTestCameraToken, configuration, cameraId.value_or(sNextId++),
- &ret);
+ kDefaultDeviceId, &ret);
if (ret) {
dprintf(out, "Successfully registered test camera %s\n",
getCamera(mTestCameraToken)->getCameraName().c_str());
diff --git a/services/camera/virtualcamera/VirtualCameraService.h b/services/camera/virtualcamera/VirtualCameraService.h
index 0b80514..63a8c9d 100644
--- a/services/camera/virtualcamera/VirtualCameraService.h
+++ b/services/camera/virtualcamera/VirtualCameraService.h
@@ -43,14 +43,14 @@
const ::ndk::SpAIBinder& token,
const ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
configuration,
- bool* _aidl_return) override EXCLUDES(mLock);
+ int32_t deviceId, bool* _aidl_return) override EXCLUDES(mLock);
// Register camera corresponding to the binder token.
ndk::ScopedAStatus registerCamera(
const ::ndk::SpAIBinder& token,
const ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration&
configuration,
- int cameraId, bool* _aidl_return) EXCLUDES(mLock);
+ int cameraId, int32_t deviceId, bool* _aidl_return) EXCLUDES(mLock);
// Unregisters camera corresponding to the binder token.
ndk::ScopedAStatus unregisterCamera(const ::ndk::SpAIBinder& token) override
diff --git a/services/camera/virtualcamera/aidl/android/companion/virtualcamera/IVirtualCameraService.aidl b/services/camera/virtualcamera/aidl/android/companion/virtualcamera/IVirtualCameraService.aidl
index bb74f5c..1bd99be 100644
--- a/services/camera/virtualcamera/aidl/android/companion/virtualcamera/IVirtualCameraService.aidl
+++ b/services/camera/virtualcamera/aidl/android/companion/virtualcamera/IVirtualCameraService.aidl
@@ -28,7 +28,8 @@
* Registers a new camera with the virtual camera hal.
* @return true if the camera was successfully registered
*/
- boolean registerCamera(in IBinder token, in VirtualCameraConfiguration configuration);
+ boolean registerCamera(in IBinder token, in VirtualCameraConfiguration configuration,
+ int deviceId);
/**
* Unregisters the camera from the virtual camera hal. After this call the virtual camera won't
diff --git a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
index ad9d83b..5c9b3b9 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraDeviceTest.cc
@@ -64,6 +64,7 @@
constexpr int kHdWidth = 1280;
constexpr int kHdHeight = 720;
constexpr int kMaxFps = 30;
+constexpr int kDefaultDeviceId = 0;
const Stream kVgaYUV420Stream = Stream{
.streamType = StreamType::OUTPUT,
@@ -137,8 +138,8 @@
cameraCharacteristicsForInputFormat) {
const VirtualCameraConfigTestParam& param = GetParam();
std::shared_ptr<VirtualCameraDevice> camera =
- ndk::SharedRefBase::make<VirtualCameraDevice>(kCameraId,
- param.inputConfig);
+ ndk::SharedRefBase::make<VirtualCameraDevice>(
+ kCameraId, param.inputConfig, kDefaultDeviceId);
CameraMetadata metadata;
ASSERT_TRUE(camera->getCameraCharacteristics(&metadata).isOk());
@@ -293,15 +294,17 @@
public:
void SetUp() override {
mCamera = ndk::SharedRefBase::make<VirtualCameraDevice>(
- kCameraId, VirtualCameraConfiguration{
- .supportedStreamConfigs = {SupportedStreamConfiguration{
- .width = kVgaWidth,
- .height = kVgaHeight,
- .pixelFormat = Format::YUV_420_888,
- .maxFps = kMaxFps}},
- .virtualCameraCallback = nullptr,
- .sensorOrientation = SensorOrientation::ORIENTATION_0,
- .lensFacing = LensFacing::FRONT});
+ kCameraId,
+ VirtualCameraConfiguration{
+ .supportedStreamConfigs = {SupportedStreamConfiguration{
+ .width = kVgaWidth,
+ .height = kVgaHeight,
+ .pixelFormat = Format::YUV_420_888,
+ .maxFps = kMaxFps}},
+ .virtualCameraCallback = nullptr,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0,
+ .lensFacing = LensFacing::FRONT},
+ kDefaultDeviceId);
}
protected:
diff --git a/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc b/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
index cd64ca5..f1b2a92 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraProviderTest.cc
@@ -54,6 +54,7 @@
constexpr int kVgaHeight = 480;
constexpr int kMaxFps = 30;
constexpr int kCameraId = 9999;
+constexpr int kDefaultDeviceId = 0;
constexpr char kVirtualCameraNameRegex[] =
"device@[0-9]+\\.[0-9]+/virtual/[0-9]+";
@@ -119,7 +120,7 @@
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfig, kCameraId);
+ mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
EXPECT_THAT(camera, Not(IsNull()));
EXPECT_THAT(camera->getCameraName(), MatchesRegex(kVirtualCameraNameRegex));
@@ -137,7 +138,7 @@
.WillOnce(Return(ndk::ScopedAStatus::ok()));
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfig, kCameraId);
+ mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
// Created camera should be in the list of cameras.
@@ -149,7 +150,7 @@
TEST_F(VirtualCameraProviderTest, RemoveCamera) {
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfig, kCameraId);
+ mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
EXPECT_CALL(*mMockCameraProviderCallback,
cameraDeviceStatusChange(Eq(camera->getCameraName()),
@@ -166,7 +167,7 @@
TEST_F(VirtualCameraProviderTest, RemoveNonExistingCamera) {
ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
std::shared_ptr<VirtualCameraDevice> camera =
- mCameraProvider->createCamera(mInputConfig, kCameraId);
+ mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
// 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 16f40ff..01f2b8c 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraServiceTest.cc
@@ -69,6 +69,7 @@
constexpr SensorOrientation kSensorOrientation =
SensorOrientation::ORIENTATION_0;
constexpr LensFacing kLensFacing = LensFacing::FRONT;
+constexpr int kDefaultDeviceId = 0;
constexpr char kCreateVirtualDevicePermissions[] =
"android.permission.CREATE_VIRTUAL_DEVICE";
@@ -131,8 +132,8 @@
bool aidlRet;
ASSERT_TRUE(mCameraService
- ->registerCamera(mNdkOwnerToken,
- mVgaYUV420OnlyConfiguration, &aidlRet)
+ ->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
+ kDefaultDeviceId, &aidlRet)
.isOk());
ASSERT_TRUE(aidlRet);
}
@@ -196,10 +197,10 @@
ndk::SpAIBinder ndkToken(AIBinder_fromPlatformBinder(token));
bool aidlRet;
- ASSERT_TRUE(
- mCameraService
- ->registerCamera(ndkToken, mVgaYUV420OnlyConfiguration, &aidlRet)
- .isOk());
+ ASSERT_TRUE(mCameraService
+ ->registerCamera(ndkToken, mVgaYUV420OnlyConfiguration,
+ kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_TRUE(aidlRet);
EXPECT_THAT(getCameraIds(), SizeIs(1));
@@ -213,7 +214,9 @@
VirtualCameraConfiguration config =
createConfiguration(kVgaWidth, kVgaHeight, Format::RGBA_8888, kMaxFps);
- ASSERT_TRUE(mCameraService->registerCamera(ndkToken, config, &aidlRet).isOk());
+ ASSERT_TRUE(mCameraService
+ ->registerCamera(ndkToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_TRUE(aidlRet);
EXPECT_THAT(getCameraIds(), SizeIs(1));
@@ -225,7 +228,7 @@
ASSERT_TRUE(mCameraService
->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
- &aidlRet)
+ kDefaultDeviceId, &aidlRet)
.isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), SizeIs(1));
@@ -236,7 +239,8 @@
ASSERT_FALSE(mCameraService
->registerCamera(mNdkOwnerToken,
- kEmptyVirtualCameraConfiguration, &aidlRet)
+ kEmptyVirtualCameraConfiguration,
+ kDefaultDeviceId, &aidlRet)
.isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
@@ -249,7 +253,9 @@
createConfiguration(kVgaWidth, kVgaHeight, Format::UNKNOWN, kMaxFps);
ASSERT_FALSE(
- mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ mCameraService
+ ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
}
@@ -260,7 +266,9 @@
createConfiguration(1000000, 1000000, Format::YUV_420_888, kMaxFps);
ASSERT_FALSE(
- mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ mCameraService
+ ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
}
@@ -271,7 +279,9 @@
createConfiguration(-1, kVgaHeight, Format::YUV_420_888, kMaxFps);
ASSERT_FALSE(
- mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ mCameraService
+ ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
}
@@ -282,7 +292,9 @@
createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 0);
ASSERT_FALSE(
- mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ mCameraService
+ ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
}
@@ -293,7 +305,9 @@
createConfiguration(kVgaWidth, kVgaHeight, Format::YUV_420_888, 90);
ASSERT_FALSE(
- mCameraService->registerCamera(mNdkOwnerToken, config, &aidlRet).isOk());
+ mCameraService
+ ->registerCamera(mNdkOwnerToken, config, kDefaultDeviceId, &aidlRet)
+ .isOk());
EXPECT_FALSE(aidlRet);
EXPECT_THAT(getCameraIds(), IsEmpty());
}
@@ -327,7 +341,7 @@
EXPECT_THAT(mCameraService
->registerCamera(mNdkOwnerToken, mVgaYUV420OnlyConfiguration,
- &aidlRet)
+ kDefaultDeviceId, &aidlRet)
.getExceptionCode(),
Eq(EX_SECURITY));
}
diff --git a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
index 5f313a0..671e031 100644
--- a/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
+++ b/services/camera/virtualcamera/tests/VirtualCameraSessionTest.cc
@@ -47,6 +47,7 @@
constexpr int kStreamId = 0;
constexpr int kSecondStreamId = 1;
constexpr int kCameraId = 42;
+constexpr int kDefaultDeviceId = 0;
using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
using ::aidl::android::companion::virtualcamera::Format;
@@ -160,7 +161,8 @@
.maxFps = kMaxFps}},
.virtualCameraCallback = mMockVirtualCameraClientCallback,
.sensorOrientation = SensorOrientation::ORIENTATION_0,
- .lensFacing = LensFacing::FRONT});
+ .lensFacing = LensFacing::FRONT},
+ kDefaultDeviceId);
mVirtualCameraSession = ndk::SharedRefBase::make<VirtualCameraSession>(
mVirtualCameraDevice, mMockCameraDeviceCallback,
mMockVirtualCameraClientCallback);
@@ -305,11 +307,13 @@
std::shared_ptr<VirtualCameraSession> createSession(
const std::vector<SupportedStreamConfiguration>& supportedInputConfigs) {
mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
- kCameraId, VirtualCameraConfiguration{
- .supportedStreamConfigs = supportedInputConfigs,
- .virtualCameraCallback = mMockVirtualCameraClientCallback,
- .sensorOrientation = SensorOrientation::ORIENTATION_0,
- .lensFacing = LensFacing::FRONT});
+ kCameraId,
+ VirtualCameraConfiguration{
+ .supportedStreamConfigs = supportedInputConfigs,
+ .virtualCameraCallback = mMockVirtualCameraClientCallback,
+ .sensorOrientation = SensorOrientation::ORIENTATION_0,
+ .lensFacing = LensFacing::FRONT},
+ kDefaultDeviceId);
return ndk::SharedRefBase::make<VirtualCameraSession>(
mVirtualCameraDevice, mMockCameraDeviceCallback,
mMockVirtualCameraClientCallback);
diff --git a/services/camera/virtualcamera/util/MetadataUtil.cc b/services/camera/virtualcamera/util/MetadataUtil.cc
index 822862b..4eeff67 100644
--- a/services/camera/virtualcamera/util/MetadataUtil.cc
+++ b/services/camera/virtualcamera/util/MetadataUtil.cc
@@ -67,6 +67,11 @@
return *this;
}
+MetadataBuilder& MetadataBuilder::setDeviceId(int32_t deviceId) {
+ mEntryMap[ANDROID_INFO_DEVICE_ID] = std::vector<int32_t>({deviceId});
+ return *this;
+}
+
MetadataBuilder& MetadataBuilder::setFlashAvailable(bool flashAvailable) {
const uint8_t metadataVal = flashAvailable
? ANDROID_FLASH_INFO_AVAILABLE_TRUE
diff --git a/services/camera/virtualcamera/util/MetadataUtil.h b/services/camera/virtualcamera/util/MetadataUtil.h
index cee867e..4d2500b 100644
--- a/services/camera/virtualcamera/util/MetadataUtil.h
+++ b/services/camera/virtualcamera/util/MetadataUtil.h
@@ -66,6 +66,9 @@
MetadataBuilder& setSupportedHardwareLevel(
camera_metadata_enum_android_info_supported_hardware_level_t hwLevel);
+ // See ANDROID_INFO_DEVICE_ID in CameraMetadataTag.aidl.
+ MetadataBuilder& setDeviceId(int32_t deviceId);
+
// Whether this camera device has a flash unit
// See ANDROID_FLASH_INFO_AVAILABLE in CameraMetadataTag.aidl.
MetadataBuilder& setFlashAvailable(bool flashAvailable);