Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / content / public / test / download_test_observer.h
bloba921555bec362f8be3ea33030c2ea4cfc2d7c4dc
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.
5 #ifndef CONTENT_PUBLIC_TEST_DOWNLOAD_TEST_OBSERVER_H_
6 #define CONTENT_PUBLIC_TEST_DOWNLOAD_TEST_OBSERVER_H_
8 #include <set>
9 #include <vector>
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"
19 namespace content {
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;
27 // The filter passed may be called multiple times, even after it
28 // returns true.
29 DownloadUpdatedObserver(DownloadItem* item, EventFilter filter);
30 ~DownloadUpdatedObserver() override;
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();
38 private:
39 // DownloadItem::Observer
40 void OnDownloadUpdated(DownloadItem* item) override;
41 void OnDownloadDestroyed(DownloadItem* item) override;
43 DownloadItem* item_;
44 EventFilter filter_;
45 bool waiting_;
46 bool event_seen_;
48 DISALLOW_COPY_AND_ASSIGN(DownloadUpdatedObserver);
51 // Detects changes to the downloads after construction.
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.
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.
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);
77 ~DownloadTestObserver() override;
79 // Wait for one of the finish conditions.
80 void WaitForFinished();
82 // Return true if we reached one of the finish conditions.
83 bool IsFinished() const;
85 // DownloadItem::Observer
86 void OnDownloadUpdated(DownloadItem* download) override;
87 void OnDownloadDestroyed(DownloadItem* download) override;
89 // DownloadManager::Observer
90 void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) override;
91 void ManagerGoingDown(DownloadManager* manager) override;
93 size_t NumDangerousDownloadsSeen() const;
95 size_t NumDownloadsSeenInState(DownloadItem::DownloadState state) const;
97 protected:
98 // Only to be called by derived classes' constructors.
99 virtual void Init();
101 // Called to see if a download item is in a final state.
102 virtual bool IsDownloadInFinalState(DownloadItem* download) = 0;
104 private:
105 typedef std::set<DownloadItem*> DownloadSet;
107 // Maps states to the number of times they have been encountered
108 typedef std::map<DownloadItem::DownloadState, size_t> StateMap;
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);
116 void SignalIfFinished();
118 // Fake user click on "Accept".
119 void AcceptDangerousDownload(uint32 download_id);
121 // Fake user click on "Deny".
122 void DenyDangerousDownload(uint32 download_id);
124 // The observed download manager.
125 DownloadManager* download_manager_;
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_;
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_;
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_;
143 // The number of downloads to wait on completing.
144 size_t wait_count_;
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_;
155 // Whether an internal message loop has been started and must be quit upon
156 // all downloads completing.
157 bool waiting_;
159 // Action to take if a dangerous download is encountered.
160 DangerousDownloadAction dangerous_download_action_;
162 // Holds the download ids which were dangerous.
163 std::set<uint32> dangerous_downloads_seen_;
165 base::WeakPtrFactory<DownloadTestObserver> weak_factory_;
167 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserver);
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);
180 ~DownloadTestObserverTerminal() override;
182 private:
183 bool IsDownloadInFinalState(DownloadItem* download) override;
185 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverTerminal);
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);
200 ~DownloadTestObserverInProgress() override;
202 private:
203 bool IsDownloadInFinalState(DownloadItem* download) override;
205 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverInProgress);
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);
217 ~DownloadTestObserverInterrupted() override;
219 private:
220 bool IsDownloadInFinalState(DownloadItem* download) override;
222 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverInterrupted);
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);
239 void WaitForFlush();
241 // DownloadsManager observer methods.
242 void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) override;
244 // DownloadItem observer methods.
245 void OnDownloadUpdated(DownloadItem* download) override;
246 void OnDownloadDestroyed(DownloadItem* download) override;
248 protected:
249 friend class base::RefCountedThreadSafe<DownloadTestFlushObserver>;
251 ~DownloadTestFlushObserver() override;
253 private:
254 typedef std::set<DownloadItem*> DownloadSet;
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);
261 void PingFileThread(int cycle);
263 void PingIOThread(int cycle);
265 DownloadManager* download_manager_;
266 DownloadSet downloads_observed_;
267 bool waiting_for_zero_inprogress_;
269 DISALLOW_COPY_AND_ASSIGN(DownloadTestFlushObserver);
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();
279 void WaitForDownloadItemCreation();
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;
288 const DownloadUrlParameters::OnStartedCallback callback();
290 private:
291 friend class base::RefCountedThreadSafe<DownloadTestItemCreationObserver>;
293 ~DownloadTestItemCreationObserver();
295 void DownloadItemCreationCallback(DownloadItem* item,
296 DownloadInterruptReason interrupt_reason);
298 // The download creation information we received.
299 uint32 download_id_;
300 DownloadInterruptReason interrupt_reason_;
302 // Count of callbacks.
303 size_t called_back_count_;
305 // We are in the message loop.
306 bool waiting_;
308 DISALLOW_COPY_AND_ASSIGN(DownloadTestItemCreationObserver);
311 } // namespace content`
313 #endif // CONTENT_PUBLIC_TEST_DOWNLOAD_TEST_OBSERVER_H_