// Copyright 2018 The Chromium 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 "pdf/pdfium/pdfium_form_filler.h"

#include <algorithm>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "pdf/pdfium/pdfium_engine.h"

namespace chrome_pdf {

namespace {

std::string WideStringToString(FPDF_WIDESTRING wide_string) {
  return base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wide_string));
}

}  // namespace

PDFiumFormFiller::PDFiumFormFiller(PDFiumEngine* engine, bool enable_javascript)
    : engine_(engine) {
  // Initialize FPDF_FORMFILLINFO member variables.  Deriving from this struct
  // allows the static callbacks to be able to cast the FPDF_FORMFILLINFO in
  // callbacks to ourself instead of maintaining a map of them to
  // PDFiumEngine.
  FPDF_FORMFILLINFO::version = 1;
  FPDF_FORMFILLINFO::Release = nullptr;
  FPDF_FORMFILLINFO::FFI_Invalidate = Form_Invalidate;
  FPDF_FORMFILLINFO::FFI_OutputSelectedRect = Form_OutputSelectedRect;
  FPDF_FORMFILLINFO::FFI_SetCursor = Form_SetCursor;
  FPDF_FORMFILLINFO::FFI_SetTimer = Form_SetTimer;
  FPDF_FORMFILLINFO::FFI_KillTimer = Form_KillTimer;
  FPDF_FORMFILLINFO::FFI_GetLocalTime = Form_GetLocalTime;
  FPDF_FORMFILLINFO::FFI_OnChange = Form_OnChange;
  FPDF_FORMFILLINFO::FFI_GetPage = Form_GetPage;
  FPDF_FORMFILLINFO::FFI_GetCurrentPage = Form_GetCurrentPage;
  FPDF_FORMFILLINFO::FFI_GetRotation = Form_GetRotation;
  FPDF_FORMFILLINFO::FFI_ExecuteNamedAction = Form_ExecuteNamedAction;
  FPDF_FORMFILLINFO::FFI_SetTextFieldFocus = Form_SetTextFieldFocus;
  FPDF_FORMFILLINFO::FFI_DoURIAction = Form_DoURIAction;
  FPDF_FORMFILLINFO::FFI_DoGoToAction = Form_DoGoToAction;
#if defined(PDF_ENABLE_XFA)
  FPDF_FORMFILLINFO::version = 2;
  FPDF_FORMFILLINFO::FFI_EmailTo = Form_EmailTo;
  FPDF_FORMFILLINFO::FFI_DisplayCaret = Form_DisplayCaret;
  FPDF_FORMFILLINFO::FFI_SetCurrentPage = Form_SetCurrentPage;
  FPDF_FORMFILLINFO::FFI_GetCurrentPageIndex = Form_GetCurrentPageIndex;
  FPDF_FORMFILLINFO::FFI_GetPageViewRect = Form_GetPageViewRect;
  FPDF_FORMFILLINFO::FFI_GetPlatform = Form_GetPlatform;
  FPDF_FORMFILLINFO::FFI_PageEvent = Form_PageEvent;
  FPDF_FORMFILLINFO::FFI_PopupMenu = Form_PopupMenu;
  FPDF_FORMFILLINFO::FFI_PostRequestURL = Form_PostRequestURL;
  FPDF_FORMFILLINFO::FFI_PutRequestURL = Form_PutRequestURL;
  FPDF_FORMFILLINFO::FFI_UploadTo = Form_UploadTo;
  FPDF_FORMFILLINFO::FFI_DownloadFromURL = Form_DownloadFromURL;
  FPDF_FORMFILLINFO::FFI_OpenFile = Form_OpenFile;
  FPDF_FORMFILLINFO::FFI_GotoURL = Form_GotoURL;
  FPDF_FORMFILLINFO::FFI_GetLanguage = Form_GetLanguage;
#endif  // defined(PDF_ENABLE_XFA)

  if (enable_javascript) {
    FPDF_FORMFILLINFO::m_pJsPlatform = this;
    IPDF_JSPLATFORM::version = 3;
    IPDF_JSPLATFORM::app_alert = Form_Alert;
    IPDF_JSPLATFORM::app_beep = Form_Beep;
    IPDF_JSPLATFORM::app_response = Form_Response;
    IPDF_JSPLATFORM::Doc_getFilePath = Form_GetFilePath;
    IPDF_JSPLATFORM::Doc_mail = Form_Mail;
    IPDF_JSPLATFORM::Doc_print = Form_Print;
    IPDF_JSPLATFORM::Doc_submitForm = Form_SubmitForm;
    IPDF_JSPLATFORM::Doc_gotoPage = Form_GotoPage;
    IPDF_JSPLATFORM::Field_browse = nullptr;
  } else {
    FPDF_FORMFILLINFO::m_pJsPlatform = nullptr;
  }
}

