// Copyright 2016 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 "camera3_test/camera3_frame_fixture.h"

#include <linux/videodev2.h>
#include <semaphore.h>
#include <stdio.h>

#include <limits>
#include <list>
#include <unordered_map>
#include <unordered_set>

#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/macros.h>
#include <base/strings/string_split.h>
#include <jpeglib.h>
#include <libyuv.h>

namespace camera3_test {

int32_t Camera3FrameFixture::CreateCaptureRequest(
    const camera_metadata_t& metadata, uint32_t* frame_number) {
  // Allocate output buffers
  std::vector<camera3_stream_buffer_t> output_buffers;
  if (cam_device_.AllocateOutputStreamBuffers(&output_buffers)) {
    ADD_FAILURE() << "Failed to allocate buffers for capture request";
    return -EINVAL;
  }

  camera3_capture_request_t capture_request = {
      .frame_number = UINT32_MAX,
      .settings = &metadata,
      .input_buffer = NULL,
      .num_output_buffers = static_cast<uint32_t>(output_buffers.size()),
      .output_buffers = output_buffers.data()};

  // Process capture request
  int32_t ret = cam_device_.ProcessCaptureRequest(&capture_request);
  if (ret == 0 && frame_number) {
    *frame_number = capture_request.frame_number;
  }
  return ret;
}

int32_t Camera3FrameFixture::CreateCaptureRequestByMetadata(
    const CameraMetadataUniquePtr& metadata, uint32_t* frame_number) {
  return CreateCaptureRequest(*metadata, frame_number);
}

int32_t Camera3FrameFixture::CreateCaptureRequestByTemplate(
    int32_t type, uint32_t* frame_number) {
  const camera_metadata_t* default_settings;
  default_settings = cam_device_.ConstructDefaultRequestSettings(type);
  if (!default_settings) {
    ADD_FAILURE() << "Camera default settings are NULL";
    return -EINVAL;
  }

  return CreateCaptureRequest(*default_settings, frame_number);
}

void Camera3FrameFixture::WaitShutterAndCaptureResult(
    const struct timespec& timeout) {
  ASSERT_EQ(0, cam_device_.WaitShutter(timeout))
      << "Timeout waiting for shutter callback";
  ASSERT_EQ(0, cam_device_.WaitCaptureResult(timeout))
      << "Timeout waiting for capture result callback";
}

std::vector<int32_t>
Camera3FrameFixture::GetAvailableColorBarsTestPatternModes() {
  std::vector<int32_t> test_pattern_modes;
  if (cam_device_.GetStaticInfo()->GetAvailableTestPatternModes(
          &test_pattern_modes) != 0) {
    ADD_FAILURE() << "Failed to get sensor available test pattern modes";
    return std::vector<int32_t>();
  }
  std::vector<int32_t> result;
  for (const auto& it : supported_color_bars_test_pattern_modes_) {
    if (std::find(test_pattern_modes.begin(), test_pattern_modes.end(), it) !=
        test_pattern_modes.end()) {
      result.push_back(it);
    }
  }
  return result;
}

Camera3FrameFixture::ImagePlane::ImagePlane(uint32_t stride,
                                            uint32_t size,
                                            uint8_t* addr)
    : stride(stride), size(size), addr(addr) {}

#define DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))
Camera3FrameFixture::Image::Image(uint32_t w, uint32_t h, ImageFormat f)
    : width(w), height(h), format(f) {
  if (format == ImageFormat::IMAGE_FORMAT_ARGB) {
    size = w * h * kARGBPixelWidth;
    data.resize(size);
    planes.emplace_back(w * kARGBPixelWidth, size, data.data());
  } else if (format == ImageFormat::IMAGE_FORMAT_I420) {
    uint32_t cstride = DIV_ROUND_UP(w, 2);
    size = w * h + cstride * DIV_ROUND_UP(h, 2) * 2;
    uint32_t uv_plane_size = cstride * DIV_ROUND_UP(h, 2);
    data.resize(size);
    planes.emplace_back(w, w * h, data.data());  // y
    planes.emplace_back(cstride, uv_plane_size,
                        planes.back().addr + planes.back().size);  // u
    planes.emplace_back(cstride, uv_plane_size,
                        planes.back().addr + planes.back().size);  // v
  }
}

int Camera3FrameFixture::Image::SaveToFile(const std::string filename) const {
  const char* suffix =
      (format == ImageFormat::IMAGE_FORMAT_ARGB) ? ".argb" : ".i420";
  base::FilePath file_path(filename + suffix);
  if (base::WriteFile(file_path, reinterpret_cast<const char*>(data.data()),
                      size) != size) {
    LOGF(ERROR) << "Failed to write file " << filename << suffix;
    return -EINVAL;
  }
  return 0;
}

Camera3FrameFixture::ImageUniquePtr Camera3FrameFixture::ConvertToImage(
    BufferHandleUniquePtr buffer,
    uint32_t width,
    uint32_t height,
    ImageFormat format) {
  if (!buffer || format >= ImageFormat::IMAGE_FORMAT_END) {
    LOGF(ERROR) << "Invalid input buffer or format";
    return ImageUniquePtr(nullptr);
  }
  buffer_handle_t handle = *buffer;
  auto hnd = camera_buffer_handle_t::FromBufferHandle(handle);
  if (!hnd || hnd->buffer_id == 0) {
    LOGF(ERROR) << "Invalid input buffer handle";
    return ImageUniquePtr(nullptr);
  }
  ImageUniquePtr out_buffer(new Image(width, height, format));
  auto gralloc = Camera3TestGralloc::GetInstance();
  if (gralloc->GetFormat(handle) == HAL_PIXEL_FORMAT_BLOB) {
    size_t jpeg_max_size = cam_device_.GetStaticInfo()->GetJpegMaxSize();
    void* buf_addr = nullptr;
    if (gralloc->Lock(handle, 0, 0, 0, jpeg_max_size, 1, &buf_addr) != 0 ||
        !buf_addr) {
      LOG(ERROR) << "Failed to lock input buffer";
      return ImageUniquePtr(nullptr);
    }
    auto jpeg_blob = reinterpret_cast<camera3_jpeg_blob_t*>(
        static_cast<uint8_t*>(buf_addr) + jpeg_max_size -
        sizeof(camera3_jpeg_blob_t));
    if (static_cast<void*>(jpeg_blob) < buf_addr ||
        jpeg_blob->jpeg_blob_id != CAMERA3_JPEG_BLOB_ID) {
      gralloc->Unlock(handle);
      LOG(ERROR) << "Invalid JPEG BLOB ID";
      return ImageUniquePtr(nullptr);
    }
    if ((format == ImageFormat::IMAGE_FORMAT_I420 &&
         libyuv::MJPGToI420(
             static_cast<uint8_t*>(buf_addr), jpeg_blob->jpeg_size,
             out_buffer->planes[0].addr, out_buffer->planes[0].stride,
             out_buffer->planes[1].addr, out_buffer->planes[1].stride,
             out_buffer->planes[2].addr, out_buffer->planes[2].stride, width,
             height, width, height) != 0) ||
        (format == ImageFormat::IMAGE_FORMAT_ARGB &&
         libyuv::MJPGToARGB(static_cast<uint8_t*>(buf_addr),
                            jpeg_blob->jpeg_size, out_buffer->planes[0].addr,
                            out_buffer->planes[0].stride, width, height, width,
                            height) != 0)) {
      LOG(ERROR) << "Failed to convert image from JPEG";
      out_buffer.reset();
    }
    gralloc->Unlock(handle);
  } else {
    struct android_ycbcr in_ycbcr_info;
    if (gralloc->LockYCbCr(handle, 0, 0, 0, width, height, &in_ycbcr_info) !=
        0) {
      LOG(ERROR) << "Failed to lock input buffer";
      return ImageUniquePtr(nullptr);
    }
    uint32_t v4l2_format =
        cros::CameraBufferManager::GetV4L2PixelFormat(handle);
    switch (v4l2_format) {
      case V4L2_PIX_FMT_NV12:
      case V4L2_PIX_FMT_NV12M:
        if ((format == ImageFormat::IMAGE_FORMAT_I420 &&
             libyuv::NV12ToI420(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cb), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 out_buffer->planes[1].addr, out_buffer->planes[1].stride,
                 out_buffer->planes[2].addr, out_buffer->planes[2].stride,
                 width, height) != 0) ||
            (format == ImageFormat::IMAGE_FORMAT_ARGB &&
             libyuv::NV12ToARGB(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cb), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 width, height) != 0)) {
          LOG(ERROR) << "Failed to convert image from NV12";
          out_buffer.reset();
        }
        break;
      case V4L2_PIX_FMT_NV21:
      case V4L2_PIX_FMT_NV21M:
        if ((format == ImageFormat::IMAGE_FORMAT_I420 &&
             libyuv::NV21ToI420(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cr), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 out_buffer->planes[1].addr, out_buffer->planes[1].stride,
                 out_buffer->planes[2].addr, out_buffer->planes[2].stride,
                 width, height) != 0) ||
            (format == ImageFormat::IMAGE_FORMAT_ARGB &&
             libyuv::NV21ToARGB(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cr), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 width, height) != 0)) {
          LOG(ERROR) << "Failed to convert image from NV21";
          out_buffer.reset();
        }
        break;
      case V4L2_PIX_FMT_YUV420:
      case V4L2_PIX_FMT_YUV420M:
      case V4L2_PIX_FMT_YVU420:
      case V4L2_PIX_FMT_YVU420M:
        if ((format == ImageFormat::IMAGE_FORMAT_I420 &&
             libyuv::I420Copy(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cb), in_ycbcr_info.cstride,
                 static_cast<uint8_t*>(in_ycbcr_info.cr), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 out_buffer->planes[1].addr, out_buffer->planes[1].stride,
                 out_buffer->planes[2].addr, out_buffer->planes[2].stride,
                 width, height) != 0) ||
            (format == ImageFormat::IMAGE_FORMAT_ARGB &&
             libyuv::I420ToARGB(
                 static_cast<uint8_t*>(in_ycbcr_info.y), in_ycbcr_info.ystride,
                 static_cast<uint8_t*>(in_ycbcr_info.cb), in_ycbcr_info.cstride,
                 static_cast<uint8_t*>(in_ycbcr_info.cr), in_ycbcr_info.cstride,
                 out_buffer->planes[0].addr, out_buffer->planes[0].stride,
                 width, height) != 0)) {
          LOG(ERROR) << "Failed to convert image from YUV420 or YVU420";
          out_buffer.reset();
        }
        break;
      default:
        LOGF(ERROR) << "Unsupported format " << FormatToString(v4l2_format);
        out_buffer.reset();
    }
    gralloc->Unlock(handle);
  }
  return out_buffer;
}

