summaryrefslogtreecommitdiffstats
path: root/chrome/browser/download
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/download')
-rw-r--r--chrome/browser/download/download_exe.cc3
-rw-r--r--chrome/browser/download/download_file.cc6
-rw-r--r--chrome/browser/download/download_file.h3
-rw-r--r--chrome/browser/download/download_manager.cc250
-rw-r--r--chrome/browser/download/download_manager.h79
-rw-r--r--chrome/browser/download/download_util.cc2
-rw-r--r--chrome/browser/download/save_package.cc6
7 files changed, 304 insertions, 45 deletions
diff --git a/chrome/browser/download/download_exe.cc b/chrome/browser/download/download_exe.cc
index c9fdc4d..ce33781 100644
--- a/chrome/browser/download/download_exe.cc
+++ b/chrome/browser/download/download_exe.cc
@@ -59,6 +59,7 @@ static const wchar_t* const g_executables[] = {
L"app",
L"application",
L"asp",
+ L"asx",
L"bas",
L"bat",
L"chm",
@@ -66,6 +67,7 @@ static const wchar_t* const g_executables[] = {
L"com",
L"cpl",
L"crt",
+ L"dll",
L"exe",
L"fxp",
L"hlp",
@@ -73,6 +75,7 @@ static const wchar_t* const g_executables[] = {
L"inf",
L"ins",
L"isp",
+ L"jar",
L"js",
L"jse",
L"lnk",
diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc
index 4fa3637..6b0fba4 100644
--- a/chrome/browser/download/download_file.cc
+++ b/chrome/browser/download/download_file.cc
@@ -578,3 +578,9 @@ void DownloadFileManager::CreateDirectory(const std::wstring& directory) {
if (!file_util::PathExists(directory))
file_util::CreateDirectory(directory);
}
+
+void DownloadFileManager::DeleteFile(const std::wstring& path) {
+ // Make sure we only delete files.
+ if (file_util::PathExists(path) && !file_util::DirectoryExists(path))
+ file_util::Delete(path, false);
+}
diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h
index 5dc5d63..cce6398 100644
--- a/chrome/browser/download/download_file.h
+++ b/chrome/browser/download/download_file.h
@@ -210,6 +210,9 @@ class DownloadFileManager
// download directory exists.
void CreateDirectory(const std::wstring& directory);
+ // Called by the donwload manager to delete non validated dangerous downloads.
+ void DeleteFile(const std::wstring& path);
+
private:
// Timer helpers for updating the UI about the current progress of a download.
void StartUpdateTimer();
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index d83ddc2..cff6935 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -15,6 +15,7 @@
#include "base/task.h"
#include "base/thread.h"
#include "base/timer.h"
+#include "base/rand_util.h"
#include "base/win_util.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
@@ -97,6 +98,7 @@ static bool DownloadPathIsDangerous(const std::wstring& download_path) {
DownloadItem::DownloadItem(const DownloadCreateInfo& info)
: id_(-1),
full_path_(info.path),
+ original_name_(info.original_name),
url_(info.url),
total_bytes_(info.total_bytes),
received_bytes_(info.received_bytes),
@@ -105,6 +107,7 @@ DownloadItem::DownloadItem(const DownloadCreateInfo& info)
start_time_(info.start_time),
db_handle_(info.db_handle),
manager_(NULL),
+ safety_state_(SAFE),
is_paused_(false),
open_when_complete_(false),
render_process_id_(-1),
@@ -118,13 +121,16 @@ DownloadItem::DownloadItem(const DownloadCreateInfo& info)
DownloadItem::DownloadItem(int32 download_id,
const std::wstring& path,
const std::wstring& url,
+ const std::wstring& original_name,
const Time start_time,
int64 download_size,
int render_process_id,
- int request_id)
+ int request_id,
+ bool is_dangerous)
: id_(download_id),
full_path_(path),
url_(url),
+ original_name_(original_name),
total_bytes_(download_size),
received_bytes_(0),
start_tick_(GetTickCount()),
@@ -132,6 +138,7 @@ DownloadItem::DownloadItem(int32 download_id,
start_time_(start_time),
db_handle_(kUninitializedHandle),
manager_(NULL),
+ safety_state_(is_dangerous ? DANGEROUS : SAFE),
is_paused_(false),
open_when_complete_(false),
render_process_id_(render_process_id),
@@ -198,14 +205,16 @@ void DownloadItem::Cancel(bool update_history) {
void DownloadItem::Finished(int64 size) {
state_ = COMPLETE;
UpdateSize(size);
- UpdateObservers();
StopProgressTimer();
}
-void DownloadItem::Remove() {
+void DownloadItem::Remove(bool delete_on_disk) {
Cancel(true);
state_ = REMOVING;
+ if (delete_on_disk)
+ manager_->DeleteDownload(full_path_);
manager_->RemoveDownload(db_handle_);
+ // We are now deleted.
}
void DownloadItem::StartProgressTimer() {
@@ -255,6 +264,12 @@ void DownloadItem::TogglePause() {
UpdateObservers();
}
+std::wstring DownloadItem::GetFileName() const {
+ if (safety_state_ == DownloadItem::SAFE)
+ return file_name_;
+ return original_name_;
+}
+
// DownloadManager implementation ----------------------------------------------
// static
@@ -313,12 +328,19 @@ void DownloadManager::Shutdown() {
// 'in_progress_' may contain DownloadItems that have not finished the start
// complete (from the history service) and thus aren't in downloads_.
DownloadMap::iterator it = in_progress_.begin();
+ std::set<DownloadItem*> to_remove;
for (; it != in_progress_.end(); ++it) {
DownloadItem* download = it->second;
- if (download->state() == DownloadItem::IN_PROGRESS) {
- download->Cancel(false);
- UpdateHistoryForDownload(download);
+ if (download->safety_state() == DownloadItem::DANGEROUS) {
+ // Forget about any download that the user did not approve.
+ // Note that we cannot call download->Remove() this would invalidate our
+ // iterator.
+ to_remove.insert(download);
+ continue;
}
+ DCHECK_EQ(DownloadItem::IN_PROGRESS, download->state());
+ download->Cancel(false);
+ UpdateHistoryForDownload(download);
if (download->db_handle() == kUninitializedHandle) {
// An invalid handle means that 'download' does not yet exist in
// 'downloads_', so we have to delete it here.
@@ -326,7 +348,25 @@ void DownloadManager::Shutdown() {
}
}
+ // 'dangerous_finished_' contains all complete downloads that have not been
+ // approved. They should be removed.
+ it = dangerous_finished_.begin();
+ for (; it != dangerous_finished_.end(); ++it)
+ to_remove.insert(it->second);
+
+ // Remove the dangerous download that are not approved.
+ for (std::set<DownloadItem*>::const_iterator rm_it = to_remove.begin();
+ rm_it != to_remove.end(); ++rm_it) {
+ DownloadItem* download = *rm_it;
+ download->Remove(true);
+ // Same as above, delete the download if it is not in 'downloads_'.
+ if (download->db_handle() == kUninitializedHandle)
+ delete download;
+ }
+ to_remove.clear();
+
in_progress_.clear();
+ dangerous_finished_.clear();
STLDeleteValues(&downloads_);
file_manager_ = NULL;
@@ -486,17 +526,36 @@ void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
// Check writability of the suggested path. If we can't write to it, default
// to the user's "My Documents" directory. We'll prompt them in this case.
- std::wstring path = file_util::GetDirectoryFromPath(info->suggested_path);
- if (!file_util::PathIsWritable(path)) {
+ std::wstring dir = file_util::GetDirectoryFromPath(info->suggested_path);
+ const std::wstring filename =
+ file_util::GetFilenameFromPath(info->suggested_path);
+ if (!file_util::PathIsWritable(dir)) {
info->save_as = true;
- const std::wstring filename =
- file_util::GetFilenameFromPath(info->suggested_path);
PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path);
file_util::AppendToPath(&info->suggested_path, filename);
}
info->suggested_path_exists = !UniquifyPath(&info->suggested_path);
+ // If the download is deemmed dangerous, we'll use a temporary name for it.
+ if (!info->save_as && IsDangerous(filename)) {
+ info->original_name = file_util::GetFilenameFromPath(info->suggested_path);
+ // Create a temporary file to hold the file until the user approves its
+ // download.
+ std::wstring file_name;
+ std::wstring path;
+ while (path.empty()) {
+ SStringPrintf(&file_name, L"dangerous_download_%d.download",
+ base::RandInt(0, 100000));
+ path = dir;
+ file_util::AppendToPath(&path, file_name);
+ if (file_util::PathExists(path))
+ path.clear();
+ }
+ info->suggested_path = path;
+ info->is_dangerous = true;
+ }
+
// Now we return to the UI thread.
ui_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this,
@@ -537,10 +596,12 @@ void DownloadManager::ContinueStartDownload(DownloadCreateInfo* info,
download = new DownloadItem(info->download_id,
info->path,
info->url,
+ info->original_name,
info->start_time,
info->total_bytes,
info->render_process_id,
- info->request_id);
+ info->request_id,
+ info->is_dangerous);
download->set_manager(this);
in_progress_[info->download_id] = download;
} else {
@@ -628,30 +689,7 @@ void DownloadManager::UpdateDownload(int32 download_id, int64 size) {
void DownloadManager::DownloadFinished(int32 download_id, int64 size) {
DownloadMap::iterator it = in_progress_.find(download_id);
- if (it != in_progress_.end()) {
- // Remove the id from the list of pending ids.
- PendingFinishedMap::iterator erase_it =
- pending_finished_downloads_.find(download_id);
- if (erase_it != pending_finished_downloads_.end())
- pending_finished_downloads_.erase(erase_it);
-
- DownloadItem* download = it->second;
- download->Finished(size);
-
- // Open the download if the user or user prefs indicate it should be.
- const std::wstring extension =
- file_util::GetFileExtensionFromPath(download->full_path());
- if (download->open_when_complete() || ShouldOpenFileExtension(extension))
- OpenDownloadInShell(download, NULL);
-
- // Clean up will happen when the history system create callback runs if we
- // don't have a valid db_handle yet.
- if (download->db_handle() != kUninitializedHandle) {
- in_progress_.erase(it);
- NotifyAboutDownloadStop();
- UpdateHistoryForDownload(download);
- }
- } else {
+ if (it == in_progress_.end()) {
// The download is done, but the user hasn't selected a final location for
// it yet (the Save As dialog box is probably still showing), so just keep
// track of the fact that this download id is complete, when the
@@ -660,7 +698,102 @@ void DownloadManager::DownloadFinished(int32 download_id, int64 size) {
pending_finished_downloads_.find(download_id);
DCHECK(erase_it == pending_finished_downloads_.end());
pending_finished_downloads_[download_id] = size;
+ return;
+ }
+
+ // Remove the id from the list of pending ids.
+ PendingFinishedMap::iterator erase_it =
+ pending_finished_downloads_.find(download_id);
+ if (erase_it != pending_finished_downloads_.end())
+ pending_finished_downloads_.erase(erase_it);
+
+ DownloadItem* download = it->second;
+ download->Finished(size);
+
+ // Clean up will happen when the history system create callback runs if we
+ // don't have a valid db_handle yet.
+ if (download->db_handle() != kUninitializedHandle) {
+ in_progress_.erase(it);
+ NotifyAboutDownloadStop();
+ UpdateHistoryForDownload(download);
+ }
+
+ // If this a dangerous download not yet validated by the user, don't do
+ // anything. When the user notifies us, it will trigger a call to
+ // ProceedWithFinishedDangerousDownload.
+ if (download->safety_state() == DownloadItem::DANGEROUS) {
+ dangerous_finished_[download_id] = download;
+ return;
+ }
+
+ if (download->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED) {
+ // We first need to rename the donwloaded file from its temporary name to
+ // its final name before we can continue.
+ file_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(
+ this, &DownloadManager::ProceedWithFinishedDangerousDownload,
+ download->db_handle(),
+ download->full_path(), download->original_name()));
+ return;
}
+ ContinueDownloadFinished(download);
+}
+
+void DownloadManager::ContinueDownloadFinished(DownloadItem* download) {
+ // If this was a dangerous download, it has now been approved and must be
+ // removed from dangerous_finished_ so it does not get deleted on shutdown.
+ DownloadMap::iterator it = dangerous_finished_.find(download->id());
+ if (it != dangerous_finished_.end())
+ dangerous_finished_.erase(it);
+
+ // Notify our observers that we are complete (the call to Finished() set the
+ // state to complete but did not notify).
+ download->UpdateObservers();
+
+ // Open the download if the user or user prefs indicate it should be.
+ const std::wstring extension =
+ file_util::GetFileExtensionFromPath(download->full_path());
+ if (download->open_when_complete() || ShouldOpenFileExtension(extension))
+ OpenDownloadInShell(download, NULL);
+}
+
+// Called on the file thread. Renames the downloaded file to its original name.
+void DownloadManager::ProceedWithFinishedDangerousDownload(
+ int64 download_handle,
+ const std::wstring& path,
+ const std::wstring& original_name) {
+ bool success = false;
+ std::wstring new_path = path;
+ if (file_util::PathExists(path)) {
+ new_path = file_util::GetDirectoryFromPath(new_path);
+ file_util::AppendToPath(&new_path, original_name);
+ success = file_util::Move(path, new_path);
+ } else {
+ NOTREACHED();
+ }
+
+ ui_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &DownloadManager::DangerousDownloadRenamed,
+ download_handle, success, new_path));
+}
+
+// Call from the file thread when the finished dangerous download was renamed.
+void DownloadManager::DangerousDownloadRenamed(int64 download_handle,
+ bool success,
+ const std::wstring& new_path) {
+ DownloadMap::iterator it = downloads_.find(download_handle);
+ if (it == downloads_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ DownloadItem* download = it->second;
+ // If we failed to rename the file, we'll just keep the name as is.
+ if (success)
+ RenameDownload(download, new_path);
+
+ // Continue the download finished sequence.
+ ContinueDownloadFinished(download);
}
// static
@@ -741,6 +874,27 @@ void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
rdh->PauseRequest(render_process_id, request_id, pause);
}
+bool DownloadManager::IsDangerous(const std::wstring& file_name) {
+ // TODO(jcampan): Improve me.
+ return IsExecutable(file_util::GetFileExtensionFromPath(file_name));
+}
+
+void DownloadManager::RenameDownload(DownloadItem* download,
+ const std::wstring& new_path) {
+ download->Rename(new_path);
+
+ // Update the history.
+
+ // No update necessary if the download was initiated while in incognito mode.
+ if (download->db_handle() <= kUninitializedHandle)
+ return;
+
+ // FIXME(acw|paulg) see bug 958058. EXPLICIT_ACCESS below is wrong.
+ HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
+ if (hs)
+ hs->UpdateDownloadPath(new_path, download->db_handle());
+}
+
void DownloadManager::RemoveDownload(int64 download_handle) {
DownloadMap::iterator it = downloads_.find(download_handle);
if (it == downloads_.end())
@@ -752,6 +906,9 @@ void DownloadManager::RemoveDownload(int64 download_handle) {
// Remove from our tables and delete.
downloads_.erase(it);
+ it = dangerous_finished_.find(download->id());
+ if (it != dangerous_finished_.end())
+ dangerous_finished_.erase(it);
delete download;
// Tell observers to refresh their views.
@@ -1014,6 +1171,29 @@ void DownloadManager::FileSelectionCanceled(void* params) {
info->download_id));
}
+void DownloadManager::DeleteDownload(const std::wstring& path) {
+ file_loop_->PostTask(FROM_HERE, NewRunnableMethod(
+ file_manager_, &DownloadFileManager::DeleteFile, path));
+}
+
+
+void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
+ DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
+ download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
+ download->UpdateObservers();
+
+ // If the download is not complete, nothing to do. The required
+ // post-processing will be performed when it does complete.
+ if (download->state() != DownloadItem::COMPLETE)
+ return;
+
+ file_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this,
+ &DownloadManager::ProceedWithFinishedDangerousDownload,
+ download->db_handle(), download->full_path(),
+ download->original_name()));
+}
+
// Operations posted to us from the history service ----------------------------
// The history service has retrieved all download entries. 'entries' contains
diff --git a/chrome/browser/download/download_manager.h b/chrome/browser/download/download_manager.h
index 0ab3dc1..6e78fb6 100644
--- a/chrome/browser/download/download_manager.h
+++ b/chrome/browser/download/download_manager.h
@@ -80,6 +80,12 @@ class DownloadItem {
REMOVING
};
+ enum SafetyState {
+ SAFE = 0,
+ DANGEROUS,
+ DANGEROUS_BUT_VALIDATED // Dangerous but the user confirmed the download.
+ };
+
// Interface that observers of a particular download must implement in order
// to receive updates to the download's status.
class Observer {
@@ -94,10 +100,12 @@ class DownloadItem {
DownloadItem(int32 download_id,
const std::wstring& path,
const std::wstring& url,
+ const std::wstring& original_name,
const Time start_time,
int64 download_size,
int render_process_id,
- int request_id);
+ int request_id,
+ bool is_dangerous);
~DownloadItem();
@@ -125,12 +133,12 @@ class DownloadItem {
// when resuming a download (assuming the server supports byte ranges).
void Cancel(bool update_history);
- // Download operation completed
+ // Download operation completed.
void Finished(int64 size);
- // The user wants to remove the download from the views and history. This
- // operation does not delete the file on the disk.
- void Remove();
+ // The user wants to remove the download from the views and history. If
+ // |delete_file| is true, the file is deleted on the disk.
+ void Remove(bool delete_file);
// Start/stop sending periodic updates to our observers
void StartProgressTimer();
@@ -158,8 +166,10 @@ class DownloadItem {
// Accessors
DownloadState state() const { return state_; }
- std::wstring full_path() const { return full_path_; }
std::wstring file_name() const { return file_name_; }
+ void set_file_name(const std::wstring& name) { file_name_ = name; }
+ std::wstring full_path() const { return full_path_; }
+ void set_full_path(const std::wstring& path) { full_path_ = path; }
std::wstring url() const { return url_; }
int64 total_bytes() const { return total_bytes_; }
void set_total_bytes(int64 total_bytes) { total_bytes_ = total_bytes; }
@@ -176,6 +186,16 @@ class DownloadItem {
void set_open_when_complete(bool open) { open_when_complete_ = open; }
int render_process_id() const { return render_process_id_; }
int request_id() const { return request_id_; }
+ SafetyState safety_state() const { return safety_state_; }
+ void set_safety_state(SafetyState safety_state) {
+ safety_state_ = safety_state;
+ }
+ std::wstring original_name() const { return original_name_; }
+ void set_original_name(const std::wstring& name) { original_name_ = name; }
+
+ // Returns the file-name that should be reported to the user, which is
+ // file_name_ for safe downloads and original_name_ for dangerous ones.
+ std::wstring GetFileName() const;
private:
// Internal helper for maintaining consistent received and total sizes.
@@ -226,6 +246,14 @@ class DownloadItem {
// A flag for indicating if the download should be opened at completion.
bool open_when_complete_;
+ // Whether the download is considered potentially safe or dangerous
+ // (executable files are typically considered dangerous).
+ SafetyState safety_state_;
+
+ // Dangerous download are given temporary names until the user approves them.
+ // This stores their original name.
+ std::wstring original_name_;
+
// For canceling or pausing requests.
int render_process_id_;
int request_id_;
@@ -354,6 +382,12 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
virtual void FileSelected(const std::wstring& path, void* params);
virtual void FileSelectionCanceled(void* params);
+ // Deletes the specified path on the file thread.
+ void DeleteDownload(const std::wstring& path);
+
+ // Called when the user has validated the donwload of a dangerous file.
+ void DangerousDownloadValidated(DownloadItem* download);
+
private:
// Shutdown the download manager. This call is needed only after Init.
void Shutdown();
@@ -405,6 +439,32 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
int request_id,
bool pause);
+ // Performs the last steps required when a download has been completed.
+ // It is necessary to break down the flow when a download is finished as
+ // dangerous downloads are downloaded to temporary files that need to be
+ // renamed on the file thread first.
+ // Invoked on the UI thread.
+ void ContinueDownloadFinished(DownloadItem* download);
+
+ // Renames a finished dangerous download from its temporary file name to its
+ // real file name.
+ // Invoked on the file thread.
+ void ProceedWithFinishedDangerousDownload(int64 download_handle,
+ const std::wstring& path,
+ const std::wstring& original_name);
+
+ // Invoked on the UI thread when a dangerous downloaded file has been renamed.
+ void DangerousDownloadRenamed(int64 download_handle,
+ bool success,
+ const std::wstring& new_path);
+
+ // Checks whether a file represents a risk if downloaded.
+ bool IsDangerous(const std::wstring& file_name);
+
+ // Changes the paths and file name of the specified |download|, propagating
+ // the change to the history system.
+ void RenameDownload(DownloadItem* download, const std::wstring& new_path);
+
// 'downloads_' is map of all downloads in this profile. The key is the handle
// returned by the history system, which is unique across sessions. This map
// owns all the DownloadItems once they have been created in the history
@@ -415,6 +475,12 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
// ResourceDispatcherHost, which is unique for the current session. This map
// does not own the DownloadItems.
//
+ // 'dangerous_finished_' is a map of dangerous download that have finished
+ // but were not yet approved by the user. Similarly to in_progress_, the key
+ // is the ID assigned by the ResourceDispatcherHost and the map does not own
+ // the DownloadItems. It is used on shutdown to delete completed downloads
+ // that have not been approved.
+ //
// When a download is created through a user action, the corresponding
// DownloadItem* is placed in 'in_progress_' and remains there until it has
// received a valid handle from the history system. Once it has a valid
@@ -426,6 +492,7 @@ class DownloadManager : public base::RefCountedThreadSafe<DownloadManager>,
typedef base::hash_map<int64, DownloadItem*> DownloadMap;
DownloadMap downloads_;
DownloadMap in_progress_;
+ DownloadMap dangerous_finished_;
// True if the download manager has been initialized and requires a shutdown.
bool shutdown_needed_;
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index 530eade..96de46c 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -133,7 +133,7 @@ void BaseContextMenu::ExecuteCommand(int id) {
break;
}
case REMOVE_ITEM:
- download_->Remove();
+ download_->Remove(false);
break;
case CANCEL:
download_->Cancel(true);
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 127fa53..ff56be2 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -126,7 +126,7 @@ SavePackage::~SavePackage() {
// We call this to remove the view from the shelf. It will invoke
// DownloadManager::RemoveDownload, but since the fake DownloadItem is not
// owned by DownloadManager, it will do nothing to our fake item.
- download_->Remove();
+ download_->Remove(false);
delete download_;
download_ = NULL;
}
@@ -174,8 +174,8 @@ bool SavePackage::Init() {
}
// Create the fake DownloadItem and display the view.
- download_ = new DownloadItem(1, saved_main_file_path_,
- page_url_, Time::Now(), 0, -1, -1);
+ download_ = new DownloadItem(1, saved_main_file_path_, page_url_,
+ std::wstring(), Time::Now(), 0, -1, -1, false);
download_->set_manager(web_contents_->profile()->GetDownloadManager());
DownloadShelfView* shelf = web_contents_->GetDownloadShelfView();
shelf->AddDownloadView(new DownloadItemView(