PDFiumFormFiller::~PDFiumFormFiller() = default;

// static
void PDFiumFormFiller::Form_Invalidate(FPDF_FORMFILLINFO* param,
                                       FPDF_PAGE page,
                                       double left,
                                       double top,
                                       double right,
                                       double bottom) {
  PDFiumEngine* engine = GetEngine(param);
  int page_index = engine->GetVisiblePageIndex(page);
  if (page_index == -1) {
    // This can sometime happen when the page is closed because it went off
    // screen, and PDFium invalidates the control as it's being deleted.
    return;
  }

  pp::Rect rect = engine->pages_[page_index]->PageToScreen(
      engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
      bottom, engine->current_rotation_);
  engine->client_->Invalidate(rect);
}

// static
void PDFiumFormFiller::Form_OutputSelectedRect(FPDF_FORMFILLINFO* param,
                                               FPDF_PAGE page,
                                               double left,
                                               double top,
                                               double right,
                                               double bottom) {
  PDFiumEngine* engine = GetEngine(param);
  int page_index = engine->GetVisiblePageIndex(page);
  if (page_index == -1) {
    NOTREACHED();
    return;
  }
  pp::Rect rect = engine->pages_[page_index]->PageToScreen(
      engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
      bottom, engine->current_rotation_);
  if (rect.IsEmpty())
    return;

  engine->form_highlights_.push_back(rect);
}

// static
void PDFiumFormFiller::Form_SetCursor(FPDF_FORMFILLINFO* param,
                                      int cursor_type) {
  // We don't need this since it's not enough to change the cursor in all
  // scenarios.  Instead, we check which form field we're under in OnMouseMove.
}

// static
int PDFiumFormFiller::Form_SetTimer(FPDF_FORMFILLINFO* param,
                                    int elapse,
                                    TimerCallback timer_func) {
  auto* form_filler = static_cast<PDFiumFormFiller*>(param);
  return form_filler->SetTimer(base::TimeDelta::FromMilliseconds(elapse),
                               timer_func);
}

// static
void PDFiumFormFiller::Form_KillTimer(FPDF_FORMFILLINFO* param, int timer_id) {
  auto* form_filler = static_cast<PDFiumFormFiller*>(param);
  form_filler->KillTimer(timer_id);
}

// static
FPDF_SYSTEMTIME PDFiumFormFiller::Form_GetLocalTime(FPDF_FORMFILLINFO* param) {
  base::Time time = base::Time::Now();
  base::Time::Exploded exploded;
  time.LocalExplode(&exploded);

  FPDF_SYSTEMTIME rv;
  rv.wYear = exploded.year;
  rv.wMonth = exploded.month;
  rv.wDayOfWeek = exploded.day_of_week;
  rv.wDay = exploded.day_of_month;
  rv.wHour = exploded.hour;
  rv.wMinute = exploded.minute;
  rv.wSecond = exploded.second;
  rv.wMilliseconds = exploded.millisecond;
  return rv;
}

// static
void PDFiumFormFiller::Form_OnChange(FPDF_FORMFILLINFO* param) {
  PDFiumEngine* engine = GetEngine(param);
  engine->SetEditMode(true);
}

// static
FPDF_PAGE PDFiumFormFiller::Form_GetPage(FPDF_FORMFILLINFO* param,
                                         FPDF_DOCUMENT document,
                                         int page_index) {
  PDFiumEngine* engine = GetEngine(param);
  if (!engine->PageIndexInBounds(page_index))
    return nullptr;
  return engine->pages_[page_index]->GetPage();
}

