blob: bd07f9de1a9ffdec2330a1302b83718b65a790ae [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/camera/lib/fake_legacy_stream/fake_legacy_stream.h"
#include <fuchsia/camera2/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <zircon/errors.h>
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
class FakeLegacyStreamTest : public gtest::TestLoopFixture {
protected:
void SetUp() override {
auto result =
camera::FakeLegacyStream::Create(stream_.NewRequest(), allocator_, 0, dispatcher());
ASSERT_TRUE(result.is_ok());
fake_legacy_stream_ = result.take_value();
stream_.set_error_handler(
[](zx_status_t status) { ADD_FAILURE() << "Stream server disconnected: " << status; });
stream_.events().OnFrameAvailable = [this](fuchsia::camera2::FrameAvailableInfo info) {
stream_->ReleaseFrame(info.buffer_id);
frames_.push_back(std::move(info));
};
stream_->Start();
RunLoopUntilIdle();
}
void TearDown() override {
stream_ = nullptr;
fake_legacy_stream_ = nullptr;
}
fuchsia::camera2::StreamPtr stream_;
std::unique_ptr<camera::FakeLegacyStream> fake_legacy_stream_;
std::vector<fuchsia::camera2::FrameAvailableInfo> frames_;
fuchsia::sysmem::AllocatorPtr allocator_;
};
// Conformant Stream client.
TEST_F(FakeLegacyStreamTest, GoodClient) {
bool callback_called = false;
stream_->GetImageFormats([&](std::vector<fuchsia::sysmem::ImageFormat_2> formats) {
callback_called = true;
ASSERT_GT(formats.size(), 0u);
});
RunLoopUntilIdle();
EXPECT_TRUE(callback_called);
EXPECT_EQ(frames_.size(), 0u);
const fuchsia::camera2::FrameAvailableInfo kFrame{
.frame_status = fuchsia::camera2::FrameStatus::OK,
.buffer_id = 42,
};
fuchsia::camera2::FrameAvailableInfo frame_copy;
ASSERT_EQ(kFrame.Clone(&frame_copy), ZX_OK);
EXPECT_EQ(fake_legacy_stream_->SendFrameAvailable(std::move(frame_copy)), ZX_OK);
RunLoopUntilIdle();
ASSERT_EQ(frames_.size(), 1u);
EXPECT_EQ(frames_[0].frame_status, kFrame.frame_status);
EXPECT_EQ(frames_[0].buffer_id, kFrame.buffer_id);
callback_called = false;
stream_->SetImageFormat(0, [&](zx_status_t status) {
callback_called = true;
EXPECT_EQ(status, ZX_OK);
});
RunLoopUntilIdle();
EXPECT_TRUE(callback_called);
callback_called = false;
stream_->SetRegionOfInterest(0, 0, 1, 1, [&](zx_status_t status) {
callback_called = true;
EXPECT_EQ(status, ZX_OK);
});
RunLoopUntilIdle();
EXPECT_TRUE(callback_called);
auto result = fake_legacy_stream_->StreamClientStatus();
EXPECT_TRUE(result.is_ok());
}
// Calls Start while started.
TEST_F(FakeLegacyStreamTest, BadClient1) {
stream_->Start();
RunLoopUntilIdle();
auto result = fake_legacy_stream_->StreamClientStatus();
ASSERT_TRUE(result.is_error());
std::cerr << result.error() << std::endl;
}
// Releases an unheld frame.
TEST_F(FakeLegacyStreamTest, BadClient2) {
stream_->ReleaseFrame(0);
RunLoopUntilIdle();
auto result = fake_legacy_stream_->StreamClientStatus();
ASSERT_TRUE(result.is_error());
std::cerr << result.error() << std::endl;
}
// Invalid region of interest.
TEST_F(FakeLegacyStreamTest, BadClient3) {
bool callback_called = false;
stream_->SetRegionOfInterest(1, 1, 0, 0, [&](zx_status_t status) {
callback_called = true;
EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
});
RunLoopUntilIdle();
EXPECT_TRUE(callback_called);
auto result = fake_legacy_stream_->StreamClientStatus();
ASSERT_TRUE(result.is_error());
std::cerr << result.error() << std::endl;
}
// Threading assert.
TEST_F(FakeLegacyStreamTest, WrongDispatcher) {
fuchsia::camera2::StreamPtr stream;
async::Loop other(&kAsyncLoopConfigNoAttachToCurrentThread);
auto result =
camera::FakeLegacyStream::Create(stream.NewRequest(), allocator_, 0, other.dispatcher());
ASSERT_TRUE(result.is_ok());
auto fake = result.take_value();
ASSERT_DEATH(fake->IsStreaming(), ".*thread.*");
}