// 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/device_impl.h"

#include <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/camera3/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <lib/async/cpp/executor.h>
#include <lib/sys/cpp/component_context.h>
#include <zircon/errors.h>

#include <limits>

#include "src/camera/bin/device/stream_impl.h"
#include "src/camera/bin/device/testing/fake_device_listener_registry.h"
#include "src/camera/lib/fake_controller/fake_controller.h"
#include "src/camera/lib/fake_legacy_stream/fake_legacy_stream.h"
#include "src/lib/fsl/handles/object_info.h"
#include "src/lib/testing/loop_fixture/real_loop_fixture.h"

namespace camera {

constexpr uint32_t kNamePriority = 30;  // Higher than Scenic but below the maximum.

// No-op function.
static void nop() {}

static void nop_stream_requested(fidl::InterfaceRequest<fuchsia::camera2::Stream> request,
                                 uint32_t format_index) {
  request.Close(ZX_ERR_NOT_SUPPORTED);
}

static void nop_buffers_requested(fuchsia::sysmem2::BufferCollectionTokenHandle token,
                                  fit::function<void(uint32_t)> callback) {
  token.Bind()->Release();
  callback(0);
}

// Constraints provided by the driver alone may resolve to zero-sized or empty collections. A set of
// placeholder constrains can be used in cases where a test requires allocation to occur but does
// not care about its properties.
static fuchsia::sysmem2::BufferCollectionConstraints minimal_constraints_for_allocation() {
  fuchsia::sysmem2::BufferCollectionConstraints constraints;
  constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
  constraints.set_min_buffer_count_for_camping(1);
  constraints.mutable_buffer_memory_constraints()->set_min_size_bytes(4096);
  return constraints;
}

class DeviceImplTest : public gtest::RealLoopFixture {
 protected:
  DeviceImplTest()
      : context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()),
        fake_listener_registry_(async_get_default_dispatcher()) {
    fake_properties_.set_image_format(
        {.pixel_format{.type = fuchsia::sysmem::PixelFormatType::NV12},
         .coded_width = 1920,
         .coded_height = 1080,
         .bytes_per_row = 1920,
         .color_space{.type = fuchsia::sysmem::ColorSpaceType::REC601_NTSC}});
    fake_properties_.set_supported_resolutions(
        {{.width = 1920, .height = 1080}, {.width = 1280, .height = 720}});
    fake_properties_.set_frame_rate({});
    fake_properties_.set_supports_crop_region(true);
    fake_legacy_config_.image_formats.resize(2, fake_properties_.image_format());
    fake_legacy_config_.image_formats[1].coded_width = 1280;
    fake_legacy_config_.image_formats[1].coded_height = 720;
  }

  void SetUp() override {
    context_->svc()->Connect(allocator_.NewRequest());
    allocator_.set_error_handler(MakeErrorHandler("Sysmem Allocator"));

    fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest set_debug_request;
    set_debug_request.set_name(fsl::GetCurrentProcessName());
    set_debug_request.set_id(fsl::GetCurrentProcessKoid());
    allocator_->SetDebugClientInfo(std::move(set_debug_request));

    fuchsia::sysmem2::AllocatorSyncPtr allocator;
    context_->svc()->Connect(allocator.NewRequest());

    {
      fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest set_debug_request;
      set_debug_request.set_name(fsl::GetCurrentProcessName());
      set_debug_request.set_id(fsl::GetCurrentProcessKoid());
      allocator->SetDebugClientInfo(std::move(set_debug_request));
    }

    fuchsia::camera2::hal::ControllerHandle controller;
    auto controller_result = FakeController::Create(controller.NewRequest(), allocator.Unbind());
    ASSERT_TRUE(controller_result.is_ok());
    controller_ = controller_result.take_value();

    context_->svc()->Connect(allocator.NewRequest());

    {
      fuchsia::sysmem2::AllocatorSetDebugClientInfoRequest set_debug_request;
      set_debug_request.set_name(fsl::GetCurrentProcessName());
      set_debug_request.set_id(fsl::GetCurrentProcessKoid());
      allocator->SetDebugClientInfo(std::move(set_debug_request));
    }

    fuchsia::ui::policy::DeviceListenerRegistryHandle registry;
    fake_listener_registry_.GetHandler()(registry.NewRequest());

    MetricsReporter::Initialize(*context_, false);

    zx::event bad_state_event;
    ASSERT_EQ(zx::event::create(0, &bad_state_event), ZX_OK);
    auto device_promise =
        DeviceImpl::Create(dispatcher(), executor_, std::move(controller), allocator.Unbind(),
                           std::move(registry), std::move(bad_state_event));
    bool device_created = false;
    executor_.schedule_task(device_promise.then(
        [this, &device_created](
            fpromise::result<std::unique_ptr<DeviceImpl>, zx_status_t>& device_result) mutable {
          device_created = true;
          ASSERT_TRUE(device_result.is_ok());
          device_ = device_result.take_value();
        }));
    RunLoopUntil([&device_created] { return device_created; });
    ASSERT_NE(device_, nullptr);
  }

  void TearDown() override {
    device_ = nullptr;
    controller_ = nullptr;
    allocator_ = nullptr;
    RunLoopUntilIdle();
  }

  static fit::function<void(zx_status_t status)> MakeErrorHandler(std::string server) {
    return [server](zx_status_t status) {
      ADD_FAILURE() << server << " server disconnected - " << status;
    };
  }

  template <class T>
  static void SetFailOnError(fidl::InterfacePtr<T>& ptr, std::string name = T::Name_) {
    ptr.set_error_handler([=](zx_status_t status) {
      ADD_FAILURE() << name << " server disconnected: " << zx_status_get_string(status);
    });
  }

  void RunLoopUntilFailureOr(bool& condition) {
    RunLoopUntil([&]() { return HasFailure() || condition; });
  }

  // Synchronizes messages to a device. This method returns when an error occurs or all messages
  // sent to |device| have been received by the server.
  void Sync(fuchsia::camera3::DevicePtr& device) {
    bool identifier_returned = false;
    device->GetIdentifier([&](fidl::StringPtr identifier) { identifier_returned = true; });
    RunLoopUntilFailureOr(identifier_returned);
  }

  // Synchronizes messages to a stream. This method returns when an error occurs or all messages
  // sent to |stream| have been received by the server.
  void Sync(fuchsia::camera3::StreamPtr& stream) {
    fuchsia::camera3::StreamPtr stream2;
    SetFailOnError(stream2, "Rebound Stream for DeviceImplTest::Sync");
    stream->Rebind(stream2.NewRequest());
    bool resolution_returned = false;
    stream2->WatchResolution([&](fuchsia::math::Size resolution) { resolution_returned = true; });
    RunLoopUntilFailureOr(resolution_returned);
  }

  async::Executor executor_{dispatcher()};
  std::unique_ptr<sys::ComponentContext> context_;
  std::unique_ptr<DeviceImpl> device_;
  std::unique_ptr<FakeController> controller_;
  fuchsia::sysmem2::AllocatorPtr allocator_;
  fuchsia::camera3::StreamProperties2 fake_properties_;
  fuchsia::camera2::hal::StreamConfig fake_legacy_config_;
  FakeDeviceListenerRegistry fake_listener_registry_;
};