Camera3FrameFixture::ImageUniquePtr
Camera3FrameFixture::ConvertToImageAndRotate(BufferHandleUniquePtr buffer,
                                             uint32_t width,
                                             uint32_t height,
                                             ImageFormat format,
                                             int32_t rotation) {
  ImageUniquePtr image =
      ConvertToImage(std::move(buffer), width, height, format);
  if (image == nullptr) {
    LOG(ERROR) << "Failed to convert image before rotate";
    return image;
  }
  if (format != ImageFormat::IMAGE_FORMAT_I420) {
    LOG(ERROR) << "Do not support rotate image with format: "
               << static_cast<int>(format);
    return image;
  }

  int new_width = width;
  int new_height = height;
  libyuv::RotationMode rotationMode;

  if (rotation % 180 == 90) {
    std::swap(new_width, new_height);
  }

  switch (rotation) {
    case 90:
      rotationMode = libyuv::kRotate90;
      break;
    case 180:
      rotationMode = libyuv::kRotate180;
      break;
    case 270:
      rotationMode = libyuv::kRotate270;
      break;
    default:
      rotationMode = libyuv::kRotate0;
      break;
  }

  ImageUniquePtr rotated_image(
      new Image(new_width, new_height, ImageFormat::IMAGE_FORMAT_I420));
  libyuv::I420Rotate(
      image->planes[0].addr, image->planes[0].stride, image->planes[1].addr,
      image->planes[1].stride, image->planes[2].addr, image->planes[2].stride,
      rotated_image->planes[0].addr, rotated_image->planes[0].stride,
      rotated_image->planes[1].addr, rotated_image->planes[1].stride,
      rotated_image->planes[2].addr, rotated_image->planes[2].stride, width,
      height, rotationMode);
  return rotated_image;
}

Camera3FrameFixture::ImageUniquePtr
Camera3FrameFixture::GenerateColorBarsPattern(
    uint32_t width,
    uint32_t height,
    ImageFormat format,
    const std::vector<std::tuple<uint8_t, uint8_t, uint8_t>>&
        color_bars_pattern,
    int32_t color_bars_pattern_mode) {
  if (format >= ImageFormat::IMAGE_FORMAT_END ||
      std::find(supported_color_bars_test_pattern_modes_.begin(),
                supported_color_bars_test_pattern_modes_.end(),
                color_bars_pattern_mode) ==
          supported_color_bars_test_pattern_modes_.end()) {
    return nullptr;
  }
  ImageUniquePtr argb_image(
      new Image(width, height, ImageFormat::IMAGE_FORMAT_ARGB));
  uint8_t* pdata = argb_image->planes[0].addr;
  int color_bar_width = width / color_bars_pattern.size();
  int color_bar_height = height / 128 * 128;
  if (color_bar_height == 0) {
    color_bar_height = height;
  }
  for (size_t h = 0; h < height; h++) {
    float gray_factor =
        static_cast<float>(color_bar_height - (h % color_bar_height)) /
        color_bar_height;
    for (size_t w = 0; w < width; w++) {
      int index = (w / color_bar_width) % color_bars_pattern.size();
      auto get_fade_color = [&](uint8_t base_color) {
        if (color_bars_pattern_mode ==
            ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS) {
          return base_color;
        }
        uint8_t color = base_color * gray_factor;
        if ((w / (color_bar_width / 2)) % 2) {
          color = (color & 0xF0) | (color >> 4);
        }
        return color;
      };
      *pdata++ = get_fade_color(std::get<2>(color_bars_pattern[index]));  // B
      *pdata++ = get_fade_color(std::get<1>(color_bars_pattern[index]));  // G
      *pdata++ = get_fade_color(std::get<0>(color_bars_pattern[index]));  // R
      *pdata++ = 0x00;
    }
  }

  if (format == ImageFormat::IMAGE_FORMAT_I420) {
    ImageUniquePtr i420_image(new Image(width, height, format));
    libyuv::ARGBToI420(argb_image->planes[0].addr, argb_image->planes[0].stride,
                       i420_image->planes[0].addr, i420_image->planes[0].stride,
                       i420_image->planes[1].addr, i420_image->planes[1].stride,
                       i420_image->planes[2].addr, i420_image->planes[2].stride,
                       width, height);
    return i420_image;
  }
  return argb_image;
}

double Camera3FrameFixture::ComputeSsim(const Image& buffer_a,
                                        const Image& buffer_b) {
  if (buffer_a.format != ImageFormat::IMAGE_FORMAT_I420 ||
      buffer_b.format != ImageFormat::IMAGE_FORMAT_I420 ||
      buffer_a.width != buffer_b.width || buffer_a.height != buffer_b.height) {
    LOGF(ERROR) << "Images are not of I420 format or resolutions do not match";
    return 0.0;
  }
  return libyuv::I420Ssim(buffer_a.planes[0].addr, buffer_a.planes[0].stride,
                          buffer_a.planes[1].addr, buffer_a.planes[1].stride,
                          buffer_a.planes[2].addr, buffer_a.planes[2].stride,
                          buffer_b.planes[0].addr, buffer_b.planes[0].stride,
                          buffer_b.planes[1].addr, buffer_b.planes[1].stride,
                          buffer_b.planes[2].addr, buffer_b.planes[2].stride,
                          buffer_a.width, buffer_a.height);
}

// Get real-time clock time after waiting for given timeout
void GetTimeOfTimeout(int32_t ms, struct timespec* ts) {
  memset(ts, 0, sizeof(*ts));
  if (clock_gettime(CLOCK_REALTIME, ts)) {
    LOG(ERROR) << "Failed to get clock time";
  }
  ts->tv_sec += ms / 1000;
  ts->tv_nsec += (ms % 1000) * 1000;
}

// Test parameters:
// - Camera ID
// - Template ID
// - Frame format
// - If true, capture with the maximum resolution supported for this format;
// otherwise, capture the minimum one.
class Camera3SingleFrameTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<
          std::tuple<int32_t, int32_t, int32_t, bool>> {
 public:
  Camera3SingleFrameTest() : Camera3FrameFixture(std::get<0>(GetParam())) {}
};

TEST_P(Camera3SingleFrameTest, GetFrame) {
  int32_t format = std::get<1>(GetParam());
  int32_t type = std::get<2>(GetParam());
  if (!cam_device_.IsTemplateSupported(type)) {
    return;
  }

  if (cam_device_.GetStaticInfo()->IsFormatAvailable(format)) {
    ResolutionInfo resolution(0, 0);
    if (std::get<3>(GetParam())) {
      ASSERT_EQ(0, GetMaxResolution(format, &resolution, true))
          << "Failed to get max resolution for format " << format;
    } else {
      ASSERT_EQ(0, GetMinResolution(format, &resolution, true))
          << "Failed to get min resolution for format " << format;
    }
    VLOGF(1) << "Device " << cam_id_;
    VLOGF(1) << "Format 0x" << std::hex << format;
    VLOGF(1) << "Resolution " << resolution.Width() << "x"
             << resolution.Height();

    cam_device_.AddOutputStream(format, resolution.Width(), resolution.Height(),
                                CAMERA3_STREAM_ROTATION_0);
    ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
        << "Configuring stream fails";

    ASSERT_EQ(0, CreateCaptureRequestByTemplate(type, nullptr))
        << "Creating capture request fails";

    struct timespec timeout;
    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    WaitShutterAndCaptureResult(timeout);
  }
}

