blob: 63c76e0f2d437c06180ebbac914949e180be413a [file] [log] [blame]
// Copyright 2020 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/bin/device/sysmem_allocator.h"
#include <fuchsia/sysmem/cpp/fidl_test_base.h>
#include <lib/async/cpp/executor.h>
#include <lib/fidl/cpp/binding.h>
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
namespace camera {
namespace {
class FakeBufferCollection : public fuchsia::sysmem::testing::BufferCollection_TestBase {
public:
FakeBufferCollection(fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> request)
: binding_{this, std::move(request)} {}
void PeerClose() { binding_.Unbind(); }
void CompleteBufferAllocation(zx_status_t status,
fuchsia::sysmem::BufferCollectionInfo_2 collection) {
ASSERT_TRUE(allocated_callback_);
allocated_callback_(status, std::move(collection));
allocated_callback_ = nullptr;
}
private:
// |fuchsia::sysmem::BufferCollection|
void Close() override { binding_.Close(ZX_OK); }
void SetName(uint32_t priority, std::string name) override {}
void SetConstraints(bool has_constraints,
fuchsia::sysmem::BufferCollectionConstraints constraints) override {}
void WaitForBuffersAllocated(WaitForBuffersAllocatedCallback callback) override {
allocated_callback_ = std::move(callback);
}
void AttachLifetimeTracking(zx::eventpair server_end, uint32_t buffers_remaining) override {
lifetime_tracking_ = std::move(server_end);
}
void NotImplemented_(const std::string& name) override {
FAIL() << "Not Implemented BufferCollection." << name;
}
fidl::Binding<fuchsia::sysmem::BufferCollection> binding_;
WaitForBuffersAllocatedCallback allocated_callback_;
zx::eventpair lifetime_tracking_;
};
class FakeAllocator : public fuchsia::sysmem::testing::Allocator_TestBase {
public:
fuchsia::sysmem::AllocatorHandle NewBinding() { return binding_.NewBinding(); }
const std::vector<std::unique_ptr<FakeBufferCollection>>& bound_collections() const {
return collections_;
}
private:
// |fuchsia::sysmem::Allocator|
void AllocateNonSharedCollection(
fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> request) override {
collections_.emplace_back(std::make_unique<FakeBufferCollection>(std::move(request)));
}
void BindSharedCollection(
fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token,
fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> request) override {
collections_.emplace_back(std::make_unique<FakeBufferCollection>(std::move(request)));
}
void NotImplemented_(const std::string& name) override {
FAIL() << "Not Implemented Allocator." << name;
}
fidl::Binding<fuchsia::sysmem::Allocator> binding_{this};
std::vector<std::unique_ptr<FakeBufferCollection>> collections_;
};
class SysmemAllocatorTest : public gtest::TestLoopFixture {
protected:
FakeBufferCollection* last_bound_collection() {
return sysmem_allocator_.bound_collections().empty()
? nullptr
: sysmem_allocator_.bound_collections().back().get();
}
FakeAllocator sysmem_allocator_;
SysmemAllocator allocator_{sysmem_allocator_.NewBinding()};
async::Executor executor_{dispatcher()};
};
TEST_F(SysmemAllocatorTest, BindSharedCollection) {
fuchsia::sysmem::BufferCollectionTokenHandle token;
auto request = token.NewRequest();
fpromise::result<BufferCollectionWithLifetime, zx_status_t> result;
executor_.schedule_task(
allocator_.BindSharedCollection(std::move(token), {}, "CollectionName")
.then([&result](fpromise::result<BufferCollectionWithLifetime, zx_status_t>& r) mutable {
result = std::move(r);
}));
RunLoopUntilIdle();
// Now we should have the shared buffer collection.
ASSERT_EQ(1u, sysmem_allocator_.bound_collections().size());
last_bound_collection()->CompleteBufferAllocation(ZX_OK,
fuchsia::sysmem::BufferCollectionInfo_2{});
RunLoopUntilIdle();
EXPECT_TRUE(result.is_ok());
}
} // namespace
} // namespace camera