blob: 615a77c5d58d2d2282ca0b7778900a884c09832d [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
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;
36using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010037using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
38using ::aidl::android::hardware::camera::common::Status;
39using ::aidl::android::hardware::camera::common::TorchModeStatus;
40using ::aidl::android::hardware::camera::provider::BnCameraProviderCallback;
41using ::testing::_;
42using ::testing::ElementsAre;
43using ::testing::Eq;
44using ::testing::IsEmpty;
45using ::testing::IsNull;
46using ::testing::MatchesRegex;
47using ::testing::Not;
48using ::testing::Return;
49
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010050constexpr int kVgaWidth = 640;
51constexpr int kVgaHeight = 480;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010052constexpr char kVirtualCameraNameRegex[] =
53 "device@[0-9]+\\.[0-9]+/virtual/[0-9]+";
54
55class MockCameraProviderCallback : public BnCameraProviderCallback {
56 public:
57 MOCK_METHOD(ndk::ScopedAStatus, cameraDeviceStatusChange,
58 (const std::string&, CameraDeviceStatus), (override));
59 MOCK_METHOD(ndk::ScopedAStatus, torchModeStatusChange,
60 (const std::string&, TorchModeStatus), (override));
61 MOCK_METHOD(ndk::ScopedAStatus, physicalCameraDeviceStatusChange,
62 (const std::string&, const std::string&, CameraDeviceStatus),
63 (override));
64};
65
66class VirtualCameraProviderTest : public ::testing::Test {
67 public:
68 void SetUp() override {
69 mCameraProvider = ndk::SharedRefBase::make<VirtualCameraProvider>();
70 mMockCameraProviderCallback =
71 ndk::SharedRefBase::make<MockCameraProviderCallback>();
72 ON_CALL(*mMockCameraProviderCallback, cameraDeviceStatusChange)
73 .WillByDefault([](const std::string&, CameraDeviceStatus) {
74 return ndk::ScopedAStatus::ok();
75 });
76 }
77
78 protected:
79 std::shared_ptr<VirtualCameraProvider> mCameraProvider;
80 std::shared_ptr<MockCameraProviderCallback> mMockCameraProviderCallback =
81 ndk::SharedRefBase::make<MockCameraProviderCallback>();
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010082 std::vector<SupportedStreamConfiguration> mInputConfigs = {
83 SupportedStreamConfiguration{.width = kVgaWidth,
84 .height = kVgaHeight,
85 .pixelFormat = Format::YUV_420_888}};
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010086};
87
88TEST_F(VirtualCameraProviderTest, SetNullCameraCallbackFails) {
89 // Attempting to set callback to nullptr should fail.
90 EXPECT_FALSE(mCameraProvider->setCallback(nullptr).isOk());
91}
92
93TEST_F(VirtualCameraProviderTest, NoCamerasInitially) {
94 std::vector<std::string> cameras;
95
96 // Initially, the camera provider should return empty list
97 // of cameras.
98 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameras).isOk());
99 EXPECT_THAT(cameras, IsEmpty());
100}
101
102TEST_F(VirtualCameraProviderTest, CreateCamera) {
103 // When new camera is created, we expect
104 // cameraDeviceStatusChange to be called exactly once with
105 // PRESENT status.
106 EXPECT_CALL(*mMockCameraProviderCallback,
107 cameraDeviceStatusChange(_, CameraDeviceStatus::PRESENT))
108 .WillOnce(Return(ndk::ScopedAStatus::ok()));
109
110 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100111 std::shared_ptr<VirtualCameraDevice> camera =
112 mCameraProvider->createCamera(mInputConfigs);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100113 EXPECT_THAT(camera, Not(IsNull()));
114 EXPECT_THAT(camera->getCameraName(), MatchesRegex(kVirtualCameraNameRegex));
115
116 // Created camera should be in the list of cameras.
117 std::vector<std::string> cameraIds;
118 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
119 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
120}
121
122TEST_F(VirtualCameraProviderTest, CreateCameraBeforeCallbackIsSet) {
123 // We expect cameraDeviceStatusChange to be invoked even when the
124 // setCallback configures the callback after camera is already created.
125 EXPECT_CALL(*mMockCameraProviderCallback,
126 cameraDeviceStatusChange(_, CameraDeviceStatus::PRESENT))
127 .WillOnce(Return(ndk::ScopedAStatus::ok()));
128
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100129 std::shared_ptr<VirtualCameraDevice> camera =
130 mCameraProvider->createCamera(mInputConfigs);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100131 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
132
133 // Created camera should be in the list of cameras.
134 std::vector<std::string> cameraIds;
135 EXPECT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
136 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
137}
138
139TEST_F(VirtualCameraProviderTest, RemoveCamera) {
140 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100141 std::shared_ptr<VirtualCameraDevice> camera =
142 mCameraProvider->createCamera(mInputConfigs);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100143
144 EXPECT_CALL(*mMockCameraProviderCallback,
145 cameraDeviceStatusChange(Eq(camera->getCameraName()),
146 CameraDeviceStatus::NOT_PRESENT))
147 .WillOnce(Return(ndk::ScopedAStatus::ok()));
148 EXPECT_TRUE(mCameraProvider->removeCamera(camera->getCameraName()));
149
150 // There are no cameras present after only camera is removed.
151 std::vector<std::string> cameraIds;
152 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
153 EXPECT_THAT(cameraIds, IsEmpty());
154}
155
156TEST_F(VirtualCameraProviderTest, RemoveNonExistingCamera) {
157 ASSERT_TRUE(mCameraProvider->setCallback(mMockCameraProviderCallback).isOk());
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100158 std::shared_ptr<VirtualCameraDevice> camera =
159 mCameraProvider->createCamera(mInputConfigs);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100160
161 // Removing non-existing camera should fail.
162 const std::string cameraName = "DefinitelyNoTCamera";
163 EXPECT_FALSE(mCameraProvider->removeCamera(cameraName));
164
165 // Camera should be still present in the camera list.
166 std::vector<std::string> cameraIds;
167 ASSERT_TRUE(mCameraProvider->getCameraIdList(&cameraIds).isOk());
168 EXPECT_THAT(cameraIds, ElementsAre(camera->getCameraName()));
169}
170
171} // namespace
172} // namespace virtualcamera
173} // namespace companion
174} // namespace android