// static
FPDF_PAGE PDFiumFormFiller::Form_GetCurrentPage(FPDF_FORMFILLINFO* param,
                                                FPDF_DOCUMENT document) {
  PDFiumEngine* engine = GetEngine(param);
  int index = engine->last_page_mouse_down_;
  if (index == -1) {
    index = engine->GetMostVisiblePage();
    if (index == -1) {
      NOTREACHED();
      return nullptr;
    }
  }

  return engine->pages_[index]->GetPage();
}

// static
int PDFiumFormFiller::Form_GetRotation(FPDF_FORMFILLINFO* param,
                                       FPDF_PAGE page) {
  return 0;
}

// static
void PDFiumFormFiller::Form_ExecuteNamedAction(FPDF_FORMFILLINFO* param,
                                               FPDF_BYTESTRING named_action) {
  PDFiumEngine* engine = GetEngine(param);
  std::string action(named_action);
  if (action == "Print") {
    engine->client_->Print();
    return;
  }

  int index = engine->last_page_mouse_down_;
  /* Don't try to calculate the most visible page if we don't have a left click
     before this event (this code originally copied Form_GetCurrentPage which of
     course needs to do that and which doesn't have recursion). This can end up
     causing infinite recursion. See http://crbug.com/240413 for more
     information. Either way, it's not necessary for the spec'd list of named
     actions.
  if (index == -1)
    index = engine->GetMostVisiblePage();
  */
  if (index == -1)
    return;

  // This is the only list of named actions per the spec (see 12.6.4.11). Adobe
  // Reader supports more, like FitWidth, but since they're not part of the spec
  // and we haven't got bugs about them, no need to now.
  if (action == "NextPage") {
    engine->ScrollToPage(index + 1);
  } else if (action == "PrevPage") {
    engine->ScrollToPage(index - 1);
  } else if (action == "FirstPage") {
    engine->ScrollToPage(0);
  } else if (action == "LastPage") {
    engine->ScrollToPage(engine->pages_.size() - 1);
  }
}

// static
void PDFiumFormFiller::Form_SetTextFieldFocus(FPDF_FORMFILLINFO* param,
                                              FPDF_WIDESTRING value,
                                              FPDF_DWORD valueLen,
                                              FPDF_BOOL is_focus) {
  // Do nothing for now.
  // TODO(gene): use this signal to trigger OSK.
}

// static
void PDFiumFormFiller::Form_DoURIAction(FPDF_FORMFILLINFO* param,
                                        FPDF_BYTESTRING uri) {
  PDFiumEngine* engine = GetEngine(param);
  engine->client_->NavigateTo(std::string(uri),
                              WindowOpenDisposition::CURRENT_TAB);
}

// static
void PDFiumFormFiller::Form_DoGoToAction(FPDF_FORMFILLINFO* param,
                                         int page_index,
                                         int zoom_mode,
                                         float* position_array,
                                         int size_of_array) {
  PDFiumEngine* engine = GetEngine(param);
  engine->ScrollToPage(page_index);
}

#if defined(PDF_ENABLE_XFA)

// static
void PDFiumFormFiller::Form_EmailTo(FPDF_FORMFILLINFO* param,
                                    FPDF_FILEHANDLER* file_handler,
                                    FPDF_WIDESTRING to,
                                    FPDF_WIDESTRING subject,
                                    FPDF_WIDESTRING cc,
                                    FPDF_WIDESTRING bcc,
                                    FPDF_WIDESTRING message) {
  std::string to_str = WideStringToString(to);
  std::string subject_str = WideStringToString(subject);
  std::string cc_str = WideStringToString(cc);
  std::string bcc_str = WideStringToString(bcc);
  std::string message_str = WideStringToString(message);

  PDFiumEngine* engine = GetEngine(param);
  engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
}

// static
void PDFiumFormFiller::Form_DisplayCaret(FPDF_FORMFILLINFO* param,
                                         FPDF_PAGE page,
                                         FPDF_BOOL visible,
                                         double left,
                                         double top,
                                         double right,
                                         double bottom) {}

// static
void PDFiumFormFiller::Form_SetCurrentPage(FPDF_FORMFILLINFO* param,
                                           FPDF_DOCUMENT document,
                                           int page) {
  PDFiumEngine* engine = GetEngine(param);
  engine->ScrollToPage(page);
}

