summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/download/download_file.cc56
-rw-r--r--chrome/browser/download/download_file.h29
-rw-r--r--chrome/browser/download/download_file_manager.cc34
3 files changed, 71 insertions, 48 deletions
diff --git a/chrome/browser/download/download_file.cc b/chrome/browser/download/download_file.cc
index 837d37e..ebdaa1c 100644
--- a/chrome/browser/download/download_file.cc
+++ b/chrome/browser/download/download_file.cc
@@ -6,6 +6,7 @@
#include "base/file_util.h"
#include "build/build_config.h"
+#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_util.h"
#include "chrome/browser/history/download_types.h"
@@ -24,38 +25,39 @@ DownloadFile::DownloadFile(const DownloadCreateInfo* info)
referrer_url_(info->referrer_url),
id_(info->download_id),
child_id_(info->child_id),
- render_view_id_(info->render_view_id),
request_id_(info->request_id),
- bytes_so_far_(0),
full_path_(info->save_info.file_path),
path_renamed_(false),
- in_progress_(true),
- dont_sleep_(true),
- save_info_(info->save_info) {
+ dont_sleep_(true) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
}
DownloadFile::~DownloadFile() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
Close();
}
bool DownloadFile::Initialize() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
if (!full_path_.empty() ||
download_util::CreateTemporaryFileForDownload(&full_path_))
return Open();
return false;
}
-bool DownloadFile::AppendDataToFile(const char* data, int data_len) {
- if (file_stream_.get()) {
- // FIXME bug 595247: handle errors on file writes.
- size_t written = file_stream_->Write(data, data_len, NULL);
- bytes_so_far_ += written;
- return true;
- }
- return false;
+bool DownloadFile::AppendDataToFile(const char* data, size_t data_len) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+
+ if (!file_stream_.get())
+ return false;
+
+ // FIXME bug 595247: handle errors on file writes.
+ size_t written = file_stream_->Write(data, data_len, NULL);
+ return (written == data_len);
}
void DownloadFile::Cancel() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
Close();
if (!full_path_.empty())
file_util::Delete(full_path_, false);
@@ -63,13 +65,19 @@ void DownloadFile::Cancel() {
// The UI has provided us with our finalized name.
bool DownloadFile::Rename(const FilePath& new_path, bool is_final_rename) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+
+ // Save the information whether the download is in progress because
+ // it will be overwritten by closing the file.
+ bool saved_in_progress = in_progress();
+
// If the new path is same as the old one, there is no need to perform the
// following renaming logic.
if (new_path == full_path_) {
path_renamed_ = is_final_rename;
// Don't close the file if we're not done (finished or canceled).
- if (!in_progress_)
+ if (!saved_in_progress)
Close();
return true;
@@ -111,7 +119,7 @@ bool DownloadFile::Rename(const FilePath& new_path, bool is_final_rename) {
path_renamed_ = is_final_rename;
// We don't need to re-open the file if we're done (finished or canceled).
- if (!in_progress_)
+ if (!saved_in_progress)
return true;
if (!Open())
@@ -129,7 +137,13 @@ void DownloadFile::DeleteCrDownload() {
file_util::Delete(crdownload, false);
}
+void DownloadFile::Finish() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+ Close();
+}
+
void DownloadFile::Close() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
if (file_stream_.get()) {
#if defined(OS_CHROMEOS)
// Currently we don't really care about the return value, since if it fails
@@ -142,6 +156,7 @@ void DownloadFile::Close() {
}
bool DownloadFile::Open() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
DCHECK(!full_path_.empty());
// Create a new file steram if it is not provided.
@@ -162,6 +177,7 @@ bool DownloadFile::Open() {
}
void DownloadFile::AnnotateWithSourceInformation() {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
#if defined(OS_WIN)
// Sets the Zone to tell Windows that this file comes from the internet.
// We ignore the return value because a failure is not fatal.
@@ -173,3 +189,13 @@ void DownloadFile::AnnotateWithSourceInformation() {
referrer_url_);
#endif
}
+
+void DownloadFile::CancelDownloadRequest(ResourceDispatcherHost* rdh) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableFunction(&download_util::CancelDownloadRequest,
+ rdh,
+ child_id_,
+ request_id_));
+}
diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h
index 6fd605e..9c9fdf6 100644
--- a/chrome/browser/download/download_file.h
+++ b/chrome/browser/download/download_file.h
@@ -18,6 +18,7 @@
#include "googleurl/src/gurl.h"
struct DownloadCreateInfo;
+class ResourceDispatcherHost;
// These objects live exclusively on the download thread and handle the writing
// operations for one download. These objects live only for the duration that
@@ -30,8 +31,9 @@ class DownloadFile {
bool Initialize();
- // Write a new chunk of data to the file. Returns true on success.
- bool AppendDataToFile(const char* data, int data_len);
+ // Write a new chunk of data to the file. Returns true on success (all bytes
+ // written to the file).
+ bool AppendDataToFile(const char* data, size_t data_len);
// Abort the download and automatically close the file.
void Cancel();
@@ -41,6 +43,9 @@ class DownloadFile {
// Marked virtual for testing.
virtual bool Rename(const FilePath& full_path, bool is_final_rename);
+ // Indicate that the download has finished. No new data will be received.
+ void Finish();
+
// Informs the OS that this file came from the internet.
void AnnotateWithSourceInformation();
@@ -48,16 +53,13 @@ class DownloadFile {
// Marked virtual for testing.
virtual void DeleteCrDownload();
+ // Cancels the download request associated with this file.
+ void CancelDownloadRequest(ResourceDispatcherHost* rdh);
+
// Accessors.
- int64 bytes_so_far() const { return bytes_so_far_; }
int id() const { return id_; }
- FilePath full_path() const { return full_path_; }
- int child_id() const { return child_id_; }
- int render_view_id() const { return render_view_id_; }
- int request_id() const { return request_id_; }
bool path_renamed() const { return path_renamed_; }
bool in_progress() const { return file_stream_ != NULL; }
- void set_in_progress(bool in_progress) { in_progress_ = in_progress; }
private:
// Open or Close the OS file stream. The stream is opened in the constructor
@@ -81,30 +83,19 @@ class DownloadFile {
// IDs for looking up the tab we are associated with.
int child_id_;
- int render_view_id_;
// Handle for informing the ResourceDispatcherHost of a UI based cancel.
int request_id_;
- // Amount of data received up to this point. We may not know in advance how
- // much data to expect since some servers don't provide that information.
- int64 bytes_so_far_;
-
// Full path to the downloaded file.
FilePath full_path_;
// Whether the download is still using its initial temporary path.
bool path_renamed_;
- // Whether the download is still receiving data.
- bool in_progress_;
-
// RAII handle to keep the system from sleeping while we're downloading.
PowerSaveBlocker dont_sleep_;
- // The provider used to save the download data.
- DownloadSaveInfo save_info_;
-
DISALLOW_COPY_AND_ASSIGN(DownloadFile);
};
diff --git a/chrome/browser/download/download_file_manager.cc b/chrome/browser/download/download_file_manager.cc
index ea0e42b..d9ba1f2 100644
--- a/chrome/browser/download/download_file_manager.cc
+++ b/chrome/browser/download/download_file_manager.cc
@@ -202,7 +202,8 @@ void DownloadFileManager::StartDownload(DownloadCreateInfo* info) {
DCHECK(GetDownloadFile(info->download_id) == NULL);
downloads_[info->download_id] = download;
- info->path = download->full_path();
+ // TODO(phajdan.jr): fix the duplication of path info below.
+ info->path = info->save_info.file_path;
{
AutoLock lock(progress_lock_);
ui_progress_[info->download_id] = info->received_bytes;
@@ -226,18 +227,24 @@ void DownloadFileManager::UpdateDownload(int id, DownloadBuffer* buffer) {
contents.swap(buffer->contents);
}
+ // Keep track of how many bytes we have successfully saved to update
+ // our progress status in the UI.
+ int64 progress_bytes = 0;
+
DownloadFile* download = GetDownloadFile(id);
for (size_t i = 0; i < contents.size(); ++i) {
net::IOBuffer* data = contents[i].first;
const int data_len = contents[i].second;
- if (download)
- download->AppendDataToFile(data->data(), data_len);
+ if (download) {
+ if (download->AppendDataToFile(data->data(), data_len))
+ progress_bytes += data_len;
+ }
data->Release();
}
if (download) {
AutoLock lock(progress_lock_);
- ui_progress_[download->id()] = download->bytes_so_far();
+ ui_progress_[download->id()] += progress_bytes;
}
}
@@ -247,13 +254,19 @@ void DownloadFileManager::DownloadFinished(int id, DownloadBuffer* buffer) {
DownloadFileMap::iterator it = downloads_.find(id);
if (it != downloads_.end()) {
DownloadFile* download = it->second;
- download->set_in_progress(false);
+ download->Finish();
+
+ int64 download_size = -1;
+ {
+ AutoLock lock(progress_lock_);
+ download_size = ui_progress_[download->id()];
+ }
ChromeThread::PostTask(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(
this, &DownloadFileManager::OnDownloadFinished,
- id, download->bytes_so_far()));
+ id, download_size));
// We need to keep the download around until the UI thread has finalized
// the name.
@@ -277,8 +290,6 @@ void DownloadFileManager::CancelDownload(int id) {
DownloadFileMap::iterator it = downloads_.find(id);
if (it != downloads_.end()) {
DownloadFile* download = it->second;
- download->set_in_progress(false);
-
download->Cancel();
ChromeThread::PostTask(
@@ -490,11 +501,6 @@ void DownloadFileManager::CancelDownloadOnRename(int id) {
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(dlm, &DownloadManager::DownloadCancelled, id));
} else {
- ChromeThread::PostTask(
- ChromeThread::IO, FROM_HERE,
- NewRunnableFunction(&download_util::CancelDownloadRequest,
- resource_dispatcher_host_,
- download->child_id(),
- download->request_id()));
+ download->CancelDownloadRequest(resource_dispatcher_host_);
}
}