TEST_F(DeviceImplTest, CreateStreamNullConnection) {
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  StreamImpl stream(dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_,
                    fake_legacy_config_, nullptr, nop_stream_requested, nop_buffers_requested, nop);
}

TEST_F(DeviceImplTest, CreateStreamFakeLegacyStream) {
  fidl::InterfaceHandle<fuchsia::camera3::Stream> stream;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  StreamImpl stream_impl(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      stream.NewRequest(),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result = FakeLegacyStream::Create(std::move(request), allocator_);
        ASSERT_TRUE(result.is_ok());
      },
      nop_buffers_requested, nop);
  RunLoopUntilIdle();
}

TEST_F(DeviceImplTest, GetFrames) {
  fuchsia::camera3::StreamPtr stream;
  stream.set_error_handler(MakeErrorHandler("Stream"));
  constexpr uint32_t kBufferId1 = 42;
  constexpr uint32_t kBufferId2 = 17;
  constexpr int64_t kCaptureTimestamp1 = 600;
  constexpr int64_t kCaptureTimestamp2 = 700;
  constexpr int64_t kTimestamp1 = 650;
  constexpr int64_t kTimestamp2 = 745;
  constexpr uint32_t kMaxCampingBuffers = 1;
  std::unique_ptr<FakeLegacyStream> legacy_stream_fake;
  bool legacy_stream_created = false;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  auto stream_impl = std::make_unique<StreamImpl>(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      stream.NewRequest(),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result = FakeLegacyStream::Create(std::move(request), allocator_);
        ASSERT_TRUE(result.is_ok());
        legacy_stream_fake = result.take_value();
        legacy_stream_created = true;
      },
      [&](fuchsia::sysmem2::BufferCollectionTokenHandle token,
          fit::function<void(uint32_t)> callback) {
        auto bound_token = token.BindSync();

        fuchsia::sysmem2::NodeSetNameRequest set_name_request;
        set_name_request.set_priority(1);
        set_name_request.set_name("DeviceImplTestFakeStream");
        bound_token->SetName(std::move(set_name_request));

        bound_token->Release();

        callback(kMaxCampingBuffers);
      },
      nop);

  fuchsia::sysmem2::BufferCollectionTokenPtr token;
  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

  stream->SetBufferCollection(
      fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
  fidl::InterfaceHandle<fuchsia::sysmem2::BufferCollectionToken> received_token;
  bool buffer_collection_returned = false;
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    received_token = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    buffer_collection_returned = true;
  });

  RunLoopUntil(
      [&]() { return HasFailure() || (legacy_stream_created && buffer_collection_returned); });
  ASSERT_FALSE(HasFailure());

  fuchsia::sysmem2::BufferCollectionPtr collection;
  collection.set_error_handler(MakeErrorHandler("Buffer Collection"));

  fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
  bind_shared_request.set_token(std::move(received_token));
  bind_shared_request.set_buffer_collection_request(collection.NewRequest());
  allocator_->BindSharedCollection(std::move(bind_shared_request));

  fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
  auto& constraints = *set_constraints_request.mutable_constraints();
  constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
  constraints.set_min_buffer_count_for_camping(kMaxCampingBuffers);
  auto& ifc = constraints.mutable_image_format_constraints()->emplace_back();
  ifc.set_pixel_format(fuchsia::images2::PixelFormat::NV12);
  ifc.mutable_color_spaces()->emplace_back(fuchsia::images2::ColorSpace::REC601_NTSC);
  ifc.set_min_size(fuchsia::math::SizeU{.width = 1, .height = 1});
  collection->SetConstraints(std::move(set_constraints_request));

  bool buffers_allocated_returned = false;
  collection->WaitForAllBuffersAllocated(
      [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
        EXPECT_TRUE(result.is_response());
        buffers_allocated_returned = true;
      });
  RunLoopUntil([&]() { return HasFailure() || buffers_allocated_returned; });
  ASSERT_FALSE(HasFailure());

  RunLoopUntil([&] { return HasFailure() || legacy_stream_fake->IsStreaming(); });
  bool frame1_received = false;
  bool frame2_received = false;
  auto callback2 = [&](fuchsia::camera3::FrameInfo2 info) {
    ASSERT_EQ(info.buffer_index(), kBufferId2);
    EXPECT_EQ(info.frame_counter(), 2u);
    EXPECT_EQ(info.timestamp(), kTimestamp2);
    EXPECT_EQ(info.capture_timestamp(), kCaptureTimestamp2);
    frame2_received = true;
  };
  auto callback1 = [&](fuchsia::camera3::FrameInfo2 info) {
    ASSERT_EQ(info.buffer_index(), kBufferId1);
    EXPECT_EQ(info.frame_counter(), 1u);
    EXPECT_EQ(info.timestamp(), kTimestamp1);
    EXPECT_EQ(info.capture_timestamp(), kCaptureTimestamp1);
    frame1_received = true;
    info.mutable_release_fence()->reset();
    fuchsia::camera2::FrameAvailableInfo frame2_info;
    frame2_info.frame_status = fuchsia::camera2::FrameStatus::OK;
    frame2_info.buffer_id = kBufferId2;
    frame2_info.metadata.set_timestamp(kTimestamp2);
    frame2_info.metadata.set_capture_timestamp(kCaptureTimestamp2);
    ASSERT_EQ(legacy_stream_fake->SendFrameAvailable(std::move(frame2_info)), ZX_OK);
    stream->GetNextFrame2(std::move(callback2));
  };
  stream->GetNextFrame2(std::move(callback1));
  fuchsia::camera2::FrameAvailableInfo frame1_info;
  frame1_info.frame_status = fuchsia::camera2::FrameStatus::OK;
  frame1_info.buffer_id = kBufferId1;
  frame1_info.metadata.set_timestamp(kTimestamp1);
  frame1_info.metadata.set_capture_timestamp(kCaptureTimestamp1);
  ASSERT_EQ(legacy_stream_fake->SendFrameAvailable(std::move(frame1_info)), ZX_OK);
  while (!HasFailure() && (!frame1_received || !frame2_received)) {
    RunLoopUntilIdle();
  }

  // Make sure the stream recycles frames once its camping allocation is exhausted.
  // Also emulate a stuck client that does not return any frames.
  std::set<zx::eventpair> fences;
  uint32_t last_received_frame = -1;
  fit::function<void(fuchsia::camera3::FrameInfo)> on_next_frame;
  on_next_frame = [&](fuchsia::camera3::FrameInfo info) {
    last_received_frame = info.buffer_index;
    fences.insert(std::move(info.release_fence));
    stream->GetNextFrame(on_next_frame.share());
  };
  stream->GetNextFrame(on_next_frame.share());
  constexpr uint32_t kNumFrames = 17;
  for (uint32_t i = 0; i < kNumFrames; ++i) {
    fuchsia::camera2::FrameAvailableInfo frame_info{.buffer_id = i};
    frame_info.metadata.set_timestamp(0);
    frame_info.metadata.set_capture_timestamp(0);
    ASSERT_EQ(legacy_stream_fake->SendFrameAvailable(std::move(frame_info)), ZX_OK);
    if (i < constraints.min_buffer_count_for_camping()) {
      // Up to the camping limit, wait until the frames are received.
      RunLoopUntil([&] { return HasFailure() || last_received_frame == i; });
    } else {
      // After the camping limit is reached due to the emulated stuck client, verify that the Stream
      // recycles the oldest buffers first.
      RunLoopUntil([&] { return HasFailure() || !legacy_stream_fake->IsOutstanding(i); });
    }
  }
  fences.clear();

  auto client_result = legacy_stream_fake->StreamClientStatus();
  EXPECT_TRUE(client_result.is_ok()) << client_result.error();
  stream = nullptr;
  stream_impl = nullptr;
}