// static
int PDFiumFormFiller::Form_GetCurrentPageIndex(FPDF_FORMFILLINFO* param,
                                               FPDF_DOCUMENT document) {
  PDFiumEngine* engine = GetEngine(param);
  return engine->GetMostVisiblePage();
}

// static
void PDFiumFormFiller::Form_GetPageViewRect(FPDF_FORMFILLINFO* param,
                                            FPDF_PAGE page,
                                            double* left,
                                            double* top,
                                            double* right,
                                            double* bottom) {
  PDFiumEngine* engine = GetEngine(param);
  int page_index = engine->GetVisiblePageIndex(page);
  if (!engine->PageIndexInBounds(page_index)) {
    *left = 0;
    *right = 0;
    *top = 0;
    *bottom = 0;
    return;
  }

  pp::Rect page_view_rect = engine->GetPageContentsRect(page_index);

  float toolbar_height_in_screen_coords =
      engine->GetToolbarHeightInScreenCoords();

  float page_width = FPDF_GetPageWidth(page);
  float page_height = FPDF_GetPageHeight(page);

  // To convert from a screen scale to a page scale, we multiply by
  // (page_height / page_view_rect.height()) and
  // (page_width / page_view_rect.width()),
  // The base point of the page in screen coords is (page_view_rect.x(),
  // page_view_rect.y()).
  // Therefore, to convert an x position from screen to page
  // coords, we use (page_width * (x - base_x) / page_view_rect.width()).
  // For y positions, (page_height * (y - base_y) / page_view_rect.height()).

  // The top-most y position that can be relied to be visible on the screen is
  // the bottom of the toolbar, which is y = toolbar_height_in_screen_coords.
  float screen_top_in_page_coords =
      page_height * (toolbar_height_in_screen_coords - page_view_rect.y()) /
      page_view_rect.height();
  // The bottom-most y position that is visible on the screen is the bottom of
  // the plugin area, which is y = engine->plugin_size_.height().
  float screen_bottom_in_page_coords =
      page_height * (engine->plugin_size_.height() - page_view_rect.y()) /
      page_view_rect.height();
  // The left-most x position that is visible on the screen is the left of the
  // plugin area, which is x = 0.
  float screen_left_in_page_coords =
      page_width * (0 - page_view_rect.x()) / page_view_rect.width();
  // The right-most x position that is visible on the screen is the right of the
  // plugin area, which is x = engine->plugin_size_.width().
  float screen_right_in_page_coords =
      page_width * (engine->plugin_size_.width() - page_view_rect.x()) /
      page_view_rect.width();

  // Return the edge of the screen or of the page, since we're restricted to
  // both.
  *left = std::max(screen_left_in_page_coords, 0.0f);
  *right = std::min(screen_right_in_page_coords, page_width);
  *top = std::max(screen_top_in_page_coords, 0.0f);
  *bottom = std::min(screen_bottom_in_page_coords, page_height);
}

// static
int PDFiumFormFiller::Form_GetPlatform(FPDF_FORMFILLINFO* param,
                                       void* platform,
                                       int length) {
  int platform_flag = -1;

#if defined(WIN32)
  platform_flag = 0;
#elif defined(__linux__)
  platform_flag = 1;
#else
  platform_flag = 2;
#endif

  std::string javascript =
      "alert(\"Platform:" + base::NumberToString(platform_flag) + "\")";

  return platform_flag;
}

// static
void PDFiumFormFiller::Form_PageEvent(FPDF_FORMFILLINFO* param,
                                      int page_count,
                                      unsigned long event_type) {
  DCHECK(page_count != 0);
  DCHECK(event_type == FXFA_PAGEVIEWEVENT_POSTADDED ||
         event_type == FXFA_PAGEVIEWEVENT_POSTREMOVED);

  PDFiumEngine* engine = GetEngine(param);
  engine->UpdatePageCount();
}

// static
FPDF_BOOL PDFiumFormFiller::Form_PopupMenu(FPDF_FORMFILLINFO* param,
                                           FPDF_PAGE page,
                                           FPDF_WIDGET widget,
                                           int menu_flag,
                                           float x,
                                           float y) {
  return false;
}

