Replace FWL timer infrastructure with CFX_Timer.

Change-Id: I6b9f6d95e09bb7c3c1fc7a4c1576b63031cb6874
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/59132
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_interactiveform.cpp b/fpdfsdk/cpdfsdk_interactiveform.cpp
index e75e58b..40c7278 100644
--- a/fpdfsdk/cpdfsdk_interactiveform.cpp
+++ b/fpdfsdk/cpdfsdk_interactiveform.cpp
@@ -40,7 +40,6 @@
 #ifdef PDF_ENABLE_XFA
 #include "fpdfsdk/cpdfsdk_xfawidget.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffwidget.h"
diff --git a/fpdfsdk/fpdf_save.cpp b/fpdfsdk/fpdf_save.cpp
index 1776d12..6275c01 100644
--- a/fpdfsdk/fpdf_save.cpp
+++ b/fpdfsdk/fpdf_save.cpp
@@ -28,7 +28,6 @@
 #include "core/fpdfapi/parser/cpdf_stream.h"
 #include "core/fxcrt/cfx_memorystream.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
 #include "public/fpdf_formfill.h"
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/parser/cxfa_object.h"
diff --git a/fpdfsdk/fpdfxfa/BUILD.gn b/fpdfsdk/fpdfxfa/BUILD.gn
index 9d9788d..ef26c60 100644
--- a/fpdfsdk/fpdfxfa/BUILD.gn
+++ b/fpdfsdk/fpdfxfa/BUILD.gn
@@ -18,8 +18,6 @@
     "cpdfxfa_page.h",
     "cpdfxfa_widgethandler.cpp",
     "cpdfxfa_widgethandler.h",
-    "cxfa_fwladaptertimermgr.cpp",
-    "cxfa_fwladaptertimermgr.h",
   ]
   deps = [
     "../../:pdfium_public_headers",
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
index 2aeeb52..88605ca 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp
@@ -13,7 +13,6 @@
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
 #include "fxjs/cjs_runtime.h"
 #include "fxjs/ijs_runtime.h"
 #include "public/fpdf_formfill.h"
@@ -301,11 +300,8 @@
          m_pFormFillEnv->PutRequestURL(wsURL, wsData, wsEncode);
 }
 