TEST_F(DeviceImplTest, GetFramesInvalidCall) {
  bool stream_errored = false;
  fuchsia::camera3::StreamPtr stream;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_BAD_STATE);
    stream_errored = true;
  });
  std::unique_ptr<FakeLegacyStream> fake_legacy_stream;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  auto stream_impl = std::make_unique<StreamImpl>(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      stream.NewRequest(),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result = FakeLegacyStream::Create(std::move(request), allocator_);
        ASSERT_TRUE(result.is_ok());
        fake_legacy_stream = result.take_value();
      },
      nop_buffers_requested, nop);
  stream->GetNextFrame([](fuchsia::camera3::FrameInfo info) {});
  stream->GetNextFrame([](fuchsia::camera3::FrameInfo info) {});
  while (!HasFailure() && !stream_errored) {
    RunLoopUntilIdle();
  }
}

TEST_F(DeviceImplTest, Configurations) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());

  uint32_t callback_count = 0;
  constexpr uint32_t kExpectedCallbackCount = 3;
  bool all_callbacks_received = false;
  device->GetConfigurations([&](std::vector<fuchsia::camera3::Configuration> configurations) {
    EXPECT_GE(configurations.size(), 2u);
    all_callbacks_received = ++callback_count == kExpectedCallbackCount;
  });
  device->SetCurrentConfiguration(0);
  RunLoopUntilIdle();
  device->WatchCurrentConfiguration([&](uint32_t index) {
    EXPECT_EQ(index, 0u);
    all_callbacks_received = ++callback_count == kExpectedCallbackCount;
    device->WatchCurrentConfiguration([&](uint32_t index) {
      EXPECT_EQ(index, 1u);
      all_callbacks_received = ++callback_count == kExpectedCallbackCount;
    });
    RunLoopUntilIdle();
    device->SetCurrentConfiguration(1);
  });
  RunLoopUntilFailureOr(all_callbacks_received);
}

TEST_F(DeviceImplTest, ConfigurationSwitchingWhileAllocated) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());

  uint32_t buffers_allocated = 0;
  constexpr uint32_t kExpectedBuffersAllocated = 2;
  bool all_buffers_allocated = false;
  bool first_stream_gone = false;
  device->GetConfigurations([&](std::vector<fuchsia::camera3::Configuration> configurations) {
    EXPECT_GE(configurations.size(), 2u);
  });
  device->SetCurrentConfiguration(0);

  // Connect and allocate stream
  fuchsia::camera3::StreamPtr stream;
  // Don't SetFailOnError as we expect stream to close when switching config
  device->ConnectToStream(0, stream.NewRequest());
  fuchsia::sysmem2::BufferCollectionTokenPtr token;

  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));
  stream->SetBufferCollection(
      fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
  fuchsia::sysmem2::BufferCollectionPtr buffers;
  bool buffers_allocated_returned = false;
  zx::vmo vmo;
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
    bind_shared_request.set_token(std::move(token_v2));
    bind_shared_request.set_buffer_collection_request(buffers.NewRequest());
    allocator_->BindSharedCollection(std::move(bind_shared_request));

    fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
    set_constraints_request.set_constraints(minimal_constraints_for_allocation());
    buffers->SetConstraints(std::move(set_constraints_request));

    fuchsia::sysmem2::NodeSetNameRequest set_name_request;
    set_name_request.set_priority(kNamePriority);
    set_name_request.set_name("Testc0s0Buffers");
    buffers->SetName(std::move(set_name_request));

    buffers->WaitForAllBuffersAllocated(
        [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
          EXPECT_TRUE(result.is_response());
          vmo = std::move(*result.response()
                               .mutable_buffer_collection_info()
                               ->mutable_buffers()
                               ->at(0)
                               .mutable_vmo());
          all_buffers_allocated = ++buffers_allocated == kExpectedBuffersAllocated;
          buffers_allocated_returned = true;
        });
  });

  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_OK);
    first_stream_gone = true;
    buffers.Unbind();
    vmo.reset();
  });

  RunLoopUntilFailureOr(buffers_allocated_returned);

  fuchsia::camera3::StreamPtr stream2;
  fuchsia::sysmem2::BufferCollectionPtr buffers2;
  fuchsia::sysmem2::BufferCollectionTokenPtr token2;
  zx::vmo vmo2;

  device->WatchCurrentConfiguration([&](uint32_t index) {
    EXPECT_EQ(index, 0u);

    device->SetCurrentConfiguration(1);
    device->WatchCurrentConfiguration([&](uint32_t index) { EXPECT_EQ(index, 1u); });

    RunLoopUntilFailureOr(first_stream_gone);

    // Connect and allocate stream
    device->ConnectToStream(0, stream2.NewRequest());

    fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
    allocate_shared_request.set_token_request(token2.NewRequest());
    allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

    stream2->SetBufferCollection(
        fuchsia::sysmem::BufferCollectionTokenHandle(token2.Unbind().TakeChannel()));
    stream2->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
      auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
      fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
      bind_shared_request.set_token(std::move(token_v2));
      bind_shared_request.set_buffer_collection_request(buffers2.NewRequest());
      allocator_->BindSharedCollection(std::move(bind_shared_request));

      fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
      set_constraints_request.set_constraints(minimal_constraints_for_allocation());
      buffers2->SetConstraints(std::move(set_constraints_request));

      fuchsia::sysmem2::NodeSetNameRequest set_name_request;
      set_name_request.set_priority(kNamePriority);
      set_name_request.set_name("Testc1s0Buffers");
      buffers2->SetName(std::move(set_name_request));

      buffers2->WaitForAllBuffersAllocated(
          [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
            EXPECT_TRUE(result.is_response());
            vmo2 = std::move(*result.response()
                                  .mutable_buffer_collection_info()
                                  ->mutable_buffers()
                                  ->at(0)
                                  .mutable_vmo());
            all_buffers_allocated = ++buffers_allocated == kExpectedBuffersAllocated;
          });
    });
  });

  RunLoopUntilFailureOr(all_buffers_allocated);
}

