blob: f1b2a9286cf773e3ce964c1e724896f148e0f9b5 [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
Biswarup Pal6152a302023-12-19 12:44:09 +00002 * Copyright 2023 The Android Open Source Project
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <memory>
18
19#include "VirtualCameraProvider.h"
20#include "aidl/android/hardware/camera/common/CameraDeviceStatus.h"
21#include "aidl/android/hardware/camera/common/Status.h"
22#include "aidl/android/hardware/camera/common/TorchModeStatus.h"
23#include "aidl/android/hardware/camera/provider/BnCameraProviderCallback.h"
24#include "android/binder_auto_utils.h"
25#include "android/binder_interface_utils.h"
26#include "gmock/gmock.h"
27#include "gtest/gtest.h"
28#include "util/Util.h"
29
30namespace android {
31namespace companion {
32namespace virtualcamera {
33namespace {
34
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010035using ::aidl::android::companion::virtualcamera::Format;
Biswarup Pal112458f2023-12-28 19:50:17 +000036using ::aidl::android::companion::virtualcamera::LensFacing;
Biswarup Pal6152a302023-12-19 12:44:09 +000037using ::aidl::android::companion::virtualcamera::SensorOrientation;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010038using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
Biswarup Pal6152a302023-12-19 12:44:09 +000039using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010040using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
41using ::aidl::android::hardware::camera::common::Status;
42using ::aidl::android::hardware::camera::common::TorchModeStatus;
43using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
44using ::testing::_;
45using ::testing::ElementsAre;
46using ::testing::Eq;
47using ::testing::IsEmpty;
48using ::testing::IsNull;
49using ::testing::MatchesRegex;
50using ::testing::Not;
51using ::testing::Return;
52
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010053constexpr int kVgaWidth = 640;
54constexpr int kVgaHeight = 480;
Biswarup Pal6152a302023-12-19 12:44:09 +000055constexpr int kMaxFps = 30;
Marvin Ramina8196132024-03-15 15:55:22 +000056constexpr int kCameraId = 9999;
Biswarup Pal37a75182024-01-16 15:53:35 +000057constexpr int kDefaultDeviceId = 0;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010058constexpr char kVirtualCameraNameRegex[] =
59 "device@[0-9]+\\.[0-9]+/virtual/[0-9]+";
60
61class MockCameraProviderCallback : public BnCameraProviderCallback {
62 public:
63 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
64 (const std::string&, CameraDeviceStatus), (override));
65 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
66 (const std::string&, TorchModeStatus), (override));
67 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
68 (const std::string&, const std::string&, CameraDeviceStatus),
69 (override));
70};
71
72class VirtualCameraProviderTest : public ::testing::Test {
73 public:
74 void SetUp() override {
75 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
76 mMockCameraProviderCallback =
77 ndk::SharedRefBase::make<MockCameraProviderCallback>();
78 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
79 .WillByDefault([](const std::string&, CameraDeviceStatus) {
80 return ndk::ScopedAStatus::ok();
81 });
82 }
83
84 protected:
85 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
86 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
87 ndk::SharedRefBase::make<MockCameraProviderCallback>();
Biswarup Pal6152a302023-12-19 12:44:09 +000088 VirtualCameraConfiguration mInputConfig = VirtualCameraConfiguration{
89 .supportedStreamConfigs = {SupportedStreamConfiguration{
90 .width = kVgaWidth,
91 .height = kVgaHeight,
92 .pixelFormat = Format::YUV_420_888,
93 .maxFps = kMaxFps}},
94 .virtualCameraCallback = nullptr,
Biswarup Pal112458f2023-12-28 19:50:17 +000095 .sensorOrientation = SensorOrientation::ORIENTATION_0,
96 .lensFacing = LensFacing::FRONT};
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010097};
98
99TEST_F(VirtualCameraProviderTest, SetNullCameraCallbackFails) {
100 // Attempting to set callback to nullptr should fail.
101 EXPECT_FALSE(mCameraProvider->setCallback(nullptr).isOk());
102}
103
104TEST_F(VirtualCameraProviderTest, NoCamerasInitially) {
105 std::vector<std::string> cameras;
106
107 // Initially, the camera provider should return empty list
108 // of cameras.
109 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameras).isOk());
110 EXPECT_THAT(cameras, IsEmpty());
111}
112
113TEST_F(VirtualCameraProviderTest, CreateCamera) {
114 // When new camera is created, we expect
115 // cameraDeviceStatusChange to be called exactly once with
116 // PRESENT status.
117 EXPECT_CALL(*mMockCameraProviderCallback,
118 cameraDeviceStatusChange(_, CameraDeviceStatus::PRESENT))
119 .WillOnce(Return(ndk::ScopedAStatus::ok()));
120
121 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100122 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal37a75182024-01-16 15:53:35 +0000123 mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100124 EXPECT_THAT(camera, Not(IsNull()));
125 EXPECT_THAT(camera->getCameraName(), MatchesRegex(kVirtualCameraNameRegex));
126
127 // Created camera should be in the list of cameras.
128 std::vector<std::string> cameraIds;
129 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
130 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
131}
132
133TEST_F(VirtualCameraProviderTest, CreateCameraBeforeCallbackIsSet) {
134 // We expect cameraDeviceStatusChange to be invoked even when the
135 // setCallback configures the callback after camera is already created.
136 EXPECT_CALL(*mMockCameraProviderCallback,
137 cameraDeviceStatusChange(_, CameraDeviceStatus::PRESENT))
138 .WillOnce(Return(ndk::ScopedAStatus::ok()));
139
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100140 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal37a75182024-01-16 15:53:35 +0000141 mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100142 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
143
144 // Created camera should be in the list of cameras.
145 std::vector<std::string> cameraIds;
146 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
147 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
148}
149
150TEST_F(VirtualCameraProviderTest, RemoveCamera) {
151 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100152 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal37a75182024-01-16 15:53:35 +0000153 mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100154
155 EXPECT_CALL(*mMockCameraProviderCallback,
156 cameraDeviceStatusChange(Eq(camera->getCameraName()),
157 CameraDeviceStatus::NOT_PRESENT))
158 .WillOnce(Return(ndk::ScopedAStatus::ok()));
159 EXPECT_TRUE(mCameraProvider->removeCamera(camera->getCameraName()));
160
161 // There are no cameras present after only camera is removed.
162 std::vector<std::string> cameraIds;
163 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
164 EXPECT_THAT(cameraIds, IsEmpty());
165}
166
167TEST_F(VirtualCameraProviderTest, RemoveNonExistingCamera) {
168 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100169 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal37a75182024-01-16 15:53:35 +0000170 mCameraProvider->createCamera(mInputConfig, kCameraId, kDefaultDeviceId);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100171
172 // Removing non-existing camera should fail.
173 const std::string cameraName = "DefinitelyNoTCamera";
174 EXPECT_FALSE(mCameraProvider->removeCamera(cameraName));
175
176 // Camera should be still present in the camera list.
177 std::vector<std::string> cameraIds;
178 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
179 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
180}
181
182} // namespace
183} // namespace virtualcamera
184} // namespace companion
185} // namespace android