/*
 * 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;

  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CameraBufferManagerImplTest);
};

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();
}