TEST_F(DeviceImplTest, Identifier) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  bool callback_received = false;
  device->GetIdentifier([&](fidl::StringPtr identifier) {
    ASSERT_TRUE(identifier.has_value());
    constexpr auto kExpectedDeviceIdentifier = "FFFF0ABC";
    EXPECT_EQ(identifier.value(), kExpectedDeviceIdentifier);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
}

TEST_F(DeviceImplTest, RequestStreamFromController) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());
  fuchsia::sysmem2::BufferCollectionTokenPtr token;

  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

  stream->SetBufferCollection(
      fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
  fuchsia::sysmem2::BufferCollectionPtr buffers;
  SetFailOnError(buffers, "BufferCollection");
  bool buffers_allocated_returned = false;
  zx::vmo vmo;
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
    bind_shared_request.set_token(std::move(token_v2));
    bind_shared_request.set_buffer_collection_request(buffers.NewRequest());
    allocator_->BindSharedCollection(std::move(bind_shared_request));

    fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
    set_constraints_request.set_constraints(minimal_constraints_for_allocation());
    buffers->SetConstraints(std::move(set_constraints_request));

    buffers->WaitForAllBuffersAllocated(
        [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
          EXPECT_TRUE(result.is_response());
          vmo = std::move(*result.response()
                               .mutable_buffer_collection_info()
                               ->mutable_buffers()
                               ->at(0)
                               .mutable_vmo());
          buffers_allocated_returned = true;
        });
  });
  RunLoopUntilFailureOr(buffers_allocated_returned);

  std::string vmo_name;
  RunLoopUntil([&] {
    vmo_name = fsl::GetObjectName(vmo.get());
    return vmo_name != "Sysmem-core";
  });
  EXPECT_EQ(vmo_name, "camera_c0s0:0");

  constexpr uint32_t kBufferId = 42;
  bool callback_received = false;
  stream->GetNextFrame([&](fuchsia::camera3::FrameInfo info) {
    EXPECT_EQ(info.buffer_index, kBufferId);
    callback_received = true;
  });
  bool frame_sent = false;
  while (!HasFailure() && !frame_sent) {
    RunLoopUntilIdle();
    fuchsia::camera2::FrameAvailableInfo info;
    info.frame_status = fuchsia::camera2::FrameStatus::OK;
    info.buffer_id = kBufferId;
    info.metadata.set_timestamp(0);
    info.metadata.set_capture_timestamp(0);
    zx_status_t status = controller_->SendFrameViaLegacyStream(std::move(info));
    if (status == ZX_OK) {
      frame_sent = true;
    } else {
      EXPECT_EQ(status, ZX_ERR_SHOULD_WAIT);
    }
  }
  RunLoopUntilFailureOr(callback_received);
  buffers->Release();
  RunLoopUntilIdle();
}

TEST_F(DeviceImplTest, MultipleDeviceClients) {
  // Create the first client.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  Sync(device);

  // Try to connect a second client, which should succeed.
  fuchsia::camera3::DevicePtr device2;
  SetFailOnError(device2, "Device");
  device_->GetHandler()(device2.NewRequest());
  Sync(device2);

  // Make sure new clients can get configurations and see the current configuration.
  bool get_configurations_returned = false;
  device2->GetConfigurations([&](std::vector<fuchsia::camera3::Configuration> configurations) {
    ASSERT_GE(configurations.size(), 1u);
    get_configurations_returned = true;
  });
  RunLoopUntilFailureOr(get_configurations_returned);
  bool watch_returned = false;
  device2->WatchCurrentConfiguration([&](uint32_t index) {
    EXPECT_EQ(index, 0u);
    watch_returned = true;
  });
  RunLoopUntilFailureOr(watch_returned);
}

TEST_F(DeviceImplTest, StreamClientDisconnect) {
  // Create the first client.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  device->ConnectToStream(0, stream.NewRequest());
  SetFailOnError(stream, "Stream");

  // Try to connect a second client, which should fail.
  fuchsia::camera3::StreamPtr stream2;
  bool error_received = false;
  stream2.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_ALREADY_BOUND);
    error_received = true;
  });
  device->ConnectToStream(0, stream2.NewRequest());
  RunLoopUntilFailureOr(error_received);

  // Disconnect the first client, then try to connect the second again.
  stream = nullptr;
  bool callback_received = false;
  while (!HasFailure() && !callback_received) {
    error_received = false;
    device->ConnectToStream(0, stream2.NewRequest());
    fuchsia::sysmem2::BufferCollectionTokenPtr token;
    SetFailOnError(token, "Token");

    fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
    allocate_shared_request.set_token_request(token.NewRequest());
    allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

    stream2->SetBufferCollection(
        fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
    // Call a returning API to verify the connection status.
    stream2->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
      auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
      EXPECT_EQ(token_v2.BindSync()->Release(), ZX_OK);
      callback_received = true;
    });
    RunLoopUntil([&] { return error_received || callback_received; });
  }
}

TEST_F(DeviceImplTest, SetResolution) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  device->ConnectToStream(0, stream.NewRequest());
  SetFailOnError(stream, "Stream");
  constexpr fuchsia::math::Size kExpectedDefaultSize{.width = 1920, .height = 1080};
  constexpr fuchsia::math::Size kRequestedSize{.width = 1025, .height = 32};
  constexpr fuchsia::math::Size kExpectedSize{.width = 1280, .height = 720};
  constexpr fuchsia::math::Size kRequestedSize2{.width = 1, .height = 1};
  constexpr fuchsia::math::Size kExpectedSize2{.width = 1024, .height = 576};
  constexpr fuchsia::math::Size kRequestedSize3{.width = 1280, .height = 720};
  constexpr fuchsia::math::Size kExpectedSize3{.width = 1280, .height = 720};
  bool callback_received = false;
  stream->WatchResolution([&](fuchsia::math::Size coded_size) {
    EXPECT_GE(coded_size.width, kExpectedDefaultSize.width);
    EXPECT_GE(coded_size.height, kExpectedDefaultSize.height);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
  stream->SetResolution(kRequestedSize);
  callback_received = false;
  stream->WatchResolution([&](fuchsia::math::Size coded_size) {
    EXPECT_GE(coded_size.width, kExpectedSize.width);
    EXPECT_GE(coded_size.height, kExpectedSize.height);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
  callback_received = false;
  stream->SetResolution(kRequestedSize2);
  stream->WatchResolution([&](fuchsia::math::Size coded_size) {
    EXPECT_GE(coded_size.width, kExpectedSize2.width);
    EXPECT_GE(coded_size.height, kExpectedSize2.height);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
  callback_received = false;
  stream->SetResolution(kRequestedSize3);
  stream->WatchResolution([&](fuchsia::math::Size coded_size) {
    EXPECT_GE(coded_size.width, kExpectedSize3.width);
    EXPECT_GE(coded_size.height, kExpectedSize3.height);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
}

TEST_F(DeviceImplTest, SetResolutionInvalid) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  device->ConnectToStream(0, stream.NewRequest());
  constexpr fuchsia::math::Size kSize{.width = std::numeric_limits<int32_t>::max(), .height = 42};
  stream->SetResolution(kSize);
  bool error_received = false;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    error_received = true;
  });
  RunLoopUntilFailureOr(error_received);
}

TEST_F(DeviceImplTest, SetConfigurationDisconnectsStreams) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  bool error_received = false;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_OK);
    error_received = true;
  });
  device->ConnectToStream(0, stream.NewRequest());
  Sync(stream);
  device->SetCurrentConfiguration(0);
  RunLoopUntilFailureOr(error_received);
}