// Test parameters:
// - Camera ID
// - Template ID
// - Number of frames to capture
class Camera3MultiFrameTest : public Camera3FrameFixture,
                              public ::testing::WithParamInterface<
                                  std::tuple<int32_t, int32_t, int32_t>> {
 public:
  Camera3MultiFrameTest() : Camera3FrameFixture(std::get<0>(GetParam())) {}
};

TEST_P(Camera3MultiFrameTest, GetFrame) {
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  std::vector<const camera3_stream_t*> streams;
  ASSERT_EQ(0, cam_device_.ConfigureStreams(&streams))
      << "Configuring stream fails";
  ASSERT_EQ(1, streams.size());
  int32_t stream_queue_depth = static_cast<int32_t>(streams[0]->max_buffers);

  int32_t type = std::get<1>(GetParam());
  if (!cam_device_.IsTemplateSupported(type)) {
    return;
  }

  int32_t num_frames = std::get<2>(GetParam());
  struct timespec timeout;
  for (int32_t i = 0; i < num_frames; i++) {
    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    if (i >= stream_queue_depth) {
      WaitShutterAndCaptureResult(timeout);
    }
    EXPECT_EQ(0, CreateCaptureRequestByTemplate(type, nullptr))
        << "Creating capture request fails";
  }

  for (int32_t i = 0; i < std::min(num_frames, stream_queue_depth); i++) {
    WaitShutterAndCaptureResult(timeout);
  }
}

// Test parameters:
// - Camera ID
class Camera3MixedTemplateMultiFrameTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<int32_t> {
 public:
  Camera3MixedTemplateMultiFrameTest() : Camera3FrameFixture(GetParam()) {}
};

TEST_P(Camera3MixedTemplateMultiFrameTest, GetFrame) {
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";

  int32_t types[] = {CAMERA3_TEMPLATE_PREVIEW, CAMERA3_TEMPLATE_STILL_CAPTURE,
                     CAMERA3_TEMPLATE_VIDEO_RECORD,
                     CAMERA3_TEMPLATE_VIDEO_SNAPSHOT};
  for (size_t i = 0; i < arraysize(types); ++i) {
    EXPECT_EQ(0, CreateCaptureRequestByTemplate(types[i], nullptr))
        << "Creating capture request fails";
  }

  struct timespec timeout;
  for (size_t i = 0; i < arraysize(types); ++i) {
    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    WaitShutterAndCaptureResult(timeout);
  }
}

// Test parameters:
// - Camera ID
// - Template ID
// - Number of frames to capture
class Camera3FlushRequestsTest : public Camera3FrameFixture,
                                 public ::testing::WithParamInterface<
                                     std::tuple<int32_t, int32_t, int32_t>> {
 public:
  Camera3FlushRequestsTest()
      : Camera3FrameFixture(std::get<0>(GetParam())), num_capture_results_(0) {}

  void SetUp() override;

 protected:
  // Callback functions from HAL device
  virtual void ProcessCaptureResult(const camera3_capture_result* result);

  // Callback functions from HAL device
  virtual void Notify(const camera3_notify_msg* msg);

  // Number of received capture results with all output buffers returned
  int32_t num_capture_results_;

  sem_t flush_result_sem_;

 private:
  // Number of configured streams
  static const int32_t kNumberOfConfiguredStreams;

  // Store number of output buffers returned in capture results with frame
  // number as the key
  std::unordered_map<uint32_t, int32_t> num_capture_result_buffers_;

  // Store frame numbers of which all partial results are received
  std::unordered_set<uint32_t> metadata_complete_frame_numbers_;

  // Store the frames numbers that had been notified with
  // CAMERA3_MSG_ERROR_REQUEST.
  std::unordered_set<uint32_t> notified_error_requests_;
};

const int32_t Camera3FlushRequestsTest::kNumberOfConfiguredStreams = 1;

void Camera3FlushRequestsTest::SetUp() {
  Camera3FrameFixture::SetUp();
  cam_device_.RegisterProcessCaptureResultCallback(base::Bind(
      &Camera3FlushRequestsTest::ProcessCaptureResult, base::Unretained(this)));
  cam_device_.RegisterNotifyCallback(
      base::Bind(&Camera3FlushRequestsTest::Notify, base::Unretained(this)));
  sem_init(&flush_result_sem_, 0, 0);
}

void Camera3FlushRequestsTest::ProcessCaptureResult(
    const camera3_capture_result* result) {
  VLOGF_ENTER();
  ASSERT_NE(nullptr, result) << "Capture result is null";

  EXPECT_EQ(result->result != nullptr, result->partial_result != 0)
      << "Inconsistent partial metadata";

  if (result->result &&
      result->partial_result ==
          cam_device_.GetStaticInfo()->GetPartialResultCount()) {
    metadata_complete_frame_numbers_.insert(result->frame_number);
  }

  num_capture_result_buffers_[result->frame_number] +=
      result->num_output_buffers;

  if (num_capture_result_buffers_[result->frame_number] ==
          kNumberOfConfiguredStreams &&
      (notified_error_requests_.find(result->frame_number) !=
           notified_error_requests_.end() ||
       metadata_complete_frame_numbers_.find(result->frame_number) !=
           metadata_complete_frame_numbers_.end())) {
    num_capture_results_++;
    sem_post(&flush_result_sem_);
  }
}

void Camera3FlushRequestsTest::Notify(const camera3_notify_msg* msg) {
  // TODO(shik): support the partial failure cases

  VLOGF_ENTER();
  if (msg->type == CAMERA3_MSG_ERROR) {
    const camera3_error_msg_t& error = msg->message.error;
    if (error.error_code == CAMERA3_MSG_ERROR_REQUEST) {
      notified_error_requests_.insert(error.frame_number);
    }
  }
}

TEST_P(Camera3FlushRequestsTest, GetFrame) {
  // TODO(hywu): spawn a thread to test simultaneous process_capture_request
  // and flush

  // The number of configured streams must match the value of
  // |kNumberOfConfiguredStreams|.
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";

  int32_t type = std::get<1>(GetParam());
  if (!cam_device_.IsTemplateSupported(type)) {
    return;
  }

  const int32_t num_frames = std::get<2>(GetParam());
  for (int32_t i = 0; i < num_frames; i++) {
    EXPECT_EQ(0, CreateCaptureRequestByTemplate(type, nullptr))
        << "Creating capture request fails";
  }

  ASSERT_EQ(0, cam_device_.Flush()) << "Flushing capture requests fails";

  // flush() should only return when there are no more outstanding buffers or
  // requests left in the HAL
  EXPECT_EQ(num_frames, num_capture_results_)
      << "There are requests left in the HAL after flushing";

  struct timespec timeout;
  for (int32_t i = 0; i < num_frames; i++) {
    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    ASSERT_EQ(0, sem_timedwait(&flush_result_sem_, &timeout));
  }
}

// Test parameters:
// - Camera ID
class Camera3MultiStreamFrameTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<int32_t> {
 public:
  Camera3MultiStreamFrameTest() : Camera3FrameFixture(GetParam()) {}
};

TEST_P(Camera3MultiStreamFrameTest, GetFrame) {
  // Preview stream with large size no bigger than 1080p
  ResolutionInfo limit_resolution(1920, 1080);
  ResolutionInfo preview_resolution(0, 0);
  ASSERT_EQ(0, GetMaxResolution(HAL_PIXEL_FORMAT_YCbCr_420_888,
                                &preview_resolution, true))
      << "Failed to get max resolution for implementation defined format";
  preview_resolution = CapResolution(preview_resolution, limit_resolution);
  cam_device_.AddOutputStream(
      HAL_PIXEL_FORMAT_YCbCr_420_888, preview_resolution.Width(),
      preview_resolution.Height(), CAMERA3_STREAM_ROTATION_0);

  // Second preview stream
  cam_device_.AddOutputStream(
      HAL_PIXEL_FORMAT_YCbCr_420_888, preview_resolution.Width(),
      preview_resolution.Height(), CAMERA3_STREAM_ROTATION_0);

  // Capture stream with largest size
  ResolutionInfo capture_resolution(0, 0);
  ASSERT_EQ(0,
            GetMaxResolution(HAL_PIXEL_FORMAT_BLOB, &capture_resolution, true))
      << "Failed to get max resolution for YCbCr 420 format";
  cam_device_.AddOutputStream(HAL_PIXEL_FORMAT_BLOB, capture_resolution.Width(),
                              capture_resolution.Height(),
                              CAMERA3_STREAM_ROTATION_0);

  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";

  ASSERT_EQ(0,
            CreateCaptureRequestByTemplate(CAMERA3_TEMPLATE_PREVIEW, nullptr))
      << "Creating capture request fails";

  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  WaitShutterAndCaptureResult(timeout);
}

