e43db829a023717af51239ff28aa80404462999d
[platform/framework/web/crosswalk.git] / src / content / public / test / download_test_observer.h
1 // Copyright (c) 2012 The Chromium 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 CONTENT_TEST_DOWNLOAD_TEST_OBSERVER_H_
6 #define CONTENT_TEST_DOWNLOAD_TEST_OBSERVER_H_
7
8 #include <set>
9 #include <vector>
10
11 #include "base/basictypes.h"
12 #include "base/callback_forward.h"
13 #include "base/memory/ref_counted.h"
14 #include "content/public/browser/download_interrupt_reasons.h"
15 #include "content/public/browser/download_item.h"
16 #include "content/public/browser/download_manager.h"
17 #include "content/public/browser/download_url_parameters.h"
18
19 namespace content {
20
21 // Detects an arbitrary change on a download item.
22 // TODO: Rewrite other observers to use this (or be replaced by it).
23 class DownloadUpdatedObserver : public DownloadItem::Observer {
24  public:
25   typedef base::Callback<bool(DownloadItem*)> EventFilter;
26
27   // The filter passed may be called multiple times, even after it
28   // returns true.
29   DownloadUpdatedObserver(DownloadItem* item, EventFilter filter);
30   ~DownloadUpdatedObserver() override;
31
32   // Returns when either the event has been seen (at least once since
33   // object construction) or the item is destroyed.  Return value indicates
34   // if the wait ended because the item was seen (true) or the object
35   // destroyed (false).
36   bool WaitForEvent();
37
38  private:
39   // DownloadItem::Observer
40   void OnDownloadUpdated(DownloadItem* item) override;
41   void OnDownloadDestroyed(DownloadItem* item) override;
42
43   DownloadItem* item_;
44   EventFilter filter_;
45   bool waiting_;
46   bool event_seen_;
47
48   DISALLOW_COPY_AND_ASSIGN(DownloadUpdatedObserver);
49 };
50
51 // Detects changes to the downloads after construction.
52 //
53 // Finishes when one of the following happens:
54 //   - A specified number of downloads change to a terminal state (defined
55 //     in derived classes).
56 //   - The download manager was shutdown.
57 //
58 // Callers may either probe for the finished state, or wait on it.
59 class DownloadTestObserver : public DownloadManager::Observer,
60                              public DownloadItem::Observer {
61  public:
62   // Action an observer should take if a dangerous download is encountered.
63   enum DangerousDownloadAction {
64     ON_DANGEROUS_DOWNLOAD_ACCEPT,  // Accept the download
65     ON_DANGEROUS_DOWNLOAD_DENY,    // Deny the download
66     ON_DANGEROUS_DOWNLOAD_FAIL,    // Fail if a dangerous download is seen
67     ON_DANGEROUS_DOWNLOAD_IGNORE,  // Make it the callers problem.
68     ON_DANGEROUS_DOWNLOAD_QUIT     // Will set final state without decision.
69   };
70
71   // Create an object that will be considered finished when |wait_count|
72   // download items have entered a terminal state.
73   DownloadTestObserver(DownloadManager* download_manager,
74                        size_t wait_count,
75                        DangerousDownloadAction dangerous_download_action);
76
77   ~DownloadTestObserver() override;
78
79   // Wait for one of the finish conditions.
80   void WaitForFinished();
81
82   // Return true if we reached one of the finish conditions.
83   bool IsFinished() const;
84
85   // DownloadItem::Observer
86   void OnDownloadUpdated(DownloadItem* download) override;
87   void OnDownloadDestroyed(DownloadItem* download) override;
88
89   // DownloadManager::Observer
90   void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) override;
91   void ManagerGoingDown(DownloadManager* manager) override;
92
93   size_t NumDangerousDownloadsSeen() const;
94
95   size_t NumDownloadsSeenInState(DownloadItem::DownloadState state) const;
96
97  protected:
98   // Only to be called by derived classes' constructors.
99   virtual void Init();
100
101   // Called to see if a download item is in a final state.
102   virtual bool IsDownloadInFinalState(DownloadItem* download) = 0;
103
104  private:
105   typedef std::set<DownloadItem*> DownloadSet;
106
107   // Maps states to the number of times they have been encountered
108   typedef std::map<DownloadItem::DownloadState, size_t> StateMap;
109
110   // Called when we know that a download item is in a final state.
111   // Note that this is not the same as it first transitioning in to the
112   // final state; multiple notifications may occur once the item is in
113   // that state.  So we keep our own track of transitions into final.
114   void DownloadInFinalState(DownloadItem* download);
115
116   void SignalIfFinished();
117
118   // Fake user click on "Accept".
119   void AcceptDangerousDownload(uint32 download_id);
120
121   // Fake user click on "Deny".
122   void DenyDangerousDownload(uint32 download_id);
123
124   // The observed download manager.
125   DownloadManager* download_manager_;
126
127   // The set of DownloadItem's that have transitioned to their finished state
128   // since construction of this object.  When the size of this array
129   // reaches wait_count_, we're done.
130   DownloadSet finished_downloads_;
131
132   // The set of DownloadItem's we are currently observing.  Generally there
133   // won't be any overlap with the above; once we see the final state
134   // on a DownloadItem, we'll stop observing it.
135   DownloadSet downloads_observed_;
136
137   // The map of states to the number of times they have been observed since
138   // we started looking.
139   // Recorded at the time downloads_observed_ is recorded, but cleared in the
140   // constructor to exclude pre-existing states.
141   StateMap states_observed_;
142
143   // The number of downloads to wait on completing.
144   size_t wait_count_;
145
146   // The number of downloads entered in final state in Init().  We use
147   // |finished_downloads_| to track the incoming transitions to final state we
148   // should ignore, and to track the number of final state transitions that
149   // occurred between construction and return from wait.  But some downloads may
150   // be in our final state (and thus be entered into |finished_downloads_|) when
151   // we construct this class.  We don't want to count those in our transition to
152   // finished.
153   int finished_downloads_at_construction_;
154
155   // Whether an internal message loop has been started and must be quit upon
156   // all downloads completing.
157   bool waiting_;
158
159   // Action to take if a dangerous download is encountered.
160   DangerousDownloadAction dangerous_download_action_;
161
162   // Holds the download ids which were dangerous.
163   std::set<uint32> dangerous_downloads_seen_;
164
165   base::WeakPtrFactory<DownloadTestObserver> weak_factory_;
166
167   DISALLOW_COPY_AND_ASSIGN(DownloadTestObserver);
168 };
169
170 class DownloadTestObserverTerminal : public DownloadTestObserver {
171  public:
172   // Create an object that will be considered finished when |wait_count|
173   // download items have entered a terminal state (DownloadItem::IsDone() is
174   // true).
175   DownloadTestObserverTerminal(
176       DownloadManager* download_manager,
177       size_t wait_count,
178       DangerousDownloadAction dangerous_download_action);
179
180   ~DownloadTestObserverTerminal() override;
181
182  private:
183   bool IsDownloadInFinalState(DownloadItem* download) override;
184
185   DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverTerminal);
186 };
187
188 // Detects changes to the downloads after construction.
189 // Finishes when a specified number of downloads change to the
190 // IN_PROGRESS state, or when the download manager is destroyed.
191 // Dangerous downloads are accepted.
192 // Callers may either probe for the finished state, or wait on it.
193 class DownloadTestObserverInProgress : public DownloadTestObserver {
194  public:
195   // Create an object that will be considered finished when |wait_count|
196   // download items have entered state |IN_PROGRESS|.
197   DownloadTestObserverInProgress(
198       DownloadManager* download_manager, size_t wait_count);
199
200   ~DownloadTestObserverInProgress() override;
201
202  private:
203   bool IsDownloadInFinalState(DownloadItem* download) override;
204
205   DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverInProgress);
206 };
207
208 class DownloadTestObserverInterrupted : public DownloadTestObserver {
209  public:
210   // Create an object that will be considered finished when |wait_count|
211   // download items are interrupted.
212   DownloadTestObserverInterrupted(
213       DownloadManager* download_manager,
214       size_t wait_count,
215       DangerousDownloadAction dangerous_download_action);
216
217   ~DownloadTestObserverInterrupted() override;
218
219  private:
220   bool IsDownloadInFinalState(DownloadItem* download) override;
221
222   DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverInterrupted);
223 };
224
225 // The WaitForFlush() method on this class returns after:
226 //      * There are no IN_PROGRESS download items remaining on the
227 //        DownloadManager.
228 //      * There have been two round trip messages through the file and
229 //        IO threads.
230 // This almost certainly means that a Download cancel has propagated through
231 // the system.
232 class DownloadTestFlushObserver
233     : public DownloadManager::Observer,
234       public DownloadItem::Observer,
235       public base::RefCountedThreadSafe<DownloadTestFlushObserver> {
236  public:
237   explicit DownloadTestFlushObserver(DownloadManager* download_manager);
238
239   void WaitForFlush();
240
241   // DownloadsManager observer methods.
242   void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) override;
243
244   // DownloadItem observer methods.
245   void OnDownloadUpdated(DownloadItem* download) override;
246   void OnDownloadDestroyed(DownloadItem* download) override;
247
248  protected:
249   friend class base::RefCountedThreadSafe<DownloadTestFlushObserver>;
250
251   ~DownloadTestFlushObserver() override;
252
253  private:
254   typedef std::set<DownloadItem*> DownloadSet;
255
256   // If we're waiting for that flush point, check the number
257   // of downloads in the IN_PROGRESS state and take appropriate
258   // action.  If requested, also observes all downloads while iterating.
259   void CheckDownloadsInProgress(bool observe_downloads);
260
261   void PingFileThread(int cycle);
262
263   void PingIOThread(int cycle);
264
265   DownloadManager* download_manager_;
266   DownloadSet downloads_observed_;
267   bool waiting_for_zero_inprogress_;
268
269   DISALLOW_COPY_AND_ASSIGN(DownloadTestFlushObserver);
270 };
271
272 // Waits for a callback indicating that the DownloadItem is about to be created,
273 // or that an error occurred and it won't be created.
274 class DownloadTestItemCreationObserver
275     : public base::RefCountedThreadSafe<DownloadTestItemCreationObserver> {
276  public:
277   DownloadTestItemCreationObserver();
278
279   void WaitForDownloadItemCreation();
280
281   uint32 download_id() const { return download_id_; }
282   DownloadInterruptReason interrupt_reason() const { return interrupt_reason_; }
283   bool started() const { return called_back_count_ > 0; }
284   bool succeeded() const {
285     return started() && interrupt_reason_ == DOWNLOAD_INTERRUPT_REASON_NONE;
286   }
287
288   const DownloadUrlParameters::OnStartedCallback callback();
289
290  private:
291   friend class base::RefCountedThreadSafe<DownloadTestItemCreationObserver>;
292
293   ~DownloadTestItemCreationObserver();
294
295   void DownloadItemCreationCallback(DownloadItem* item,
296                                     DownloadInterruptReason interrupt_reason);
297
298   // The download creation information we received.
299   uint32 download_id_;
300   DownloadInterruptReason interrupt_reason_;
301
302   // Count of callbacks.
303   size_t called_back_count_;
304
305   // We are in the message loop.
306   bool waiting_;
307
308   DISALLOW_COPY_AND_ASSIGN(DownloadTestItemCreationObserver);
309 };
310
311 }  // namespace content`
312
313 #endif  // CONTENT_TEST_DOWNLOAD_TEST_OBSERVER_H_