TEST_F(DeviceImplTest, Rebind) {
  // First device connection.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());

  // First stream connection.
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());
  Sync(stream);

  // Rebind second device connection.
  fuchsia::camera3::DevicePtr device2;
  SetFailOnError(device2, "Device");
  device->Rebind(device2.NewRequest());

  // Attempt to bind second stream independently.
  fuchsia::camera3::StreamPtr stream2;
  bool error_received = false;
  stream2.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_ALREADY_BOUND);
    error_received = true;
  });
  device->ConnectToStream(0, stream2.NewRequest());
  RunLoopUntilFailureOr(error_received);

  // Attempt to bind second stream via rebind.
  SetFailOnError(stream2, "Stream");
  stream->Rebind(stream2.NewRequest());
  Sync(stream2);
}

TEST_F(DeviceImplTest, OrphanStream) {
  // Connect to the device.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  Sync(device);

  // Connect to the stream.
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());
  Sync(stream);

  // Disconnect from the device.
  device = nullptr;

  // Reset the error handler to expect peer-closed.
  bool stream_error_received = false;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_OK);
    stream_error_received = true;
  });

  // Connect to the device as a new client and set the configuration.
  fuchsia::camera3::DevicePtr device2;
  SetFailOnError(device2, "Device2");
  device_->GetHandler()(device2.NewRequest());
  device2->SetCurrentConfiguration(0);

  // Make sure the first stream is closed when the new device connects.
  RunLoopUntilFailureOr(stream_error_received);

  // The second client should be able to connect to the stream now.
  fuchsia::camera3::StreamPtr stream2;
  SetFailOnError(stream, "Stream2");
  device2->ConnectToStream(0, stream2.NewRequest());
  Sync(stream2);
}

TEST_F(DeviceImplTest, SetCropRegion) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  device->ConnectToStream(0, stream.NewRequest());
  SetFailOnError(stream, "Stream");
  bool callback_received = false;
  stream->WatchCropRegion([&](std::unique_ptr<fuchsia::math::RectF> region) {
    EXPECT_EQ(region, nullptr);
    callback_received = true;
  });
  RunLoopUntilFailureOr(callback_received);
  constexpr fuchsia::math::RectF kCropRegion{.x = 0.1f, .y = 0.4f, .width = 0.7f, .height = 0.2f};
  callback_received = false;
  stream->WatchCropRegion([&](std::unique_ptr<fuchsia::math::RectF> region) {
    ASSERT_NE(region, nullptr);
    EXPECT_EQ(region->x, kCropRegion.x);
    EXPECT_EQ(region->y, kCropRegion.y);
    EXPECT_EQ(region->width, kCropRegion.width);
    EXPECT_EQ(region->height, kCropRegion.height);
    callback_received = true;
  });
  stream->SetCropRegion(std::make_unique<fuchsia::math::RectF>(kCropRegion));
  RunLoopUntilFailureOr(callback_received);
  bool error_received = false;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_INVALID_ARGS);
    error_received = true;
  });
  constexpr fuchsia::math::RectF kInvalidCropRegion{
      .x = 0.1f, .y = 0.4f, .width = 0.7f, .height = 0.7f};
  stream->SetCropRegion(std::make_unique<fuchsia::math::RectF>(kInvalidCropRegion));
  RunLoopUntilFailureOr(error_received);
}

TEST_F(DeviceImplTest, SoftwareMuteState) {
  // Connect to the device.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  bool watch_returned = false;
  device->WatchMuteState([&](bool software_muted, bool hardware_muted) {
    EXPECT_FALSE(software_muted);
    EXPECT_FALSE(hardware_muted);
    watch_returned = true;
  });
  RunLoopUntilFailureOr(watch_returned);

  // Connect to the stream.
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());

  fuchsia::sysmem2::BufferCollectionTokenPtr token;

  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

  stream->SetBufferCollection(
      fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
  fidl::InterfaceHandle<fuchsia::sysmem2::BufferCollectionToken> received_token;
  watch_returned = false;
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    received_token = std::move(token_v2);
    watch_returned = true;
  });
  RunLoopUntilFailureOr(watch_returned);

  fuchsia::sysmem2::BufferCollectionPtr collection;
  collection.set_error_handler(MakeErrorHandler("Buffer Collection"));

  fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
  bind_shared_request.set_token(std::move(received_token));
  bind_shared_request.set_buffer_collection_request(collection.NewRequest());
  allocator_->BindSharedCollection(std::move(bind_shared_request));

  fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
  auto& constraints = *set_constraints_request.mutable_constraints();
  constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
  constraints.set_min_buffer_count_for_camping(5);
  auto& ifc = constraints.mutable_image_format_constraints()->emplace_back();
  ifc.set_pixel_format(fuchsia::images2::PixelFormat::NV12);
  ifc.mutable_color_spaces()->emplace_back(fuchsia::images2::ColorSpace::REC601_NTSC);
  ifc.set_min_size(fuchsia::math::SizeU{.width = 1, .height = 1});
  collection->SetConstraints(std::move(set_constraints_request));

  bool buffers_allocated_returned = false;
  collection->WaitForAllBuffersAllocated(
      [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
        EXPECT_TRUE(result.is_response());
        buffers_allocated_returned = true;
      });
  RunLoopUntil([&]() { return HasFailure() || buffers_allocated_returned; });
  ASSERT_FALSE(HasFailure());

  uint32_t next_buffer_id = 0;
  fit::closure send_frame = [&] {
    fuchsia::camera2::FrameAvailableInfo frame_info{
        .frame_status = fuchsia::camera2::FrameStatus::OK, .buffer_id = next_buffer_id};
    frame_info.metadata.set_timestamp(0);
    frame_info.metadata.set_capture_timestamp(0);
    zx_status_t status = controller_->SendFrameViaLegacyStream(std::move(frame_info));
    if (status == ZX_ERR_SHOULD_WAIT || status == ZX_ERR_BAD_STATE) {
      // Keep trying until the device starts streaming.
      async::PostTask(async_get_default_dispatcher(), send_frame.share());
    } else {
      ++next_buffer_id;
      ASSERT_EQ(status, ZX_OK);
    }
  };

  // Because the device and stream protocols are asynchronous, mute requests may be handled by
  // streams while in a number of different states. Without deep hooks into the implementation, it
  // is impossible to force the stream into a particular state. Instead, this test repeatedly
  // toggles mute state in an attempt to exercise all cases.
  constexpr uint32_t kToggleCount = 50;
  for (uint32_t i = 0; i < kToggleCount; ++i) {
    // Get a frame (unmuted).
    bool frame_received = false;
    stream->GetNextFrame([&](fuchsia::camera3::FrameInfo info) { frame_received = true; });
    send_frame();
    RunLoopUntilFailureOr(frame_received);

    // Get a frame then immediately try to mute the device.
    bool mute_completed = false;
    bool muted_frame_requested = false;
    bool unmute_requested = false;
    bool unmuted_frame_received = false;
    fuchsia::camera3::Stream::GetNextFrameCallback callback =
        [&](fuchsia::camera3::FrameInfo info) {
          if (muted_frame_requested) {
            ASSERT_TRUE(unmute_requested)
                << "Frame requested after receiving mute callback returned anyway.";
          }
          if (unmute_requested) {
            unmuted_frame_received = true;
          } else {
            if (mute_completed) {
              muted_frame_requested = true;
            }
            stream->GetNextFrame(callback.share());
            send_frame();
          }
        };
    callback({});
    uint32_t mute_buffer_id_begin = next_buffer_id;
    uint32_t mute_buffer_id_end = mute_buffer_id_begin;
    device->SetSoftwareMuteState(true, [&] {
      mute_completed = true;
      mute_buffer_id_end = next_buffer_id;
    });
    RunLoopUntilFailureOr(mute_completed);

    // Make sure all buffers were returned.
    for (uint32_t j = mute_buffer_id_begin; j < mute_buffer_id_end; ++j) {
      RunLoopUntil(
          [&] { return HasFailure() || !controller_->LegacyStreamBufferIsOutstanding(j); });
    }

    // Unmute the device to get the last frame. Note that frames received while internally muted are
    // discarded, so repeated sending of frames is necessary.
    unmute_requested = true;
    device->SetSoftwareMuteState(false, [] {});
    while (!HasFailure() && !unmuted_frame_received) {
      send_frame();
      // Delay each attempt to avoid flooding the channel.
      RunLoopWithTimeout(zx::msec(10));
    }

    ASSERT_FALSE(HasFailure());
  }

  collection->Release();
}

