blob: 5da080b76c5575465322275ae3f968112468b273 [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 <cstdint>
18#include <memory>
19
20#include "VirtualCameraSession.h"
21#include "aidl/android/companion/virtualcamera/BnVirtualCameraCallback.h"
22#include "aidl/android/companion/virtualcamera/IVirtualCameraCallback.h"
23#include "aidl/android/hardware/camera/device/BnCameraDeviceCallback.h"
24#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
25#include "aidl/android/hardware/graphics/common/PixelFormat.h"
26#include "android/binder_auto_utils.h"
27#include "android/binder_interface_utils.h"
28#include "gmock/gmock.h"
29#include "gtest/gtest.h"
30#include "util/MetadataBuilder.h"
31
32namespace android {
33namespace companion {
34namespace virtualcamera {
35namespace {
36
37constexpr int kWidth = 640;
38constexpr int kHeight = 480;
39constexpr int kStreamId = 0;
40const std::string kCameraName = "virtual_camera";
41
42using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
43using ::aidl::android::companion::virtualcamera::Format;
44using ::aidl::android::hardware::camera::device::BnCameraDeviceCallback;
45using ::aidl::android::hardware::camera::device::BufferRequest;
46using ::aidl::android::hardware::camera::device::BufferRequestStatus;
47using ::aidl::android::hardware::camera::device::CaptureRequest;
48using ::aidl::android::hardware::camera::device::CaptureResult;
49using ::aidl::android::hardware::camera::device::HalStream;
50using ::aidl::android::hardware::camera::device::NotifyMsg;
51using ::aidl::android::hardware::camera::device::Stream;
52using ::aidl::android::hardware::camera::device::StreamBuffer;
53using ::aidl::android::hardware::camera::device::StreamBufferRet;
54using ::aidl::android::hardware::camera::device::StreamConfiguration;
55using ::aidl::android::hardware::graphics::common::PixelFormat;
56using ::aidl::android::view::Surface;
57using ::testing::_;
58using ::testing::ElementsAre;
59using ::testing::Eq;
60using ::testing::Return;
61using ::testing::SizeIs;
62
63Stream createStream(int streamId, int width, int height, PixelFormat format) {
64 Stream s;
65 s.id = streamId;
66 s.width = width;
67 s.height = height;
68 s.format = format;
69 return s;
70}
71
72class MockCameraDeviceCallback : public BnCameraDeviceCallback {
73 public:
74 MOCK_METHOD(ndk::ScopedAStatus, notify, (const std::vector<NotifyMsg>&),
75 (override));
76 MOCK_METHOD(ndk::ScopedAStatus, processCaptureResult,
77 (const std::vector<CaptureResult>&), (override));
78 MOCK_METHOD(ndk::ScopedAStatus, requestStreamBuffers,
79 (const std::vector<BufferRequest>&, std::vector<StreamBufferRet>*,
80 BufferRequestStatus*),
81 (override));
82 MOCK_METHOD(ndk::ScopedAStatus, returnStreamBuffers,
83 (const std::vector<StreamBuffer>&), (override));
84};
85
86class MockVirtualCameraCallback : public BnVirtualCameraCallback {
87 public:
88 MOCK_METHOD(ndk::ScopedAStatus, onStreamConfigured,
89 (int, const Surface&, int32_t, int32_t, Format), (override));
90 MOCK_METHOD(ndk::ScopedAStatus, onProcessCaptureRequest, (int, int),
91 (override));
92 MOCK_METHOD(ndk::ScopedAStatus, onStreamClosed, (int), (override));
93};
94
95class VirtualCameraSessionTest : public ::testing::Test {
96 public:
97 void SetUp() override {
98 mMockCameraDeviceCallback =
99 ndk::SharedRefBase::make<MockCameraDeviceCallback>();
100 mMockVirtualCameraClientCallback =
101 ndk::SharedRefBase::make<MockVirtualCameraCallback>();
102 mVirtualCameraSession = ndk::SharedRefBase::make<VirtualCameraSession>(
103 kCameraName, mMockCameraDeviceCallback,
104 mMockVirtualCameraClientCallback);
105
106 ON_CALL(*mMockVirtualCameraClientCallback, onStreamConfigured)
107 .WillByDefault(ndk::ScopedAStatus::ok);
108 ON_CALL(*mMockVirtualCameraClientCallback, onProcessCaptureRequest)
109 .WillByDefault(ndk::ScopedAStatus::ok);
110 }
111
112 protected:
113 std::shared_ptr<MockCameraDeviceCallback> mMockCameraDeviceCallback;
114 std::shared_ptr<MockVirtualCameraCallback> mMockVirtualCameraClientCallback;
115 std::shared_ptr<VirtualCameraSession> mVirtualCameraSession;
116};
117
118TEST_F(VirtualCameraSessionTest, ConfigureTriggersClientConfigureCallback) {
119 PixelFormat format = PixelFormat::YCBCR_420_888;
120 StreamConfiguration streamConfiguration;
121 streamConfiguration.streams = {
122 createStream(kStreamId, kWidth, kHeight, format)};
123 std::vector<HalStream> halStreams;
124 EXPECT_CALL(
125 *mMockVirtualCameraClientCallback,
126 onStreamConfigured(kStreamId, _, kWidth, kHeight, Format::YUV_420_888));
127
128 ASSERT_TRUE(
129 mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
130 .isOk());
131
132 EXPECT_THAT(halStreams, SizeIs(streamConfiguration.streams.size()));
133 EXPECT_THAT(mVirtualCameraSession->getStreamIds(), ElementsAre(0));
134}
135
136TEST_F(VirtualCameraSessionTest, SecondConfigureDropsUnreferencedStreams) {
137 PixelFormat format = PixelFormat::YCBCR_420_888;
138 StreamConfiguration streamConfiguration;
139 std::vector<HalStream> halStreams;
140
141 streamConfiguration.streams = {createStream(0, kWidth, kHeight, format),
142 createStream(1, kWidth, kHeight, format),
143 createStream(2, kWidth, kHeight, format)};
144 ASSERT_TRUE(
145 mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
146 .isOk());
147
148 EXPECT_THAT(mVirtualCameraSession->getStreamIds(), ElementsAre(0, 1, 2));
149
150 streamConfiguration.streams = {createStream(0, kWidth, kHeight, format),
151 createStream(2, kWidth, kHeight, format),
152 createStream(3, kWidth, kHeight, format)};
153 ASSERT_TRUE(
154 mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
155 .isOk());
156
157 EXPECT_THAT(mVirtualCameraSession->getStreamIds(), ElementsAre(0, 2, 3));
158}
159
160TEST_F(VirtualCameraSessionTest, CloseTriggersClientTerminateCallback) {
161 EXPECT_CALL(*mMockVirtualCameraClientCallback, onStreamClosed(kStreamId))
162 .WillOnce(Return(ndk::ScopedAStatus::ok()));
163
164 ASSERT_TRUE(mVirtualCameraSession->close().isOk());
165}
166
167TEST_F(VirtualCameraSessionTest, onProcessCaptureRequestTriggersClientCallback) {
168 StreamConfiguration streamConfiguration;
169 streamConfiguration.streams = {
170 createStream(kStreamId, kWidth, kHeight, PixelFormat::YCBCR_420_888)};
171 std::vector<CaptureRequest> requests(1);
172 requests[0].frameNumber = 42;
173 requests[0].settings = *(
174 MetadataBuilder().setControlAfMode(ANDROID_CONTROL_AF_MODE_AUTO).build());
175
176 std::vector<HalStream> halStreams;
177 ASSERT_TRUE(
178 mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
179 .isOk());
180
181 EXPECT_CALL(*mMockVirtualCameraClientCallback,
182 onProcessCaptureRequest(kStreamId, requests[0].frameNumber))
183 .WillOnce(Return(ndk::ScopedAStatus::ok()));
184 int32_t aidlReturn = 0;
185 ASSERT_TRUE(mVirtualCameraSession
186 ->processCaptureRequest(requests, /*in_cachesToRemove=*/{},
187 &aidlReturn)
188 .isOk());
189 EXPECT_THAT(aidlReturn, Eq(requests.size()));
190}
191
192} // namespace
193} // namespace virtualcamera
194} // namespace companion
195} // namespace android