1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Each download is represented by a DownloadItem, and all DownloadItems
// are owned by the DownloadManager which maintains a global list of all
// downloads. DownloadItems are created when a user initiates a download,
// and exist for the duration of the browser life time.
//
// Download observers:
// DownloadItem::Observer:
// - allows observers to receive notifications about one download from start
// to completion
// Use AddObserver() / RemoveObserver() on the appropriate download object to
// receive state updates.
#ifndef CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_
#define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_
#pragma once
#include <string>
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/observer_list.h"
#include "base/time.h"
#include "base/timer.h"
#include "content/browser/download/download_request_handle.h"
#include "content/browser/download/download_state_info.h"
#include "content/common/content_export.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
class DownloadFileManager;
class DownloadManager;
struct DownloadCreateInfo;
struct DownloadPersistentStoreInfo;
// One DownloadItem per download. This is the model class that stores all the
// state for a download. Multiple views, such as a tab's download shelf and the
// Destination tab's download view, may refer to a given DownloadItem.
//
// This is intended to be used only on the UI thread.
class CONTENT_EXPORT DownloadItem {
public:
enum DownloadState {
// Download is actively progressing.
IN_PROGRESS = 0,
// Download is completely finished.
COMPLETE,
// Download has been cancelled.
CANCELLED,
// This state indicates that the download item is about to be destroyed,
// and observers seeing this state should release all references.
REMOVING,
// This state indicates that the download has been interrupted.
INTERRUPTED,
// Maximum value.
MAX_DOWNLOAD_STATE
};
enum SafetyState {
SAFE = 0,
DANGEROUS,
DANGEROUS_BUT_VALIDATED // Dangerous but the user confirmed the download.
};
// This enum is used by histograms. Do not change the ordering or remove
// items.
enum DangerType {
NOT_DANGEROUS = 0,
// A dangerous file to the system (e.g.: an executable or extension from
// places other than gallery).
DANGEROUS_FILE,
// Safebrowsing service shows this URL leads to malicious file download.
DANGEROUS_URL,
// Memory space for histograms is determined by the max.
// ALWAYS ADD NEW VALUES BEFORE THIS ONE.
DANGEROUS_TYPE_MAX
};
// Reason for deleting the download. Passed to Delete().
enum DeleteReason {
DELETE_DUE_TO_BROWSER_SHUTDOWN = 0,
DELETE_DUE_TO_USER_DISCARD
};
// A fake download table ID which represents a download that has started,
// but is not yet in the table.
static const int kUninitializedHandle;
// Interface that observers of a particular download must implement in order
// to receive updates to the download's status.
class CONTENT_EXPORT Observer {
public:
virtual void OnDownloadUpdated(DownloadItem* download) = 0;
// Called when a downloaded file has been opened.
virtual void OnDownloadOpened(DownloadItem* download) = 0;
protected:
virtual ~Observer() {}
};
// Constructing from persistent store:
DownloadItem(DownloadManager* download_manager,
const DownloadPersistentStoreInfo& info);
// Constructing for a regular download:
DownloadItem(DownloadManager* download_manager,
const DownloadCreateInfo& info,
bool is_otr);
// Constructing for the "Save Page As..." feature:
DownloadItem(DownloadManager* download_manager,
const FilePath& path,
const GURL& url,
bool is_otr,
int download_id);
virtual ~DownloadItem();
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Notifies our observers periodically.
void UpdateObservers();
// Returns true if it is OK to open a folder which this file is inside.
bool CanShowInFolder();
// Returns true if it is OK to register the type of this file so that
// it opens automatically.
bool CanOpenDownload();
// Tests if a file type should be opened automatically.
bool ShouldOpenFileBasedOnExtension();
// Open the file associated with this download (wait for the download to
// complete if it is in progress).
void OpenDownload();
// Show the download via the OS shell.
void ShowDownloadInShell();
// Called when the user has validated the download of a dangerous file.
void DangerousDownloadValidated();
// Received a new chunk of data
void Update(int64 bytes_so_far);
// Cancel the download operation. This may be called at any time; if
// it is called before all download attributes have been finalized and
// the download entered into the history, it will remove the download from
// the system.
void Cancel();
// Called by external code (SavePackage) using the DownloadItem interface
// to display progress when the DownloadItem should be considered complete.
void MarkAsComplete();
// Called by the delegate after it delayed completing the download in
// DownloadManagerDelegate::ShouldCompleteDownload.
void CompleteDelayedDownload();
// Called when all data has been saved. Only has display effects.
void OnAllDataSaved(int64 size);
// Called when the downloaded file is removed.
void OnDownloadedFileRemoved();
// Download operation had an error; call to interrupt the processing.
// Note that if the download attributes haven't yet been finalized and
// the download entered into the history (which implies that it hasn't
// yet been made visible in the UI), this call will remove the
// download from the system.
// |size| is the amount of data received so far, and |net_error| is the
// error code that the operation received.
void Interrupt(int64 size, net::Error net_error);
// Deletes the file from disk and removes the download from the views and
// history. |user| should be true if this is the result of the user clicking
// the discard button, and false if it is being deleted for other reasons like
// browser shutdown.
void Delete(DeleteReason reason);
// Removes the download from the views and history.
void Remove();
// Simple calculation of the amount of time remaining to completion. Fills
// |*remaining| with the amount of time remaining if successful. Fails and
// returns false if we do not have the number of bytes or the speed so can
// not estimate.
bool TimeRemaining(base::TimeDelta* remaining) const;
// Simple speed estimate in bytes/s
int64 CurrentSpeed() const;
// Rough percent complete, -1 means we don't know (since we didn't receive a
// total size).
int PercentComplete() const;
// Called when the final path has been determined.
void OnPathDetermined(const FilePath& path);
// Returns true if this download has saved all of its data.
bool all_data_saved() const { return all_data_saved_; }
// Update the fields that may have changed in DownloadStateInfo as a
// result of analyzing the file and figuring out its type, location, etc.
// May only be called once.
void SetFileCheckResults(const DownloadStateInfo& state);
// Update the download's path, the actual file is renamed on the download
// thread.
void Rename(const FilePath& full_path);
// Allow the user to temporarily pause a download or resume a paused download.
void TogglePause();
// Called when the download is ready to complete.
// This may perform final rename if necessary and will eventually call
// DownloadItem::Completed().
void OnDownloadCompleting(DownloadFileManager* file_manager);
// Called when the file name for the download is renamed to its final name.
void OnDownloadRenamedToFinalName(const FilePath& full_path);
// Returns true if this item matches |query|. |query| must be lower-cased.
bool MatchesQuery(const string16& query) const;
// Returns true if the download needs more data.
bool IsPartialDownload() const;
// Returns true if the download is still receiving data.
bool IsInProgress() const;
// Returns true if the download has been cancelled or was interrupted.
bool IsCancelled() const;
// Returns true if the download was interrupted.
bool IsInterrupted() const;
// Returns true if we have all the data and know the final file name.
bool IsComplete() const;
// Accessors
DownloadState state() const { return state_; }
const FilePath& full_path() const { return full_path_; }
void set_path_uniquifier(int uniquifier) {
state_info_.path_uniquifier = uniquifier;
}
const GURL& GetURL() const;
const std::vector<GURL>& url_chain() const { return url_chain_; }
const GURL& original_url() const { return url_chain_.front(); }
const GURL& referrer_url() const { return referrer_url_; }
std::string suggested_filename() const { return suggested_filename_; }
std::string content_disposition() const { return content_disposition_; }
std::string mime_type() const { return mime_type_; }
std::string original_mime_type() const { return original_mime_type_; }
std::string referrer_charset() const { return referrer_charset_; }
int64 total_bytes() const { return total_bytes_; }
void set_total_bytes(int64 total_bytes) {
total_bytes_ = total_bytes;
}
int64 received_bytes() const { return received_bytes_; }
int32 id() const { return download_id_; }
base::Time start_time() const { return start_time_; }
void set_db_handle(int64 handle) { db_handle_ = handle; }
int64 db_handle() const { return db_handle_; }
DownloadManager* download_manager() { return download_manager_; }
bool is_paused() const { return is_paused_; }
bool open_when_complete() const { return open_when_complete_; }
void set_open_when_complete(bool open) { open_when_complete_ = open; }
bool file_externally_removed() const { return file_externally_removed_; }
SafetyState safety_state() const { return safety_state_; }
// Why |safety_state_| is not SAFE.
DangerType GetDangerType() const;
bool IsDangerous() const;
void MarkFileDangerous();
void MarkUrlDangerous();
bool auto_opened() { return auto_opened_; }
const FilePath& target_name() const { return state_info_.target_name; }
bool prompt_user_for_save_location() const {
return state_info_.prompt_user_for_save_location;
}
bool is_otr() const { return is_otr_; }
const FilePath& suggested_path() const { return state_info_.suggested_path; }
bool is_temporary() const { return is_temporary_; }
void set_opened(bool opened) { opened_ = opened; }
bool opened() const { return opened_; }
net::Error last_error() const { return last_error_; }
DownloadPersistentStoreInfo GetPersistentStoreInfo() const;
DownloadStateInfo state_info() const { return state_info_; }
const DownloadRequestHandle& request_handle() const {
return request_handle_;
}
// Returns the final target file path for the download.
FilePath GetTargetFilePath() const;
// Returns the file-name that should be reported to the user, which is
// target_name possibly with the uniquifier number.
FilePath GetFileNameToReportUser() const;
// Returns the user-verified target file path for the download.
// This returns the same path as GetTargetFilePath() for safe downloads
// but does not for dangerous downloads until the name is verified.
FilePath GetUserVerifiedFilePath() const;
// Returns true if the current file name is not the final target name yet.
bool NeedsRename() const {
return state_info_.target_name != full_path_.BaseName();
}
// Cancels the off-thread aspects of the download.
// TODO(rdsmith): This should be private and only called from
// DownloadItem::Cancel/Interrupt; it isn't now because we can't
// call those functions from
// DownloadManager::FileSelectionCancelled() without doing some
// rewrites of the DownloadManager queues.
void OffThreadCancel(DownloadFileManager* file_manager);
std::string DebugString(bool verbose) const;
#ifdef UNIT_TEST
// Mock opening downloads (for testing only).
void TestMockDownloadOpen() { open_enabled_ = false; }
#endif
private:
// Construction common to all constructors. |active| should be true for new
// downloads and false for downloads from the history.
void Init(bool active);
// Internal helper for maintaining consistent received and total sizes.
void UpdateSize(int64 size);
// Called when the entire download operation (including renaming etc)
// is completed.
void Completed();
// Start/stop sending periodic updates to our observers
void StartProgressTimer();
void StopProgressTimer();
// Does the actual work of transition state; all state
// transitions should go through this.
void TransitionTo(DownloadState new_state);
// Called when safety_state_ should be recomputed from is_dangerous_file
// and is_dangerous_url.
void UpdateSafetyState();
// Helper function to recompute |state_info_.target_name| when
// it may have changed. (If it's non-null it should be left alone,
// otherwise updated from |full_path_|.)
void UpdateTarget();
// State information used by the download manager.
DownloadStateInfo state_info_;
// The handle to the request information. Used for operations outside the
// download system.
DownloadRequestHandle request_handle_;
// Download ID assigned by DownloadResourceHandler.
int32 download_id_;
// Full path to the downloaded or downloading file.
FilePath full_path_;
// A number that should be appended to the path to make it unique, or 0 if the
// path should be used as is.
int path_uniquifier_;
// The chain of redirects that leading up to and including the final URL.
std::vector<GURL> url_chain_;
// The URL of the page that initiated the download.
GURL referrer_url_;
// Suggested filename in 'download' attribute of an anchor. Details:
// http://www.whatwg.org/specs/web-apps/current-work/#downloading-hyperlinks
std::string suggested_filename_;
// Information from the request.
// Content-disposition field from the header.
std::string content_disposition_;
// Mime-type from the header. Subject to change.
std::string mime_type_;
// The value of the content type header sent with the downloaded item. It
// may be different from |mime_type_|, which may be set based on heuristics
// which may look at the file extension and first few bytes of the file.
std::string original_mime_type_;
// The charset of the referring page where the download request comes from.
// It's used to construct a suggested filename.
std::string referrer_charset_;
// Total bytes expected
int64 total_bytes_;
// Current received bytes
int64 received_bytes_;
// Last error.
net::Error last_error_;
// Start time for calculating remaining time
base::TimeTicks start_tick_;
// The current state of this download
DownloadState state_;
// The views of this item in the download shelf and download tab
ObserverList<Observer> observers_;
// Time the download was started
base::Time start_time_;
// Our persistent store handle
int64 db_handle_;
// Timer for regularly updating our observers
base::RepeatingTimer<DownloadItem> update_timer_;
// Our owning object
DownloadManager* download_manager_;
// In progress downloads may be paused by the user, we note it here
bool is_paused_;
// A flag for indicating if the download should be opened at completion.
bool open_when_complete_;
// A flag for indicating if the downloaded file is externally removed.
bool file_externally_removed_;
// Indicates if the download is considered potentially safe or dangerous
// (executable files are typically considered dangerous).
SafetyState safety_state_;
// True if the download was auto-opened. We set this rather than using
// an observer as it's frequently possible for the download to be auto opened
// before the observer is added.
bool auto_opened_;
// True if the download was initiated in an incognito window.
bool is_otr_;
// True if the item was downloaded temporarily.
bool is_temporary_;
// True if we've saved all the data for the download.
bool all_data_saved_;
// Did the user open the item either directly or indirectly (such as by
// setting always open files of this type)? The shelf also sets this field
// when the user closes the shelf before the item has been opened but should
// be treated as though the user opened it.
bool opened_;
// Do we actual open downloads when requested? For testing purposes
// only.
bool open_enabled_;
// Did the delegate delay calling Complete on this download?
bool delegate_delayed_complete_;
DISALLOW_COPY_AND_ASSIGN(DownloadItem);
};
#endif // CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_ITEM_H_
|