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

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: 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.
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
benjhayden 2013/04/09 15:46:32 Would DTD be more modular if those strings were pa
asanka 2013/04/16 20:34:01 It also checks for auto-open behavior, which isn't
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|.
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
76 // well. However the paths will be empty.
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 {
Randy Smith (Not in Mondays) 2013/04/08 15:39:33 I understand that keeping it in sync with the code
asanka 2013/04/08 22:44:58 I added comments next to each declaration.
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.
112 COMPLETE // Target determination is complete.
113 };
114
115 // Construct a DownloadTargetDeterminer object.
116 DownloadTargetDeterminer(
117 content::DownloadItem* download,
118 DownloadPrefs* download_prefs,
119 const base::FilePath& last_selected_directory,
120 DownloadTargetDeterminerDelegate* delegate,
Randy Smith (Not in Mondays) 2013/04/08 15:39:33 Lifetime guarantees? At least spec the assumption
asanka 2013/04/08 22:44:58 Added a comment indicating that the constraints ar
121 const CompletionCallback& callback);
122
123 virtual ~DownloadTargetDeterminer();
124
125 // Invoke each successive handler until a handler returns PENDING or
126 // COMPLETE. Note that as a result, this object might be deleted. So |this|
127 // should not be accessed after calling DoLoop().
128 void DoLoop();
129
130 // === Main workflow ===
131
132 // Generates an initial target path. This target is based only on the state of
133 // the download item. If the download is not in-progress, this handler returns
134 // COMPLETE after determining the path. All other downloads proceed to
135 // NOTIFY_EXTENSIONS.
136 Result DoGenerateTargetPath();
137
138 // Notifies downloads extensions. If any extension wishes to override the
139 // download filename, it will respond to the OnDeterminingFilename()
140 // notification.
141 Result DoNotifyExtensions();
142
143 // Callback invoked after extensions are notified.
144 void NotifyExtensionsDone(const base::FilePath& new_path, bool overwrite);
145
146 // Invokes ReserveVirtualPath() on the delegate to acquire a reservation for
147 // the path. See DownloadPathReservationTracker.
148 Result DoReserveVirtualPath();
149
150 // Callback invoked after the delegate aquires a path reservation.
151 void ReserveVirtualPathDone(const base::FilePath& path, bool verified);
152
153 // Presents a file picker to the user if necessary.
154 Result DoPromptUserForDownloadPath();
155
156 // Callback invoked after the file picker completes. Cancels the download if
157 // the user cancels the file picker.
158 void PromptUserForDownloadPathDone(const base::FilePath& virtual_path,
159 const base::FilePath& local_path);
160
161 // Up until this point, the path that was used is considered to be a virtual
162 // path. This step determines the local file system path corresponding to this
163 // virtual path. The translation is done by invoking the DetermineLocalPath()
164 // method on the delegate.
165 Result DoDetermineLocalPath();
166
167 // Callback invoked when the delegate has determined local path.
168 void DetermineLocalPathDone(const base::FilePath& local_path);
169
170 // Checks whether the downloaded URL is malicious. Invokes the
171 // DownloadProtectionService via the delegate.
172 Result DoCheckDownloadUrl();
173
174 // Callback invoked when the download URL has been checked.
175 void CheckDownloadUrlDone(
176 safe_browsing::DownloadProtectionService::DownloadCheckResult result);
177
178 // Determines the danger type of the download.
179 Result DoDetermineDangerType();
180
181 // Checks if the user has visited the referrer URL of the download prior to
182 // today. This step is only performed if the DoDetermineDangerType step
183 // determines that the danger level of the download depends on the user having
184 // prior visits to the referrer.
185 Result DoCheckVisitedReferrerBefore();
186
187 // Callback invoked after completion of history check for prior visits to
188 // referrer URL.
189 void CheckVisitedReferrerBeforeDone(bool visited_referrer_before);
190
191 // Determins the intermediate path. Once this step completes, downloads target
192 // determination is complete.
193 Result DoDetermineIntermediatePath();
Randy Smith (Not in Mondays) 2013/04/08 15:39:33 We had talked about separating out intermediate pa
asanka 2013/04/08 22:44:58 Good point. I think that will be a static method +
194
195 // === End of main workflow ===
196
197 // Utilities:
198
199 void ScheduleCallbackAndDeleteSelf();
200
201 void CancelOnFailureAndDeleteSelf();
202
203 Profile* GetProfile();
204
205 bool ShouldPromptForDownload(const base::FilePath& filename);
206
207 // Returns true if this download should show the "dangerous file" warning.
208 // Various factors are considered, such as the type of the file, whether a
209 // user action initiated the download, and whether the user has explicitly
210 // marked the file type as "auto open". Protected virtual for testing.
211 bool IsDangerousFile(bool visited_referrer_before);
212
213 // content::DownloadItem::Observer
214 virtual void OnDownloadDestroyed(content::DownloadItem* download) OVERRIDE;
215
216 // state
217 State next_state_;
218 bool should_prompt_;
219 bool should_overwrite_;
220 content::DownloadDangerType danger_type_;
221 base::FilePath virtual_path_;
222 base::FilePath local_path_;
223 base::FilePath intermediate_path_;
224
225 content::DownloadItem* download_;
226 DownloadPrefs* download_prefs_;
227 DownloadTargetDeterminerDelegate* delegate_;
228 base::FilePath last_selected_directory_;
229 CompletionCallback completion_callback_;
230 CancelableRequestConsumer history_consumer_;
231
232 base::WeakPtrFactory<DownloadTargetDeterminer> weak_ptr_factory_;
233 };
benjhayden 2013/04/09 15:46:32 DISALLOW_COPY_AND_ASSIGN?
asanka 2013/04/16 20:34:01 Done.
234
235 #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_TARGET_DETERMINER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698