Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Side by Side Diff: chrome/browser/download/download_target_determiner.h

Issue 12850002: Move download filename determintion into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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 CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_DETERMINER_H_
6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_DETERMINER_H_
7
8 #include "base/files/file_path.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/weak_ptr.h"
12 #include "chrome/browser/common/cancelable_request.h"
13 #include "chrome/browser/download/download_target_determiner_delegate.h"
14 #include "chrome/browser/safe_browsing/download_protection_service.h"
15 #include "content/public/browser/download_item.h"
16
17 class ChromeDownloadManagerDelegate;
18 class DownloadFilePickerFactory;
19 class DownloadPrefs;
20 class Profile;
21
22 namespace safe_browsing {
23 class DownloadProtectionService;
24 }
25
26 // Determines the target of the download.
27 //
28 // Terminology:
29 // Virtual Path: A path representing the target of the download that may or
30 // may not be a physical file path. E.g. if the target of the download is in
31 // cloud storage, then the virtual path may be relative to a logical mount
32 // point.
33 //
34 // Local Path: A local file system path where the downloads system should
35 // write the file to.
36 //
37 // Intermediate Path: Where the data should be written to during the course of
38 // the download. Once the download completes, the file could be renamed to
39 // Local Path.
40 //
41 // DownloadTargetDeterminer is a self owned object that performs the work of
42 // determining the download target. It observes the DownloadItem and aborts the
43 // process if the download is removed. DownloadTargetDeterminerDelegate is
44 // responsible for providing external dependencies and prompting the user if
45 // necessary.
46 //
47 // The only public entrypoint is the static Start() method which creates an
48 // instance of DownloadTargetDeterminer.
49 class DownloadTargetDeterminer
50 : public content::DownloadItem::Observer {
51 public:
52 // Call to be invoked when the target is available. If the target
53 // determination is cancelled, then the paths will be empty. |virtual_path|,
54 // |local_path| and |intermediate_path| are as defined above. The
55 // |disposition| will be TARGET_DISPOSITION_PROMPT if the user was prompted
56 // during the process of determining the target. The |danger_type| is the
57 // danger type assigned to the download.
58 typedef base::Callback<void(
59 const base::FilePath& virtual_path,
60 const base::FilePath& local_path,
61 const base::FilePath& intermediate_path,
62 content::DownloadItem::TargetDisposition disposition,
63 content::DownloadDangerType danger_type)> CompletionCallback;
64
65 // Start the process of determing the target of |download|.
66 //
67 // |download_prefs| is required and must outlive |download|. It is used for
68 // determining the user's preferences regarding the default downloads
69 // directory, prompting and auto-open behavior.
70 // |last_selected_directory| is the most recent directory that was chosen by
71 // the user. If the user needs to be prompted, then this directory will be
72 // used as the directory for the download instead of the user's default
73 // downloads directory.
74 // |delegate| is required and must live until |callback| is invoked.
75 // |callback| will be scheduled asynchronously on the UI thread after download
76 // determination is complete or after |download| is destroyed.
77 //
78 // Start() should be called on the UI thread.
79 static void Start(content::DownloadItem* download,
80 DownloadPrefs* download_prefs,
81 DownloadFilePickerFactory* file_picker_factory,
82 const base::FilePath& last_selected_directory,
83 DownloadTargetDeterminerDelegate* delegate,
84 const CompletionCallback& callback);
85
86 private:
87 // The main workflow is controlled via a set of state transitions. Each state
88 // has an associated handler. The handler for STATE_FOO is DoFoo. Each handler
89 // performs work, determines the next state to transition to and returns a
90 // Result indicating how the workflow should proceed. The loop ends when a
91 // handler returns COMPLETE.
92 enum State {
93 STATE_GENERATE_TARGET_PATH,
94 STATE_NOTIFY_EXTENSIONS,
95 STATE_RESERVE_VIRTUAL_PATH,
96 STATE_PROMPT_USER_FOR_DOWNLOAD_PATH,
97 STATE_DETERMINE_LOCAL_PATH,
98 STATE_CHECK_DOWNLOAD_URL,
99 STATE_DETERMINE_DANGER_TYPE,
100 STATE_CHECK_VISITED_REFERRER_BEFORE,
101 STATE_DETERMINE_INTERMEDIATE_PATH,
102 STATE_NONE,
103 };
104
105 // Result code returned by each step of the workflow below. Controls execution
106 // of DoLoop().
107 enum Result {
108 // Continue processing. next_state_ is required to not be STATE_NONE.
109 CONTINUE,
110
111 // The DoLoop() that invoked the handler should exit. This value is
112 // typically returned when the handler has invoked an asynchronous operation
113 // and is expecting a callback. If a handler returns this value, it has
114 // taken responsibility for ensuring that DoLoop() is invoked. It is
115 // possible that the handler has invoked another DoLoop() already.
116 QUIT_DOLOOP,
117
118 // Target determination is complete.
119 COMPLETE
120 };
121
122 // Used with IsDangerousFile to indicate whether the user has visited the
123 // referrer URL for the download prior to today.
124 enum PriorVisitsToReferrer {
benjhayden 2013/04/18 17:33:46 Is there some reason to prefer an enum over a bool
asanka 2013/04/24 23:16:30 It's an argument to IsDangerousFile(). It turns th
125 NO_VISITS_TO_REFERRER,
126 VISITED_REFERRER,
127 };
128
129 // Construct a DownloadTargetDeterminer object. Constraints on the arguments
130 // are as per Start() above.
131 DownloadTargetDeterminer(
132 content::DownloadItem* download,
133 DownloadPrefs* download_prefs,
134 DownloadFilePickerFactory* file_picker_factory,
135 const base::FilePath& last_selected_directory,
136 DownloadTargetDeterminerDelegate* delegate,
137 const CompletionCallback& callback);
138
139 virtual ~DownloadTargetDeterminer();
140
141 // Invoke each successive handler until a handler returns QUIT_DOLOOP or
142 // COMPLETE. Note that as a result, this object might be deleted. So |this|
143 // should not be accessed after calling DoLoop().
144 void DoLoop();
145
146 // === Main workflow ===
147
148 // Generates an initial target path. This target is based only on the state of
149 // the download item.
150 // Next state:
151 // - STATE_NONE : If the download is not in progress, returns COMPLETE.
152 // - STATE_NOTIFY_EXTENSIONS : All other downloads.
153 Result DoGenerateTargetPath();
154
155 // Notifies downloads extensions. If any extension wishes to override the
156 // download filename, it will respond to the OnDeterminingFilename()
157 // notification.
158 // Next state:
159 // - STATE_RESERVE_VIRTUAL_PATH.
160 Result DoNotifyExtensions();
161
162 // Callback invoked after extensions are notified.
163 void NotifyExtensionsDone(const base::FilePath& new_path, bool overwrite);
164
165 // Invokes ReserveVirtualPath() on the delegate to acquire a reservation for
166 // the path. See DownloadPathReservationTracker.
167 // Next state:
168 // - STATE_PROMPT_USER_FOR_DOWNLOAD_PATH.
169 Result DoReserveVirtualPath();
170
171 // Callback invoked after the delegate aquires a path reservation.
172 void ReserveVirtualPathDone(const base::FilePath& path, bool verified);
173
174 // Presents a file picker to the user if necessary.
175 // Next state:
176 // - STATE_CHECK_DOWNLOAD_URL : If a prompt is shown to the user (the file
177 // picker returns both a local path and a virtual path).
178 // - STATE_DETERMINE_LOCAL_PATH : All other downloads.
179 Result DoPromptUserForDownloadPath();
180
181 // Callback invoked after the file picker completes. Cancels the download if
182 // the user cancels the file picker.
183 void PromptUserForDownloadPathDone(const base::FilePath& virtual_path,
184 const base::FilePath& local_path);
185
186 // Up until this point, the path that was used is considered to be a virtual
187 // path. This step determines the local file system path corresponding to this
188 // virtual path. The translation is done by invoking the DetermineLocalPath()
189 // method on the delegate.
190 // Next state:
191 // - STATE_CHECK_DOWNLOAD_URL.
192 Result DoDetermineLocalPath();
193
194 // Callback invoked when the delegate has determined local path.
195 void DetermineLocalPathDone(const base::FilePath& local_path);
196
197 // Checks whether the downloaded URL is malicious. Invokes the
198 // DownloadProtectionService via the delegate.
199 // Next state:
200 // - STATE_DETERMINE_DANGER_TYPE.
201 Result DoCheckDownloadUrl();
202
203 // Callback invoked when the download URL has been checked.
204 void CheckDownloadUrlDone(
205 safe_browsing::DownloadProtectionService::DownloadCheckResult result);
206
207 // Determines the danger type of the download.
208 // Next state:
209 // - STATE_DETERMINE_INTERMEDIATE_PATH.
210 Result DoDetermineDangerType();
211
212 // Checks if the user has visited the referrer URL of the download prior to
213 // today. The actual check is only performed if it would be needed to
214 // determine the danger type of the download.
215 // Next state:
216 // - STATE_DETERMINE_INTERMEDIATE_PATH.
217 Result DoCheckVisitedReferrerBefore();
218
219 // Callback invoked after completion of history check for prior visits to
220 // referrer URL.
221 void CheckVisitedReferrerBeforeDone(bool visited_referrer_before);
222
223 // Determins the intermediate path. Once this step completes, downloads target
224 // determination is complete. The determination assumes that the intermediate
225 // file will never be overwritten (always uniquified if needed).
226 // - STATE_NONE: Returns COMPLETE.
227 Result DoDetermineIntermediatePath();
228
229 // === End of main workflow ===
230
231 // Utilities:
232
233 void ScheduleCallbackAndDeleteSelf();
234
235 void CancelOnFailureAndDeleteSelf();
236
237 Profile* GetProfile();
238
239 bool ShouldPromptForDownload(const base::FilePath& filename);
240
241 // Returns true if this download should show the "dangerous file" warning.
242 // Various factors are considered, such as the type of the file, whether a
243 // user action initiated the download, and whether the user has explicitly
244 // marked the file type as "auto open". Protected virtual for testing.
245 bool IsDangerousFile(PriorVisitsToReferrer visits);
246
247 // content::DownloadItem::Observer
248 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE;
249
250 // state
251 State next_state_;
252 bool should_prompt_;
253 bool should_overwrite_;
254 content::DownloadDangerType danger_type_;
255 base::FilePath virtual_path_;
256 base::FilePath local_path_;
257 base::FilePath intermediate_path_;
258
259 content::DownloadItem* download_;
260 DownloadPrefs* download_prefs_;
261 DownloadFilePickerFactory* file_picker_factory_;
262 DownloadTargetDeterminerDelegate* delegate_;
263 base::FilePath last_selected_directory_;
264 CompletionCallback completion_callback_;
265 CancelableRequestConsumer history_consumer_;
266
267 base::WeakPtrFactory<DownloadTargetDeterminer> weak_ptr_factory_;
268
269 DISALLOW_COPY_AND_ASSIGN(DownloadTargetDeterminer);
270 };
271
272 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_DETERMINER_H_
OLDNEW
« no previous file with comments | « chrome/browser/download/download_prefs.cc ('k') | chrome/browser/download/download_target_determiner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698