Move virtual camera service to frameworks/av/services
Bug: 311647154
Bug: 301023410
Test: atest virtual_camera_tests
Test: build & flash & adb shell cmd virtual_camera help
Change-Id: I6d43a2b70f454c9c01ec2abcae9f138cd78c6a85
diff --git a/services/camera/virtualcamera/tests/VirtualCameraRenderThreadTest.cc b/services/camera/virtualcamera/tests/VirtualCameraRenderThreadTest.cc
new file mode 100644
index 0000000..2e40d16
--- /dev/null
+++ b/services/camera/virtualcamera/tests/VirtualCameraRenderThreadTest.cc
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/cdefs.h>
+
+#include <memory>
+
+#include "VirtualCameraRenderThread.h"
+#include "VirtualCameraSessionContext.h"
+#include "aidl/android/hardware/camera/common/CameraDeviceStatus.h"
+#include "aidl/android/hardware/camera/common/TorchModeStatus.h"
+#include "aidl/android/hardware/camera/device/BnCameraDeviceCallback.h"
+#include "aidl/android/hardware/camera/device/BufferRequest.h"
+#include "aidl/android/hardware/camera/device/BufferRequestStatus.h"
+#include "aidl/android/hardware/camera/device/BufferStatus.h"
+#include "aidl/android/hardware/camera/device/CaptureResult.h"
+#include "aidl/android/hardware/camera/device/NotifyMsg.h"
+#include "aidl/android/hardware/camera/device/StreamBuffer.h"
+#include "aidl/android/hardware/camera/device/StreamBufferRet.h"
+#include "android/binder_auto_utils.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace android {
+namespace companion {
+namespace virtualcamera {
+namespace {
+
+using ::aidl::android::hardware::camera::common::CameraDeviceStatus;
+using ::aidl::android::hardware::camera::common::TorchModeStatus;
+using ::aidl::android::hardware::camera::device::BnCameraDeviceCallback;
+using ::aidl::android::hardware::camera::device::BufferRequest;
+using ::aidl::android::hardware::camera::device::BufferRequestStatus;
+using ::aidl::android::hardware::camera::device::BufferStatus;
+using ::aidl::android::hardware::camera::device::CaptureResult;
+using ::aidl::android::hardware::camera::device::ErrorMsg;
+using ::aidl::android::hardware::camera::device::NotifyMsg;
+using ::aidl::android::hardware::camera::device::StreamBuffer;
+using ::aidl::android::hardware::camera::device::StreamBufferRet;
+using ::testing::AllOf;
+using ::testing::ElementsAre;
+using ::testing::Eq;
+using ::testing::Field;
+using ::testing::Matcher;
+using ::testing::Property;
+using ::testing::Return;
+using ::testing::SizeIs;
+
+constexpr int kInputWidth = 640;
+constexpr int kInputHeight = 480;
+
+Matcher<StreamBuffer> IsStreamBufferWithStatus(const int streamId,
+ const int bufferId,
+ const BufferStatus status) {
+ return AllOf(Field(&StreamBuffer::streamId, Eq(streamId)),
+ Field(&StreamBuffer::bufferId, Eq(bufferId)),
+ Field(&StreamBuffer::status, Eq(status)));
+}
+
+Matcher<NotifyMsg> IsRequestErrorNotifyMsg(const int frameId) {
+ return AllOf(Property(&NotifyMsg::getTag, Eq(NotifyMsg::error)),
+ Property(&NotifyMsg::get<NotifyMsg::error>,
+ Field(&ErrorMsg::frameNumber, Eq(frameId))));
+}
+
+class MockCameraDeviceCallback : public BnCameraDeviceCallback {
+ public:
+ MOCK_METHOD(ndk::ScopedAStatus, notify, (const std::vector<NotifyMsg>&),
+ (override));
+ MOCK_METHOD(ndk::ScopedAStatus, processCaptureResult,
+ (const std::vector<CaptureResult>&), (override));
+ MOCK_METHOD(ndk::ScopedAStatus, requestStreamBuffers,
+ (const std::vector<BufferRequest>&, std::vector<StreamBufferRet>*,
+ BufferRequestStatus*),
+ (override));
+ MOCK_METHOD(ndk::ScopedAStatus, returnStreamBuffers,
+ (const std::vector<StreamBuffer>&), (override));
+};
+
+class VirtualCameraRenderThreadTest : public ::testing::Test {
+ public:
+ void SetUp() override {
+ mSessionContext = std::make_unique<VirtualCameraSessionContext>();
+ mMockCameraDeviceCallback =
+ ndk::SharedRefBase::make<MockCameraDeviceCallback>();
+ mRenderThread = std::make_unique<VirtualCameraRenderThread>(
+ *mSessionContext, kInputWidth, kInputHeight, mMockCameraDeviceCallback);
+ }
+
+ protected:
+ std::unique_ptr<VirtualCameraSessionContext> mSessionContext;
+ std::unique_ptr<VirtualCameraRenderThread> mRenderThread;
+ std::shared_ptr<MockCameraDeviceCallback> mMockCameraDeviceCallback;
+};
+
+TEST_F(VirtualCameraRenderThreadTest, FlushReturnsErrorForInFlightRequests) {
+ const int frameNumber = 42;
+ const int firstStreamId = 1;
+ const int firstStreamBufferId = 1234;
+ const int secondStreamId = 7;
+ const int secondStreamBufferId = 4321;
+
+ // Notify should be called with the error set to corresponding frame.
+ EXPECT_CALL(*mMockCameraDeviceCallback,
+ notify(ElementsAre(IsRequestErrorNotifyMsg(frameNumber))))
+ .WillOnce(Return(ndk::ScopedAStatus::ok()));
+
+ // Process capture result should be called with all buffers in error state.
+ EXPECT_CALL(
+ *mMockCameraDeviceCallback,
+ processCaptureResult(ElementsAre(AllOf(
+ Field(&CaptureResult::frameNumber, frameNumber),
+ Field(&CaptureResult::outputBuffers,
+ testing::UnorderedElementsAre(
+ IsStreamBufferWithStatus(firstStreamId, firstStreamBufferId,
+ BufferStatus::ERROR),
+ IsStreamBufferWithStatus(secondStreamId, secondStreamBufferId,
+ BufferStatus::ERROR)))))))
+ .WillOnce([]() { return ndk::ScopedAStatus::ok(); });
+
+ mRenderThread->enqueueTask(std::make_unique<ProcessCaptureRequestTask>(
+ frameNumber,
+ std::vector<CaptureRequestBuffer>{
+ CaptureRequestBuffer(firstStreamId, firstStreamBufferId),
+ CaptureRequestBuffer(secondStreamId, secondStreamBufferId)}));
+
+ mRenderThread->flush();
+}
+
+} // namespace
+} // namespace virtualcamera
+} // namespace companion
+} // namespace android
\ No newline at end of file