-std::unique_ptr<IFWL_AdapterTimerMgr> CPDFXFA_Context::NewTimerMgr() {
-  if (!m_pFormFillEnv)
-    return nullptr;
-  return pdfium::MakeUnique<CXFA_FWLAdapterTimerMgr>(
-      m_pFormFillEnv->GetTimerHandler());
+TimerHandlerIface* CPDFXFA_Context::GetTimerHandler() const {
+  return m_pFormFillEnv ? m_pFormFillEnv->GetTimerHandler() : nullptr;
 }
 
 void CPDFXFA_Context::SendPostSaveToXFADoc() {
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
index 67404d6..0617d19 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h
@@ -13,6 +13,7 @@
 #include "core/fpdfapi/parser/cpdf_document.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/observed_ptr.h"
+#include "core/fxcrt/timerhandler_iface.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h"
@@ -67,7 +68,6 @@
   WideString GetPlatform() override;
   WideString GetAppName() override;
   WideString GetAppTitle() const override;
-
   void Beep(uint32_t dwType) override;
   int32_t MsgBox(const WideString& wsMessage,
                  const WideString& wsTitle,
@@ -88,8 +88,8 @@
   bool PutRequestURL(const WideString& wsURL,
                      const WideString& wsData,
                      const WideString& wsEncode) override;
+  TimerHandlerIface* GetTimerHandler() const override;
 
-  std::unique_ptr<IFWL_AdapterTimerMgr> NewTimerMgr() override;
   void SendPostSaveToXFADoc();
   void SendPreSaveToXFADoc(
       std::vector<RetainPtr<IFX_SeekableStream>>* fileList);
diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
index 45d6e90..39874eb 100644
--- a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
+++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp
@@ -13,7 +13,6 @@
 #include "core/fpdfapi/render/cpdf_pagerendercache.h"
 #include "fpdfsdk/cpdfsdk_pageview.h"
 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
 #include "third_party/base/ptr_util.h"
 #include "xfa/fxfa/cxfa_ffdocview.h"
 #include "xfa/fxfa/cxfa_ffpageview.h"
diff --git a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp
deleted file mode 100644
index 6e4137b..0000000
--- a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "third_party/base/ptr_util.h"
-#include "third_party/base/stl_util.h"
-
-namespace {
-
-std::vector<std::unique_ptr<CFWL_TimerInfo>>* g_TimerArray = nullptr;
-
-class CFWL_FWLAdapterTimerInfo final : public CFWL_TimerInfo {
- public:
-  CFWL_FWLAdapterTimerInfo(IFWL_AdapterTimerMgr* mgr,
-                           int32_t event,
-                           CFWL_Timer* timer)
-      : CFWL_TimerInfo(mgr), idEvent(event), pTimer(timer) {}
-
-  int32_t idEvent;
-  CFWL_Timer* pTimer;
-};
-
-void TimerProc(int32_t idEvent) {
-  if (!g_TimerArray)
-    return;
-
-  for (const auto& info : *g_TimerArray) {
-    auto* pInfo = static_cast<CFWL_FWLAdapterTimerInfo*>(info.get());
-    if (pInfo->idEvent == idEvent) {
-      pInfo->pTimer->OnTimerFired();
-      break;
-    }
-  }
-}
-
-}  // namespace
-
-CXFA_FWLAdapterTimerMgr::CXFA_FWLAdapterTimerMgr(
-    TimerHandlerIface* pTimerHandler)
-    : m_pTimerHandler(pTimerHandler) {}
-
-CXFA_FWLAdapterTimerMgr::~CXFA_FWLAdapterTimerMgr() = default;
-
-CFWL_TimerInfo* CXFA_FWLAdapterTimerMgr::Start(CFWL_Timer* pTimer,
-                                               uint32_t dwElapse) {
-  if (!g_TimerArray)
-    g_TimerArray = new std::vector<std::unique_ptr<CFWL_TimerInfo>>;
-
-  if (!m_pTimerHandler)
-    return nullptr;
-
-  int32_t id_event = m_pTimerHandler->SetTimer(dwElapse, TimerProc);
-  g_TimerArray->push_back(
-      pdfium::MakeUnique<CFWL_FWLAdapterTimerInfo>(this, id_event, pTimer));
-  return g_TimerArray->back().get();
-}
-
-void CXFA_FWLAdapterTimerMgr::Stop(CFWL_TimerInfo* pTimerInfo) {
-  if (!pTimerInfo || !m_pTimerHandler)
-    return;
-
-  CFWL_FWLAdapterTimerInfo* pInfo =
-      static_cast<CFWL_FWLAdapterTimerInfo*>(pTimerInfo);
-  m_pTimerHandler->KillTimer(pInfo->idEvent);
-  if (!g_TimerArray)
-    return;
-
-  pdfium::FakeUniquePtr<CFWL_TimerInfo> fake(pInfo);
-  auto it = std::find(g_TimerArray->begin(), g_TimerArray->end(), fake);
-  if (it != g_TimerArray->end())
-    g_TimerArray->erase(it);
-}
diff --git a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h b/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
deleted file mode 100644
index f8aaeca..0000000
--- a/fpdfsdk/fpdfxfa/cxfa_fwladaptertimermgr.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef FPDFSDK_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
-#define FPDFSDK_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
-
-#include <vector>
-
-#include "core/fxcrt/timerhandler_iface.h"
-#include "core/fxcrt/unowned_ptr.h"
-#include "xfa/fwl/cfwl_timerinfo.h"
-#include "xfa/fwl/ifwl_adaptertimermgr.h"
-
-class CXFA_FWLAdapterTimerMgr final : public IFWL_AdapterTimerMgr {
- public:
-  explicit CXFA_FWLAdapterTimerMgr(TimerHandlerIface* pTimerHandler);
-  ~CXFA_FWLAdapterTimerMgr() override;
-
-  CFWL_TimerInfo* Start(CFWL_Timer* pTimer, uint32_t dwElapse) override;
-  void Stop(CFWL_TimerInfo* pTimerInfo) override;
-
- private:
-  UnownedPtr<TimerHandlerIface> const m_pTimerHandler;
-};
-
-#endif  // FPDFSDK_FPDFXFA_CXFA_FWLADAPTERTIMERMGR_H_
diff --git a/xfa/fwl/BUILD.gn b/xfa/fwl/BUILD.gn
index a30ba5e..f392502 100644
--- a/xfa/fwl/BUILD.gn
+++ b/xfa/fwl/BUILD.gn
@@ -74,10 +74,6 @@
     "cfwl_themepart.cpp",
     "cfwl_themepart.h",
     "cfwl_themetext.h",
-    "cfwl_timer.cpp",
-    "cfwl_timer.h",
-    "cfwl_timerinfo.cpp",
-    "cfwl_timerinfo.h",
     "cfwl_widget.cpp",
     "cfwl_widget.h",
     "cfwl_widgetmgr.cpp",
@@ -88,7 +84,6 @@
     "cfx_barcode.h",
     "fwl_widgetdef.h",
     "fwl_widgethit.h",
-    "ifwl_adaptertimermgr.h",
     "ifwl_themeprovider.h",
     "ifwl_widgetdelegate.h",
     "theme/cfwl_barcodetp.cpp",
diff --git a/xfa/fwl/cfwl_app.h b/xfa/fwl/cfwl_app.h
index 3bac5bd..a911ab2 100644
--- a/xfa/fwl/cfwl_app.h
+++ b/xfa/fwl/cfwl_app.h
@@ -10,12 +10,11 @@
 #include <memory>
 
 #include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/timerhandler_iface.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
 
 class CFWL_NoteDriver;
 class CFWL_WidgetMgr;
-class CFWL_Widget;
-class IFWL_AdapterTimerMgr;
 
 enum FWL_KeyFlag {
   FWL_KEYFLAG_Ctrl = 1 << 0,
@@ -31,9 +30,9 @@
  public:
   class AdapterIface {
    public:
-    virtual ~AdapterIface() {}
+    virtual ~AdapterIface() = default;
     virtual CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() = 0;
-    virtual std::unique_ptr<IFWL_AdapterTimerMgr> NewTimerMgr() = 0;
+    virtual TimerHandlerIface* GetTimerHandler() = 0;
   };
 
   explicit CFWL_App(AdapterIface* pAdapter);
diff --git a/xfa/fwl/cfwl_caret.cpp b/xfa/fwl/cfwl_caret.cpp
index ee38cac..ef5bdcc 100644
--- a/xfa/fwl/cfwl_caret.cpp
+++ b/xfa/fwl/cfwl_caret.cpp
@@ -9,9 +9,9 @@
 #include <utility>
 
 #include "third_party/base/ptr_util.h"
+#include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_themebackground.h"
-#include "xfa/fwl/cfwl_timerinfo.h"
 #include "xfa/fwl/cfwl_widgetproperties.h"
 #include "xfa/fwl/ifwl_themeprovider.h"
 
@@ -26,18 +26,11 @@
 CFWL_Caret::CFWL_Caret(const CFWL_App* app,
                        std::unique_ptr<CFWL_WidgetProperties> properties,
                        CFWL_Widget* pOuter)
-    : CFWL_Widget(app, std::move(properties), pOuter),
-      m_pTimer(pdfium::MakeUnique<CFWL_Caret::Timer>(this)),
-      m_pTimerInfo(nullptr) {
+    : CFWL_Widget(app, std::move(properties), pOuter) {
   SetStates(kStateHighlight);
 }
 
-CFWL_Caret::~CFWL_Caret() {
-  if (m_pTimerInfo) {
-    m_pTimerInfo->StopTimer();
-    m_pTimerInfo = nullptr;
-  }
-}
+CFWL_Caret::~CFWL_Caret() = default;
 
 FWL_Type CFWL_Caret::GetClassID() const {
   return FWL_Type::Caret;
@@ -58,22 +51,15 @@
 }
 
 void CFWL_Caret::ShowCaret() {
-  if (m_pTimerInfo) {
-    CFWL_TimerInfo* pOldTimerInfo = m_pTimerInfo.Release();
-    pOldTimerInfo->StopTimer();
-  }
-
-  m_pTimerInfo = m_pTimer->StartTimer(kBlinkPeriodMs);
+  m_pTimer = pdfium::MakeUnique<CFX_Timer>(
+      GetOwnerApp()->GetAdapterNative()->GetTimerHandler(), this,
+      kBlinkPeriodMs);
   RemoveStates(FWL_WGTSTATE_Invisible);
   SetStates(kStateHighlight);
 }
 
 void CFWL_Caret::HideCaret() {
-  if (m_pTimerInfo) {
-    CFWL_TimerInfo* pOldTimerInfo = m_pTimerInfo.Release();
-    pOldTimerInfo->StopTimer();
-  }
-
+  m_pTimer.reset();
   SetStates(FWL_WGTSTATE_Invisible);
 }
 
@@ -101,15 +87,12 @@
   DrawWidget(pGraphics, matrix);
 }
 
-CFWL_Caret::Timer::Timer(CFWL_Caret* pCaret) : CFWL_Timer(pCaret) {}
-
-void CFWL_Caret::Timer::OnTimerFired() {
-  CFWL_Caret* pCaret = static_cast<CFWL_Caret*>(m_pWidget.Get());
-  if (!(pCaret->GetStates() & kStateHighlight))
-    pCaret->SetStates(kStateHighlight);
+void CFWL_Caret::OnTimerFired() {
+  if (!(GetStates() & kStateHighlight))
+    SetStates(kStateHighlight);
   else
-    pCaret->RemoveStates(kStateHighlight);
+    RemoveStates(kStateHighlight);
 
-  CFX_RectF rt = pCaret->GetWidgetRect();
-  pCaret->RepaintRect(CFX_RectF(0, 0, rt.width + 1, rt.height));
+  CFX_RectF rt = GetWidgetRect();
+  RepaintRect(CFX_RectF(0, 0, rt.width + 1, rt.height));
 }
diff --git a/xfa/fwl/cfwl_caret.h b/xfa/fwl/cfwl_caret.h
index 3889f66..7f5dfdf 100644
--- a/xfa/fwl/cfwl_caret.h
+++ b/xfa/fwl/cfwl_caret.h
@@ -9,21 +9,21 @@
 
 #include <memory>
 
-#include "xfa/fwl/cfwl_timer.h"
+#include "core/fxcrt/cfx_timer.h"
 #include "xfa/fwl/cfwl_widget.h"
 #include "xfa/fxgraphics/cxfa_gecolor.h"
 
 class CFWL_WidgetProperties;
 class CFWL_Widget;
 
-class CFWL_Caret final : public CFWL_Widget {
+class CFWL_Caret final : public CFWL_Widget, public CFX_Timer::CallbackIface {
  public:
   CFWL_Caret(const CFWL_App* app,
              std::unique_ptr<CFWL_WidgetProperties> properties,
              CFWL_Widget* pOuter);
   ~CFWL_Caret() override;
 
-  // CFWL_Widget
+  // CFWL_Widget:
   FWL_Type GetClassID() const override;
   void DrawWidget(CXFA_Graphics* pGraphics, const CFX_Matrix& matrix) override;
   void OnProcessMessage(CFWL_Message* pMessage) override;
@@ -31,25 +31,18 @@
                     const CFX_Matrix& matrix) override;
   void Update() override;
 
+  // CFX_Timer::CallbackIface:
+  void OnTimerFired() override;
+
   void ShowCaret();
   void HideCaret();
 
  private:
-  class Timer final : public CFWL_Timer {
-   public:
-    explicit Timer(CFWL_Caret* pCaret);
-    ~Timer() override {}
-
-    void OnTimerFired() override;
-  };
-  friend class CFWL_Caret::Timer;
-
   void DrawCaretBK(CXFA_Graphics* pGraphics,
                    IFWL_ThemeProvider* pTheme,
                    const CFX_Matrix* pMatrix);
 
-  std::unique_ptr<CFWL_Caret::Timer> m_pTimer;
-  UnownedPtr<CFWL_TimerInfo> m_pTimerInfo;
+  std::unique_ptr<CFX_Timer> m_pTimer;
 };
 
 #endif  // XFA_FWL_CFWL_CARET_H_
diff --git a/xfa/fwl/cfwl_scrollbar.cpp b/xfa/fwl/cfwl_scrollbar.cpp
index 2cfa1ad..acc144f 100644
--- a/xfa/fwl/cfwl_scrollbar.cpp
+++ b/xfa/fwl/cfwl_scrollbar.cpp
@@ -10,13 +10,14 @@
 #include <memory>
 #include <utility>
 
+#include "third_party/base/ptr_util.h"
 #include "third_party/base/stl_util.h"
+#include "xfa/fwl/cfwl_app.h"
 #include "xfa/fwl/cfwl_messagemouse.h"
 #include "xfa/fwl/cfwl_messagemousewheel.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_themebackground.h"
 #include "xfa/fwl/cfwl_themepart.h"
-#include "xfa/fwl/cfwl_timerinfo.h"
 #include "xfa/fwl/ifwl_themeprovider.h"
 
 #define FWL_SCROLLBAR_Elapse 500
@@ -31,11 +32,9 @@
     const CFWL_App* app,
     std::unique_ptr<CFWL_WidgetProperties> properties,
     CFWL_Widget* pOuter)
-    : CFWL_Widget(app, std::move(properties), pOuter),
-      m_Timer(this) {
-}
+    : CFWL_Widget(app, std::move(properties), pOuter) {}
 
-CFWL_ScrollBar::~CFWL_ScrollBar() {}
+CFWL_ScrollBar::~CFWL_ScrollBar() = default;
 
 FWL_Type CFWL_ScrollBar::GetClassID() const {
   return FWL_Type::ScrollBar;
@@ -356,16 +355,15 @@
   else
     DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, point);
 
-  if (!SendEvent())
-    m_pTimerInfo = m_Timer.StartTimer(FWL_SCROLLBAR_Elapse);
+  if (!SendEvent()) {
+    m_pTimer = pdfium::MakeUnique<CFX_Timer>(
+        GetOwnerApp()->GetAdapterNative()->GetTimerHandler(), this,
+        FWL_SCROLLBAR_Elapse);
+  }
 }
 
 void CFWL_ScrollBar::OnLButtonUp(const CFX_PointF& point) {
-  if (m_pTimerInfo) {
-    m_pTimerInfo->StopTimer();
-    m_pTimerInfo = nullptr;
-  }
-
+  m_pTimer.reset();
   m_bMouseDown = false;
   DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, point);
   DoMouseUp(1, m_rtThumb, m_iThumbButtonState, point);
@@ -462,15 +460,10 @@
   RepaintRect(rtItem);
 }
 
-CFWL_ScrollBar::Timer::Timer(CFWL_ScrollBar* pToolTip) : CFWL_Timer(pToolTip) {}
-
-void CFWL_ScrollBar::Timer::OnTimerFired() {
-  CFWL_ScrollBar* pScrollBar = static_cast<CFWL_ScrollBar*>(m_pWidget.Get());
-  if (pScrollBar->m_pTimerInfo) {
-    pScrollBar->m_pTimerInfo->StopTimer();
-    pScrollBar->m_pTimerInfo = nullptr;
+void CFWL_ScrollBar::OnTimerFired() {
+  m_pTimer.reset();
+  if (!SendEvent()) {
+    m_pTimer = pdfium::MakeUnique<CFX_Timer>(
+        GetOwnerApp()->GetAdapterNative()->GetTimerHandler(), this, 0);
   }
-
-  if (!pScrollBar->SendEvent())
-    pScrollBar->m_pTimerInfo = StartTimer(0);
 }
diff --git a/xfa/fwl/cfwl_scrollbar.h b/xfa/fwl/cfwl_scrollbar.h
index af35bc8..c98479d 100644
--- a/xfa/fwl/cfwl_scrollbar.h
+++ b/xfa/fwl/cfwl_scrollbar.h
@@ -9,10 +9,10 @@
 
 #include <memory>
 
+#include "core/fxcrt/cfx_timer.h"
 #include "core/fxcrt/fx_system.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "xfa/fwl/cfwl_eventscroll.h"
-#include "xfa/fwl/cfwl_timer.h"
 #include "xfa/fwl/cfwl_widget.h"
 #include "xfa/fwl/cfwl_widgetproperties.h"
 
@@ -21,14 +21,15 @@
 #define FWL_STYLEEXT_SCB_Horz (0L << 0)
 #define FWL_STYLEEXT_SCB_Vert (1L << 0)
 
-class CFWL_ScrollBar final : public CFWL_Widget {
+class CFWL_ScrollBar final : public CFWL_Widget,
+                             public CFX_Timer::CallbackIface {
  public:
   CFWL_ScrollBar(const CFWL_App* app,
                  std::unique_ptr<CFWL_WidgetProperties> properties,
                  CFWL_Widget* pOuter);
   ~CFWL_ScrollBar() override;
 
-  // CFWL_Widget
+  // CFWL_Widget:
   FWL_Type GetClassID() const override;
   void Update() override;
   void DrawWidget(CXFA_Graphics* pGraphics, const CFX_Matrix& matrix) override;
@@ -36,6 +37,9 @@
   void OnDrawWidget(CXFA_Graphics* pGraphics,
                     const CFX_Matrix& matrix) override;
 
+  // CFX_Timer::CallbackIface:
+  void OnTimerFired() override;
+
   void GetRange(float* fMin, float* fMax) const {
     ASSERT(fMin);
     ASSERT(fMax);
@@ -55,15 +59,6 @@
   void SetTrackPos(float fTrackPos);
 
  private:
-  class Timer final : public CFWL_Timer {
-   public:
-    explicit Timer(CFWL_ScrollBar* pToolTip);
-    ~Timer() override {}
-
-    void OnTimerFired() override;
-  };
-  friend class CFWL_ScrollBar::Timer;
-
   bool IsVertical() const {
     return !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_SCB_Vert);
   }
@@ -110,7 +105,6 @@
   void DoMouseLeave(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState);
   void DoMouseHover(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState);
 
-  UnownedPtr<CFWL_TimerInfo> m_pTimerInfo;
   float m_fRangeMin = 0.0f;
   float m_fRangeMax = -1.0f;
   float m_fPageSize = 0.0f;
@@ -134,7 +128,7 @@
   CFX_RectF m_rtMaxBtn;
   CFX_RectF m_rtMinTrack;
   CFX_RectF m_rtMaxTrack;
-  CFWL_ScrollBar::Timer m_Timer;
+  std::unique_ptr<CFX_Timer> m_pTimer;
 };
 
 #endif  // XFA_FWL_CFWL_SCROLLBAR_H_
diff --git a/xfa/fwl/cfwl_timer.cpp b/xfa/fwl/cfwl_timer.cpp
deleted file mode 100644
index fd35e06..0000000
--- a/xfa/fwl/cfwl_timer.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/fwl/cfwl_timer.h"
-
-#include "xfa/fwl/cfwl_app.h"
-#include "xfa/fwl/cfwl_timerinfo.h"
-#include "xfa/fwl/cfwl_widget.h"
-#include "xfa/fwl/ifwl_adaptertimermgr.h"
-
-CFWL_Timer::CFWL_Timer(CFWL_Widget* parent) : m_pWidget(parent) {}
-
-CFWL_Timer::~CFWL_Timer() {}
-
-CFWL_TimerInfo* CFWL_Timer::StartTimer(uint32_t dwElapse) {
-  CFWL_App::AdapterIface* pAdapterNative =
-      m_pWidget->GetOwnerApp()->GetAdapterNative();
-  if (!pAdapterNative)
-    return nullptr;
-
-  if (!m_pAdapterTimerMgr)
-    m_pAdapterTimerMgr = pAdapterNative->NewTimerMgr();
-
-  if (!m_pAdapterTimerMgr)
-    return nullptr;
-
-  return m_pAdapterTimerMgr->Start(this, dwElapse);
-}
diff --git a/xfa/fwl/cfwl_timer.h b/xfa/fwl/cfwl_timer.h
deleted file mode 100644
index 47f7254..0000000
--- a/xfa/fwl/cfwl_timer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef XFA_FWL_CFWL_TIMER_H_
-#define XFA_FWL_CFWL_TIMER_H_
-
-#include <memory>
-
-#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/unowned_ptr.h"
-
-class CFWL_TimerInfo;
-class CFWL_Widget;
-class IFWL_AdapterTimerMgr;
-
-class CFWL_Timer {
- public:
-  explicit CFWL_Timer(CFWL_Widget* parent);
-  virtual ~CFWL_Timer();
-
-  virtual void OnTimerFired() = 0;
-  CFWL_TimerInfo* StartTimer(uint32_t dwElapse);
-
- protected:
-  UnownedPtr<CFWL_Widget> m_pWidget;
-  std::unique_ptr<IFWL_AdapterTimerMgr> m_pAdapterTimerMgr;
-};
-
-#endif  // XFA_FWL_CFWL_TIMER_H_
diff --git a/xfa/fwl/cfwl_timerinfo.cpp b/xfa/fwl/cfwl_timerinfo.cpp
deleted file mode 100644
index ee4746a..0000000
--- a/xfa/fwl/cfwl_timerinfo.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "xfa/fwl/cfwl_timerinfo.h"
-
-#include "xfa/fwl/ifwl_adaptertimermgr.h"
-
-CFWL_TimerInfo::CFWL_TimerInfo(IFWL_AdapterTimerMgr* mgr) : m_pMgr(mgr) {
-  ASSERT(mgr);
-}
-
-CFWL_TimerInfo::~CFWL_TimerInfo() {}
-
-void CFWL_TimerInfo::StopTimer() {
-  m_pMgr->Stop(this);
-}
diff --git a/xfa/fwl/cfwl_timerinfo.h b/xfa/fwl/cfwl_timerinfo.h
deleted file mode 100644
index c58bcff..0000000
--- a/xfa/fwl/cfwl_timerinfo.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef XFA_FWL_CFWL_TIMERINFO_H_
-#define XFA_FWL_CFWL_TIMERINFO_H_
-
-#include "core/fxcrt/fx_system.h"
-#include "core/fxcrt/unowned_ptr.h"
-
-class IFWL_AdapterTimerMgr;
-
-class CFWL_TimerInfo {
- public:
-  explicit CFWL_TimerInfo(IFWL_AdapterTimerMgr* mgr);
-  virtual ~CFWL_TimerInfo();
-
-  void StopTimer();
-
- private:
-  UnownedPtr<IFWL_AdapterTimerMgr> m_pMgr;
-};
-
-#endif  // XFA_FWL_CFWL_TIMERINFO_H_
diff --git a/xfa/fwl/ifwl_adaptertimermgr.h b/xfa/fwl/ifwl_adaptertimermgr.h
deleted file mode 100644
index 106de53..0000000
--- a/xfa/fwl/ifwl_adaptertimermgr.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#ifndef XFA_FWL_IFWL_ADAPTERTIMERMGR_H_
-#define XFA_FWL_IFWL_ADAPTERTIMERMGR_H_
-
-#include "xfa/fwl/cfwl_timer.h"
-
-class IFWL_AdapterTimerMgr {
- public:
-  virtual ~IFWL_AdapterTimerMgr() = default;
-
-  virtual CFWL_TimerInfo* Start(CFWL_Timer* pTimer, uint32_t dwElapse) = 0;
-  virtual void Stop(CFWL_TimerInfo* pTimerInfo) = 0;
-};
-
-#endif  // XFA_FWL_IFWL_ADAPTERTIMERMGR_H_
diff --git a/xfa/fxfa/cxfa_ffapp.cpp b/xfa/fxfa/cxfa_ffapp.cpp
index a70de91..656b559 100644
--- a/xfa/fxfa/cxfa_ffapp.cpp
+++ b/xfa/fxfa/cxfa_ffapp.cpp
@@ -15,7 +15,6 @@
 #include "xfa/fgas/font/cfgas_fontmgr.h"
 #include "xfa/fwl/cfwl_notedriver.h"
 #include "xfa/fwl/cfwl_widgetmgr.h"
-#include "xfa/fwl/ifwl_adaptertimermgr.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffwidgethandler.h"
 #include "xfa/fxfa/cxfa_fontmgr.h"
@@ -66,8 +65,8 @@
   return m_pAdapterWidgetMgr.get();
 }
 
-std::unique_ptr<IFWL_AdapterTimerMgr> CXFA_FFApp::NewTimerMgr() {
-  return m_pProvider->NewTimerMgr();
+TimerHandlerIface* CXFA_FFApp::GetTimerHandler() {
+  return m_pProvider->GetTimerHandler();
 }
 
 void CXFA_FFApp::ClearEventTargets() {
diff --git a/xfa/fxfa/cxfa_ffapp.h b/xfa/fxfa/cxfa_ffapp.h
index 3bf0a93..b01ba2f 100644
--- a/xfa/fxfa/cxfa_ffapp.h
+++ b/xfa/fxfa/cxfa_ffapp.h
@@ -18,7 +18,6 @@
 class CFWL_WidgetMgr;
 class CXFA_FWLAdapterWidgetMgr;
 class CXFA_FWLTheme;
-class IFWL_AdapterTimerMgr;
 
 class CXFA_FFApp : public CFWL_App::AdapterIface {
  public:
@@ -29,7 +28,7 @@
 
   // CFWL_App::AdapterIface:
   CFWL_WidgetMgr::AdapterIface* GetWidgetMgrAdapter() override;
-  std::unique_ptr<IFWL_AdapterTimerMgr> NewTimerMgr() override;
+  TimerHandlerIface* GetTimerHandler() override;
 
   CFWL_WidgetMgr* GetFWLWidgetMgr() const { return m_pFWLApp->GetWidgetMgr(); }
   CFGAS_FontMgr* GetFDEFontMgr();
diff --git a/xfa/fxfa/fxfa.h b/xfa/fxfa/fxfa.h
index 83fb3cc..350e0e4 100644
--- a/xfa/fxfa/fxfa.h
+++ b/xfa/fxfa/fxfa.h
@@ -9,6 +9,7 @@
 
 #include <memory>
 
+#include "core/fxcrt/cfx_timer.h"
 #include "core/fxcrt/fx_coordinates.h"
 #include "core/fxcrt/retain_ptr.h"
 #include "core/fxge/fx_dib.h"
@@ -19,7 +20,6 @@
 class CXFA_FFPageView;
 class CXFA_FFWidget;
 class CXFA_Submit;
-class IFWL_AdapterTimerMgr;
 class IFX_SeekableReadStream;
 
 // Note, values must match fpdf_formfill.h JSPLATFORM_ALERT_BUTTON_* flags.
@@ -217,7 +217,7 @@
                              const WideString& wsData,
                              const WideString& wsEncode) = 0;
 
-  virtual std::unique_ptr<IFWL_AdapterTimerMgr> NewTimerMgr() = 0;
+  virtual TimerHandlerIface* GetTimerHandler() const = 0;
 };
 
 class IXFA_DocEnvironment {