xref: /aosp_15_r20/external/pdfium/fxjs/global_timer.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "fxjs/global_timer.h"
8 
9 #include <map>
10 
11 #include "core/fxcrt/cfx_timer.h"
12 #include "fxjs/cjs_app.h"
13 #include "third_party/base/check.h"
14 #include "third_party/base/containers/contains.h"
15 #include "third_party/base/no_destructor.h"
16 
17 namespace {
18 
19 using TimerMap = std::map<int32_t, GlobalTimer*>;
GetGlobalTimerMap()20 TimerMap& GetGlobalTimerMap() {
21   static pdfium::base::NoDestructor<TimerMap> timer_map;
22   return *timer_map;
23 }
24 
25 }  // namespace
26 
GlobalTimer(CJS_App * pObj,CJS_Runtime * pRuntime,Type nType,const WideString & script,uint32_t dwElapse,uint32_t dwTimeOut)27 GlobalTimer::GlobalTimer(CJS_App* pObj,
28                          CJS_Runtime* pRuntime,
29                          Type nType,
30                          const WideString& script,
31                          uint32_t dwElapse,
32                          uint32_t dwTimeOut)
33     : m_nType(nType),
34       m_nTimerID(pRuntime->GetTimerHandler()->SetTimer(dwElapse, Trigger)),
35       m_dwTimeOut(dwTimeOut),
36       m_swJScript(script),
37       m_pRuntime(pRuntime),
38       m_pEmbedApp(pObj) {
39   if (HasValidID()) {
40     DCHECK(!pdfium::Contains(GetGlobalTimerMap(), m_nTimerID));
41     GetGlobalTimerMap()[m_nTimerID] = this;
42   }
43 }
44 
~GlobalTimer()45 GlobalTimer::~GlobalTimer() {
46   if (!HasValidID())
47     return;
48 
49   if (m_pRuntime && m_pRuntime->GetTimerHandler())
50     m_pRuntime->GetTimerHandler()->KillTimer(m_nTimerID);
51 
52   DCHECK(pdfium::Contains(GetGlobalTimerMap(), m_nTimerID));
53   GetGlobalTimerMap().erase(m_nTimerID);
54 }
55 
56 // static
Trigger(int32_t nTimerID)57 void GlobalTimer::Trigger(int32_t nTimerID) {
58   auto it = GetGlobalTimerMap().find(nTimerID);
59   if (it == GetGlobalTimerMap().end())
60     return;
61 
62   GlobalTimer* pTimer = it->second;
63   if (pTimer->m_bProcessing)
64     return;
65 
66   pTimer->m_bProcessing = true;
67   if (pTimer->m_pEmbedApp)
68     pTimer->m_pEmbedApp->TimerProc(pTimer);
69 
70   // Timer proc may have destroyed timer, find it again.
71   it = GetGlobalTimerMap().find(nTimerID);
72   if (it == GetGlobalTimerMap().end())
73     return;
74 
75   pTimer = it->second;
76   pTimer->m_bProcessing = false;
77   if (pTimer->IsOneShot())
78     pTimer->m_pEmbedApp->CancelProc(pTimer);
79 }
80 
81 // static
Cancel(int32_t nTimerID)82 void GlobalTimer::Cancel(int32_t nTimerID) {
83   auto it = GetGlobalTimerMap().find(nTimerID);
84   if (it == GetGlobalTimerMap().end())
85     return;
86 
87   GlobalTimer* pTimer = it->second;
88   pTimer->m_pEmbedApp->CancelProc(pTimer);
89 }
90 
HasValidID() const91 bool GlobalTimer::HasValidID() const {
92   return m_nTimerID != CFX_Timer::HandlerIface::kInvalidTimerID;
93 }
94