Merge to XFA: CJS_Timer should observe CJS_Runtime destruction.

Also remove dead CJS_EmbedObj::{Begin,End}Timer code.

BUG=539107
R=tsepez@chromium.org

Review URL: https://codereview.chromium.org/1384883002 .

(cherry picked from commit 794c9b67d3d519342aa7e15052766f7d4a99f551)

Review URL: https://codereview.chromium.org/1386053002 .
diff --git a/fpdfsdk/src/javascript/JS_Object.cpp b/fpdfsdk/src/javascript/JS_Object.cpp
index 429d268..a3f972c 100644
--- a/fpdfsdk/src/javascript/JS_Object.cpp
+++ b/fpdfsdk/src/javascript/JS_Object.cpp
@@ -55,20 +55,6 @@
   CJS_Object::Alert(pContext, swMsg);
 }
 
-CJS_Timer* CJS_EmbedObj::BeginTimer(CPDFDoc_Environment* pApp,
-                                    FX_UINT nElapse) {
-  CJS_Timer* pTimer = new CJS_Timer(this, pApp);
-  pTimer->SetJSTimer(nElapse);
-
-  return pTimer;
-}
-
-void CJS_EmbedObj::EndTimer(CJS_Timer* pTimer) {
-  ASSERT(pTimer != NULL);
-  pTimer->KillJSTimer();
-  delete pTimer;
-}
-
 void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
   CJS_Object* pJSObj = data.GetParameter();
   pJSObj->ExitInstance();
@@ -122,20 +108,40 @@
   }
 }
 
-FX_UINT CJS_Timer::SetJSTimer(FX_UINT nElapse) {
-  if (m_nTimerID)
-    KillJSTimer();
+CJS_Timer::CJS_Timer(CJS_EmbedObj* pObj,
+                     CPDFDoc_Environment* pApp,
+                     CJS_Runtime* pRuntime,
+                     int nType,
+                     const CFX_WideString& script,
+                     FX_DWORD dwElapse,
+                     FX_DWORD dwTimeOut)
+    : m_nTimerID(0),
+      m_pEmbedObj(pObj),
+      m_bProcessing(false),
+      m_bValid(true),
+      m_nType(nType),
+      m_dwTimeOut(dwTimeOut),
+      m_pRuntime(pRuntime),
+      m_pApp(pApp) {
   IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
-  m_nTimerID = pHandler->SetTimer(nElapse, TimerProc);
+  m_nTimerID = pHandler->SetTimer(dwElapse, TimerProc);
   (*GetGlobalTimerMap())[m_nTimerID] = this;
-  m_dwElapse = nElapse;
-  return m_nTimerID;
+  m_pRuntime->AddObserver(this);
+}
+
+CJS_Timer::~CJS_Timer() {
+  CJS_Runtime* pRuntime = GetRuntime();
+  if (pRuntime)
+    pRuntime->RemoveObserver(this);
+  KillJSTimer();
 }
 
 void CJS_Timer::KillJSTimer() {
   if (m_nTimerID) {
-    IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
-    pHandler->KillTimer(m_nTimerID);
+    if (m_bValid) {
+      IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
+      pHandler->KillTimer(m_nTimerID);
+    }
     GetGlobalTimerMap()->erase(m_nTimerID);
     m_nTimerID = 0;
   }
@@ -147,10 +153,10 @@
   if (it != GetGlobalTimerMap()->end()) {
     CJS_Timer* pTimer = it->second;
     if (!pTimer->m_bProcessing) {
-      pTimer->m_bProcessing = TRUE;
+      CFX_AutoRestorer<bool> scoped_processing(&pTimer->m_bProcessing);
+      pTimer->m_bProcessing = true;
       if (pTimer->m_pEmbedObj)
         pTimer->m_pEmbedObj->TimerProc(pTimer);
-      pTimer->m_bProcessing = FALSE;
     }
   }
 }
@@ -161,3 +167,7 @@
   static auto* s_TimerMap = new TimerMap;
   return s_TimerMap;
 }
+
+void CJS_Timer::OnDestroyed() {
+  m_bValid = false;
+}