// Test parameters:
// - Camera ID
class Camera3InvalidRequestTest : public Camera3FrameFixture,
                                  public ::testing::WithParamInterface<int> {
 public:
  Camera3InvalidRequestTest() : Camera3FrameFixture(GetParam()) {}
};

TEST_P(Camera3InvalidRequestTest, NullOrUnconfiguredRequest) {
  // Reference:
  // camera2/cts/CameraDeviceTest.java#testInvalidCapture
  EXPECT_NE(0, cam_device_.ProcessCaptureRequest(nullptr))
      << "Capturing with null request should fail";

  const camera_metadata_t* default_settings;
  default_settings =
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW);
  std::vector<camera3_stream_buffer_t> output_buffers;
  std::vector<camera3_stream_t> streams(1);
  streams[0].stream_type = CAMERA3_STREAM_OUTPUT;
  streams[0].width = static_cast<uint32_t>(default_width_);
  streams[0].height = static_cast<uint32_t>(default_height_);
  streams[0].format = default_format_;
  std::vector<const camera3_stream_t*> stream_ptrs(1, &streams[0]);
  ASSERT_EQ(0, cam_device_.AllocateOutputBuffersByStreams(stream_ptrs,
                                                          &output_buffers))
      << "Failed to allocate buffers for capture request";
  camera3_capture_request_t capture_request = {
      .frame_number = 0,
      .settings = default_settings,
      .input_buffer = NULL,
      .num_output_buffers = static_cast<uint32_t>(output_buffers.size()),
      .output_buffers = output_buffers.data()};
  EXPECT_NE(0, cam_device_.ProcessCaptureRequest(&capture_request))
      << "Capturing with stream unconfigured should fail";
}

// Test parameters:
// - Camera ID
// - Number of frames to capture
class Camera3SimpleCaptureFrames
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<std::tuple<int32_t, int32_t>> {
 public:
  Camera3SimpleCaptureFrames()
      : Camera3FrameFixture(std::get<0>(GetParam())),
        num_frames_(std::get<1>(GetParam())) {}

 protected:
  // Process result metadata and/or output buffers
  void ProcessResultMetadataOutputBuffers(
      uint32_t frame_number,
      CameraMetadataUniquePtr metadata,
      std::vector<BufferHandleUniquePtr> buffers) override;

  // Validate capture result keys
  void ValidateCaptureResultKeys(
      const CameraMetadataUniquePtr& request_metadata);

  // Get waiver keys per camera device hardware level and capability
  void GetWaiverKeys(std::set<int32_t>* waiver_keys) const;

  // Process partial metadata
  void ProcessPartialMetadata(
      std::vector<CameraMetadataUniquePtr>* partial_metadata) override;

  // Validate partial results
  void ValidatePartialMetadata();

  const int32_t num_frames_;

  // Store result metadata in the first-in-first-out order
  std::list<CameraMetadataUniquePtr> result_metadata_;

  // Store partial metadata in the first-in-first-out order
  std::list<std::vector<CameraMetadataUniquePtr>> partial_metadata_list_;

  static const int32_t kCaptureResultKeys[69];
};

void Camera3SimpleCaptureFrames::ProcessResultMetadataOutputBuffers(
    uint32_t frame_number,
    CameraMetadataUniquePtr metadata,
    std::vector<BufferHandleUniquePtr> buffers) {
  result_metadata_.push_back(std::move(metadata));
}

void Camera3SimpleCaptureFrames::ValidateCaptureResultKeys(
    const CameraMetadataUniquePtr& request_metadata) {
  std::set<int32_t> waiver_keys;
  GetWaiverKeys(&waiver_keys);
  while (!result_metadata_.empty()) {
    camera_metadata_t* metadata = result_metadata_.front().get();
    for (auto key : kCaptureResultKeys) {
      if (waiver_keys.find(key) != waiver_keys.end()) {
        continue;
      }
      // Check the critical tags here.
      switch (key) {
        case ANDROID_CONTROL_AE_MODE:
        case ANDROID_CONTROL_AF_MODE:
        case ANDROID_CONTROL_AWB_MODE:
        case ANDROID_CONTROL_MODE:
        case ANDROID_STATISTICS_FACE_DETECT_MODE:
        case ANDROID_NOISE_REDUCTION_MODE:
          camera_metadata_ro_entry_t request_entry;
          if (find_camera_metadata_ro_entry(request_metadata.get(), key,
                                            &request_entry)) {
            ADD_FAILURE() << "Metadata " << get_camera_metadata_tag_name(key)
                          << " is unavailable in capture request";
            continue;
          }
          camera_metadata_ro_entry_t result_entry;
          if (find_camera_metadata_ro_entry(metadata, key, &result_entry)) {
            ADD_FAILURE() << "Metadata " << get_camera_metadata_tag_name(key)
                          << " is not present in capture result";
            continue;
          }
          EXPECT_EQ(request_entry.data.i32[0], result_entry.data.i32[0])
              << "Wrong value of metadata " << get_camera_metadata_tag_name(key)
              << " in capture result";
          break;
        case ANDROID_REQUEST_PIPELINE_DEPTH:
          break;
        default:
          // Only do non-null check for the rest of keys.
          camera_metadata_ro_entry_t entry;
          EXPECT_EQ(0, find_camera_metadata_ro_entry(metadata, key, &entry))
              << "Metadata " << get_camera_metadata_tag_name(key)
              << " is unavailable in capture result";
          break;
      }
    }
    result_metadata_.pop_front();
  }
}

const int32_t Camera3SimpleCaptureFrames::kCaptureResultKeys[] = {
    ANDROID_COLOR_CORRECTION_MODE,
    ANDROID_COLOR_CORRECTION_TRANSFORM,
    ANDROID_COLOR_CORRECTION_GAINS,
    ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
    ANDROID_CONTROL_AE_ANTIBANDING_MODE,
    ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
    ANDROID_CONTROL_AE_LOCK,
    ANDROID_CONTROL_AE_MODE,
    ANDROID_CONTROL_AE_REGIONS,
    ANDROID_CONTROL_AF_REGIONS,
    ANDROID_CONTROL_AWB_REGIONS,
    ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
    ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
    ANDROID_CONTROL_AF_MODE,
    ANDROID_CONTROL_AF_TRIGGER,
    ANDROID_CONTROL_AWB_LOCK,
    ANDROID_CONTROL_AWB_MODE,
    ANDROID_CONTROL_CAPTURE_INTENT,
    ANDROID_CONTROL_EFFECT_MODE,
    ANDROID_CONTROL_MODE,
    ANDROID_CONTROL_SCENE_MODE,
    ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
    ANDROID_CONTROL_AE_STATE,
    ANDROID_CONTROL_AF_STATE,
    ANDROID_CONTROL_AWB_STATE,
    ANDROID_EDGE_MODE,
    ANDROID_FLASH_MODE,
    ANDROID_FLASH_STATE,
    ANDROID_HOT_PIXEL_MODE,
    ANDROID_JPEG_ORIENTATION,
    ANDROID_JPEG_QUALITY,
    ANDROID_JPEG_THUMBNAIL_QUALITY,
    ANDROID_JPEG_THUMBNAIL_SIZE,
    ANDROID_LENS_APERTURE,
    ANDROID_LENS_FILTER_DENSITY,
    ANDROID_LENS_FOCAL_LENGTH,
    ANDROID_LENS_FOCUS_DISTANCE,
    ANDROID_LENS_OPTICAL_STABILIZATION_MODE,
    ANDROID_LENS_POSE_ROTATION,
    ANDROID_LENS_POSE_TRANSLATION,
    ANDROID_LENS_FOCUS_RANGE,
    ANDROID_LENS_STATE,
    ANDROID_LENS_INTRINSIC_CALIBRATION,
    ANDROID_LENS_RADIAL_DISTORTION,
    ANDROID_NOISE_REDUCTION_MODE,
    ANDROID_REQUEST_PIPELINE_DEPTH,
    ANDROID_SCALER_CROP_REGION,
    ANDROID_SENSOR_EXPOSURE_TIME,
    ANDROID_SENSOR_FRAME_DURATION,
    ANDROID_SENSOR_SENSITIVITY,
    ANDROID_SENSOR_TIMESTAMP,
    ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
    ANDROID_SENSOR_NOISE_PROFILE,
    ANDROID_SENSOR_GREEN_SPLIT,
    ANDROID_SENSOR_TEST_PATTERN_DATA,
    ANDROID_SENSOR_TEST_PATTERN_MODE,
    ANDROID_SENSOR_ROLLING_SHUTTER_SKEW,
    ANDROID_SHADING_MODE,
    ANDROID_STATISTICS_FACE_DETECT_MODE,
    ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,
    ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP,
    ANDROID_STATISTICS_SCENE_FLICKER,
    ANDROID_STATISTICS_HOT_PIXEL_MAP,
    ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,
    ANDROID_TONEMAP_MODE,
    ANDROID_TONEMAP_GAMMA,
    ANDROID_TONEMAP_PRESET_CURVE,
    ANDROID_BLACK_LEVEL_LOCK,
    ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR};

