OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ | 5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ |
6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ | 6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "content/public/browser/download_item.h" | 13 #include "content/public/browser/download_item.h" |
14 #include "content/public/browser/download_manager.h" | 14 #include "content/public/browser/download_manager.h" |
15 | 15 |
16 // Construction of this class defines a system state, based on some number | 16 // Detects changes to the downloads after construction. |
17 // of downloads being seen in a particular state + other events that | 17 // Finishes when one of the following happens: |
18 // may occur in the download system. That state will be recorded if it | 18 // - A specified number of downloads change to a terminal state (defined |
19 // occurs at any point after construction. When that state occurs, the class | 19 // in derived classes). |
20 // is considered finished. Callers may either probe for the finished state, or | 20 // - Specific events, such as a select file dialog. |
21 // wait on it. | 21 // Callers may either probe for the finished state, or wait on it. |
22 // | 22 // |
23 // TODO(rdsmith): Detect manager going down, remove pointer to | 23 // TODO(rdsmith): Detect manager going down, remove pointer to |
24 // DownloadManager, transition to finished. (For right now we | 24 // DownloadManager, transition to finished. (For right now we |
25 // just use a scoped_refptr<> to keep it around, but that may cause | 25 // just use a scoped_refptr<> to keep it around, but that may cause |
26 // timeouts on waiting if a DownloadManager::Shutdown() occurs which | 26 // timeouts on waiting if a DownloadManager::Shutdown() occurs which |
27 // cancels our in-progress downloads.) | 27 // cancels our in-progress downloads.) |
28 class DownloadTestObserver : public content::DownloadManager::Observer, | 28 class DownloadTestObserver : public content::DownloadManager::Observer, |
29 public content::DownloadItem::Observer { | 29 public content::DownloadItem::Observer { |
30 public: | 30 public: |
31 // Action an observer should take if a dangerous download is encountered. | 31 // Action an observer should take if a dangerous download is encountered. |
32 enum DangerousDownloadAction { | 32 enum DangerousDownloadAction { |
33 ON_DANGEROUS_DOWNLOAD_ACCEPT, // Accept the download | 33 ON_DANGEROUS_DOWNLOAD_ACCEPT, // Accept the download |
34 ON_DANGEROUS_DOWNLOAD_DENY, // Deny the download | 34 ON_DANGEROUS_DOWNLOAD_DENY, // Deny the download |
35 ON_DANGEROUS_DOWNLOAD_FAIL // Fail if a dangerous download is seen | 35 ON_DANGEROUS_DOWNLOAD_FAIL // Fail if a dangerous download is seen |
36 }; | 36 }; |
37 | 37 |
38 // Create an object that will be considered finished when |wait_count| | 38 // Create an object that will be considered finished when |wait_count| |
39 // download items have entered state |download_finished_state|. | 39 // download items have entered a terminal state. |
40 // If |finish_on_select_file| is true, the object will also be | 40 // If |finish_on_select_file| is true, the object will also be |
41 // considered finished if the DownloadManager raises a | 41 // considered finished if the DownloadManager raises a |
42 // SelectFileDialogDisplayed() notification. | 42 // SelectFileDialogDisplayed() notification. |
43 | |
44 // TODO(rdsmith): Consider rewriting the interface to take a list of events | |
45 // to treat as completion events. | |
46 DownloadTestObserver( | 43 DownloadTestObserver( |
47 content::DownloadManager* download_manager, | 44 content::DownloadManager* download_manager, |
48 size_t wait_count, | 45 size_t wait_count, |
49 content::DownloadItem::DownloadState download_finished_state, | |
50 bool finish_on_select_file, | 46 bool finish_on_select_file, |
51 DangerousDownloadAction dangerous_download_action); | 47 DangerousDownloadAction dangerous_download_action); |
52 | 48 |
53 virtual ~DownloadTestObserver(); | 49 virtual ~DownloadTestObserver(); |
54 | 50 |
55 // State accessors. | 51 // State accessors. |
56 bool select_file_dialog_seen() const { return select_file_dialog_seen_; } | 52 bool select_file_dialog_seen() const { return select_file_dialog_seen_; } |
57 | 53 |
58 // Wait for whatever state was specified in the constructor. | 54 // Wait for the requested number of downloads to enter a terminal state. |
59 void WaitForFinished(); | 55 void WaitForFinished(); |
60 | 56 |
61 // Return true if everything's happened that we're configured for. | 57 // Return true if everything's happened that we're configured for. |
62 bool IsFinished() const; | 58 bool IsFinished() const; |
63 | 59 |
64 // content::DownloadItem::Observer | 60 // content::DownloadItem::Observer |
65 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; | 61 virtual void OnDownloadUpdated(content::DownloadItem* download) OVERRIDE; |
66 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {} | 62 virtual void OnDownloadOpened(content::DownloadItem* download) OVERRIDE {} |
67 | 63 |
68 // content::DownloadManager::Observer | 64 // content::DownloadManager::Observer |
69 virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE; | 65 virtual void ModelChanged(content::DownloadManager* manager) OVERRIDE; |
70 | 66 |
71 virtual void SelectFileDialogDisplayed( | 67 virtual void SelectFileDialogDisplayed( |
72 content::DownloadManager* manager, int32 id) OVERRIDE; | 68 content::DownloadManager* manager, int32 id) OVERRIDE; |
73 | 69 |
74 size_t NumDangerousDownloadsSeen() const; | 70 size_t NumDangerousDownloadsSeen() const; |
75 | 71 |
76 private: | 72 size_t NumDownloadsSeenInState( |
73 content::DownloadItem::DownloadState state) const; | |
Randy Smith (Not in Mondays)
2012/03/08 18:25:31
Up to you, but I'd be more inclined to leave this
ahendrickson
2012/03/08 20:56:34
It's here specifically for IN_PROGRESS tests, whic
Randy Smith (Not in Mondays)
2012/03/09 18:39:38
Ah, makes sense. Ok.
| |
74 | |
75 protected: | |
77 typedef std::set<content::DownloadItem*> DownloadSet; | 76 typedef std::set<content::DownloadItem*> DownloadSet; |
78 | 77 |
79 // Called when we know that a download item is in a final state. | 78 // Maps states to the number of times they have been encountered |
80 // Note that this is not the same as it first transitioning in to the | 79 typedef std::map<content::DownloadItem::DownloadState, size_t> StateMap; |
81 // final state; multiple notifications may occur once the item is in | |
82 // that state. So we keep our own track of transitions into final. | |
83 void DownloadInFinalState(content::DownloadItem* download); | |
84 | 80 |
85 void SignalIfFinished(); | 81 // Called to see if a download item is in a final state. |
82 virtual bool IsDownloadInFinalState(content::DownloadItem* download) = 0; | |
86 | 83 |
87 // The observed download manager. | 84 // The observed download manager. |
88 scoped_refptr<content::DownloadManager> download_manager_; | 85 scoped_refptr<content::DownloadManager> download_manager_; |
benjhayden
2012/03/08 20:30:02
Would it be too much trouble to keep member fields
ahendrickson
2012/03/08 21:28:55
My preference would be to punt this to another CL,
Randy Smith (Not in Mondays)
2012/03/09 18:39:38
For this kind of issue, it's useful to look at whe
ahendrickson
2012/03/09 20:07:23
OK, done.
| |
89 | 86 |
90 // The set of DownloadItem's that have transitioned to their finished state | 87 // The set of DownloadItem's that have transitioned to their finished state |
91 // since construction of this object. When the size of this array | 88 // since construction of this object. When the size of this array |
92 // reaches wait_count_, we're done. | 89 // reaches wait_count_, we're done. |
93 DownloadSet finished_downloads_; | 90 DownloadSet finished_downloads_; |
94 | 91 |
95 // The set of DownloadItem's we are currently observing. Generally there | 92 // The map of states to the number of times they have been observed since |
96 // won't be any overlap with the above; once we see the final state | 93 // we started looking. |
97 // on a DownloadItem, we'll stop observing it. | 94 // Recorded at the time downloads_observed_ is recorded, but cleared in the |
98 DownloadSet downloads_observed_; | 95 // constructor to exclude pre-existing states. |
99 | 96 StateMap states_observed_; |
100 // The number of downloads to wait on completing. | |
101 size_t wait_count_; | |
102 | 97 |
103 // The number of downloads entered in final state in initial | 98 // The number of downloads entered in final state in initial |
104 // ModelChanged(). We use |finished_downloads_| to track the incoming | 99 // ModelChanged(). We use |finished_downloads_| to track the incoming |
105 // transitions to final state we should ignore, and to track the | 100 // transitions to final state we should ignore, and to track the |
106 // number of final state transitions that occurred between | 101 // number of final state transitions that occurred between |
107 // construction and return from wait. But some downloads may be in our | 102 // construction and return from wait. But some downloads may be in our |
108 // final state (and thus be entered into |finished_downloads_|) when we | 103 // final state (and thus be entered into |finished_downloads_|) when we |
109 // construct this class. We don't want to count those in our transition | 104 // construct this class. We don't want to count those in our transition |
110 // to finished. | 105 // to finished. |
111 int finished_downloads_at_construction_; | 106 int finished_downloads_at_construction_; |
112 | 107 |
108 private: | |
109 // Called when we know that a download item is in a final state. | |
110 // Note that this is not the same as it first transitioning in to the | |
111 // final state; multiple notifications may occur once the item is in | |
112 // that state. So we keep our own track of transitions into final. | |
113 void DownloadInFinalState(content::DownloadItem* download); | |
114 | |
115 void SignalIfFinished(); | |
116 | |
117 // The set of DownloadItem's we are currently observing. Generally there | |
118 // won't be any overlap with the above; once we see the final state | |
119 // on a DownloadItem, we'll stop observing it. | |
120 DownloadSet downloads_observed_; | |
121 | |
122 // The number of downloads to wait on completing. | |
123 size_t wait_count_; | |
124 | |
113 // Whether an internal message loop has been started and must be quit upon | 125 // Whether an internal message loop has been started and must be quit upon |
114 // all downloads completing. | 126 // all downloads completing. |
115 bool waiting_; | 127 bool waiting_; |
116 | 128 |
117 // The state on which to consider the DownloadItem finished. | |
118 content::DownloadItem::DownloadState download_finished_state_; | |
119 | |
120 // True if we should transition the DownloadTestObserver to finished if | 129 // True if we should transition the DownloadTestObserver to finished if |
121 // the select file dialog comes up. | 130 // the select file dialog comes up. |
122 bool finish_on_select_file_; | 131 bool finish_on_select_file_; |
123 | 132 |
124 // True if we've seen the select file dialog. | 133 // True if we've seen the select file dialog. |
125 bool select_file_dialog_seen_; | 134 bool select_file_dialog_seen_; |
126 | 135 |
127 // Action to take if a dangerous download is encountered. | 136 // Action to take if a dangerous download is encountered. |
128 DangerousDownloadAction dangerous_download_action_; | 137 DangerousDownloadAction dangerous_download_action_; |
129 | 138 |
130 // Holds the download ids which were dangerous. | 139 // Holds the download ids which were dangerous. |
131 std::set<int32> dangerous_downloads_seen_; | 140 std::set<int32> dangerous_downloads_seen_; |
132 | 141 |
133 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserver); | 142 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserver); |
134 }; | 143 }; |
135 | 144 |
145 class DownloadTestObserverTerminal : public DownloadTestObserver { | |
146 public: | |
147 // Create an object that will be considered finished when |wait_count| | |
148 // download items have entered a terminal state (any but IN_PROGRESS). | |
149 // If |finish_on_select_file| is true, the object will also be | |
150 // considered finished if the DownloadManager raises a | |
151 // SelectFileDialogDisplayed() notification. | |
152 DownloadTestObserverTerminal( | |
153 content::DownloadManager* download_manager, | |
154 size_t wait_count, | |
155 bool finish_on_select_file, | |
156 DangerousDownloadAction dangerous_download_action); | |
157 | |
158 virtual ~DownloadTestObserverTerminal(); | |
159 | |
160 private: | |
161 virtual bool IsDownloadInFinalState(content::DownloadItem* download) OVERRIDE; | |
162 | |
163 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverTerminal); | |
164 }; | |
165 | |
166 // Detects changes to the downloads after construction. | |
167 // Finishes when one of the following happens: | |
168 // - A specified number of downloads change to the IN_PROGRESS state. | |
Randy Smith (Not in Mondays)
2012/03/08 18:25:31
You haven't specified the behavior on a dangerous
ahendrickson
2012/03/08 20:56:34
I think we're in trouble if the select file dialog
Randy Smith (Not in Mondays)
2012/03/09 18:39:38
Confused, and I'd like to be unconfused before we
ahendrickson
2012/03/09 20:07:23
OK, added the parameter to DownloadObserverTestInP
| |
169 // Callers may either probe for the finished state, or wait on it. | |
170 // | |
Randy Smith (Not in Mondays)
2012/03/08 18:25:31
nit: Could you nuke the blank comment line? I thi
ahendrickson
2012/03/08 20:56:34
Done.
| |
171 class DownloadTestObserverInProgress : public DownloadTestObserver { | |
172 public: | |
173 // Create an object that will be considered finished when |wait_count| | |
174 // download items have entered state |IN_PROGRESS|. | |
175 | |
176 DownloadTestObserverInProgress( | |
177 content::DownloadManager* download_manager, | |
178 size_t wait_count); | |
179 | |
180 virtual ~DownloadTestObserverInProgress(); | |
181 | |
182 private: | |
183 virtual bool IsDownloadInFinalState(content::DownloadItem* download) OVERRIDE; | |
184 | |
185 DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverInProgress); | |
186 }; | |
187 | |
136 // The WaitForFlush() method on this class returns after: | 188 // The WaitForFlush() method on this class returns after: |
137 // * There are no IN_PROGRESS download items remaining on the | 189 // * There are no IN_PROGRESS download items remaining on the |
138 // DownloadManager. | 190 // DownloadManager. |
139 // * There have been two round trip messages through the file and | 191 // * There have been two round trip messages through the file and |
140 // IO threads. | 192 // IO threads. |
141 // This almost certainly means that a Download cancel has propagated through | 193 // This almost certainly means that a Download cancel has propagated through |
142 // the system. | 194 // the system. |
143 class DownloadTestFlushObserver | 195 class DownloadTestFlushObserver |
144 : public content::DownloadManager::Observer, | 196 : public content::DownloadManager::Observer, |
145 public content::DownloadItem::Observer, | 197 public content::DownloadItem::Observer, |
(...skipping 29 matching lines...) Expand all Loading... | |
175 void PingIOThread(int cycle); | 227 void PingIOThread(int cycle); |
176 | 228 |
177 content::DownloadManager* download_manager_; | 229 content::DownloadManager* download_manager_; |
178 DownloadSet downloads_observed_; | 230 DownloadSet downloads_observed_; |
179 bool waiting_for_zero_inprogress_; | 231 bool waiting_for_zero_inprogress_; |
180 | 232 |
181 DISALLOW_COPY_AND_ASSIGN(DownloadTestFlushObserver); | 233 DISALLOW_COPY_AND_ASSIGN(DownloadTestFlushObserver); |
182 }; | 234 }; |
183 | 235 |
184 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ | 236 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TEST_OBSERVER_H_ |
OLD | NEW |