TEST_F(DeviceImplTest, HardwareMuteState) {
  // Connect to the device.
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());

  // Device should start unmuted.
  bool watch_returned = false;
  device->WatchMuteState([&](bool software_muted, bool hardware_muted) {
    EXPECT_FALSE(software_muted);
    EXPECT_FALSE(hardware_muted);
    watch_returned = true;
  });
  RunLoopUntilFailureOr(watch_returned);

  // Verify mute event.
  watch_returned = false;
  device->WatchMuteState([&](bool software_muted, bool hardware_muted) {
    EXPECT_FALSE(software_muted);
    EXPECT_TRUE(hardware_muted);
    watch_returned = true;
  });
  fuchsia::ui::input::MediaButtonsEvent mute_event;
  mute_event.set_mic_mute(true);
  fake_listener_registry_.SendMediaButtonsEvent(std::move(mute_event));
  RunLoopUntilFailureOr(watch_returned);

  // Verify unmute event.
  watch_returned = false;
  device->WatchMuteState([&](bool software_muted, bool hardware_muted) {
    EXPECT_FALSE(software_muted);
    EXPECT_FALSE(hardware_muted);
    watch_returned = true;
  });
  fuchsia::ui::input::MediaButtonsEvent unmute_event;
  unmute_event.set_mic_mute(false);
  fake_listener_registry_.SendMediaButtonsEvent(std::move(unmute_event));
  RunLoopUntilFailureOr(watch_returned);
}

TEST_F(DeviceImplTest, GetProperties) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  bool configs_returned = false;
  std::vector<fuchsia::camera3::Configuration> configs;
  device->GetConfigurations([&](std::vector<fuchsia::camera3::Configuration> configurations) {
    configs = std::move(configurations);
    configs_returned = true;
  });
  RunLoopUntilFailureOr(configs_returned);
  fuchsia::camera3::StreamPtr stream;
  device->ConnectToStream(0, stream.NewRequest());
  bool properties_returned = false;
  stream->GetProperties([&](fuchsia::camera3::StreamProperties properties) {
    EXPECT_EQ(properties.supports_crop_region, configs[0].streams[0].supports_crop_region);
    EXPECT_EQ(properties.frame_rate.numerator, configs[0].streams[0].frame_rate.numerator);
    EXPECT_EQ(properties.frame_rate.denominator, configs[0].streams[0].frame_rate.denominator);
    EXPECT_EQ(properties.image_format.coded_width, configs[0].streams[0].image_format.coded_width);
    EXPECT_EQ(properties.image_format.coded_height,
              configs[0].streams[0].image_format.coded_height);
    properties_returned = true;
  });
  RunLoopUntilFailureOr(properties_returned);
  properties_returned = false;
  stream->GetProperties2([&](fuchsia::camera3::StreamProperties2 properties) {
    ASSERT_FALSE(properties.supported_resolutions().empty());
    EXPECT_EQ(static_cast<uint32_t>(properties.supported_resolutions().at(0).width),
              configs[0].streams[0].image_format.coded_width);
    EXPECT_EQ(static_cast<uint32_t>(properties.supported_resolutions().at(0).height),
              configs[0].streams[0].image_format.coded_height);
    properties_returned = true;
  });
  RunLoopUntilFailureOr(properties_returned);
}

TEST_F(DeviceImplTest, DISABLED_SetBufferCollectionAgainWhileFramesHeld) {
  constexpr uint32_t kCycleCount = 10;
  uint32_t cycle = 0;

  fuchsia::camera3::StreamPtr stream;
  constexpr uint32_t kMaxCampingBuffers = 1;
  std::array<std::unique_ptr<FakeLegacyStream>, kCycleCount> legacy_stream_fakes;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  auto stream_impl = std::make_unique<StreamImpl>(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      stream.NewRequest(),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result = FakeLegacyStream::Create(std::move(request), allocator_);
        ASSERT_TRUE(result.is_ok());
        legacy_stream_fakes[cycle] = result.take_value();
      },
      [&](fuchsia::sysmem2::BufferCollectionTokenHandle token,
          fit::function<void(uint32_t)> callback) {
        token.Bind()->Release();
        callback(kMaxCampingBuffers);
      },
      nop);

  std::vector<fuchsia::camera3::FrameInfo> frames(kCycleCount);
  for (cycle = 0; cycle < kCycleCount; ++cycle) {
    fuchsia::sysmem2::BufferCollectionTokenPtr token;

    fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
    allocate_shared_request.set_token_request(token.NewRequest());
    allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

    stream->SetBufferCollection(
        fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
    bool frame_received = false;
    stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
      auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
      fuchsia::sysmem2::BufferCollectionSyncPtr collection;

      fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
      bind_shared_request.set_token(std::move(token_v2));
      bind_shared_request.set_buffer_collection_request(collection.NewRequest());
      allocator_->BindSharedCollection(std::move(bind_shared_request));

      fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
      auto& constraints = *set_constraints_request.mutable_constraints();
      constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
      constraints.set_min_buffer_count_for_camping(kMaxCampingBuffers);
      auto& ifc = constraints.mutable_image_format_constraints()->emplace_back();
      ifc.set_pixel_format(fuchsia::images2::PixelFormat::NV12);
      ifc.mutable_color_spaces()->emplace_back(fuchsia::images2::ColorSpace::REC601_NTSC);
      ifc.set_min_size(fuchsia::math::SizeU{.width = 1, .height = 1});
      collection->SetConstraints(std::move(set_constraints_request));

      fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result wait_result;
      collection->WaitForAllBuffersAllocated(&wait_result);
      EXPECT_TRUE(wait_result.is_response());
      ;
      collection->Release();
      stream->GetNextFrame([&](fuchsia::camera3::FrameInfo info) {
        // Keep the frame; do not release it.
        frames[cycle] = std::move(info);
        frame_received = true;
      });
      fuchsia::camera2::FrameAvailableInfo frame_info;
      frame_info.frame_status = fuchsia::camera2::FrameStatus::OK;
      frame_info.buffer_id = cycle;
      frame_info.metadata.set_timestamp(0);
      frame_info.metadata.set_capture_timestamp(0);
      while (!HasFailure() && !legacy_stream_fakes[cycle]->IsStreaming()) {
        RunLoopUntilIdle();
      }
      ASSERT_EQ(legacy_stream_fakes[cycle]->SendFrameAvailable(std::move(frame_info)), ZX_OK);
    });
    RunLoopUntilFailureOr(frame_received);
  }
}