void Camera3SimpleCaptureFrames::GetWaiverKeys(
    std::set<int32_t>* waiver_keys) const {
  // Global waiver keys
  waiver_keys->insert(ANDROID_JPEG_ORIENTATION);
  waiver_keys->insert(ANDROID_JPEG_QUALITY);
  waiver_keys->insert(ANDROID_JPEG_THUMBNAIL_QUALITY);
  waiver_keys->insert(ANDROID_JPEG_THUMBNAIL_SIZE);

  // Keys only present when corresponding control is on are being verified in
  // its own functional test
  // Only present in certain tonemap mode
  waiver_keys->insert(ANDROID_TONEMAP_CURVE_BLUE);
  waiver_keys->insert(ANDROID_TONEMAP_CURVE_GREEN);
  waiver_keys->insert(ANDROID_TONEMAP_CURVE_RED);
  waiver_keys->insert(ANDROID_TONEMAP_GAMMA);
  waiver_keys->insert(ANDROID_TONEMAP_PRESET_CURVE);
  // Only present when test pattern mode is SOLID_COLOR.
  waiver_keys->insert(ANDROID_SENSOR_TEST_PATTERN_DATA);
  // Only present when STATISTICS_LENS_SHADING_MAP_MODE is ON
  waiver_keys->insert(ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP);
  // Only present when STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES is ON
  waiver_keys->insert(ANDROID_STATISTICS_HOT_PIXEL_MAP);
  // Only present when face detection is on
  waiver_keys->insert(ANDROID_STATISTICS_FACE_IDS);
  waiver_keys->insert(ANDROID_STATISTICS_FACE_LANDMARKS);
  waiver_keys->insert(ANDROID_STATISTICS_FACE_RECTANGLES);
  waiver_keys->insert(ANDROID_STATISTICS_FACE_SCORES);
  // Only present in reprocessing capture result.
  waiver_keys->insert(ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);

  // Keys not required if RAW is not supported
  if (!cam_device_.GetStaticInfo()->IsCapabilitySupported(
          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
    waiver_keys->insert(ANDROID_SENSOR_NEUTRAL_COLOR_POINT);
    waiver_keys->insert(ANDROID_SENSOR_GREEN_SPLIT);
    waiver_keys->insert(ANDROID_SENSOR_NOISE_PROFILE);
  }

  // Keys for depth output capability
  if (!cam_device_.GetStaticInfo()->IsCapabilitySupported(
          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT)) {
    waiver_keys->insert(ANDROID_LENS_POSE_ROTATION);
    waiver_keys->insert(ANDROID_LENS_POSE_TRANSLATION);
    waiver_keys->insert(ANDROID_LENS_INTRINSIC_CALIBRATION);
    waiver_keys->insert(ANDROID_LENS_RADIAL_DISTORTION);
  }

  if (cam_device_.GetStaticInfo()->GetAeMaxRegions() == 0) {
    waiver_keys->insert(ANDROID_CONTROL_AE_REGIONS);
  }
  if (cam_device_.GetStaticInfo()->GetAwbMaxRegions() == 0) {
    waiver_keys->insert(ANDROID_CONTROL_AWB_REGIONS);
  }
  if (cam_device_.GetStaticInfo()->GetAfMaxRegions() == 0) {
    waiver_keys->insert(ANDROID_CONTROL_AF_REGIONS);
  }

  if (cam_device_.GetStaticInfo()->IsHardwareLevelAtLeastFull()) {
    return;
  }

  // Keys to waive for limited devices
  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(
          ANDROID_COLOR_CORRECTION_MODE)) {
    waiver_keys->insert(ANDROID_COLOR_CORRECTION_GAINS);
    waiver_keys->insert(ANDROID_COLOR_CORRECTION_MODE);
    waiver_keys->insert(ANDROID_COLOR_CORRECTION_TRANSFORM);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(
          ANDROID_COLOR_CORRECTION_ABERRATION_MODE)) {
    waiver_keys->insert(ANDROID_COLOR_CORRECTION_ABERRATION_MODE);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(ANDROID_TONEMAP_MODE)) {
    waiver_keys->insert(ANDROID_TONEMAP_MODE);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(ANDROID_EDGE_MODE)) {
    waiver_keys->insert(ANDROID_EDGE_MODE);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(ANDROID_HOT_PIXEL_MODE)) {
    waiver_keys->insert(ANDROID_HOT_PIXEL_MODE);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(
          ANDROID_NOISE_REDUCTION_MODE)) {
    waiver_keys->insert(ANDROID_NOISE_REDUCTION_MODE);
  }

  if (!cam_device_.GetStaticInfo()->IsKeyAvailable(ANDROID_SHADING_MODE)) {
    waiver_keys->insert(ANDROID_SHADING_MODE);
  }

  // Keys not required if neither MANUAL_SENSOR nor READ_SENSOR_SETTINGS is
  // supported
  if (!cam_device_.GetStaticInfo()->IsCapabilitySupported(
          ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
    waiver_keys->insert(ANDROID_SENSOR_EXPOSURE_TIME);
    waiver_keys->insert(ANDROID_SENSOR_FRAME_DURATION);
    waiver_keys->insert(ANDROID_SENSOR_SENSITIVITY);
    waiver_keys->insert(ANDROID_BLACK_LEVEL_LOCK);
    waiver_keys->insert(ANDROID_LENS_FOCUS_RANGE);
    waiver_keys->insert(ANDROID_LENS_FOCUS_DISTANCE);
    waiver_keys->insert(ANDROID_LENS_STATE);
    waiver_keys->insert(ANDROID_LENS_APERTURE);
    waiver_keys->insert(ANDROID_LENS_FILTER_DENSITY);
  }
}

void Camera3SimpleCaptureFrames::ProcessPartialMetadata(
    std::vector<CameraMetadataUniquePtr>* partial_metadata) {
  partial_metadata_list_.resize(partial_metadata_list_.size() + 1);
  for (auto& it : *partial_metadata) {
    partial_metadata_list_.back().push_back(std::move(it));
  }
}

void Camera3SimpleCaptureFrames::ValidatePartialMetadata() {
  for (const auto& it : partial_metadata_list_) {
    // Number of partial results is less than or equal to
    // REQUEST_PARTIAL_RESULT_COUNT
    EXPECT_GE(cam_device_.GetStaticInfo()->GetPartialResultCount(), it.size())
        << "Number of received partial results is wrong";

    // Each key appeared in partial results must be unique across all partial
    // results
    for (size_t i = 0; i < it.size(); i++) {
      size_t entry_count = get_camera_metadata_entry_count(it[i].get());
      for (size_t entry_index = 0; entry_index < entry_count; entry_index++) {
        camera_metadata_ro_entry_t entry;
        ASSERT_EQ(
            0, get_camera_metadata_ro_entry(it[i].get(), entry_index, &entry));
        int32_t key = entry.tag;
        for (size_t j = i + 1; j < it.size(); j++) {
          EXPECT_NE(0, find_camera_metadata_ro_entry(it[j].get(), key, &entry))
              << "Key " << get_camera_metadata_tag_name(key)
              << " appears in multiple partial results";
        }
      }
    }
  }
}

TEST_P(Camera3SimpleCaptureFrames, Camera3ResultAllKeysTest) {
  // Reference:
  // camera2/cts/CaptureResultTest.java#testCameraCaptureResultAllKeys
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";
  CameraMetadataUniquePtr metadata(clone_camera_metadata(
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW)));

  for (int32_t i = 0; i < num_frames_; i++) {
    ASSERT_EQ(0, CreateCaptureRequestByMetadata(metadata, nullptr))
        << "Creating capture request fails";
  }

  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  for (int32_t i = 0; i < num_frames_; i++) {
    WaitShutterAndCaptureResult(timeout);
  }

  ValidateCaptureResultKeys(metadata);
}

TEST_P(Camera3SimpleCaptureFrames, Camera3PartialResultTest) {
  // Reference:
  // camera2/cts/CaptureResultTest.java#testPartialResult
  // Skip the test if partial result is not supported
  if (cam_device_.GetStaticInfo()->GetPartialResultCount() == 1) {
    return;
  }

  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";

  for (int32_t i = 0; i < num_frames_; i++) {
    ASSERT_EQ(0,
              CreateCaptureRequestByTemplate(CAMERA3_TEMPLATE_PREVIEW, nullptr))
        << "Creating capture request fails";
  }

  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  for (int32_t i = 0; i < num_frames_; i++) {
    WaitShutterAndCaptureResult(timeout);
  }

  ValidatePartialMetadata();
}

// Test parameters:
// - Camera ID
class Camera3ResultTimestampsTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<int32_t> {
 public:
  Camera3ResultTimestampsTest() : Camera3FrameFixture(GetParam()) {}

  void SetUp() override;

 protected:
  virtual void Notify(const camera3_notify_msg* msg);

  // Process result metadata and/or output buffers
  void ProcessResultMetadataOutputBuffers(
      uint32_t frame_number,
      CameraMetadataUniquePtr metadata,
      std::vector<BufferHandleUniquePtr> buffers) override;

