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

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: Add 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 Profile;
19 class DownloadPrefs;
20
21 namespace safe_browsing {
22 class DownloadProtectionService;
23 }
24
25 // Determines the target of the download.
26 //
27 // Terminology:
28 // Virtual Path: A path representing the target of the download that may or
29 // may not be a physical file path. E.g. if the target of the download is in
30 // cloud storage, then the virtual path may be relative to a logical mount
31 // point.
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 I wince a little bit at this, in that restricting
asanka 2013/04/16 20:34:01 Addressed elsewhere.
32 //
33 // Local Path: A local file system path where the downloads system should
34 // write the file to.
35 //
36 // Intermediate Path: Where the data should be written to during the course of
37 // the download. Once the download completes, the file could be renamed to
38 // Local Path.
39 //
40 // DownloadTargetDeterminer is a self owned object that performs the work of
41 // determining the download target. It observes the DownloadItem and aborts the
42 // process if the download is removed. DownloadTargetDeterminerDelegate is
43 // responsible for providing external dependencies and prompting the user if
44 // necessary.
45 //
46 // The only public entrypoint is the static Start() method which creates an
47 // instance of DownloadTargetDeterminer.
48 class DownloadTargetDeterminer
49 : public content::DownloadItem::Observer {
50 public:
51 // Call to be invoked when the target is available. If the target
52 // determination is cancelled, then the paths will be empty. |virtual_path|,
53 // |local_path| and |intermediate_path| are as defined above. The
54 // |disposition| will be TARGET_DISPOSITION_PROMPT if the user was prompted
55 // during the process of determining the target. The |danger_type| is the
56 // danger type assigned to the download.
57 typedef base::Callback<void(
58 const base::FilePath& virtual_path,
59 const base::FilePath& local_path,
60 const base::FilePath& intermediate_path,
61 content::DownloadItem::TargetDisposition disposition,
62 content::DownloadDangerType danger_type)> CompletionCallback;
63
64 // Start the process of determing the target of |download|.
65 //
66 // |download_prefs| is required and must outlive |download|. It is used for
67 // determining the user's preferences regarding the default downloads
68 // directory and prompting.
69 // |last_selected_directory| is the most recent directory that was chosen by
70 // the user. If the user needs to be prompted, then this directory will be
71 // used as the directory for the download instead of the user's default
72 // downloads directory.
73 // |delegate| is required and must outlive the |download|.
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 In this practical situation (with the delegate bei
asanka 2013/04/16 20:34:01 The actual lifetime requirement is that the delega
74 // |callback| will be invoked when the target has been determined. If
75 // download| is destroyed prior to that, then |callback| will be invoked as
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 nit: missing '|'
asanka 2013/04/16 20:34:01 Done.
asanka 2013/04/16 20:34:01 Done.
76 // well. However the paths will be empty.
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 Maybe make clear that the callback may be invoked
asanka 2013/04/16 20:34:01 Done.
77 //
78 // Should be called on the UI thread. |callback| is also invoked on the UI
79 // thread. |callback| is always invoked asynchronously.
80 static void Start(content::DownloadItem* download,
81 DownloadPrefs* download_prefs,
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.
106 enum Result {
107 CONTINUE, // Continue processing.
108 PENDING, // Waiting for a callback. If a handler
109 // returns this value, it should ensure
110 // that DoLoop() is invoked once the
111 // callback is received.
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 I'd modify this comment to include the possibility
asanka 2013/04/16 20:34:01 Done.
112 COMPLETE // Target determination is complete.
113 };
114
115 // Construct a DownloadTargetDeterminer object. Constraints on the arguments
116 // are as per Start() above.
117 DownloadTargetDeterminer(
118 content::DownloadItem* download,
119 DownloadPrefs* download_prefs,
120 const base::FilePath& last_selected_directory,
121 DownloadTargetDeterminerDelegate* delegate,
122 const CompletionCallback& callback);
123
124 virtual ~DownloadTargetDeterminer();
125
126 // Invoke each successive handler until a handler returns PENDING or
127 // COMPLETE. Note that as a result, this object might be deleted. So |this|
128 // should not be accessed after calling DoLoop().
129 void DoLoop();
130
131 // === Main workflow ===
132
133 // Generates an initial target path. This target is based only on the state of
134 // the download item.
135 // Next state:
136 // - STATE_NONE : If the download is not in progress, returns COMPLETE.
137 // - STATE_NOTIFY_EXTENSIONS : All other downloads.
138 Result DoGenerateTargetPath();
139
140 // Notifies downloads extensions. If any extension wishes to override the
141 // download filename, it will respond to the OnDeterminingFilename()
142 // notification.
143 // Next state:
144 // - STATE_RESERVE_VIRTUAL_PATH.
145 Result DoNotifyExtensions();
146
147 // Callback invoked after extensions are notified.
148 void NotifyExtensionsDone(const base::FilePath& new_path, bool overwrite);
149
150 // Invokes ReserveVirtualPath() on the delegate to acquire a reservation for
151 // the path. See DownloadPathReservationTracker.
152 // Next state:
153 // - STATE_PROMPT_USER_FOR_DOWNLOAD_PATH.
154 Result DoReserveVirtualPath();
155
156 // Callback invoked after the delegate aquires a path reservation.
157 void ReserveVirtualPathDone(const base::FilePath& path, bool verified);
158
159 // Presents a file picker to the user if necessary.
160 // Next state:
161 // - STATE_CHECK_DOWNLOAD_URL : If a prompt is shown to the user.
162 // - STATE_DETERMINE_LOCAL_PATH : All other downloads.
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 (Thanks very much for doing these comments, by the
asanka 2013/04/16 20:34:01 The file picker returns both a virtual path and a
163 Result DoPromptUserForDownloadPath();
164
165 // Callback invoked after the file picker completes. Cancels the download if
166 // the user cancels the file picker.
167 void PromptUserForDownloadPathDone(const base::FilePath& virtual_path,
168 const base::FilePath& local_path);
169
170 // Up until this point, the path that was used is considered to be a virtual
171 // path. This step determines the local file system path corresponding to this
172 // virtual path. The translation is done by invoking the DetermineLocalPath()
173 // method on the delegate.
174 // Next state:
175 // - STATE_CHECK_DOWNLOAD_URL.
176 Result DoDetermineLocalPath();
177
178 // Callback invoked when the delegate has determined local path.
179 void DetermineLocalPathDone(const base::FilePath& local_path);
180
181 // Checks whether the downloaded URL is malicious. Invokes the
182 // DownloadProtectionService via the delegate.
183 // Next state:
184 // - STATE_DETERMINE_DANGER_TYPE.
185 Result DoCheckDownloadUrl();
186
187 // Callback invoked when the download URL has been checked.
188 void CheckDownloadUrlDone(
189 safe_browsing::DownloadProtectionService::DownloadCheckResult result);
190
191 // Determines the danger type of the download.
192 // Next state:
193 // - STATE_CHECK_VISITED_REFERRER_BEFORE: If information about prior visits is
194 // needed to determine the danger type.
195 // - STATE_DETERMINE_INTERMEDIATE_PATH: All other downloads.
196 Result DoDetermineDangerType();
197
198 // Checks if the user has visited the referrer URL of the download prior to
199 // today. This step is only performed if the DoDetermineDangerType step
200 // determines that the danger level of the download depends on the user having
201 // prior visits to the referrer.
202 // Next state:
203 // - STATE_DETERMINE_INTERMEDIATE_PATH.
204 Result DoCheckVisitedReferrerBefore();
205
206 // Callback invoked after completion of history check for prior visits to
207 // referrer URL.
208 void CheckVisitedReferrerBeforeDone(bool visited_referrer_before);
209
210 // Determins the intermediate path. Once this step completes, downloads target
Randy Smith (Not in Mondays) 2013/04/09 19:32:17 Worth mentioning that we implicitly assuming in do
asanka 2013/04/16 20:34:01 Done.
211 // determination is complete.
212 // - STATE_NONE: Returns COMPLETE.
213 Result DoDetermineIntermediatePath();
214
215 // === End of main workflow ===
216
217 // Utilities:
218
219 void ScheduleCallbackAndDeleteSelf();
220
221 void CancelOnFailureAndDeleteSelf();
222
223 Profile* GetProfile();
224
225 bool ShouldPromptForDownload(const base::FilePath& filename);
226
227 // Returns true if this download should show the "dangerous file" warning.
228 // Various factors are considered, such as the type of the file, whether a
229 // user action initiated the download, and whether the user has explicitly
230 // marked the file type as "auto open". Protected virtual for testing.
231 bool IsDangerousFile(bool visited_referrer_before);
232
233 // content::DownloadItem::Observer
234 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE;
235
236 // state
237 State next_state_;
238 bool should_prompt_;
239 bool should_overwrite_;
240 content::DownloadDangerType danger_type_;
241 base::FilePath virtual_path_;
242 base::FilePath local_path_;
243 base::FilePath intermediate_path_;
244
245 content::DownloadItem* download_;
246 DownloadPrefs* download_prefs_;
247 DownloadTargetDeterminerDelegate* delegate_;
248 base::FilePath last_selected_directory_;
249 CompletionCallback completion_callback_;
250 CancelableRequestConsumer history_consumer_;
251
252 base::WeakPtrFactory<DownloadTargetDeterminer> weak_ptr_factory_;
253 };
254
255 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_DETERMINER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698