TEST_F(DeviceImplTest, FrameWaiterTest) {
  {  // Test that destructor of a non-triggered waiter does not panic.
    zx::eventpair client;
    std::vector<zx::eventpair> server(1);
    ASSERT_EQ(zx::eventpair::create(0, &client, &server[0]), ZX_OK);
    bool signaled = false;
    {
      FrameWaiter waiter(dispatcher(), std::move(server), [&] { signaled = true; });
      RunLoopUntilIdle();
    }
    RunLoopUntilIdle();
    EXPECT_FALSE(signaled);
  }

  {  // Test that closing the client endpoint triggers the wait.
    zx::eventpair client;
    std::vector<zx::eventpair> server(1);
    ASSERT_EQ(zx::eventpair::create(0, &client, &server[0]), ZX_OK);
    bool signaled = false;
    FrameWaiter waiter(dispatcher(), std::move(server), [&] { signaled = true; });
    client.reset();
    RunLoopUntilFailureOr(signaled);
  }

  {  // Test that only closing all client endpoints triggers the wait.
    constexpr uint32_t kNumFences = 3;
    std::vector<zx::eventpair> client(kNumFences);
    std::vector<zx::eventpair> server(kNumFences);
    for (uint32_t i = 0; i < kNumFences; ++i) {
      ASSERT_EQ(zx::eventpair::create(0, &client[i], &server[i]), ZX_OK);
    }
    bool signaled = false;
    FrameWaiter waiter(dispatcher(), std::move(server), [&] { signaled = true; });

    // Release some out of order first.
    client[0].reset();
    RunLoopUntilIdle();
    EXPECT_FALSE(signaled);
    client[2].reset();
    RunLoopUntilIdle();
    EXPECT_FALSE(signaled);

    // Release all remaining fences, which should trigger the waiter.
    client.clear();
    RunLoopUntilFailureOr(signaled);
  }
}

TEST_F(DeviceImplTest, NullToken) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  bool complete = false;
  stream.set_error_handler([&](zx_status_t status) {
    EXPECT_EQ(status, ZX_ERR_BAD_STATE);
    ADD_FAILURE() << "Stream shouldn't disconnect";
  });
  device->ConnectToStream(0, stream.NewRequest());
  // Pass invalid handle
  stream->SetBufferCollection(fuchsia::sysmem::BufferCollectionTokenHandle{});
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token) {
    ADD_FAILURE() << "Watch should not return when given an invalid token.";
  });
  auto kDelay = zx::msec(250);
  async::PostDelayedTask(dispatcher(), [&] { complete = true; }, kDelay);
  RunLoopUntilFailureOr(complete);
}

TEST_F(DeviceImplTest, GoodToken) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());
  fuchsia::sysmem2::BufferCollectionTokenHandle token;

  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

  stream->SetBufferCollection(fuchsia::sysmem::BufferCollectionTokenHandle(token.TakeChannel()));
  bool watch_returned = false;
  stream->WatchBufferCollection([&](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    token_v2.BindSync()->Release();
    watch_returned = true;
  });
  RunLoopUntilFailureOr(watch_returned);
}

TEST_F(DeviceImplTest, GetFramesMultiClient) {
  constexpr uint32_t kNumClients = 2;
  constexpr uint32_t kBufferId1 = 42;
  constexpr uint32_t kBufferId2 = 17;
  static constexpr uint32_t kMaxCampingBuffers = 1;
  fuchsia::camera3::StreamPtr original_stream;
  original_stream.set_error_handler(MakeErrorHandler("Stream"));
  std::unique_ptr<FakeLegacyStream> legacy_stream_fake;
  bool legacy_stream_created = false;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  auto stream_impl = std::make_unique<StreamImpl>(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      original_stream.NewRequest(),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result = FakeLegacyStream::Create(std::move(request), allocator_);
        ASSERT_TRUE(result.is_ok());
        legacy_stream_fake = result.take_value();
        legacy_stream_created = true;
      },
      [&](fuchsia::sysmem2::BufferCollectionTokenHandle token,
          fit::function<void(uint32_t)> callback) {
        auto bound_token = token.BindSync();

        fuchsia::sysmem2::NodeSetNameRequest set_name_request;
        set_name_request.set_priority(1);
        set_name_request.set_name("DeviceImplTestFakeStream");
        bound_token->SetName(std::move(set_name_request));

        bound_token->Release();
        callback(kMaxCampingBuffers * kNumClients);
      },
      nop);
  struct PerClient {
    explicit PerClient(fuchsia::sysmem2::AllocatorPtr& allocator) : allocator_(allocator) {}
    fuchsia::camera3::StreamPtr stream;
    fuchsia::sysmem2::BufferCollectionTokenPtr initial_token;
    fuchsia::sysmem2::BufferCollectionPtr collection;
    void OnToken(fuchsia::sysmem2::BufferCollectionTokenHandle token) {
      fuchsia::sysmem2::AllocatorBindSharedCollectionRequest bind_shared_request;
      bind_shared_request.set_token(std::move(token));
      bind_shared_request.set_buffer_collection_request(collection.NewRequest());
      allocator_->BindSharedCollection(std::move(bind_shared_request));

      fuchsia::sysmem2::BufferCollectionSetConstraintsRequest set_constraints_request;
      auto& constraints = *set_constraints_request.mutable_constraints();
      constraints.mutable_usage()->set_cpu(fuchsia::sysmem2::CPU_USAGE_READ);
      constraints.set_min_buffer_count_for_camping(kMaxCampingBuffers);
      auto& ifc = constraints.mutable_image_format_constraints()->emplace_back();
      ifc.set_pixel_format(fuchsia::images2::PixelFormat::NV12);
      ifc.mutable_color_spaces()->emplace_back(fuchsia::images2::ColorSpace::REC601_NTSC);
      ifc.set_min_size(fuchsia::math::SizeU{.width = 1, .height = 1});
      collection->SetConstraints(std::move(set_constraints_request));

      collection->WaitForAllBuffersAllocated(
          [&](fuchsia::sysmem2::BufferCollection_WaitForAllBuffersAllocated_Result result) {
            EXPECT_TRUE(result.is_response());
          });
      stream->WatchBufferCollection([this](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
        auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
        OnToken(std::move(token_v2));
      });
    }
    fuchsia::sysmem2::AllocatorPtr& allocator_;
  };
  std::array<PerClient, kNumClients> clients{PerClient(allocator_), PerClient(allocator_)};
  for (auto& client : clients) {
    client.stream.set_error_handler(MakeErrorHandler("Stream"));
    original_stream->Rebind(client.stream.NewRequest());

    fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
    allocate_shared_request.set_token_request(client.initial_token.NewRequest());
    allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

    client.stream->SetBufferCollection(
        fuchsia::sysmem::BufferCollectionTokenHandle(client.initial_token.Unbind().TakeChannel()));
    client.stream->WatchBufferCollection(
        [client = &client](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
          auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
          client->OnToken(std::move(token_v2));
        });
  }
  original_stream = nullptr;

  RunLoopUntil([&]() {
    return HasFailure() || (legacy_stream_created && legacy_stream_fake->IsStreaming());
  });
  ASSERT_FALSE(HasFailure());

  // Send two frames from the driver.
  fuchsia::camera2::FrameAvailableInfo frame1_info;
  frame1_info.frame_status = fuchsia::camera2::FrameStatus::OK;
  frame1_info.buffer_id = kBufferId1;
  frame1_info.metadata.set_timestamp(0);
  frame1_info.metadata.set_capture_timestamp(0);
  ASSERT_EQ(legacy_stream_fake->SendFrameAvailable(std::move(frame1_info)), ZX_OK);
  fuchsia::camera2::FrameAvailableInfo frame2_info;
  frame2_info.frame_status = fuchsia::camera2::FrameStatus::OK;
  frame2_info.buffer_id = kBufferId2;
  frame2_info.metadata.set_timestamp(0);
  frame2_info.metadata.set_capture_timestamp(0);
  ASSERT_EQ(legacy_stream_fake->SendFrameAvailable(std::move(frame2_info)), ZX_OK);

  // Try to receive each frame independently via each client.
  for (auto& client : clients) {
    bool frame1_received = false;
    bool frame2_received = false;
    auto callback2 = [&](fuchsia::camera3::FrameInfo info) {
      ASSERT_EQ(info.buffer_index, kBufferId2);
      frame2_received = true;
    };
    auto callback1 = [&](fuchsia::camera3::FrameInfo info) {
      ASSERT_EQ(info.buffer_index, kBufferId1);
      frame1_received = true;
      info.release_fence.reset();
      client.stream->GetNextFrame(std::move(callback2));
    };
    client.stream->GetNextFrame(std::move(callback1));
    while (!HasFailure() && (!frame1_received || !frame2_received)) {
      RunLoopUntilIdle();
    }
  }

  auto client_result = legacy_stream_fake->StreamClientStatus();
  EXPECT_TRUE(client_result.is_ok()) << client_result.error();
  for (auto& client : clients) {
    client.stream = nullptr;
  }
  stream_impl = nullptr;
}