  // Validate and get one timestamp
  void ValidateAndGetTimestamp(int64_t* timestamp);

 private:
  // Store timestamps of shutter callback in the first-in-first-out order
  std::list<uint64_t> capture_timestamps_;

  // Store result metadata in the first-in-first-out order
  std::list<CameraMetadataUniquePtr> result_metadata_;
};

void Camera3ResultTimestampsTest::SetUp() {
  Camera3FrameFixture::SetUp();
  cam_device_.RegisterNotifyCallback(
      base::Bind(&Camera3ResultTimestampsTest::Notify, base::Unretained(this)));
}

void Camera3ResultTimestampsTest::Notify(const camera3_notify_msg* msg) {
  VLOGF_ENTER();
  EXPECT_EQ(CAMERA3_MSG_SHUTTER, msg->type)
      << "Shutter error = " << msg->message.error.error_code;

  if (msg->type == CAMERA3_MSG_SHUTTER) {
    capture_timestamps_.push_back(msg->message.shutter.timestamp);
  }
}

void Camera3ResultTimestampsTest::ProcessResultMetadataOutputBuffers(
    uint32_t frame_number,
    CameraMetadataUniquePtr metadata,
    std::vector<BufferHandleUniquePtr> buffers) {
  VLOGF_ENTER();
  result_metadata_.push_back(std::move(metadata));
}

void Camera3ResultTimestampsTest::ValidateAndGetTimestamp(int64_t* timestamp) {
  ASSERT_FALSE(capture_timestamps_.empty())
      << "Capture timestamp is unavailable";
  ASSERT_FALSE(result_metadata_.empty()) << "Result metadata is unavailable";
  camera_metadata_ro_entry_t entry;
  ASSERT_EQ(0, find_camera_metadata_ro_entry(result_metadata_.front().get(),
                                             ANDROID_SENSOR_TIMESTAMP, &entry))
      << "Metadata key ANDROID_SENSOR_TIMESTAMP not found";
  *timestamp = entry.data.i64[0];
  EXPECT_EQ(capture_timestamps_.front(), *timestamp)
      << "Shutter notification timestamp must be same as capture result"
         " timestamp";
  capture_timestamps_.pop_front();
  result_metadata_.pop_front();
}

TEST_P(Camera3ResultTimestampsTest, GetFrame) {
  // Reference:
  // camera2/cts/CaptureResultTest.java#testResultTimestamps
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";

  ASSERT_EQ(0,
            CreateCaptureRequestByTemplate(CAMERA3_TEMPLATE_PREVIEW, nullptr))
      << "Creating capture request fails";
  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  ASSERT_EQ(0, cam_device_.WaitCaptureResult(timeout));
  int64_t timestamp1 = 0;
  ValidateAndGetTimestamp(&timestamp1);

  ASSERT_EQ(0,
            CreateCaptureRequestByTemplate(CAMERA3_TEMPLATE_PREVIEW, nullptr))
      << "Creating capture request fails";
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  ASSERT_EQ(0, cam_device_.WaitCaptureResult(timeout));
  int64_t timestamp2 = 0;
  ValidateAndGetTimestamp(&timestamp2);

  ASSERT_LT(timestamp1, timestamp2) << "Timestamps must be increasing";
}

// Test parameters:
// - Camera ID
class Camera3InvalidBufferTest : public Camera3FrameFixture,
                                 public ::testing::WithParamInterface<int32_t> {
 public:
  Camera3InvalidBufferTest() : Camera3FrameFixture(GetParam()) {}

  void SetUp() override;

 protected:
  // Callback functions from HAL device
  virtual void ProcessCaptureResult(const camera3_capture_result* result);

  void RunInvalidBufferTest(buffer_handle_t* handle);

  // Callback functions from HAL device
  // Do nothing.
  virtual void Notify(const camera3_notify_msg* msg) {}

  sem_t capture_result_sem_;

 private:
  // Number of configured streams
  static const int32_t kNumberOfConfiguredStreams;
};

const int32_t Camera3InvalidBufferTest::kNumberOfConfiguredStreams = 1;

void Camera3InvalidBufferTest::SetUp() {
  Camera3FrameFixture::SetUp();
  cam_device_.RegisterProcessCaptureResultCallback(base::Bind(
      &Camera3InvalidBufferTest::ProcessCaptureResult, base::Unretained(this)));
  cam_device_.RegisterNotifyCallback(
      base::Bind(&Camera3InvalidBufferTest::Notify, base::Unretained(this)));
  sem_init(&capture_result_sem_, 0, 0);
}

void Camera3InvalidBufferTest::ProcessCaptureResult(
    const camera3_capture_result* result) {
  VLOGF_ENTER();
  ASSERT_NE(nullptr, result) << "Capture result is null";
  for (uint32_t i = 0; i < result->num_output_buffers; i++) {
    EXPECT_EQ(CAMERA3_BUFFER_STATUS_ERROR, result->output_buffers[i].status)
        << "Capture result should return error on invalid buffer";
  }
  if (result->num_output_buffers > 0) {
    sem_post(&capture_result_sem_);
  }
}

void Camera3InvalidBufferTest::RunInvalidBufferTest(buffer_handle_t* handle) {
  cam_device_.AddOutputStream(default_format_, default_width_, default_height_,
                              CAMERA3_STREAM_ROTATION_0);
  std::vector<const camera3_stream_t*> streams;
  ASSERT_EQ(0, cam_device_.ConfigureStreams(&streams))
      << "Configuring stream fails";
  const camera_metadata_t* default_settings;
  default_settings =
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW);
  ASSERT_NE(nullptr, default_settings) << "Camera default settings are NULL";
  camera3_stream_buffer_t stream_buffer = {
      .stream = const_cast<camera3_stream_t*>(streams.front()),
      .buffer = handle,
      .status = CAMERA3_BUFFER_STATUS_OK,
      .acquire_fence = -1,
      .release_fence = -1};
  std::vector<camera3_stream_buffer_t> stream_buffers(1, stream_buffer);
  camera3_capture_request_t capture_request = {
      .frame_number = UINT32_MAX,
      .settings = default_settings,
      .input_buffer = NULL,
      .num_output_buffers = static_cast<uint32_t>(stream_buffers.size()),
      .output_buffers = stream_buffers.data()};
  int ret = cam_device_.ProcessCaptureRequest(&capture_request);
  if (ret == -EINVAL) {
    return;
  }
  ASSERT_EQ(0, ret);
  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  ASSERT_EQ(0, sem_timedwait(&capture_result_sem_, &timeout));
}

TEST_P(Camera3InvalidBufferTest, NullBufferHandle) {
  buffer_handle_t handle = nullptr;
  RunInvalidBufferTest(&handle);
}

TEST_P(Camera3InvalidBufferTest, FreedBufferHandle) {
  BufferHandleUniquePtr buffer = Camera3TestGralloc::GetInstance()->Allocate(
      default_width_, default_height_, HAL_PIXEL_FORMAT_YCbCr_420_888,
      GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_CAMERA_WRITE);
  ASSERT_NE(nullptr, buffer);
  buffer_handle_t handle = *buffer.get();
  buffer.reset();
  RunInvalidBufferTest(&handle);
}

// Test parameters:
// - Camera ID, frame format, resolution width, resolution height
class Camera3FrameContentTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<
          std::tuple<int32_t, int32_t, int32_t, int32_t>> {
 public:
  const double kContentTestSsimThreshold = 0.75;

  Camera3FrameContentTest()
      : Camera3FrameFixture(std::get<0>(GetParam())),
        format_(std::get<1>(GetParam())),
        width_(std::get<2>(GetParam())),
        height_(std::get<3>(GetParam())) {}

 protected:
  void ProcessResultMetadataOutputBuffers(
      uint32_t frame_number,
      CameraMetadataUniquePtr metadata,
      std::vector<BufferHandleUniquePtr> buffers) override;

  int32_t format_;

  int32_t width_;

  int32_t height_;

  BufferHandleUniquePtr buffer_handle_;
};

void Camera3FrameContentTest::ProcessResultMetadataOutputBuffers(
    uint32_t frame_number,
    CameraMetadataUniquePtr metadata,
    std::vector<BufferHandleUniquePtr> buffers) {
  ASSERT_EQ(nullptr, buffer_handle_);
  buffer_handle_ = std::move(buffers.front());
}

