/*
 * Copyright 2017 The Chromium OS 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 "common/camera_buffer_manager_impl.h"

#include <sys/mman.h>

#include <functional>
#include <memory>

#include <base/at_exit.h>
#include <drm_fourcc.h>
#include <gbm.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "common/camera_buffer_handle.h"
#include "common/camera_buffer_manager_internal.h"

// Dummy objects / values used for testing.
struct gbm_device {
  void* dummy;
} dummy_device;

struct gbm_bo {
  void* dummy;
} dummy_bo;

int dummy_fd = 0xdeadbeef;

void* dummy_addr = reinterpret_cast<void*>(0xbeefdead);

// Stubs for global scope mock functions.
static std::function<int(int fd)> _close;
static std::function<struct gbm_device*()> _create_gbm_device;
static std::function<int(struct gbm_device*)> _gbm_device_get_fd;
static std::function<void(struct gbm_device*)> _gbm_device_destroy;
static std::function<struct gbm_bo*(struct gbm_device* device,
                                    uint32_t width,
                                    uint32_t height,
                                    uint32_t format,
                                    uint32_t flags)>
    _gbm_bo_create;
static std::function<struct gbm_bo*(
    struct gbm_device* device, uint32_t type, void* buffer, uint32_t usage)>
    _gbm_bo_import;
static std::function<void*(struct gbm_bo* bo,
                           uint32_t x,
                           uint32_t y,
                           uint32_t width,
                           uint32_t height,
                           uint32_t flags,
                           uint32_t* stride,
                           void** map_data,
                           size_t plane)>
    _gbm_bo_map;
static std::function<void(struct gbm_bo* bo, void* map_data)> _gbm_bo_unmap;
static std::function<size_t(struct gbm_bo* bo)> _gbm_bo_get_plane_count;
static std::function<int(struct gbm_bo* bo, size_t plane)> _gbm_bo_get_plane_fd;
static std::function<uint32_t(struct gbm_bo* bo, size_t plane)>
    _gbm_bo_get_offset;
static std::function<uint32_t(struct gbm_bo* bo, size_t plane)>
    _gbm_bo_get_stride_for_plane;
static std::function<void(struct gbm_bo* bo)> _gbm_bo_destroy;
static std::function<void*(
    void* addr, size_t length, int prot, int flags, int fd, off_t offset)>
    _mmap;
static std::function<int(void* addr, size_t length)> _munmap;
static std::function<off_t(int fd, off_t offset, int whence)> _lseek;

// Implementations of the mock functions.
struct MockGbm {
  MockGbm() {
    EXPECT_EQ(_close, nullptr);
    _close = [this](int fd) { return Close(fd); };

    EXPECT_EQ(_create_gbm_device, nullptr);
    _create_gbm_device = [this]() { return CreateGbmDevice(); };

    EXPECT_EQ(_gbm_device_get_fd, nullptr);
    _gbm_device_get_fd = [this](struct gbm_device* device) {
      return GbmDeviceGetFd(device);
    };

    EXPECT_EQ(_gbm_device_destroy, nullptr);
    _gbm_device_destroy = [this](struct gbm_device* device) {
      GbmDeviceDestroy(device);
    };

    EXPECT_EQ(_gbm_bo_create, nullptr);
    _gbm_bo_create = [this](struct gbm_device* device, uint32_t width,
                            uint32_t height, uint32_t format, uint32_t flags) {
      return GbmBoCreate(device, width, height, format, flags);
    };

    EXPECT_EQ(_gbm_bo_import, nullptr);
    _gbm_bo_import = [this](struct gbm_device* device, uint32_t type,
                            void* buffer, uint32_t usage) {
      return GbmBoImport(device, type, buffer, usage);
    };

    EXPECT_EQ(_gbm_bo_map, nullptr);
    _gbm_bo_map = [this](struct gbm_bo* bo, uint32_t x, uint32_t y,
                         uint32_t width, uint32_t height, uint32_t flags,
                         uint32_t* stride, void** map_data, size_t plane) {
      // Point |map_data| to a dummy address.
      *map_data = reinterpret_cast<void*>(0xdeadbeef);
      return GbmBoMap(bo, x, y, width, height, flags, stride, map_data, plane);
    };

    EXPECT_EQ(_gbm_bo_unmap, nullptr);
    _gbm_bo_unmap = [this](struct gbm_bo* bo, void* map_data) {
      GbmBoUnmap(bo, map_data);
    };

    EXPECT_EQ(_gbm_bo_get_plane_count, nullptr);
    _gbm_bo_get_plane_count = [this](struct gbm_bo* bo) {
      return GbmBoGetNumPlanes(bo);
    };

    EXPECT_EQ(_gbm_bo_get_plane_fd, nullptr);
    _gbm_bo_get_plane_fd = [this](struct gbm_bo* bo, size_t plane) {
      return GbmBoGetPlaneFd(bo, plane);
    };

    EXPECT_EQ(_gbm_bo_get_offset, nullptr);
    _gbm_bo_get_offset = [this](struct gbm_bo* bo, size_t plane) {
      return GbmBoGetPlaneOffset(bo, plane);
    };

    EXPECT_EQ(_gbm_bo_get_stride_for_plane, nullptr);
    _gbm_bo_get_stride_for_plane = [this](struct gbm_bo* bo, size_t plane) {
      return GbmBoGetPlaneStride(bo, plane);
    };

    EXPECT_EQ(_gbm_bo_destroy, nullptr);
    _gbm_bo_destroy = [this](struct gbm_bo* bo) { GbmBoDestroy(bo); };

    EXPECT_EQ(_mmap, nullptr);
    _mmap = [this](void* addr, size_t length, int prot, int flags, int fd,
                   off_t offset) {
      return Mmap(addr, length, prot, flags, fd, offset);
    };

    EXPECT_EQ(_munmap, nullptr);
    _munmap = [this](void* addr, size_t length) {
      return Munmap(addr, length);
    };

    EXPECT_EQ(_lseek, nullptr);
    _lseek = [this](int fd, off_t offset, int whence) {
      return Lseek(fd, offset, whence);
    };
  }

  ~MockGbm() {
    _close = nullptr;
    _create_gbm_device = nullptr;
    _gbm_device_get_fd = nullptr;
    _gbm_device_destroy = nullptr;
    _gbm_bo_create = nullptr;
    _gbm_bo_import = nullptr;
    _gbm_bo_map = nullptr;
    _gbm_bo_unmap = nullptr;
    _gbm_bo_get_plane_count = nullptr;
    _gbm_bo_get_plane_fd = nullptr;
    _gbm_bo_get_offset = nullptr;
    _gbm_bo_get_stride_for_plane = nullptr;
    _gbm_bo_destroy = nullptr;
    _mmap = nullptr;
    _munmap = nullptr;
    _lseek = nullptr;
  }

  MOCK_METHOD(int, Close, (int), (override));
  MOCK_METHOD(struct gbm_device*, CreateGbmDevice, (), (override));
  MOCK_METHOD(int, GbmDeviceGetFd, (struct gbm_device*), (override));
  MOCK_METHOD(void, GbmDeviceDestroy, (struct gbm_device*), (override));
  MOCK_METHOD(struct gbm_bo*,
              GbmBoCreate,
              (struct gbm_device*, uint32_t, uint32_t, uint32_t, uint32_t),
              (override));
  MOCK_METHOD(struct gbm_bo*,
              GbmBoImport,
              (struct gbm_device*, uint32_t, void*, uint32_t),
              (override));
  MOCK_METHOD(void*,
              GbmBoMap,
              (struct gbm_bo*,
               uint32_t,
               uint32_t,
               uint32_t,
               uint32_t,
               uint32_t,
               uint32_t*,
               void**,
               size_t),
              (override));
  MOCK_METHOD(void, GbmBoUnmap, (struct gbm_bo*, void*), (override));
  MOCK_METHOD(size_t, GbmBoGetNumPlanes, (struct gbm_bo*), (override));
  MOCK_METHOD(int, GbmBoGetPlaneFd, (struct gbm_bo*, size_t), (override));
  MOCK_METHOD(uint32_t,
              GbmBoGetPlaneOffset,
              (struct gbm_bo*, size_t),
              (override));
  MOCK_METHOD(uint32_t,
              GbmBoGetPlaneStride,
              (struct gbm_bo*, size_t),
              (override));
  MOCK_METHOD(void, GbmBoDestroy, (struct gbm_bo*), (override));
  MOCK_METHOD(void*, Mmap, (void*, size_t, int, int, int, off_t), (override));
  MOCK_METHOD(int, Munmap, (void*, size_t), (override));
  MOCK_METHOD(off_t, Lseek, (int, off_t, int), (override));
};

// global scope mock functions. These functions indirectly invoke the mock
// function implementations through the stubs.
int close(int fd) {
  return _close(fd);
}

struct gbm_device* ::cros::internal::CreateGbmDevice() {
  return _create_gbm_device();
}

int gbm_device_get_fd(struct gbm_device* device) {
  return _gbm_device_get_fd(device);
}

void gbm_device_destroy(struct gbm_device* device) {
  return _gbm_device_destroy(device);
}

struct gbm_bo* gbm_bo_create(struct gbm_device* device,
                             uint32_t width,
                             uint32_t height,
                             uint32_t format,
                             uint32_t flags) {
  return _gbm_bo_create(device, width, height, format, flags);
}

struct gbm_bo* gbm_bo_import(struct gbm_device* device,
                             uint32_t type,
                             void* buffer,
                             uint32_t usage) {
  return _gbm_bo_import(device, type, buffer, usage);
}

void* gbm_bo_map(struct gbm_bo* bo,
                 uint32_t x,
                 uint32_t y,
                 uint32_t width,
                 uint32_t height,
                 uint32_t flags,
                 uint32_t* stride,
                 void** map_data,
                 size_t plane) {
  return _gbm_bo_map(bo, x, y, width, height, flags, stride, map_data, plane);
}

void gbm_bo_unmap(struct gbm_bo* bo, void* map_data) {
  return _gbm_bo_unmap(bo, map_data);
}

void gbm_bo_destroy(struct gbm_bo* bo) {
  return _gbm_bo_destroy(bo);
}

void* mmap(
    void* addr, size_t length, int prot, int flags, int fd, off_t offset) {
  return _mmap(addr, length, prot, flags, fd, offset);
}

int munmap(void* addr, size_t length) {
  return _munmap(addr, length);
}

size_t gbm_bo_get_plane_count(struct gbm_bo* bo) {
  return _gbm_bo_get_plane_count(bo);
}

int gbm_bo_get_plane_fd(struct gbm_bo* bo, size_t plane) {
  return _gbm_bo_get_plane_fd(bo, plane);
}

uint32_t gbm_bo_get_offset(struct gbm_bo* bo, size_t plane) {
  return _gbm_bo_get_offset(bo, plane);
}

uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo* bo, size_t plane) {
  return _gbm_bo_get_stride_for_plane(bo, plane);
}

off_t lseek(int fd, off_t offset, int whence) {
  return _lseek(fd, offset, whence);
}

namespace cros {

namespace tests {

using ::testing::A;
using ::testing::Return;

static size_t GetFormatBpp(uint32_t drm_format) {
  switch (drm_format) {
    case DRM_FORMAT_BGR233:
    case DRM_FORMAT_C8:
    case DRM_FORMAT_R8:
    case DRM_FORMAT_RGB332:
    case DRM_FORMAT_YUV420:
    case DRM_FORMAT_YVU420:
    case DRM_FORMAT_NV12:
    case DRM_FORMAT_NV21:
      return 1;

    case DRM_FORMAT_ABGR1555:
    case DRM_FORMAT_ABGR4444:
    case DRM_FORMAT_ARGB1555:
    case DRM_FORMAT_ARGB4444:
    case DRM_FORMAT_BGR565:
    case DRM_FORMAT_BGRA4444:
    case DRM_FORMAT_BGRA5551:
    case DRM_FORMAT_BGRX4444:
    case DRM_FORMAT_BGRX5551:
    case DRM_FORMAT_GR88:
    case DRM_FORMAT_RG88:
    case DRM_FORMAT_RGB565:
    case DRM_FORMAT_RGBA4444:
    case DRM_FORMAT_RGBA5551:
    case DRM_FORMAT_RGBX4444:
    case DRM_FORMAT_RGBX5551:
    case DRM_FORMAT_UYVY:
    case DRM_FORMAT_VYUY:
    case DRM_FORMAT_XBGR1555:
    case DRM_FORMAT_XBGR4444:
    case DRM_FORMAT_XRGB1555:
    case DRM_FORMAT_XRGB4444:
    case DRM_FORMAT_YUYV:
    case DRM_FORMAT_YVYU:
      return 2;

    case DRM_FORMAT_BGR888:
    case DRM_FORMAT_RGB888:
      return 3;

    case DRM_FORMAT_ABGR2101010:
    case DRM_FORMAT_ABGR8888:
    case DRM_FORMAT_ARGB2101010:
    case DRM_FORMAT_ARGB8888:
    case DRM_FORMAT_AYUV:
    case DRM_FORMAT_BGRA1010102:
    case DRM_FORMAT_BGRA8888:
    case DRM_FORMAT_BGRX1010102:
    case DRM_FORMAT_BGRX8888:
    case DRM_FORMAT_RGBA1010102:
    case DRM_FORMAT_RGBA8888:
    case DRM_FORMAT_RGBX1010102:
    case DRM_FORMAT_RGBX8888:
    case DRM_FORMAT_XBGR2101010:
    case DRM_FORMAT_XBGR8888:
    case DRM_FORMAT_XRGB2101010:
    case DRM_FORMAT_XRGB8888:
      return 4;
  }

  LOG(ERROR) << "Unknown format: " << FormatToString(drm_format);
  return 0;
}

class CameraBufferManagerImplTest : public ::testing::Test {
 public:
  CameraBufferManagerImplTest() = default;
  CameraBufferManagerImplTest(const CameraBufferManagerImplTest&) = delete;
  CameraBufferManagerImplTest& operator=(const CameraBufferManagerImplTest&) =
      delete;

  void SetUp() {
    EXPECT_CALL(gbm_, CreateGbmDevice())
        .Times(1)
        .WillOnce(Return(&dummy_device));
    cbm_ = new CameraBufferManagerImpl();
  }

  void TearDown() {
    // Verify that gbm_device is properly tear down.
    EXPECT_CALL(gbm_, GbmDeviceGetFd(&dummy_device))
        .Times(1)
        .WillOnce(Return(dummy_fd));
    EXPECT_CALL(gbm_, Close(dummy_fd)).Times(1);
    EXPECT_CALL(gbm_, GbmDeviceDestroy(&dummy_device)).Times(1);
    delete cbm_;
    EXPECT_EQ(::testing::Mock::VerifyAndClear(&gbm_), true);
  }

  std::unique_ptr<camera_buffer_handle_t> CreateBuffer(
      uint32_t buffer_id,
      BufferType type,
      uint32_t drm_format,
      uint32_t hal_pixel_format,
      uint32_t width,
      uint32_t height) {
    std::unique_ptr<camera_buffer_handle_t> buffer(new camera_buffer_handle_t);
    buffer->fds[0] = dummy_fd;
    buffer->magic = kCameraBufferMagic;
    buffer->buffer_id = buffer_id;
    buffer->type = type;
    buffer->drm_format = drm_format;
    buffer->hal_pixel_format = hal_pixel_format;
    buffer->width = width;
    buffer->height = height;
    buffer->strides[0] = width * GetFormatBpp(drm_format);
    buffer->offsets[0] = 0;
    switch (drm_format) {
      case DRM_FORMAT_NV12:
      case DRM_FORMAT_NV21:
        buffer->strides[1] = width * GetFormatBpp(drm_format);
        buffer->offsets[1] = buffer->strides[0] * height;
        break;
      case DRM_FORMAT_YUV420:
      case DRM_FORMAT_YVU420:
        buffer->strides[1] = width * GetFormatBpp(drm_format) / 2;
        buffer->strides[2] = width * GetFormatBpp(drm_format) / 2;
        buffer->offsets[1] = buffer->strides[0] * height;
        buffer->offsets[2] =
            buffer->offsets[1] + (buffer->strides[1] * height / 2);
        break;
      default:
        // Single planar buffer.
        break;
    }
    return buffer;
  }

  const MappedGrallocBufferInfoCache& GetMappedBufferInfo() const {
    return cbm_->buffer_info_;
  }

 protected:
  CameraBufferManagerImpl* cbm_;

  MockGbm gbm_;
};

TEST_F(CameraBufferManagerImplTest, AllocateTest) {
  const uint32_t kBufferWidth = 1280, kBufferHeight = 720,
                 usage = GRALLOC_USAGE_FORCE_I420;
  buffer_handle_t buffer_handle;
  uint32_t stride;

  // Allocate the buffer.
  EXPECT_CALL(
      gbm_,
      GbmBoCreate(&dummy_device, kBufferWidth, kBufferHeight, DRM_FORMAT_YUV420,
                  GBM_BO_USE_SW_READ_OFTEN | GBM_BO_USE_SW_WRITE_OFTEN))
      .Times(1)
      .WillOnce(Return(&dummy_bo));
  EXPECT_CALL(gbm_, GbmBoGetNumPlanes(&dummy_bo)).Times(1).WillOnce(Return(3));
  for (size_t plane = 0; plane < 3; ++plane) {
    EXPECT_CALL(gbm_, GbmBoGetPlaneFd(&dummy_bo, plane))
        .Times(1)
        .WillOnce(Return(dummy_fd));
    EXPECT_CALL(gbm_, GbmBoGetPlaneOffset(&dummy_bo, plane))
        .Times(1)
        .WillOnce(Return(0));
    EXPECT_CALL(gbm_, GbmBoGetPlaneStride(&dummy_bo, plane))
        .Times(1)
        .WillOnce(Return(0));
  }
  EXPECT_EQ(cbm_->Allocate(kBufferWidth, kBufferHeight,
                           HAL_PIXEL_FORMAT_YCbCr_420_888, usage, GRALLOC,
                           &buffer_handle, &stride),
            0);

  // Lock the buffer.  All the planes should be mapped.
  for (size_t plane = 0; plane < 3; ++plane) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), plane))
        .Times(1)
        .WillOnce(Return(dummy_addr));
  }
  struct android_ycbcr ycbcr;
  EXPECT_EQ(cbm_->LockYCbCr(buffer_handle, 0, 0, 0, kBufferWidth, kBufferHeight,
                            &ycbcr),
            0);

  // Unlock the buffer.  All the planes should be unmapped.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(3);
  EXPECT_EQ(cbm_->Unlock(buffer_handle), 0);

  // Free the buffer.  The GBM bo should be destroyed and All the FDs should be
  // closed.
  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo)).Times(1);
  EXPECT_CALL(gbm_, Close(dummy_fd)).Times(3);
  EXPECT_EQ(cbm_->Free(buffer_handle), 0);
}

TEST_F(CameraBufferManagerImplTest, LockTest) {
  // Create a dummy buffer.
  const int kBufferWidth = 1280, kBufferHeight = 720;
  auto buffer = CreateBuffer(1, GRALLOC, DRM_FORMAT_XBGR8888,
                             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
                             kBufferWidth, kBufferHeight);
  buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(buffer.get());

  // Register the buffer.
  EXPECT_CALL(gbm_, GbmBoImport(&dummy_device, A<uint32_t>(), A<void*>(),
                                A<uint32_t>()))
      .Times(1)
      .WillOnce(Return(&dummy_bo));
  EXPECT_EQ(cbm_->Register(handle), 0);

  // The call to Lock |handle| should succeed with valid width and height.
  EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                             GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                             A<void**>(), 0))
      .Times(1)
      .WillOnce(Return(dummy_addr));
  void* addr;
  EXPECT_EQ(cbm_->Lock(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &addr), 0);
  EXPECT_EQ(addr, dummy_addr);

  // And the call to Unlock on |handle| should also succeed.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(1);
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  // Now let's Lock |handle| twice.
  EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                             GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                             A<void**>(), 0))
      .Times(1)
      .WillOnce(Return(dummy_addr));
  EXPECT_EQ(cbm_->Lock(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &addr), 0);
  EXPECT_EQ(addr, dummy_addr);
  // The second Lock call should return the previously mapped virtual address
  // without calling gbm_bo_map() again.
  EXPECT_EQ(cbm_->Lock(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &addr), 0);
  EXPECT_EQ(addr, dummy_addr);

  // And just Unlock |handle| once, which should not unmap the buffer.
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  // Finally the bo for |handle| should be unmapped and destroyed when we
  // deregister the buffer.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(1);
  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle), 0);

  // The fd of the buffer plane should be closed.
  EXPECT_CALL(gbm_, Close(dummy_fd)).Times(1);
}

TEST_F(CameraBufferManagerImplTest, LockYCbCrTest) {
  // Create a dummy buffer.
  const int kBufferWidth = 1280, kBufferHeight = 720;
  auto buffer =
      CreateBuffer(1, GRALLOC, DRM_FORMAT_YUV420,
                   HAL_PIXEL_FORMAT_YCbCr_420_888, kBufferWidth, kBufferHeight);
  buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(buffer.get());

  // Register the buffer.
  EXPECT_CALL(gbm_, GbmBoImport(&dummy_device, A<uint32_t>(), A<void*>(),
                                A<uint32_t>()))
      .Times(1)
      .WillOnce(Return(&dummy_bo));
  EXPECT_EQ(cbm_->Register(handle), 0);

  // The call to Lock |handle| should succeed with valid width and height.
  for (size_t i = 0; i < 3; ++i) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), i))
        .Times(1)
        .WillOnce(Return(reinterpret_cast<uint8_t*>(dummy_addr) +
                         buffer->offsets[i]));
  }
  struct android_ycbcr ycbcr;
  EXPECT_EQ(
      cbm_->LockYCbCr(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr), 0);
  EXPECT_EQ(ycbcr.y, dummy_addr);
  EXPECT_EQ(ycbcr.cb,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[1]);
  EXPECT_EQ(ycbcr.cr,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[2]);
  EXPECT_EQ(ycbcr.ystride, buffer->strides[0]);
  EXPECT_EQ(ycbcr.cstride, buffer->strides[1]);
  EXPECT_EQ(ycbcr.chroma_step, 1);

  // And the call to Unlock on |handle| should also succeed.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(3);
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  // Now let's Lock |handle| twice.
  for (size_t i = 0; i < 3; ++i) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), i))
        .Times(1)
        .WillOnce(Return(reinterpret_cast<uint8_t*>(dummy_addr) +
                         buffer->offsets[i]));
  }
  EXPECT_EQ(
      cbm_->LockYCbCr(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr), 0);
  EXPECT_EQ(ycbcr.y, dummy_addr);
  EXPECT_EQ(ycbcr.cb,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[1]);
  EXPECT_EQ(ycbcr.cr,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[2]);
  EXPECT_EQ(ycbcr.ystride, buffer->strides[0]);
  EXPECT_EQ(ycbcr.cstride, buffer->strides[1]);
  EXPECT_EQ(ycbcr.chroma_step, 1);

  // The second LockYCbCr call should return the previously mapped virtual
  // address without calling gbm_bo_map() again.
  EXPECT_EQ(
      cbm_->LockYCbCr(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr), 0);
  EXPECT_EQ(ycbcr.y, dummy_addr);
  EXPECT_EQ(ycbcr.cb,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[1]);
  EXPECT_EQ(ycbcr.cr,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[2]);
  EXPECT_EQ(ycbcr.ystride, buffer->strides[0]);
  EXPECT_EQ(ycbcr.cstride, buffer->strides[1]);
  EXPECT_EQ(ycbcr.chroma_step, 1);

  // And just Unlock |handle| once, which should not unmap the buffer.
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  // Finally the bo for |handle| should be unmapped and destroyed when we
  // deregister the buffer.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(3);
  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle), 0);

  // The fd of the buffer plane should be closed.
  EXPECT_CALL(gbm_, Close(dummy_fd)).Times(1);

  // Test semi-planar buffer.
  buffer =
      CreateBuffer(2, GRALLOC, DRM_FORMAT_NV12, HAL_PIXEL_FORMAT_YCbCr_420_888,
                   kBufferWidth, kBufferHeight);
  handle = reinterpret_cast<buffer_handle_t>(buffer.get());

  EXPECT_CALL(gbm_, GbmBoImport(&dummy_device, A<uint32_t>(), A<void*>(),
                                A<uint32_t>()))
      .Times(1)
      .WillOnce(Return(&dummy_bo));
  EXPECT_EQ(cbm_->Register(handle), 0);

  for (size_t i = 0; i < 2; ++i) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), i))
        .Times(1)
        .WillOnce(Return(reinterpret_cast<uint8_t*>(dummy_addr) +
                         buffer->offsets[i]));
  }
  EXPECT_EQ(
      cbm_->LockYCbCr(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr), 0);
  EXPECT_EQ(ycbcr.y, dummy_addr);
  EXPECT_EQ(ycbcr.cb,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[1]);
  EXPECT_EQ(ycbcr.cr,
            reinterpret_cast<uint8_t*>(dummy_addr) + buffer->offsets[1] + 1);
  EXPECT_EQ(ycbcr.ystride, buffer->strides[0]);
  EXPECT_EQ(ycbcr.cstride, buffer->strides[1]);
  EXPECT_EQ(ycbcr.chroma_step, 2);

  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo, A<void*>())).Times(2);
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle), 0);

  // The fd of the buffer plane should be closed.
  EXPECT_CALL(gbm_, Close(dummy_fd)).Times(1);
}

TEST_F(CameraBufferManagerImplTest, ShmBufferTest) {
  // Create a dummy buffer.
  const int kBufferWidth = 1280, kBufferHeight = 720;
  auto buffer = CreateBuffer(1, SHM, DRM_FORMAT_XBGR8888,
                             HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
                             kBufferWidth, kBufferHeight);
  const size_t kBufferSize = kBufferWidth * kBufferHeight * 4;
  buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(buffer.get());

  // Register the buffer.
  EXPECT_CALL(gbm_, Lseek(dummy_fd, 0, SEEK_END))
      .Times(1)
      .WillOnce(Return(kBufferSize));
  EXPECT_CALL(gbm_, Lseek(dummy_fd, 0, SEEK_SET)).Times(1);
  EXPECT_CALL(gbm_, Mmap(nullptr, kBufferSize, PROT_READ | PROT_WRITE,
                         MAP_SHARED, dummy_fd, 0))
      .Times(1)
      .WillOnce(Return(dummy_addr));
  EXPECT_EQ(cbm_->Register(handle), 0);

  // The call to Lock |handle| should succeed with valid width and height.
  void* addr;
  EXPECT_EQ(cbm_->Lock(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &addr), 0);
  EXPECT_EQ(addr, dummy_addr);

  // Another call to Lock |handle| should return the same mapped address.
  EXPECT_EQ(cbm_->Lock(handle, 0, 0, 0, kBufferWidth, kBufferHeight, &addr), 0);
  EXPECT_EQ(addr, dummy_addr);

  // And the call to Unlock on |handle| should also succeed.
  EXPECT_EQ(cbm_->Unlock(handle), 0);
  EXPECT_EQ(cbm_->Unlock(handle), 0);

  // Finally the shm buffer should be unmapped when we deregister the buffer.
  EXPECT_CALL(gbm_, Munmap(dummy_addr, kBufferSize)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle), 0);
}

TEST_F(CameraBufferManagerImplTest, GetPlaneSizeTest) {
  const int kBufferWidth = 1280, kBufferHeight = 720;

  auto gralloc_buffer = CreateBuffer(0, GRALLOC, DRM_FORMAT_XBGR8888,
                                     HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
                                     kBufferWidth, kBufferHeight);
  buffer_handle_t rgbx_handle =
      reinterpret_cast<buffer_handle_t>(gralloc_buffer.get());
  const size_t kRGBXBufferSize =
      kBufferWidth * kBufferHeight * GetFormatBpp(DRM_FORMAT_XBGR8888);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(rgbx_handle, 0),
            kRGBXBufferSize);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(rgbx_handle, 1), 0);

  auto nv12_buffer =
      CreateBuffer(1, SHM, DRM_FORMAT_NV21, HAL_PIXEL_FORMAT_YCbCr_420_888,
                   kBufferWidth, kBufferHeight);
  const size_t kNV12Plane0Size =
      kBufferWidth * kBufferHeight * GetFormatBpp(DRM_FORMAT_NV12);
  const size_t kNV12Plane1Size =
      kBufferWidth * kBufferHeight * GetFormatBpp(DRM_FORMAT_NV12) / 2;
  buffer_handle_t nv12_handle =
      reinterpret_cast<buffer_handle_t>(nv12_buffer.get());
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(nv12_handle, 0),
            kNV12Plane0Size);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(nv12_handle, 1),
            kNV12Plane1Size);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(nv12_handle, 2), 0);

  auto yuv420_buffer =
      CreateBuffer(2, SHM, DRM_FORMAT_YUV420, HAL_PIXEL_FORMAT_YCbCr_420_888,
                   kBufferWidth, kBufferHeight);
  const size_t kYuv420Plane0Size =
      kBufferWidth * kBufferHeight * GetFormatBpp(DRM_FORMAT_YUV420);
  const size_t kYuv420Plane12Size =
      kBufferWidth * kBufferHeight * GetFormatBpp(DRM_FORMAT_YUV420) / 4;
  buffer_handle_t yuv420_handle =
      reinterpret_cast<buffer_handle_t>(yuv420_buffer.get());
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(yuv420_handle, 0),
            kYuv420Plane0Size);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(yuv420_handle, 1),
            kYuv420Plane12Size);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(yuv420_handle, 2),
            kYuv420Plane12Size);
  EXPECT_EQ(CameraBufferManagerImpl::GetPlaneSize(yuv420_handle, 3), 0);
}

TEST_F(CameraBufferManagerImplTest, DeregisterTest) {
  // Create two dummy buffers.
  const int kBufferWidth = 1280, kBufferHeight = 720;
  auto buffer1 =
      CreateBuffer(1, GRALLOC, DRM_FORMAT_YUV420,
                   HAL_PIXEL_FORMAT_YCbCr_420_888, kBufferWidth, kBufferHeight);
  buffer_handle_t handle1 = reinterpret_cast<buffer_handle_t>(buffer1.get());
  auto buffer2 =
      CreateBuffer(1, GRALLOC, DRM_FORMAT_YUV420,
                   HAL_PIXEL_FORMAT_YCbCr_420_888, kBufferWidth, kBufferHeight);
  buffer_handle_t handle2 = reinterpret_cast<buffer_handle_t>(buffer2.get());

  // Register the buffers.
  struct gbm_bo dummy_bo1, dummy_bo2;
  EXPECT_CALL(gbm_, GbmBoImport(&dummy_device, A<uint32_t>(), A<void*>(),
                                A<uint32_t>()))
      .Times(1)
      .WillOnce(Return(&dummy_bo1));
  EXPECT_EQ(cbm_->Register(handle1), 0);
  EXPECT_CALL(gbm_, GbmBoImport(&dummy_device, A<uint32_t>(), A<void*>(),
                                A<uint32_t>()))
      .Times(1)
      .WillOnce(Return(&dummy_bo2));
  EXPECT_EQ(cbm_->Register(handle2), 0);

  // Lock both buffers
  struct android_ycbcr ycbcr;
  for (size_t i = 0; i < 3; ++i) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo1, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), i))
        .Times(1);
  }
  EXPECT_EQ(
      cbm_->LockYCbCr(handle1, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr),
      0);
  for (size_t i = 0; i < 3; ++i) {
    EXPECT_CALL(gbm_, GbmBoMap(&dummy_bo2, 0, 0, kBufferWidth, kBufferHeight,
                               GBM_BO_TRANSFER_READ_WRITE, A<uint32_t*>(),
                               A<void**>(), i))
        .Times(1);
  }
  EXPECT_EQ(
      cbm_->LockYCbCr(handle2, 0, 0, 0, kBufferWidth, kBufferHeight, &ycbcr),
      0);

  // There should be six mapped planes.
  EXPECT_EQ(GetMappedBufferInfo().size(), 6);

  // Deregister one buffer should only delete three mapped planes.
  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo1, A<void*>())).Times(3);
  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo1)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle1), 0);
  EXPECT_EQ(GetMappedBufferInfo().size(), 3);

  EXPECT_CALL(gbm_, GbmBoUnmap(&dummy_bo2, A<void*>())).Times(3);
  EXPECT_CALL(gbm_, GbmBoDestroy(&dummy_bo2)).Times(1);
  EXPECT_EQ(cbm_->Deregister(handle2), 0);
  EXPECT_EQ(GetMappedBufferInfo().size(), 0);
}

}  // namespace tests

}  // namespace cros

int main(int argc, char** argv) {
  base::AtExitManager exit_manager;
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
