1 // Copyright 2015 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TESTING_EMBEDDER_TEST_TIMER_HANDLING_DELEGATE_H_
6 #define TESTING_EMBEDDER_TEST_TIMER_HANDLING_DELEGATE_H_
7 
8 #include <map>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "embedder_test.h"
14 #include "test_support.h"
15 
16 class EmbedderTestTimerHandlingDelegate : public EmbedderTest::Delegate {
17  public:
18   struct ReceivedAlert {
ReceivedAlertReceivedAlert19     ReceivedAlert(FPDF_WIDESTRING message_in,
20                   FPDF_WIDESTRING title_in,
21                   int type_in,
22                   int icon_in)
23         : type(type_in), icon(icon_in) {
24       message = GetPlatformWString(message_in);
25       title = GetPlatformWString(title_in);
26     }
27 
28     std::wstring message;
29     std::wstring title;
30     int type;
31     int icon;
32   };
33 
Alert(FPDF_WIDESTRING message,FPDF_WIDESTRING title,int type,int icon)34   int Alert(FPDF_WIDESTRING message,
35             FPDF_WIDESTRING title,
36             int type,
37             int icon) override {
38     alerts_.push_back(ReceivedAlert(message, title, type, icon));
39     return 0;
40   }
41 
SetTimer(int msecs,TimerCallback fn)42   int SetTimer(int msecs, TimerCallback fn) override {
43     expiry_to_timer_map_.insert(std::pair<int, Timer>(
44         msecs + imaginary_elapsed_msecs_, Timer(++next_timer_id_, fn)));
45     return next_timer_id_;
46   }
47 
KillTimer(int id)48   void KillTimer(int id) override {
49     for (auto iter = expiry_to_timer_map_.begin();
50          iter != expiry_to_timer_map_.end(); ++iter) {
51       if (iter->second.first == id) {
52         expiry_to_timer_map_.erase(iter);
53         break;
54       }
55     }
56   }
57 
AdvanceTime(int increment_msecs)58   void AdvanceTime(int increment_msecs) {
59     imaginary_elapsed_msecs_ += increment_msecs;
60     while (1) {
61       auto iter = expiry_to_timer_map_.begin();
62       if (iter == expiry_to_timer_map_.end()) {
63         break;
64       }
65       Timer t = iter->second;
66       if (t.first > imaginary_elapsed_msecs_) {
67         break;
68       }
69       expiry_to_timer_map_.erase(iter);
70       t.second(t.first);  // Fire timer.
71     }
72   }
73 
GetAlerts()74   const std::vector<ReceivedAlert>& GetAlerts() const { return alerts_; }
75 
76  protected:
77   using Timer = std::pair<int, TimerCallback>;     // ID, callback pair.
78   std::multimap<int, Timer> expiry_to_timer_map_;  // Keyed by timeout.
79   int next_timer_id_ = 0;
80   int imaginary_elapsed_msecs_ = 0;
81   std::vector<ReceivedAlert> alerts_;
82 };
83 
84 #endif  // TESTING_EMBEDDER_TEST_TIMER_HANDLING_DELEGATE_H_
85