TEST_P(Camera3FrameContentTest, CorruptionDetection) {
  auto test_pattern_modes = GetAvailableColorBarsTestPatternModes();
  ASSERT_FALSE(test_pattern_modes.empty())
      << "Failed to get sensor available test pattern modes";

  cam_device_.AddOutputStream(format_, width_, height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";
  CameraMetadataUniquePtr metadata(clone_camera_metadata(
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW)));
  UpdateMetadata(ANDROID_SENSOR_TEST_PATTERN_MODE, test_pattern_modes.data(), 1,
                 &metadata);
  ASSERT_EQ(0, CreateCaptureRequestByMetadata(metadata, nullptr))
      << "Creating capture request fails";

  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  WaitShutterAndCaptureResult(timeout);
  ASSERT_NE(nullptr, buffer_handle_) << "Failed to get frame buffer";
  auto capture_image = ConvertToImage(std::move(buffer_handle_), width_,
                                      height_, ImageFormat::IMAGE_FORMAT_I420);
  ASSERT_NE(nullptr, capture_image);

  for (const auto& it : color_bars_test_patterns_) {
    auto pattern_image = GenerateColorBarsPattern(
        width_, height_, ImageFormat::IMAGE_FORMAT_I420, it,
        test_pattern_modes.front());
    ASSERT_NE(nullptr, pattern_image);

    if (ComputeSsim(*capture_image, *pattern_image) >
        kContentTestSsimThreshold) {
      return;
    }
  }
  std::stringstream ss;
  ss << "/tmp/corruption_test_0x" << std::hex << format_ << "_" << std::dec
     << width_ << "x" << height_;
  capture_image->SaveToFile(ss.str());
  ADD_FAILURE() << "The frame content is corrupted";
}

TEST_P(Camera3FrameContentTest, DetectGreenLine) {
  auto test_pattern_modes = GetAvailableColorBarsTestPatternModes();
  ASSERT_FALSE(test_pattern_modes.empty())
      << "Failed to get sensor available test pattern modes";

  cam_device_.AddOutputStream(format_, width_, height_,
                              CAMERA3_STREAM_ROTATION_0);
  ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
      << "Configuring stream fails";
  CameraMetadataUniquePtr metadata(clone_camera_metadata(
      cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW)));
  UpdateMetadata(ANDROID_SENSOR_TEST_PATTERN_MODE, test_pattern_modes.data(), 1,
                 &metadata);
  ASSERT_EQ(0, CreateCaptureRequestByMetadata(metadata, nullptr))
      << "Creating capture request fails";

  struct timespec timeout;
  GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
  WaitShutterAndCaptureResult(timeout);
  ASSERT_NE(nullptr, buffer_handle_) << "Failed to get frame buffer";
  auto argb_image = ConvertToImage(std::move(buffer_handle_), width_, height_,
                                   ImageFormat::IMAGE_FORMAT_ARGB);
  ASSERT_NE(nullptr, argb_image);

  auto IsGreenPixel = [](const uint8_t* pixel) {
    const uint8_t kRedOrBlueUpperLimit = 50;
    const uint8_t kGreenLowerLimit = 100;
    const uint32_t kRedOffset = 0;
    const uint32_t kGreenOffset = 1;
    const uint32_t kBlueOffset = 2;
    return *(pixel + kRedOffset)<kRedOrBlueUpperLimit&&*(pixel + kGreenOffset)>
               kGreenLowerLimit &&
           *(pixel + kBlueOffset) < kRedOrBlueUpperLimit;
  };
  auto IsBottomLineGreen = [&](const ImageUniquePtr& argb_image) {
    uint8_t* pixel_of_last_line =
        argb_image->planes[0].addr +
        argb_image->planes[0].stride * (argb_image->height - 1);
    for (size_t i = 0; i < argb_image->planes[0].stride;
         i += kARGBPixelWidth, pixel_of_last_line += kARGBPixelWidth) {
      if (!IsGreenPixel(pixel_of_last_line)) {
        return false;
      }
    }
    return true;
  };
  EXPECT_FALSE(IsBottomLineGreen(argb_image))
      << "Green line at the bottom of captured frame";
  auto IsRightMostLineGreen = [&](const ImageUniquePtr& argb_image) {
    uint8_t* last_pixel_of_line = argb_image->planes[0].addr +
                                  argb_image->planes[0].stride -
                                  kARGBPixelWidth;
    for (size_t i = 0; i < argb_image->height;
         i++, last_pixel_of_line += argb_image->planes[0].stride) {
      if (!IsGreenPixel(last_pixel_of_line)) {
        return false;
      }
    }
    return true;
  };
  EXPECT_FALSE(IsRightMostLineGreen(argb_image))
      << "Green line at the rightmost of captured frame";
}

// Test parameters:
// - Camera ID, frame format, resolution width, resolution height
// - Rotation degrees
class Camera3PortraitRotationTest
    : public Camera3FrameFixture,
      public ::testing::WithParamInterface<
          std::tuple<std::tuple<int32_t, int32_t, int32_t, int32_t>, int32_t>> {
 public:
  const double kPortraitTestSsimThreshold = 0.75;

  Camera3PortraitRotationTest()
      : Camera3FrameFixture(std::get<0>(std::get<0>(GetParam()))),
        format_(std::get<1>(std::get<0>(GetParam()))),
        width_(std::get<2>(std::get<0>(GetParam()))),
        height_(std::get<3>(std::get<0>(GetParam()))),
        rotation_degrees_(std::get<1>(GetParam())),
        save_images_(base::CommandLine::ForCurrentProcess()->HasSwitch(
            "save_portrait_test_images")) {}

 protected:
  void ProcessResultMetadataOutputBuffers(
      uint32_t frame_number,
      CameraMetadataUniquePtr metadata,
      std::vector<BufferHandleUniquePtr> buffers) override;

  // Rotate |in_buffer| 180 degrees to |out_buffer|.
  int Rotate180(const Image& in_buffer, Image* out_buffer);

  // Crop-rotate-scale |in_buffer| to |out_buffer|.
  int CropRotateScale(const Image& in_buffer, Image* out_buffer);

  int32_t format_;

  int32_t width_;

  int32_t height_;

  int32_t rotation_degrees_;

  bool save_images_;

  BufferHandleUniquePtr buffer_handle_;
};

void Camera3PortraitRotationTest::ProcessResultMetadataOutputBuffers(
    uint32_t frame_number,
    CameraMetadataUniquePtr metadata,
    std::vector<BufferHandleUniquePtr> buffers) {
  ASSERT_EQ(nullptr, buffer_handle_);
  buffer_handle_ = std::move(buffers.front());
}

int Camera3PortraitRotationTest::Rotate180(const Image& in_buffer,
                                           Image* out_buffer) {
  if (in_buffer.format != ImageFormat::IMAGE_FORMAT_I420 ||
      out_buffer->format != ImageFormat::IMAGE_FORMAT_I420 ||
      in_buffer.width != out_buffer->width ||
      in_buffer.height != out_buffer->height) {
    return -EINVAL;
  }
  return libyuv::I420Rotate(
      in_buffer.planes[0].addr, in_buffer.planes[0].stride,
      in_buffer.planes[1].addr, in_buffer.planes[1].stride,
      in_buffer.planes[2].addr, in_buffer.planes[2].stride,
      out_buffer->planes[0].addr, out_buffer->planes[0].stride,
      out_buffer->planes[1].addr, out_buffer->planes[1].stride,
      out_buffer->planes[2].addr, out_buffer->planes[2].stride, in_buffer.width,
      in_buffer.height, libyuv::RotationMode::kRotate180);
}

int Camera3PortraitRotationTest::CropRotateScale(const Image& in_buffer,
                                                 Image* out_buffer) {
  if (in_buffer.format != ImageFormat::IMAGE_FORMAT_I420 || !out_buffer ||
      out_buffer->format != ImageFormat::IMAGE_FORMAT_I420 ||
      in_buffer.width != out_buffer->width ||
      in_buffer.height != out_buffer->height) {
    return -EINVAL;
  }
  int width = in_buffer.width;
  int height = in_buffer.height;
  int cropped_width = height * height / width;
  if (cropped_width % 2 == 1) {
    // Make cropped_width to the closest even number.
    cropped_width++;
  }
  int cropped_height = height;
  int margin = (width - cropped_width) / 2;

  int rotated_height = cropped_width;
  int rotated_width = cropped_height;
  libyuv::RotationMode rotation_mode = libyuv::RotationMode::kRotate90;
  switch (rotation_degrees_) {
    case 90:
      rotation_mode = libyuv::RotationMode::kRotate90;
      break;
    case 270:
      rotation_mode = libyuv::RotationMode::kRotate270;
      break;
    default:
      LOG(ERROR) << "Invalid rotation degree: " << rotation_degrees_;
      return -EINVAL;
  }

  ImageUniquePtr rotated_buffer(
      new Image(rotated_width, rotated_height, ImageFormat::IMAGE_FORMAT_I420));
  // This libyuv method first crops the frame and then rotates it 90 degrees
  // clockwise or counterclockwise.
  int res = libyuv::ConvertToI420(
      in_buffer.planes[0].addr, in_buffer.planes[0].stride,
      rotated_buffer->planes[0].addr, rotated_buffer->planes[0].stride,
      rotated_buffer->planes[1].addr, rotated_buffer->planes[1].stride,
      rotated_buffer->planes[2].addr, rotated_buffer->planes[2].stride, margin,
      0, width, height, cropped_width, cropped_height, rotation_mode,
      libyuv::FourCC::FOURCC_I420);
  if (res) {
    LOG(ERROR) << "ConvertToI420 failed: " << res;
    return res;
  }

  res = libyuv::I420Scale(
      rotated_buffer->planes[0].addr, rotated_buffer->planes[0].stride,
      rotated_buffer->planes[1].addr, rotated_buffer->planes[1].stride,
      rotated_buffer->planes[2].addr, rotated_buffer->planes[2].stride,
      rotated_width, rotated_height, out_buffer->planes[0].addr,
      out_buffer->planes[0].stride, out_buffer->planes[1].addr,
      out_buffer->planes[1].stride, out_buffer->planes[2].addr,
      out_buffer->planes[2].stride, width, height,
      libyuv::FilterMode::kFilterNone);
  if (res) {
    LOG(ERROR) << "I420Scale failed: " << res;
  }
  return res;
}