// static
FPDF_BOOL PDFiumFormFiller::Form_PostRequestURL(FPDF_FORMFILLINFO* param,
                                                FPDF_WIDESTRING url,
                                                FPDF_WIDESTRING data,
                                                FPDF_WIDESTRING content_type,
                                                FPDF_WIDESTRING encode,
                                                FPDF_WIDESTRING header,
                                                FPDF_BSTR* response) {
  std::string url_str = WideStringToString(url);
  std::string data_str = WideStringToString(data);
  std::string content_type_str = WideStringToString(content_type);
  std::string encode_str = WideStringToString(encode);
  std::string header_str = WideStringToString(header);

  std::string javascript = "alert(\"Post:" + url_str + "," + data_str + "," +
                           content_type_str + "," + encode_str + "," +
                           header_str + "\")";
  return true;
}

// static
FPDF_BOOL PDFiumFormFiller::Form_PutRequestURL(FPDF_FORMFILLINFO* param,
                                               FPDF_WIDESTRING url,
                                               FPDF_WIDESTRING data,
                                               FPDF_WIDESTRING encode) {
  std::string url_str = WideStringToString(url);
  std::string data_str = WideStringToString(data);
  std::string encode_str = WideStringToString(encode);

  std::string javascript =
      "alert(\"Put:" + url_str + "," + data_str + "," + encode_str + "\")";

  return true;
}

// static
void PDFiumFormFiller::Form_UploadTo(FPDF_FORMFILLINFO* param,
                                     FPDF_FILEHANDLER* file_handle,
                                     int file_flag,
                                     FPDF_WIDESTRING to) {
  std::string to_str = WideStringToString(to);
  // TODO: needs the full implementation of form uploading
}

// static
FPDF_LPFILEHANDLER PDFiumFormFiller::Form_DownloadFromURL(
    FPDF_FORMFILLINFO* param,
    FPDF_WIDESTRING url) {
  // NOTE: Think hard about the security implications before allowing
  // a PDF file to perform this action.
  return nullptr;
}

// static
FPDF_FILEHANDLER* PDFiumFormFiller::Form_OpenFile(FPDF_FORMFILLINFO* param,
                                                  int file_flag,
                                                  FPDF_WIDESTRING url,
                                                  const char* mode) {
  // NOTE: Think hard about the security implications before allowing
  // a PDF file to perform this action.
  return nullptr;
}

// static
void PDFiumFormFiller::Form_GotoURL(FPDF_FORMFILLINFO* param,
                                    FPDF_DOCUMENT document,
                                    FPDF_WIDESTRING url) {
  std::string url_str = WideStringToString(url);
  // TODO: needs to implement GOTO URL action
}

// static
int PDFiumFormFiller::Form_GetLanguage(FPDF_FORMFILLINFO* param,
                                       void* language,
                                       int length) {
  return 0;
}

#endif  // defined(PDF_ENABLE_XFA)

// static
int PDFiumFormFiller::Form_Alert(IPDF_JSPLATFORM* param,
                                 FPDF_WIDESTRING message,
                                 FPDF_WIDESTRING title,
                                 int type,
                                 int icon) {
  // See fpdfformfill.h for these values.
  enum AlertType {
    ALERT_TYPE_OK = 0,
    ALERT_TYPE_OK_CANCEL,
    ALERT_TYPE_YES_ON,
    ALERT_TYPE_YES_NO_CANCEL
  };

  enum AlertResult {
    ALERT_RESULT_OK = 1,
    ALERT_RESULT_CANCEL,
    ALERT_RESULT_NO,
    ALERT_RESULT_YES
  };

  PDFiumEngine* engine = GetEngine(param);
  std::string message_str = WideStringToString(message);
  if (type == ALERT_TYPE_OK) {
    engine->client_->Alert(message_str);
    return ALERT_RESULT_OK;
  }

  bool rv = engine->client_->Confirm(message_str);
  if (type == ALERT_TYPE_OK_CANCEL)
    return rv ? ALERT_RESULT_OK : ALERT_RESULT_CANCEL;
  return rv ? ALERT_RESULT_YES : ALERT_RESULT_NO;
}

// static
void PDFiumFormFiller::Form_Beep(IPDF_JSPLATFORM* param, int type) {
  PDFiumEngine* engine = GetEngine(param);
  engine->client_->Beep();
}