TEST_F(DeviceImplTest, LegacyStreamPropertiesRestored) {
  constexpr struct {
    fuchsia::math::Size resolution{.width = 1280, .height = 720};
    uint32_t format_index = 1;
  } kLegacyStreamFormatAssociation;
  constexpr fuchsia::math::RectF kCropRegion{.x = 0.1f, .y = 0.2f, .width = 0.6f, .height = 0.4f};
  fuchsia::camera3::StreamPtr stream;
  stream.set_error_handler(MakeErrorHandler("Stream"));
  auto request = stream.NewRequest();
  // Send these messages first on the channel, before buffers have been negotiated.
  stream->SetCropRegion(std::make_unique<fuchsia::math::RectF>(kCropRegion));
  stream->SetResolution(kLegacyStreamFormatAssociation.resolution);
  std::unique_ptr<FakeLegacyStream> legacy_stream_fake;
  bool legacy_stream_created = false;
  auto config_metrics = MetricsReporter::Get().CreateConfigurationRecord(0, 1);
  auto stream_impl = std::make_unique<StreamImpl>(
      dispatcher(), config_metrics->GetStreamRecord(0), fake_properties_, fake_legacy_config_,
      std::move(request),
      [&](fidl::InterfaceRequest<fuchsia::camera2::Stream> request, uint32_t format_index) {
        auto result =
            FakeLegacyStream::Create(std::move(request), allocator_, format_index, dispatcher());
        ASSERT_TRUE(result.is_ok());
        legacy_stream_fake = result.take_value();
        legacy_stream_created = true;
      },
      [&](fuchsia::sysmem2::BufferCollectionTokenHandle token,
          fit::function<void(uint32_t)> callback) {
        token.BindSync()->Release();
        callback(1);
      },
      nop);
  fuchsia::sysmem2::BufferCollectionTokenPtr token;

  fuchsia::sysmem2::AllocatorAllocateSharedCollectionRequest allocate_shared_request;
  allocate_shared_request.set_token_request(token.NewRequest());
  allocator_->AllocateSharedCollection(std::move(allocate_shared_request));

  stream->SetBufferCollection(
      fuchsia::sysmem::BufferCollectionTokenHandle(token.Unbind().TakeChannel()));
  stream->WatchBufferCollection([](fuchsia::sysmem::BufferCollectionTokenHandle token_v1) {
    auto token_v2 = fuchsia::sysmem2::BufferCollectionTokenHandle(token_v1.TakeChannel());
    token_v2.BindSync()->Release();
  });
  RunLoopUntil([&]() {
    return HasFailure() || (legacy_stream_created && legacy_stream_fake->IsStreaming());
  });
  ASSERT_FALSE(HasFailure());
  auto [x_min, y_min, x_max, y_max] = legacy_stream_fake->GetRegionOfInterest();
  EXPECT_EQ(x_min, kCropRegion.x);
  EXPECT_EQ(y_min, kCropRegion.y);
  constexpr float kEpsilon = 0.001f;
  EXPECT_NEAR(x_max - x_min, kCropRegion.width, kEpsilon);
  EXPECT_NEAR(y_max - y_min, kCropRegion.height, kEpsilon);
  auto image_format = legacy_stream_fake->GetImageFormat();
  EXPECT_EQ(image_format, kLegacyStreamFormatAssociation.format_index);
}

TEST_F(DeviceImplTest, WatchOrientation) {
  fuchsia::camera3::DevicePtr device;
  SetFailOnError(device, "Device");
  device_->GetHandler()(device.NewRequest());
  fuchsia::camera3::StreamPtr stream;
  SetFailOnError(stream, "Stream");
  device->ConnectToStream(0, stream.NewRequest());
  bool orientation_returned = false;
  stream->WatchOrientation([&](fuchsia::camera3::Orientation orientation) {
    EXPECT_EQ(orientation, fuchsia::camera3::Orientation::UP);
    orientation_returned = true;
  });
  RunLoopUntilFailureOr(orientation_returned);
  stream->WatchOrientation([&](fuchsia::camera3::Orientation orientation) {
    ADD_FAILURE() << "WatchOrientation should not return a second time.";
  });
  // Run the loop for long enough that we can be confident the callback won't be invoked.
  RunLoopWithTimeout(zx::sec(2));
}

}  // namespace camera