TEST_P(Camera3PortraitRotationTest, GetFrame) {
  auto test_pattern_modes = GetAvailableColorBarsTestPatternModes();
  ASSERT_FALSE(test_pattern_modes.empty())
      << "Failed to get sensor available test pattern modes";

  if (cam_device_.GetStaticInfo()->IsFormatAvailable(format_)) {
    VLOGF(1) << "Device " << cam_id_;
    VLOGF(1) << "Format 0x" << std::hex << format_;
    VLOGF(1) << "Resolution " << width_ << "x" << height_;
    VLOGF(1) << "Rotation " << rotation_degrees_;

    cam_device_.AddOutputStream(format_, width_, height_,
                                CAMERA3_STREAM_ROTATION_0);
    ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
        << "Configuring stream fails";

    // Get original pattern
    CameraMetadataUniquePtr metadata(clone_camera_metadata(
        cam_device_.ConstructDefaultRequestSettings(CAMERA3_TEMPLATE_PREVIEW)));
    UpdateMetadata(ANDROID_SENSOR_TEST_PATTERN_MODE, test_pattern_modes.data(),
                   1, &metadata);
    ASSERT_EQ(0, CreateCaptureRequestByMetadata(metadata, nullptr))
        << "Creating capture request fails";

    struct timespec timeout;
    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    WaitShutterAndCaptureResult(timeout);
    ASSERT_NE(nullptr, buffer_handle_) << "Failed to get original frame buffer";
    auto orig_i420_image =
        ConvertToImage(std::move(buffer_handle_), width_, height_,
                       ImageFormat::IMAGE_FORMAT_I420);
    ASSERT_NE(nullptr, orig_i420_image);
    auto SaveImage = [this](const Image& image, const std::string suffix) {
      std::stringstream ss;
      ss << "/tmp/portrait_test_0x" << std::hex << format_ << "_" << std::dec
         << width_ << "x" << height_ << "_" << rotation_degrees_ << suffix;
      EXPECT_EQ(0, image.SaveToFile(ss.str()));
    };
    if (save_images_) {
      SaveImage(*orig_i420_image, "_orig");
    }

    // Re-configure streams with rotation
    camera3_stream_rotation_t crop_rotate_scale_degrees =
        CAMERA3_STREAM_ROTATION_0;
    switch (rotation_degrees_) {
      case 90:
        crop_rotate_scale_degrees = CAMERA3_STREAM_ROTATION_90;
        break;
      case 270:
        crop_rotate_scale_degrees = CAMERA3_STREAM_ROTATION_270;
        break;
      default:
        FAIL() << "Invalid rotation degree: " << rotation_degrees_;
    }
    cam_device_.AddOutputStream(format_, width_, height_,
                                crop_rotate_scale_degrees);
    ASSERT_EQ(0, cam_device_.ConfigureStreams(nullptr))
        << "Configuring stream fails";
    ASSERT_EQ(0, CreateCaptureRequestByMetadata(metadata, nullptr))
        << "Creating capture request fails";

    // Verify the original pattern is asymmetric
    ImageUniquePtr orig_rotated_i420_image(
        new Image(width_, height_, ImageFormat::IMAGE_FORMAT_I420));
    ASSERT_EQ(0, Rotate180(*orig_i420_image, orig_rotated_i420_image.get()));
    ASSERT_LE(ComputeSsim(*orig_i420_image, *orig_rotated_i420_image),
              kPortraitTestSsimThreshold)
        << "Test pattern appears to be symmetric";

    // Generate software crop-rotate-scaled pattern
    ImageUniquePtr sw_portrait_i420_image(
        new Image(width_, height_, ImageFormat::IMAGE_FORMAT_I420));
    ASSERT_NE(nullptr, sw_portrait_i420_image);
    ASSERT_EQ(0,
              CropRotateScale(*orig_i420_image, sw_portrait_i420_image.get()));
    if (save_images_) {
      SaveImage(*sw_portrait_i420_image, "_swconv");
    }

    GetTimeOfTimeout(kDefaultTimeoutMs, &timeout);
    WaitShutterAndCaptureResult(timeout);
    ASSERT_NE(nullptr, buffer_handle_) << "Failed to get portrait frame buffer";
    auto portrait_i420_image =
        ConvertToImage(std::move(buffer_handle_), width_, height_,
                       ImageFormat::IMAGE_FORMAT_I420);
    ASSERT_NE(nullptr, portrait_i420_image);
    if (save_images_) {
      SaveImage(*portrait_i420_image, "_conv");
    }

    // Compare similarity of crop-rotate-scaled patterns
    ASSERT_GT(ComputeSsim(*sw_portrait_i420_image, *portrait_i420_image),
              kPortraitTestSsimThreshold)
        << "SSIM value is lower than threshold";
  }
}

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3SingleFrameTest,
    ::testing::Combine(
        ::testing::ValuesIn(Camera3Module().GetTestCameraIds()),
        ::testing::Values(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
                          HAL_PIXEL_FORMAT_YCbCr_420_888,
                          HAL_PIXEL_FORMAT_YCrCb_420_SP,
                          HAL_PIXEL_FORMAT_BLOB,
                          HAL_PIXEL_FORMAT_YV12,
                          HAL_PIXEL_FORMAT_Y8,
                          HAL_PIXEL_FORMAT_Y16,
                          HAL_PIXEL_FORMAT_RAW16),
        ::testing::Values(CAMERA3_TEMPLATE_PREVIEW,
                          CAMERA3_TEMPLATE_STILL_CAPTURE,
                          CAMERA3_TEMPLATE_VIDEO_RECORD,
                          CAMERA3_TEMPLATE_VIDEO_SNAPSHOT,
                          CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
                          CAMERA3_TEMPLATE_MANUAL),
        ::testing::Bool()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3MultiFrameTest,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetTestCameraIds()),
                       ::testing::Values(CAMERA3_TEMPLATE_PREVIEW,
                                         CAMERA3_TEMPLATE_STILL_CAPTURE,
                                         CAMERA3_TEMPLATE_VIDEO_RECORD,
                                         CAMERA3_TEMPLATE_VIDEO_SNAPSHOT,
                                         CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
                                         CAMERA3_TEMPLATE_MANUAL),
                       ::testing::Range(1, 10)));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3MixedTemplateMultiFrameTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3FlushRequestsTest,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetTestCameraIds()),
                       ::testing::Values(CAMERA3_TEMPLATE_PREVIEW,
                                         CAMERA3_TEMPLATE_STILL_CAPTURE,
                                         CAMERA3_TEMPLATE_VIDEO_RECORD,
                                         CAMERA3_TEMPLATE_VIDEO_SNAPSHOT,
                                         CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
                                         CAMERA3_TEMPLATE_MANUAL),
                       ::testing::Values(10)));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3MultiStreamFrameTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3InvalidRequestTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3SimpleCaptureFrames,
    ::testing::Combine(::testing::ValuesIn(Camera3Module().GetTestCameraIds()),
                       ::testing::Values(10)));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3ResultTimestampsTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3InvalidBufferTest,
    ::testing::ValuesIn(Camera3Module().GetTestCameraIds()));

static std::vector<std::tuple<int32_t, int32_t, int32_t, int32_t>>
IterateCameraIdFormatResolution() {
  std::vector<std::tuple<int32_t, int32_t, int32_t, int32_t>> result;
  auto cam_ids = Camera3Module().GetTestCameraIds();
  auto formats =
      std::vector<int>({HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
                        HAL_PIXEL_FORMAT_YCbCr_420_888, HAL_PIXEL_FORMAT_BLOB});
  for (const auto& cam_id : cam_ids) {
    for (const auto& format : formats) {
      auto resolutions =
          Camera3Module().GetSortedOutputResolutions(cam_id, format);
      for (const auto& resolution : resolutions) {
        result.emplace_back(cam_id, format, resolution.Width(),
                            resolution.Height());
      }
    }
  }
  return result;
}

INSTANTIATE_TEST_CASE_P(Camera3FrameTest,
                        Camera3FrameContentTest,
                        ::testing::ValuesIn(IterateCameraIdFormatResolution()));

INSTANTIATE_TEST_CASE_P(
    Camera3FrameTest,
    Camera3PortraitRotationTest,
    ::testing::Combine(::testing::ValuesIn(IterateCameraIdFormatResolution()),
                       ::testing::Values(90, 270)));

}  // namespace camera3_test