// static
int PDFiumFormFiller::Form_Response(IPDF_JSPLATFORM* param,
                                    FPDF_WIDESTRING question,
                                    FPDF_WIDESTRING title,
                                    FPDF_WIDESTRING default_response,
                                    FPDF_WIDESTRING label,
                                    FPDF_BOOL password,
                                    void* response,
                                    int length) {
  std::string question_str = WideStringToString(question);
  std::string default_str = WideStringToString(default_response);

  PDFiumEngine* engine = GetEngine(param);
  std::string rv = engine->client_->Prompt(question_str, default_str);
  base::string16 rv_16 = base::UTF8ToUTF16(rv);
  int rv_bytes = rv_16.size() * sizeof(base::char16);
  if (response) {
    int bytes_to_copy = rv_bytes < length ? rv_bytes : length;
    memcpy(response, rv_16.c_str(), bytes_to_copy);
  }
  return rv_bytes;
}

// static
int PDFiumFormFiller::Form_GetFilePath(IPDF_JSPLATFORM* param,
                                       void* file_path,
                                       int length) {
  PDFiumEngine* engine = GetEngine(param);
  std::string rv = engine->client_->GetURL();
  if (file_path && rv.size() <= static_cast<size_t>(length))
    memcpy(file_path, rv.c_str(), rv.size());
  return rv.size();
}

// static
void PDFiumFormFiller::Form_Mail(IPDF_JSPLATFORM* param,
                                 void* mail_data,
                                 int length,
                                 FPDF_BOOL ui,
                                 FPDF_WIDESTRING to,
                                 FPDF_WIDESTRING subject,
                                 FPDF_WIDESTRING cc,
                                 FPDF_WIDESTRING bcc,
                                 FPDF_WIDESTRING message) {
  // Note: |mail_data| and |length| are ignored. We don't handle attachments;
  // there is no way with mailto.
  std::string to_str = WideStringToString(to);
  std::string cc_str = WideStringToString(cc);
  std::string bcc_str = WideStringToString(bcc);
  std::string subject_str = WideStringToString(subject);
  std::string message_str = WideStringToString(message);

  PDFiumEngine* engine = GetEngine(param);
  engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
}

// static
void PDFiumFormFiller::Form_Print(IPDF_JSPLATFORM* param,
                                  FPDF_BOOL ui,
                                  int start,
                                  int end,
                                  FPDF_BOOL silent,
                                  FPDF_BOOL shrink_to_fit,
                                  FPDF_BOOL print_as_image,
                                  FPDF_BOOL reverse,
                                  FPDF_BOOL annotations) {
  // No way to pass the extra information to the print dialog using JavaScript.
  // Just opening it is fine for now.
  PDFiumEngine* engine = GetEngine(param);
  engine->client_->Print();
}

// static
void PDFiumFormFiller::Form_SubmitForm(IPDF_JSPLATFORM* param,
                                       void* form_data,
                                       int length,
                                       FPDF_WIDESTRING url) {
  std::string url_str = WideStringToString(url);
  PDFiumEngine* engine = GetEngine(param);
  engine->client_->SubmitForm(url_str, form_data, length);
}

// static
void PDFiumFormFiller::Form_GotoPage(IPDF_JSPLATFORM* param, int page_number) {
  PDFiumEngine* engine = GetEngine(param);
  engine->ScrollToPage(page_number);
}

// static
PDFiumEngine* PDFiumFormFiller::GetEngine(FPDF_FORMFILLINFO* info) {
  auto* form_filler = static_cast<PDFiumFormFiller*>(info);
  return form_filler->engine_;
}

// static
PDFiumEngine* PDFiumFormFiller::GetEngine(IPDF_JSPLATFORM* platform) {
  auto* form_filler = static_cast<PDFiumFormFiller*>(platform);
  return form_filler->engine_;
}

int PDFiumFormFiller::SetTimer(const base::TimeDelta& delay,
                               TimerCallback timer_func) {
  const int timer_id = ++last_timer_id_;
  auto timer = std::make_unique<base::RepeatingTimer>();
  timer->Start(FROM_HERE, delay, base::BindRepeating(timer_func, timer_id));
  timers_[timer_id] = std::move(timer);
  return timer_id;
}

void PDFiumFormFiller::KillTimer(int timer_id) {
  timers_.erase(timer_id);
}

}  // namespace chrome_pdf
