summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 23:41:28 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-14 23:41:28 +0000
commit0ffaa48416edf9bbb6a1ccac8df6aa4eec6255aa (patch)
treecc653d2995ebd5174e7308d976d3625d49fc05e2 /chrome/browser
parentae57efd76a9bf4bb4d01b009e38d7f7c9b2f9e00 (diff)
downloadchromium_src-0ffaa48416edf9bbb6a1ccac8df6aa4eec6255aa.zip
chromium_src-0ffaa48416edf9bbb6a1ccac8df6aa4eec6255aa.tar.gz
chromium_src-0ffaa48416edf9bbb6a1ccac8df6aa4eec6255aa.tar.bz2
Move the save file code from chrome to content. This is just a file move so the DEPS in content\browser\download is very permissive for now. The one exception is save_package.cc, where I had to split off the usage of SelectFileDialog because the code depended on grit which can't be used in content (circular dependencies in gyp).
TBR=rdsmith BUG=82782 Review URL: http://codereview.chromium.org/7373004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92623 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc2
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc2
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc5
-rw-r--r--chrome/browser/browser_encoding_uitest.cc2
-rw-r--r--chrome/browser/browser_process_impl.cc2
-rw-r--r--chrome/browser/chrome_content_browser_client.cc10
-rw-r--r--chrome/browser/chrome_content_browser_client.h7
-rw-r--r--chrome/browser/download/base_file.cc248
-rw-r--r--chrome/browser/download/base_file.h108
-rw-r--r--chrome/browser/download/base_file_unittest.cc230
-rw-r--r--chrome/browser/download/download_file.h2
-rw-r--r--chrome/browser/download/download_item_model.cc2
-rw-r--r--chrome/browser/download/download_prefs.cc2
-rw-r--r--chrome/browser/download/save_file.cc22
-rw-r--r--chrome/browser/download/save_file.h42
-rw-r--r--chrome/browser/download/save_file_manager.cc541
-rw-r--r--chrome/browser/download/save_file_manager.h255
-rw-r--r--chrome/browser/download/save_item.cc130
-rw-r--r--chrome/browser/download/save_item.h112
-rw-r--r--chrome/browser/download/save_package.cc1476
-rw-r--r--chrome/browser/download/save_package.h327
-rw-r--r--chrome/browser/download/save_package_file_picker.cc165
-rw-r--r--chrome/browser/download/save_package_file_picker.h40
-rw-r--r--chrome/browser/download/save_package_unittest.cc426
-rw-r--r--chrome/browser/download/save_page_uitest.cc2
-rw-r--r--chrome/browser/download/save_types.cc31
-rw-r--r--chrome/browser/download/save_types.h68
-rw-r--r--chrome/browser/renderer_host/DEPS4
-rw-r--r--chrome/browser/renderer_host/save_file_resource_handler.cc119
-rw-r--r--chrome/browser/renderer_host/save_file_resource_handler.h79
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc2
-rw-r--r--chrome/browser/ui/browser.cc2
-rw-r--r--chrome/browser/ui/cocoa/applescript/tab_applescript.mm2
-rw-r--r--chrome/browser/ui/download/download_tab_helper.h2
34 files changed, 236 insertions, 4233 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index eb9f6df..058fb3b 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -42,7 +42,6 @@
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/download/download_item.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_host.h"
@@ -81,6 +80,7 @@
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
#include "content/browser/debugger/devtools_manager.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/ssl/ssl_manager.h"
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 9c0a3f9..1281a6b 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -26,7 +26,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/dom_operation_notification_details.h"
#include "chrome/browser/download/download_item.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_process_manager.h"
@@ -63,6 +62,7 @@
#include "chrome/common/automation_messages.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_controller.h"
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index b7eccd8..e003231 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -43,7 +43,7 @@
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/download/download_prefs.h"
-#include "chrome/browser/download/save_package.h"
+#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_updater.h"
@@ -97,6 +97,7 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/browser/debugger/devtools_window.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/renderer_host/render_process_host.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/interstitial_page.h"
@@ -2063,7 +2064,7 @@ void TestingAutomationProvider::GoForwardBlockUntilNavigationsComplete(
void TestingAutomationProvider::SavePackageShouldPromptUser(
bool should_prompt) {
- SavePackage::SetShouldPromptUser(should_prompt);
+ SavePackageFilePicker::SetShouldPromptUser(should_prompt);
}
void TestingAutomationProvider::SetShelfVisibility(int handle, bool visible) {
diff --git a/chrome/browser/browser_encoding_uitest.cc b/chrome/browser/browser_encoding_uitest.cc
index 46e5a2a..d7fe2dc 100644
--- a/chrome/browser/browser_encoding_uitest.cc
+++ b/chrome/browser/browser_encoding_uitest.cc
@@ -5,13 +5,13 @@
#include "base/file_util.h"
#include "base/scoped_temp_dir.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui_test_utils.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/net/url_request_mock_http_job.h"
static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("encoding_tests");
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 21d502e..225bbb7 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -22,7 +22,6 @@
#include "chrome/browser/browser_trial.h"
#include "chrome/browser/download/download_file_manager.h"
#include "chrome/browser/download/mhtml_generation_manager.h"
-#include "chrome/browser/download/save_file_manager.h"
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
#include "chrome/browser/extensions/extension_tab_id_map.h"
#include "chrome/browser/extensions/user_script_listener.h"
@@ -72,6 +71,7 @@
#include "content/browser/debugger/devtools_http_protocol_handler.h"
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/devtools_protocol_handler.h"
+#include "content/browser/download/save_file_manager.h"
#include "content/browser/gpu/gpu_process_host_ui_shim.h"
#include "content/browser/net/browser_online_state_observer.h"
#include "content/browser/plugin_service.h"
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 9758443..7cce656 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/chrome_worker_message_filter.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
+#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/browser/extensions/extension_message_handler.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -710,6 +711,15 @@ void ChromeContentBrowserClient::ClearCookies(RenderViewHost* rvh) {
// BrowsingDataRemover takes care of deleting itself when done.
}
+void ChromeContentBrowserClient::ChooseSavePath(
+ SavePackage* save_package,
+ const FilePath& suggested_path,
+ bool can_save_as_complete) {
+ // Deletes itself.
+ new SavePackageFilePicker(
+ save_package, suggested_path, can_save_as_complete);
+}
+
#if defined(OS_LINUX)
int ChromeContentBrowserClient::GetCrashSignalFD(
const std::string& process_type) {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index edc23d9..a55cfa6 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -100,8 +100,11 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
const std::string& value) OVERRIDE;
virtual void ClearInspectorSettings(RenderViewHost* rvh) OVERRIDE;
virtual void BrowserURLHandlerCreated(BrowserURLHandler* handler) OVERRIDE;
- virtual void ClearCache(RenderViewHost* rvh);
- virtual void ClearCookies(RenderViewHost* rvh);
+ virtual void ClearCache(RenderViewHost* rvh) OVERRIDE;
+ virtual void ClearCookies(RenderViewHost* rvh) OVERRIDE;
+ virtual void ChooseSavePath(SavePackage* save_package,
+ const FilePath& suggested_path,
+ bool can_save_as_complete) OVERRIDE;
#if defined(OS_POSIX) && !defined(OS_MACOSX)
// Can return an optional fd for crash handling, otherwise returns -1.
diff --git a/chrome/browser/download/base_file.cc b/chrome/browser/download/base_file.cc
deleted file mode 100644
index e52f08a..0000000
--- a/chrome/browser/download/base_file.cc
+++ /dev/null
@@ -1,248 +0,0 @@
-// 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.
-
-#include "chrome/browser/download/base_file.h"
-
-#include "base/file_util.h"
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/stringprintf.h"
-#include "base/utf_string_conversions.h"
-#include "crypto/secure_hash.h"
-#include "net/base/file_stream.h"
-#include "net/base/net_errors.h"
-#include "chrome/browser/download/download_util.h"
-#include "content/browser/browser_thread.h"
-
-#if defined(OS_WIN)
-#include "chrome/common/win_safe_util.h"
-#elif defined(OS_MACOSX)
-#include "chrome/browser/mac/file_metadata.h"
-#endif
-
-BaseFile::BaseFile(const FilePath& full_path,
- const GURL& source_url,
- const GURL& referrer_url,
- int64 received_bytes,
- const linked_ptr<net::FileStream>& file_stream)
- : full_path_(full_path),
- source_url_(source_url),
- referrer_url_(referrer_url),
- file_stream_(file_stream),
- bytes_so_far_(received_bytes),
- power_save_blocker_(true),
- calculate_hash_(false),
- detached_(false) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- memset(sha256_hash_, 0, sizeof(sha256_hash_));
-}
-
-BaseFile::~BaseFile() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- if (detached_)
- Close();
- else
- Cancel(); // Will delete the file.
-}
-
-bool BaseFile::Initialize(bool calculate_hash) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!detached_);
-
- calculate_hash_ = calculate_hash;
-
- if (calculate_hash_)
- secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
-
- if (!full_path_.empty() ||
- download_util::CreateTemporaryFileForDownload(&full_path_))
- return Open();
- return false;
-}
-
-bool BaseFile::AppendDataToFile(const char* data, size_t data_len) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!detached_);
-
- if (!file_stream_.get())
- return false;
-
- // TODO(phajdan.jr): get rid of this check.
- if (data_len == 0)
- return true;
-
- bytes_so_far_ += data_len;
-
- // TODO(phajdan.jr): handle errors on file writes. http://crbug.com/58355
- size_t written = file_stream_->Write(data, data_len, NULL);
- if (written != data_len)
- return false;
-
- if (calculate_hash_)
- secure_hash_->Update(data, data_len);
-
- return true;
-}
-
-bool BaseFile::Rename(const FilePath& new_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::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_) {
- // Don't close the file if we're not done (finished or canceled).
- if (!saved_in_progress)
- Close();
-
- return true;
- }
-
- Close();
-
- file_util::CreateDirectory(new_path.DirName());
-
-#if defined(OS_WIN)
- // We cannot rename because rename will keep the same security descriptor
- // on the destination file. We want to recreate the security descriptor
- // with the security that makes sense in the new path.
- if (!file_util::RenameFileAndResetSecurityDescriptor(full_path_, new_path))
- return false;
-#elif defined(OS_POSIX)
- {
- // Similarly, on Unix, we're moving a temp file created with permissions
- // 600 to |new_path|. Here, we try to fix up the destination file with
- // appropriate permissions.
- struct stat st;
- // First check the file existence and create an empty file if it doesn't
- // exist.
- if (!file_util::PathExists(new_path))
- file_util::WriteFile(new_path, "", 0);
- bool stat_succeeded = (stat(new_path.value().c_str(), &st) == 0);
-
- // TODO(estade): Move() falls back to copying and deleting when a simple
- // rename fails. Copying sucks for large downloads. crbug.com/8737
- if (!file_util::Move(full_path_, new_path))
- return false;
-
- if (stat_succeeded)
- chmod(new_path.value().c_str(), st.st_mode);
- }
-#endif
-
- full_path_ = new_path;
-
- // We don't need to re-open the file if we're done (finished or canceled).
- if (!saved_in_progress)
- return true;
-
- if (!Open())
- return false;
-
- return true;
-}
-
-void BaseFile::Detach() {
- detached_ = true;
-}
-
-void BaseFile::Cancel() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!detached_);
-
- Close();
-
- if (!full_path_.empty())
- file_util::Delete(full_path_, false);
-}
-
-void BaseFile::Finish() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- if (calculate_hash_)
- secure_hash_->Finish(sha256_hash_, kSha256HashLen);
-
- Close();
-}
-
-bool BaseFile::GetSha256Hash(std::string* hash) {
- DCHECK(!detached_);
- if (!calculate_hash_ || in_progress())
- return false;
- hash->assign(reinterpret_cast<const char*>(sha256_hash_),
- sizeof(sha256_hash_));
- return true;
-}
-
-void BaseFile::AnnotateWithSourceInformation() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!detached_);
-
-#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.
- win_util::SetInternetZoneIdentifier(full_path_,
- UTF8ToWide(source_url_.spec()));
-#elif defined(OS_MACOSX)
- file_metadata::AddQuarantineMetadataToFile(full_path_, source_url_,
- referrer_url_);
- file_metadata::AddOriginMetadataToFile(full_path_, source_url_,
- referrer_url_);
-#endif
-}
-
-bool BaseFile::Open() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!detached_);
- DCHECK(!full_path_.empty());
-
- // Create a new file stream if it is not provided.
- if (!file_stream_.get()) {
- file_stream_.reset(new net::FileStream);
- if (file_stream_->Open(full_path_,
- base::PLATFORM_FILE_OPEN_ALWAYS |
- base::PLATFORM_FILE_WRITE) != net::OK) {
- file_stream_.reset();
- return false;
- }
-
- // We may be re-opening the file after rename. Always make sure we're
- // writing at the end of the file.
- if (file_stream_->Seek(net::FROM_END, 0) < 0) {
- file_stream_.reset();
- return false;
- }
- }
-
-#if defined(OS_WIN)
- AnnotateWithSourceInformation();
-#endif
- return true;
-}
-
-void BaseFile::Close() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- if (file_stream_.get()) {
-#if defined(OS_CHROMEOS)
- // Currently we don't really care about the return value, since if it fails
- // theres not much we can do. But we might in the future.
- file_stream_->Flush();
-#endif
- file_stream_->Close();
- file_stream_.reset();
- }
-}
-
-std::string BaseFile::DebugString() const {
- return base::StringPrintf("{ source_url_ = \"%s\""
- " full_path_ = \"%" PRFilePath "\""
- " bytes_so_far_ = %" PRId64 " detached_ = %c }",
- source_url_.spec().c_str(),
- full_path_.value().c_str(),
- bytes_so_far_,
- detached_ ? 'T' : 'F');
-}
diff --git a/chrome/browser/download/base_file.h b/chrome/browser/download/base_file.h
deleted file mode 100644
index 02563b7..0000000
--- a/chrome/browser/download/base_file.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_BASE_FILE_H_
-#define CHROME_BROWSER_DOWNLOAD_BASE_FILE_H_
-#pragma once
-
-#include <string>
-
-#include "base/file_path.h"
-#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/power_save_blocker.h"
-#include "googleurl/src/gurl.h"
-
-namespace crypto {
-class SecureHash;
-}
-namespace net {
-class FileStream;
-}
-
-// File being downloaded and saved to disk. This is a base class
-// for DownloadFile and SaveFile, which keep more state information.
-class BaseFile {
- public:
- BaseFile(const FilePath& full_path,
- const GURL& source_url,
- const GURL& referrer_url,
- int64 received_bytes,
- const linked_ptr<net::FileStream>& file_stream);
- virtual ~BaseFile();
-
- // If calculate_hash is true, sha256 hash will be calculated.
- bool Initialize(bool calculate_hash);
-
- // 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);
-
- // Rename the download file. Returns true on success.
- virtual bool Rename(const FilePath& full_path);
-
- // Detach the file so it is not deleted on destruction.
- virtual void Detach();
-
- // Abort the download and automatically close the file.
- void Cancel();
-
- // 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();
-
- FilePath full_path() const { return full_path_; }
- bool in_progress() const { return file_stream_ != NULL; }
- int64 bytes_so_far() const { return bytes_so_far_; }
-
- // Set |hash| with sha256 digest for the file.
- // Returns true if digest is successfully calculated.
- virtual bool GetSha256Hash(std::string* hash);
-
- virtual std::string DebugString() const;
-
- protected:
- bool Open();
- void Close();
-
- // Full path to the file including the file name.
- FilePath full_path_;
-
- private:
- static const size_t kSha256HashLen = 32;
-
- // Source URL for the file being downloaded.
- GURL source_url_;
-
- // The URL where the download was initiated.
- GURL referrer_url_;
-
- // OS file stream for writing
- linked_ptr<net::FileStream> file_stream_;
-
- // Amount of data received up so far, in bytes.
- int64 bytes_so_far_;
-
- // RAII handle to keep the system from sleeping while we're downloading.
- PowerSaveBlocker power_save_blocker_;
-
- // Indicates if sha256 hash should be calculated for the file.
- bool calculate_hash_;
-
- // Used to calculate sha256 hash for the file when calculate_hash_
- // is set.
- scoped_ptr<crypto::SecureHash> secure_hash_;
-
- unsigned char sha256_hash_[kSha256HashLen];
-
- // Indicates that this class no longer owns the associated file, and so
- // won't delete it on destruction.
- bool detached_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseFile);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_BASE_FILE_H_
diff --git a/chrome/browser/download/base_file_unittest.cc b/chrome/browser/download/base_file_unittest.cc
deleted file mode 100644
index f8da90b..0000000
--- a/chrome/browser/download/base_file_unittest.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// 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.
-
-#include "base/file_util.h"
-#include "base/message_loop.h"
-#include "base/scoped_temp_dir.h"
-#include "base/string_number_conversions.h"
-#include "chrome/browser/download/base_file.h"
-#include "content/browser/browser_thread.h"
-#include "net/base/file_stream.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-const char kTestData1[] = "Let's write some data to the file!\n";
-const char kTestData2[] = "Writing more data.\n";
-const char kTestData3[] = "Final line.";
-
-class BaseFileTest : public testing::Test {
- public:
- BaseFileTest()
- : expect_file_survives_(false),
- file_thread_(BrowserThread::FILE, &message_loop_) {
- }
-
- virtual void SetUp() {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- base_file_.reset(
- new BaseFile(FilePath(), GURL(), GURL(), 0, file_stream_));
- }
-
- virtual void TearDown() {
- EXPECT_FALSE(base_file_->in_progress());
- EXPECT_EQ(static_cast<int64>(expected_data_.size()),
- base_file_->bytes_so_far());
-
- FilePath full_path = base_file_->full_path();
-
- if (!expected_data_.empty()) {
- // Make sure the data has been properly written to disk.
- std::string disk_data;
- EXPECT_TRUE(file_util::ReadFileToString(full_path, &disk_data));
- EXPECT_EQ(expected_data_, disk_data);
- }
-
- // Make sure the mock BrowserThread outlives the BaseFile to satisfy
- // thread checks inside it.
- base_file_.reset();
-
- EXPECT_EQ(expect_file_survives_, file_util::PathExists(full_path));
- }
-
- void AppendDataToFile(const std::string& data) {
- ASSERT_TRUE(base_file_->in_progress());
- base_file_->AppendDataToFile(data.data(), data.size());
- expected_data_ += data;
- EXPECT_EQ(static_cast<int64>(expected_data_.size()),
- base_file_->bytes_so_far());
- }
-
- protected:
- linked_ptr<net::FileStream> file_stream_;
-
- // BaseClass instance we are testing.
- scoped_ptr<BaseFile> base_file_;
-
- // Temporary directory for renamed downloads.
- ScopedTempDir temp_dir_;
-
- // Expect the file to survive deletion of the BaseFile instance.
- bool expect_file_survives_;
-
- private:
- // Keep track of what data should be saved to the disk file.
- std::string expected_data_;
-
- // Mock file thread to satisfy debug checks in BaseFile.
- MessageLoop message_loop_;
- BrowserThread file_thread_;
-};
-
-// Test the most basic scenario: just create the object and do a sanity check
-// on all its accessors. This is actually a case that rarely happens
-// in production, where we would at least Initialize it.
-TEST_F(BaseFileTest, CreateDestroy) {
- EXPECT_EQ(FilePath().value(), base_file_->full_path().value());
-}
-
-// Cancel the download explicitly.
-TEST_F(BaseFileTest, Cancel) {
- ASSERT_TRUE(base_file_->Initialize(false));
- EXPECT_TRUE(file_util::PathExists(base_file_->full_path()));
- base_file_->Cancel();
- EXPECT_FALSE(file_util::PathExists(base_file_->full_path()));
- EXPECT_NE(FilePath().value(), base_file_->full_path().value());
-}
-
-// Write data to the file and detach it, so it doesn't get deleted
-// automatically when base_file_ is destructed.
-TEST_F(BaseFileTest, WriteAndDetach) {
- ASSERT_TRUE(base_file_->Initialize(false));
- AppendDataToFile(kTestData1);
- base_file_->Finish();
- base_file_->Detach();
- expect_file_survives_ = true;
-}
-
-// Write data to the file and detach it, and calculate its sha256 hash.
-TEST_F(BaseFileTest, WriteWithHashAndDetach) {
- ASSERT_TRUE(base_file_->Initialize(true));
- AppendDataToFile(kTestData1);
- base_file_->Finish();
-
- std::string hash;
- base_file_->GetSha256Hash(&hash);
- EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
- base::HexEncode(hash.data(), hash.size()));
-
- base_file_->Detach();
- expect_file_survives_ = true;
-}
-
-// Rename the file after writing to it, then detach.
-TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
- ASSERT_TRUE(base_file_->Initialize(false));
-
- FilePath initial_path(base_file_->full_path());
- EXPECT_TRUE(file_util::PathExists(initial_path));
- FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
- EXPECT_FALSE(file_util::PathExists(new_path));
-
- AppendDataToFile(kTestData1);
-
- EXPECT_TRUE(base_file_->Rename(new_path));
- EXPECT_FALSE(file_util::PathExists(initial_path));
- EXPECT_TRUE(file_util::PathExists(new_path));
-
- base_file_->Finish();
- base_file_->Detach();
- expect_file_survives_ = true;
-}
-
-// Write data to the file once.
-TEST_F(BaseFileTest, SingleWrite) {
- ASSERT_TRUE(base_file_->Initialize(false));
- AppendDataToFile(kTestData1);
- base_file_->Finish();
-}
-
-// Write data to the file multiple times.
-TEST_F(BaseFileTest, MultipleWrites) {
- ASSERT_TRUE(base_file_->Initialize(false));
- AppendDataToFile(kTestData1);
- AppendDataToFile(kTestData2);
- AppendDataToFile(kTestData3);
- std::string hash;
- EXPECT_FALSE(base_file_->GetSha256Hash(&hash));
- base_file_->Finish();
-}
-
-// Write data to the file once and calculate its sha256 hash.
-TEST_F(BaseFileTest, SingleWriteWithHash) {
- ASSERT_TRUE(base_file_->Initialize(true));
- AppendDataToFile(kTestData1);
- base_file_->Finish();
-
- std::string hash;
- base_file_->GetSha256Hash(&hash);
- EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
- base::HexEncode(hash.data(), hash.size()));
-}
-
-// Write data to the file multiple times and calculate its sha256 hash.
-TEST_F(BaseFileTest, MultipleWritesWithHash) {
- std::string hash;
-
- ASSERT_TRUE(base_file_->Initialize(true));
- AppendDataToFile(kTestData1);
- AppendDataToFile(kTestData2);
- AppendDataToFile(kTestData3);
- // no hash before Finish() is called either.
- EXPECT_FALSE(base_file_->GetSha256Hash(&hash));
- base_file_->Finish();
-
- EXPECT_TRUE(base_file_->GetSha256Hash(&hash));
- EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8",
- base::HexEncode(hash.data(), hash.size()));
-}
-
-// Rename the file after all writes to it.
-TEST_F(BaseFileTest, WriteThenRename) {
- ASSERT_TRUE(base_file_->Initialize(false));
-
- FilePath initial_path(base_file_->full_path());
- EXPECT_TRUE(file_util::PathExists(initial_path));
- FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
- EXPECT_FALSE(file_util::PathExists(new_path));
-
- AppendDataToFile(kTestData1);
-
- EXPECT_TRUE(base_file_->Rename(new_path));
- EXPECT_FALSE(file_util::PathExists(initial_path));
- EXPECT_TRUE(file_util::PathExists(new_path));
-
- base_file_->Finish();
-}
-
-// Rename the file while the download is still in progress.
-TEST_F(BaseFileTest, RenameWhileInProgress) {
- ASSERT_TRUE(base_file_->Initialize(false));
-
- FilePath initial_path(base_file_->full_path());
- EXPECT_TRUE(file_util::PathExists(initial_path));
- FilePath new_path(temp_dir_.path().AppendASCII("NewFile"));
- EXPECT_FALSE(file_util::PathExists(new_path));
-
- AppendDataToFile(kTestData1);
-
- EXPECT_TRUE(base_file_->in_progress());
- EXPECT_TRUE(base_file_->Rename(new_path));
- EXPECT_FALSE(file_util::PathExists(initial_path));
- EXPECT_TRUE(file_util::PathExists(new_path));
-
- AppendDataToFile(kTestData2);
-
- base_file_->Finish();
-}
-
-} // namespace
diff --git a/chrome/browser/download/download_file.h b/chrome/browser/download/download_file.h
index 4fa3bfc..b94f9aa 100644
--- a/chrome/browser/download/download_file.h
+++ b/chrome/browser/download/download_file.h
@@ -10,9 +10,9 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
-#include "chrome/browser/download/base_file.h"
#include "chrome/browser/download/download_request_handle.h"
#include "chrome/browser/download/download_types.h"
+#include "content/browser/download/base_file.h"
struct DownloadCreateInfo;
class DownloadManager;
diff --git a/chrome/browser/download/download_item_model.cc b/chrome/browser/download/download_item_model.cc
index f37cb1f..5c8e793 100644
--- a/chrome/browser/download/download_item_model.cc
+++ b/chrome/browser/download/download_item_model.cc
@@ -9,8 +9,8 @@
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/download/download_item.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/common/time_format.h"
+#include "content/browser/download/save_package.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/text/bytes_formatting.h"
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc
index e9e0b76..01202d8 100644
--- a/chrome/browser/download/download_prefs.cc
+++ b/chrome/browser/download/download_prefs.cc
@@ -12,10 +12,10 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/download/download_extensions.h"
#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/pref_names.h"
#include "content/browser/browser_thread.h"
+#include "content/browser/download/save_package.h"
DownloadPrefs::DownloadPrefs(PrefService* prefs) : prefs_(prefs) {
prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL);
diff --git a/chrome/browser/download/save_file.cc b/chrome/browser/download/save_file.cc
deleted file mode 100644
index 4c53c2d..0000000
--- a/chrome/browser/download/save_file.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/download/save_file.h"
-
-#include "base/logging.h"
-#include "content/browser/browser_thread.h"
-#include "net/base/file_stream.h"
-
-SaveFile::SaveFile(const SaveFileCreateInfo* info)
- : BaseFile(FilePath(), info->url, GURL(), 0, linked_ptr<net::FileStream>()),
- info_(info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- DCHECK(info);
- DCHECK(info->path.empty());
-}
-
-SaveFile::~SaveFile() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-}
diff --git a/chrome/browser/download/save_file.h b/chrome/browser/download/save_file.h
deleted file mode 100644
index fc610f7..0000000
--- a/chrome/browser/download/save_file.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_FILE_H_
-#define CHROME_BROWSER_DOWNLOAD_SAVE_FILE_H_
-#pragma once
-
-#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "base/memory/scoped_ptr.h"
-#include "chrome/browser/download/base_file.h"
-#include "chrome/browser/download/save_types.h"
-
-// SaveFile ----------------------------------------------------------------
-
-// These objects live exclusively on the file thread and handle the writing
-// operations for one save item. These objects live only for the duration that
-// the saving job is 'in progress': once the saving job has been completed or
-// canceled, the SaveFile is destroyed. One SaveFile object represents one item
-// in a save session.
-class SaveFile : public BaseFile {
- public:
- explicit SaveFile(const SaveFileCreateInfo* info);
- virtual ~SaveFile();
-
- // Accessors.
- int save_id() const { return info_->save_id; }
- int render_process_id() const { return info_->render_process_id; }
- int render_view_id() const { return info_->render_view_id; }
- int request_id() const { return info_->request_id; }
- SaveFileCreateInfo::SaveFileSource save_source() const {
- return info_->save_source;
- }
-
- private:
- scoped_ptr<const SaveFileCreateInfo> info_;
-
- DISALLOW_COPY_AND_ASSIGN(SaveFile);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_SAVE_FILE_H_
diff --git a/chrome/browser/download/save_file_manager.cc b/chrome/browser/download/save_file_manager.cc
deleted file mode 100644
index d5df502..0000000
--- a/chrome/browser/download/save_file_manager.cc
+++ /dev/null
@@ -1,541 +0,0 @@
-// 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.
-
-#include "build/build_config.h"
-
-#include "chrome/browser/download/save_file_manager.h"
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/stl_util-inl.h"
-#include "base/string_util.h"
-#include "base/task.h"
-#include "base/threading/thread.h"
-#include "chrome/browser/download/save_file.h"
-#include "chrome/browser/download/save_package.h"
-#include "chrome/browser/platform_util.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/ui/download/download_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
-#include "chrome/common/chrome_paths.h"
-#include "content/browser/browser_thread.h"
-#include "content/browser/renderer_host/resource_dispatcher_host.h"
-#include "content/browser/tab_contents/tab_contents.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/net_util.h"
-#include "net/base/io_buffer.h"
-
-SaveFileManager::SaveFileManager(ResourceDispatcherHost* rdh)
- : next_id_(0),
- resource_dispatcher_host_(rdh) {
- DCHECK(resource_dispatcher_host_);
-}
-
-SaveFileManager::~SaveFileManager() {
- // Check for clean shutdown.
- DCHECK(save_file_map_.empty());
-}
-
-// Called during the browser shutdown process to clean up any state (open files,
-// timers) that live on the saving thread (file thread).
-void SaveFileManager::Shutdown() {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &SaveFileManager::OnShutdown));
-}
-
-// Stop file thread operations.
-void SaveFileManager::OnShutdown() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- STLDeleteValues(&save_file_map_);
-}
-
-SaveFile* SaveFileManager::LookupSaveFile(int save_id) {
- SaveFileMap::iterator it = save_file_map_.find(save_id);
- return it == save_file_map_.end() ? NULL : it->second;
-}
-
-// Called on the IO thread when
-// a) The ResourceDispatcherHost has decided that a request is savable.
-// b) The resource does not come from the network, but we still need a
-// save ID for for managing the status of the saving operation. So we
-// file a request from the file thread to the IO thread to generate a
-// unique save ID.
-int SaveFileManager::GetNextId() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- return next_id_++;
-}
-
-void SaveFileManager::RegisterStartingRequest(const GURL& save_url,
- SavePackage* save_package) {
- // Make sure it runs in the UI thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- int tab_id = save_package->tab_id();
-
- // Register this starting request.
- StartingRequestsMap& starting_requests = tab_starting_requests_[tab_id];
- bool never_present = starting_requests.insert(
- StartingRequestsMap::value_type(save_url.spec(), save_package)).second;
- DCHECK(never_present);
-}
-
-SavePackage* SaveFileManager::UnregisterStartingRequest(
- const GURL& save_url, int tab_id) {
- // Make sure it runs in UI thread.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- TabToStartingRequestsMap::iterator it = tab_starting_requests_.find(tab_id);
- if (it != tab_starting_requests_.end()) {
- StartingRequestsMap& requests = it->second;
- StartingRequestsMap::iterator sit = requests.find(save_url.spec());
- if (sit == requests.end())
- return NULL;
-
- // Found, erase it from starting list and return SavePackage.
- SavePackage* save_package = sit->second;
- requests.erase(sit);
- // If there is no element in requests, remove it
- if (requests.empty())
- tab_starting_requests_.erase(it);
- return save_package;
- }
-
- return NULL;
-}
-
-// Look up a SavePackage according to a save id.
-SavePackage* SaveFileManager::LookupPackage(int save_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- SavePackageMap::iterator it = packages_.find(save_id);
- if (it != packages_.end())
- return it->second;
- return NULL;
-}
-
-// Call from SavePackage for starting a saving job
-void SaveFileManager::SaveURL(
- const GURL& url,
- const GURL& referrer,
- int render_process_host_id,
- int render_view_id,
- SaveFileCreateInfo::SaveFileSource save_source,
- const FilePath& file_full_path,
- const content::ResourceContext& context,
- SavePackage* save_package) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- // Register a saving job.
- RegisterStartingRequest(url, save_package);
- if (save_source == SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
- DCHECK(url.is_valid());
-
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(this,
- &SaveFileManager::OnSaveURL,
- url,
- referrer,
- render_process_host_id,
- render_view_id,
- &context));
- } else {
- // We manually start the save job.
- SaveFileCreateInfo* info = new SaveFileCreateInfo(file_full_path,
- url,
- save_source,
- -1);
- info->render_process_id = render_process_host_id;
- info->render_view_id = render_view_id;
-
- // Since the data will come from render process, so we need to start
- // this kind of save job by ourself.
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnRequireSaveJobFromOtherSource, info));
- }
-}
-
-// Utility function for look up table maintenance, called on the UI thread.
-// A manager may have multiple save page job (SavePackage) in progress,
-// so we just look up the save id and remove it from the tracking table.
-// If the save id is -1, it means we just send a request to save, but the
-// saving action has still not happened, need to call UnregisterStartingRequest
-// to remove it from the tracking map.
-void SaveFileManager::RemoveSaveFile(int save_id, const GURL& save_url,
- SavePackage* package) {
- DCHECK(package);
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // A save page job (SavePackage) can only have one manager,
- // so remove it if it exists.
- if (save_id == -1) {
- SavePackage* old_package = UnregisterStartingRequest(save_url,
- package->tab_id());
- DCHECK_EQ(old_package, package);
- } else {
- SavePackageMap::iterator it = packages_.find(save_id);
- if (it != packages_.end())
- packages_.erase(it);
- }
-}
-
-// Static
-// Utility function for converting request IDs to a TabContents. Must be called
-// only on the UI thread.
-SavePackage* SaveFileManager::GetSavePackageFromRenderIds(
- int render_process_id, int render_view_id) {
- TabContents* contents = tab_util::GetTabContentsByID(render_process_id,
- render_view_id);
- if (contents) {
- TabContentsWrapper* wrapper =
- TabContentsWrapper::GetCurrentWrapperForContents(contents);
- return wrapper->download_tab_helper()->save_package();
- }
-
- return NULL;
-}
-
-// Utility function for deleting specified file.
-void SaveFileManager::DeleteDirectoryOrFile(const FilePath& full_path,
- bool is_dir) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnDeleteDirectoryOrFile, full_path, is_dir));
-}
-
-void SaveFileManager::SendCancelRequest(int save_id) {
- // Cancel the request which has specific save id.
- DCHECK_GT(save_id, -1);
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &SaveFileManager::CancelSave, save_id));
-}
-
-// Notifications sent from the IO thread and run on the file thread:
-
-// The IO thread created |info|, but the file thread (this method) uses it
-// to create a SaveFile which will hold and finally destroy |info|. It will
-// then passes |info| to the UI thread for reporting saving status.
-void SaveFileManager::StartSave(SaveFileCreateInfo* info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(info);
- SaveFile* save_file = new SaveFile(info);
-
- // TODO(phajdan.jr): We should check the return value and handle errors here.
- save_file->Initialize(false); // No need to calculate hash.
-
- DCHECK(!LookupSaveFile(info->save_id));
- save_file_map_[info->save_id] = save_file;
- info->path = save_file->full_path();
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &SaveFileManager::OnStartSave, info));
-}
-
-// We do forward an update to the UI thread here, since we do not use timer to
-// update the UI. If the user has canceled the saving action (in the UI
-// thread). We may receive a few more updates before the IO thread gets the
-// cancel message. We just delete the data since the SaveFile has been deleted.
-void SaveFileManager::UpdateSaveProgress(int save_id,
- net::IOBuffer* data,
- int data_len) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- SaveFile* save_file = LookupSaveFile(save_id);
- if (save_file) {
- bool write_success = save_file->AppendDataToFile(data->data(), data_len);
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnUpdateSaveProgress, save_file->save_id(),
- save_file->bytes_so_far(), write_success));
- }
-}
-
-// The IO thread will call this when saving is completed or it got error when
-// fetching data. In the former case, we forward the message to OnSaveFinished
-// in UI thread. In the latter case, the save ID will be -1, which means the
-// saving action did not even start, so we need to call OnErrorFinished in UI
-// thread, which will use the save URL to find corresponding request record and
-// delete it.
-void SaveFileManager::SaveFinished(int save_id,
- const GURL& save_url,
- int render_process_id,
- bool is_success) {
- VLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << save_id
- << " save_url = \"" << save_url.spec() << "\""
- << " is_success = " << is_success;
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- SaveFileMap::iterator it = save_file_map_.find(save_id);
- if (it != save_file_map_.end()) {
- SaveFile* save_file = it->second;
- VLOG(20) << " " << __FUNCTION__ << "()"
- << " save_file = " << save_file->DebugString();
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnSaveFinished, save_id,
- save_file->bytes_so_far(), is_success));
-
- save_file->Finish();
- save_file->Detach();
- } else if (save_id == -1) {
- // Before saving started, we got error. We still call finish process.
- DCHECK(!save_url.is_empty());
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnErrorFinished, save_url,
- render_process_id));
- }
-}
-
-// Notifications sent from the file thread and run on the UI thread.
-
-void SaveFileManager::OnStartSave(const SaveFileCreateInfo* info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- SavePackage* save_package =
- GetSavePackageFromRenderIds(info->render_process_id,
- info->render_view_id);
- if (!save_package) {
- // Cancel this request.
- SendCancelRequest(info->save_id);
- return;
- }
-
- // Insert started saving job to tracking list.
- SavePackageMap::iterator sit = packages_.find(info->save_id);
- if (sit == packages_.end()) {
- // Find the registered request. If we can not find, it means we have
- // canceled the job before.
- SavePackage* old_save_package = UnregisterStartingRequest(info->url,
- info->render_process_id);
- if (!old_save_package) {
- // Cancel this request.
- SendCancelRequest(info->save_id);
- return;
- }
- DCHECK_EQ(old_save_package, save_package);
- packages_[info->save_id] = save_package;
- } else {
- NOTREACHED();
- }
-
- // Forward this message to SavePackage.
- save_package->StartSave(info);
-}
-
-void SaveFileManager::OnUpdateSaveProgress(int save_id, int64 bytes_so_far,
- bool write_success) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- SavePackage* package = LookupPackage(save_id);
- if (package)
- package->UpdateSaveProgress(save_id, bytes_so_far, write_success);
- else
- SendCancelRequest(save_id);
-}
-
-void SaveFileManager::OnSaveFinished(int save_id,
- int64 bytes_so_far,
- bool is_success) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- SavePackage* package = LookupPackage(save_id);
- if (package)
- package->SaveFinished(save_id, bytes_so_far, is_success);
-}
-
-void SaveFileManager::OnErrorFinished(const GURL& save_url, int tab_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- SavePackage* save_package = UnregisterStartingRequest(save_url, tab_id);
- if (save_package)
- save_package->SaveFailed(save_url);
-}
-
-// Notifications sent from the UI thread and run on the IO thread.
-
-void SaveFileManager::OnSaveURL(
- const GURL& url,
- const GURL& referrer,
- int render_process_host_id,
- int render_view_id,
- const content::ResourceContext* context) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- resource_dispatcher_host_->BeginSaveFile(url,
- referrer,
- render_process_host_id,
- render_view_id,
- *context);
-}
-
-void SaveFileManager::OnRequireSaveJobFromOtherSource(
- SaveFileCreateInfo* info) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK_EQ(info->save_id, -1);
- // Generate a unique save id.
- info->save_id = GetNextId();
- // Start real saving action.
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &SaveFileManager::StartSave, info));
-}
-
-void SaveFileManager::ExecuteCancelSaveRequest(int render_process_id,
- int request_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- resource_dispatcher_host_->CancelRequest(render_process_id,
- request_id,
- false);
-}
-
-// Notifications sent from the UI thread and run on the file thread.
-
-// This method will be sent via a user action, or shutdown on the UI thread,
-// and run on the file thread. We don't post a message back for cancels,
-// but we do forward the cancel to the IO thread. Since this message has been
-// sent from the UI thread, the saving job may have already completed and
-// won't exist in our map.
-void SaveFileManager::CancelSave(int save_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- SaveFileMap::iterator it = save_file_map_.find(save_id);
- if (it != save_file_map_.end()) {
- SaveFile* save_file = it->second;
-
- // If the data comes from the net IO thread, then forward the cancel
- // message to IO thread. If the data comes from other sources, just
- // ignore the cancel message.
- if (save_file->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::ExecuteCancelSaveRequest,
- save_file->render_process_id(), save_file->request_id()));
-
- // UI thread will notify the render process to stop sending data,
- // so in here, we need not to do anything, just close the save file.
- save_file->Cancel();
- } else {
- // If we did not find SaveFile in map, the saving job should either get
- // data from other sources or have finished.
- DCHECK(save_file->save_source() !=
- SaveFileCreateInfo::SAVE_FILE_FROM_NET ||
- !save_file->in_progress());
- }
- // Whatever the save file is renamed or not, just delete it.
- save_file_map_.erase(it);
- delete save_file;
- }
-}
-
-// It is possible that SaveItem which has specified save_id has been canceled
-// before this function runs. So if we can not find corresponding SaveFile by
-// using specified save_id, just return.
-void SaveFileManager::SaveLocalFile(const GURL& original_file_url,
- int save_id,
- int render_process_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- SaveFile* save_file = LookupSaveFile(save_id);
- if (!save_file)
- return;
- // If it has finished, just return.
- if (!save_file->in_progress())
- return;
-
- // Close the save file before the copy operation.
- save_file->Finish();
- save_file->Detach();
-
- DCHECK(original_file_url.SchemeIsFile());
- FilePath file_path;
- net::FileURLToFilePath(original_file_url, &file_path);
- // If we can not get valid file path from original URL, treat it as
- // disk error.
- if (file_path.empty())
- SaveFinished(save_id, original_file_url, render_process_id, false);
-
- // Copy the local file to the temporary file. It will be renamed to its
- // final name later.
- bool success = file_util::CopyFile(file_path, save_file->full_path());
- if (!success)
- file_util::Delete(save_file->full_path(), false);
- SaveFinished(save_id, original_file_url, render_process_id, success);
-}
-
-void SaveFileManager::OnDeleteDirectoryOrFile(const FilePath& full_path,
- bool is_dir) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- DCHECK(!full_path.empty());
-
- file_util::Delete(full_path, is_dir);
-}
-
-// Open a saved page package, show it in a Windows Explorer window.
-// We run on this thread to avoid blocking the UI with slow Shell operations.
-#if !defined(OS_MACOSX)
-void SaveFileManager::OnShowSavedFileInShell(const FilePath full_path) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- platform_util::ShowItemInFolder(full_path);
-}
-#endif
-
-void SaveFileManager::RenameAllFiles(
- const FinalNameList& final_names,
- const FilePath& resource_dir,
- int render_process_id,
- int render_view_id,
- int save_package_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- if (!resource_dir.empty() && !file_util::PathExists(resource_dir))
- file_util::CreateDirectory(resource_dir);
-
- for (FinalNameList::const_iterator i = final_names.begin();
- i != final_names.end(); ++i) {
- SaveFileMap::iterator it = save_file_map_.find(i->first);
- if (it != save_file_map_.end()) {
- SaveFile* save_file = it->second;
- DCHECK(!save_file->in_progress());
- save_file->Rename(i->second);
- delete save_file;
- save_file_map_.erase(it);
- }
- }
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(
- this, &SaveFileManager::OnFinishSavePageJob, render_process_id,
- render_view_id, save_package_id));
-}
-
-void SaveFileManager::OnFinishSavePageJob(int render_process_id,
- int render_view_id,
- int save_package_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- SavePackage* save_package =
- GetSavePackageFromRenderIds(render_process_id, render_view_id);
-
- if (save_package && save_package->id() == save_package_id)
- save_package->Finish();
-}
-
-void SaveFileManager::RemoveSavedFileFromFileMap(
- const SaveIDList& save_ids) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
- for (SaveIDList::const_iterator i = save_ids.begin();
- i != save_ids.end(); ++i) {
- SaveFileMap::iterator it = save_file_map_.find(*i);
- if (it != save_file_map_.end()) {
- SaveFile* save_file = it->second;
- DCHECK(!save_file->in_progress());
- file_util::Delete(save_file->full_path(), false);
- delete save_file;
- save_file_map_.erase(it);
- }
- }
-}
diff --git a/chrome/browser/download/save_file_manager.h b/chrome/browser/download/save_file_manager.h
deleted file mode 100644
index 60a831c..0000000
--- a/chrome/browser/download/save_file_manager.h
+++ /dev/null
@@ -1,255 +0,0 @@
-// 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.
-//
-// Objects that handle file operations for saving files, on the file thread.
-//
-// The SaveFileManager owns a set of SaveFile objects, each of which connects
-// with a SaveItem object which belongs to one SavePackage and runs on the file
-// thread for saving data in order to avoid disk activity on either network IO
-// thread or the UI thread. It coordinates the notifications from the network
-// and UI.
-//
-// The SaveFileManager itself is a singleton object owned by the
-// ResourceDispatcherHost.
-//
-// The data sent to SaveFileManager have 2 sources, one is from
-// ResourceDispatcherHost, run in network IO thread, the all sub-resources
-// and save-only-HTML pages will be got from network IO. The second is from
-// render process, those html pages which are serialized from DOM will be
-// composed in render process and encoded to its original encoding, then sent
-// to UI loop in browser process, then UI loop will dispatch the data to
-// SaveFileManager on the file thread. SaveFileManager will directly
-// call SaveFile's method to persist data.
-//
-// A typical saving job operation involves multiple threads:
-//
-// Updating an in progress save file
-// io_thread
-// |----> data from net ---->|
-// |
-// |
-// |----> data from ---->| |
-// | render process | |
-// ui_thread | |
-// file_thread (writes to disk)
-// |----> stats ---->|
-// ui_thread (feedback for user)
-//
-//
-// Cancel operations perform the inverse order when triggered by a user action:
-// ui_thread (user click)
-// |----> cancel command ---->|
-// | | file_thread (close file)
-// | |---------------------> cancel command ---->|
-// | io_thread (stops net IO
-// ui_thread (user close tab) for saving)
-// |----> cancel command ---->|
-// Render process(stop serializing DOM and sending
-// data)
-//
-//
-// The SaveFileManager tracks saving requests, mapping from a save ID
-// (unique integer created in the IO thread) to the SavePackage for the
-// tab where the saving job was initiated. In the event of a tab closure
-// during saving, the SavePackage will notice the SaveFileManage to
-// cancel all SaveFile job.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H__
-#define CHROME_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H__
-#pragma once
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/hash_tables.h"
-#include "base/memory/ref_counted.h"
-#include "chrome/browser/download/save_types.h"
-
-class FilePath;
-class GURL;
-class SaveFile;
-class SavePackage;
-class ResourceDispatcherHost;
-class Task;
-
-namespace content {
-class ResourceContext;
-}
-
-namespace net {
-class IOBuffer;
-}
-
-class SaveFileManager
- : public base::RefCountedThreadSafe<SaveFileManager> {
- public:
- explicit SaveFileManager(ResourceDispatcherHost* rdh);
-
- // Lifetime management.
- void Shutdown();
-
- // Called on the IO thread
- int GetNextId();
-
- // Save the specified URL. Called on the UI thread and forwarded to the
- // ResourceDispatcherHost on the IO thread.
- void SaveURL(const GURL& url,
- const GURL& referrer,
- int render_process_host_id,
- int render_view_id,
- SaveFileCreateInfo::SaveFileSource save_source,
- const FilePath& file_full_path,
- const content::ResourceContext& context,
- SavePackage* save_package);
-
- // Notifications sent from the IO thread and run on the file thread:
- void StartSave(SaveFileCreateInfo* info);
- void UpdateSaveProgress(int save_id, net::IOBuffer* data, int size);
- void SaveFinished(int save_id,
- const GURL& save_url,
- int render_process_id,
- bool is_success);
-
- // Notifications sent from the UI thread and run on the file thread.
- // Cancel a SaveFile instance which has specified save id.
- void CancelSave(int save_id);
-
- // Called on the UI thread to remove a save package from SaveFileManager's
- // tracking map.
- void RemoveSaveFile(int save_id, const GURL& save_url,
- SavePackage* package);
-
-#if !defined(OS_MACOSX)
- // Handler for shell operations sent from the UI to the file thread. Mac OS X
- // requires opening downloads on the UI thread, so it does not use this
- // method.
- void OnShowSavedFileInShell(const FilePath full_path);
-#endif
-
- // Helper function for deleting specified file.
- void DeleteDirectoryOrFile(const FilePath& full_path, bool is_dir);
-
- // Runs on file thread to save a file by copying from file system when
- // original url is using file scheme.
- void SaveLocalFile(const GURL& original_file_url,
- int save_id,
- int render_process_id);
-
- // Renames all the successfully saved files.
- // |final_names| points to a vector which contains pairs of save ids and
- // final names of successfully saved files.
- void RenameAllFiles(
- const FinalNameList& final_names,
- const FilePath& resource_dir,
- int render_process_id,
- int render_view_id,
- int save_package_id);
-
- // When the user cancels the saving, we need to remove all remaining saved
- // files of this page saving job from save_file_map_.
- void RemoveSavedFileFromFileMap(const SaveIDList & save_ids);
-
- private:
- friend class base::RefCountedThreadSafe<SaveFileManager>;
-
- ~SaveFileManager();
-
- // A cleanup helper that runs on the file thread.
- void OnShutdown();
-
- // Called only on UI thread to get the SavePackage for a tab's profile.
- static SavePackage* GetSavePackageFromRenderIds(int render_process_id,
- int review_view_id);
-
- // Register a starting request. Associate the save URL with a
- // SavePackage for further matching.
- void RegisterStartingRequest(const GURL& save_url,
- SavePackage* save_package);
- // Unregister a start request according save URL, disassociate
- // the save URL and SavePackage.
- SavePackage* UnregisterStartingRequest(const GURL& save_url,
- int tab_id);
-
- // Look up the SavePackage according to save id.
- SavePackage* LookupPackage(int save_id);
-
- // Called only on the file thread.
- // Look up one in-progress saving item according to save id.
- SaveFile* LookupSaveFile(int save_id);
-
- // Help function for sending notification of canceling specific request.
- void SendCancelRequest(int save_id);
-
- // Notifications sent from the file thread and run on the UI thread.
-
- // Lookup the SaveManager for this TabContents' saving profile and inform it
- // the saving job has been started.
- void OnStartSave(const SaveFileCreateInfo* info);
- // Update the SavePackage with the current state of a started saving job.
- // If the SavePackage for this saving job is gone, cancel the request.
- void OnUpdateSaveProgress(int save_id,
- int64 bytes_so_far,
- bool write_success);
- // Update the SavePackage with the finish state, and remove the request
- // tracking entries.
- void OnSaveFinished(int save_id, int64 bytes_so_far, bool is_success);
- // For those requests that do not have valid save id, use
- // map:(url, SavePackage) to find the request and remove it.
- void OnErrorFinished(const GURL& save_url, int tab_id);
- // Notifies SavePackage that the whole page saving job is finished.
- void OnFinishSavePageJob(int render_process_id,
- int render_view_id,
- int save_package_id);
-
- // Notifications sent from the UI thread and run on the file thread.
-
- // Deletes a specified file on the file thread.
- void OnDeleteDirectoryOrFile(const FilePath& full_path, bool is_dir);
-
- // Notifications sent from the UI thread and run on the IO thread
-
- // Initiates a request for URL to be saved.
- void OnSaveURL(const GURL& url,
- const GURL& referrer,
- int render_process_host_id,
- int render_view_id,
- const content::ResourceContext* context);
- // Handler for a notification sent to the IO thread for generating save id.
- void OnRequireSaveJobFromOtherSource(SaveFileCreateInfo* info);
- // Call ResourceDispatcherHost's CancelRequest method to execute cancel
- // action in the IO thread.
- void ExecuteCancelSaveRequest(int render_process_id, int request_id);
-
- // Unique ID for the next SaveFile object.
- int next_id_;
-
- // A map of all saving jobs by using save id.
- typedef base::hash_map<int, SaveFile*> SaveFileMap;
- SaveFileMap save_file_map_;
-
- ResourceDispatcherHost* resource_dispatcher_host_;
-
- // Tracks which SavePackage to send data to, called only on UI thread.
- // SavePackageMap maps save IDs to their SavePackage.
- typedef base::hash_map<int, SavePackage*> SavePackageMap;
- SavePackageMap packages_;
-
- // There is a gap between after calling SaveURL() and before calling
- // StartSave(). In this gap, each request does not have save id for tracking.
- // But sometimes users might want to stop saving job or ResourceDispatcherHost
- // calls SaveFinished with save id -1 for network error. We name the requests
- // as starting requests. For tracking those starting requests, we need to
- // have some data structure.
- // First we use a hashmap to map the request URL to SavePackage, then we
- // use a hashmap to map the tab id (we actually use render_process_id) to the
- // hashmap since it is possible to save same URL in different tab at
- // same time.
- typedef base::hash_map<std::string, SavePackage*> StartingRequestsMap;
- typedef base::hash_map<int, StartingRequestsMap> TabToStartingRequestsMap;
- TabToStartingRequestsMap tab_starting_requests_;
-
- DISALLOW_COPY_AND_ASSIGN(SaveFileManager);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_SAVE_FILE_MANAGER_H__
diff --git a/chrome/browser/download/save_item.cc b/chrome/browser/download/save_item.cc
deleted file mode 100644
index adb60b3..0000000
--- a/chrome/browser/download/save_item.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2006-2008 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.
-
-#include "chrome/browser/download/save_item.h"
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/string_util.h"
-#include "chrome/browser/download/save_file.h"
-#include "chrome/browser/download/save_file_manager.h"
-#include "chrome/browser/download/save_package.h"
-
-// Constructor for SaveItem when creating each saving job.
-SaveItem::SaveItem(const GURL& url,
- const GURL& referrer,
- SavePackage* package,
- SaveFileCreateInfo::SaveFileSource save_source)
- : save_id_(-1),
- url_(url),
- referrer_(referrer),
- total_bytes_(0),
- received_bytes_(0),
- state_(WAIT_START),
- has_final_name_(false),
- is_success_(false),
- save_source_(save_source),
- package_(package) {
- DCHECK(package);
-}
-
-SaveItem::~SaveItem() {
-}
-
-// Set start state for save item.
-void SaveItem::Start() {
- DCHECK(state_ == WAIT_START);
- state_ = IN_PROGRESS;
-}
-
-// If we've received more data than we were expecting (bad server info?),
-// revert to 'unknown size mode'.
-void SaveItem::UpdateSize(int64 bytes_so_far) {
- received_bytes_ = bytes_so_far;
- if (received_bytes_ >= total_bytes_)
- total_bytes_ = 0;
-}
-
-// Updates from the file thread may have been posted while this saving job
-// was being canceled in the UI thread, so we'll accept them unless we're
-// complete.
-void SaveItem::Update(int64 bytes_so_far) {
- if (state_ != IN_PROGRESS) {
- NOTREACHED();
- return;
- }
- UpdateSize(bytes_so_far);
-}
-
-// Cancel this saving item job. If the job is not in progress, ignore
-// this command. The SavePackage will each in-progress SaveItem's cancel
-// when canceling whole saving page job.
-void SaveItem::Cancel() {
- // If item is in WAIT_START mode, which means no request has been sent.
- // So we need not to cancel it.
- if (state_ != IN_PROGRESS) {
- // Small downloads might be complete before method has a chance to run.
- return;
- }
- state_ = CANCELED;
- is_success_ = false;
- Finish(received_bytes_, false);
- package_->SaveCanceled(this);
-}
-
-// Set finish state for a save item
-void SaveItem::Finish(int64 size, bool is_success) {
- // When this function is called, the SaveItem should be one of following
- // three situations.
- // a) The data of this SaveItem is finished saving. So it should have
- // generated final name.
- // b) Error happened before the start of saving process. So no |save_id_| is
- // generated for this SaveItem and the |is_success_| should be false.
- // c) Error happened in the start of saving process, the SaveItem has a save
- // id, |is_success_| should be false, and the |size| should be 0.
- DCHECK(has_final_name() || (save_id_ == -1 && !is_success_) ||
- (save_id_ != -1 && !is_success_ && !size));
- state_ = COMPLETE;
- is_success_ = is_success;
- UpdateSize(size);
-}
-
-// Calculate the percentage of the save item
-int SaveItem::PercentComplete() const {
- switch (state_) {
- case COMPLETE:
- case CANCELED:
- return 100;
- case WAIT_START:
- return 0;
- case IN_PROGRESS: {
- int percent = 0;
- if (total_bytes_ > 0)
- percent = static_cast<int>(received_bytes_ * 100.0 / total_bytes_);
- return percent;
- }
- default: {
- NOTREACHED();
- return -1;
- }
- }
-}
-
-// Rename the save item with new path.
-void SaveItem::Rename(const FilePath& full_path) {
- DCHECK(!full_path.empty() && !has_final_name());
- full_path_ = full_path;
- file_name_ = full_path_.BaseName();
- has_final_name_ = true;
-}
-
-void SaveItem::SetSaveId(int32 save_id) {
- DCHECK(save_id_ == -1);
- save_id_ = save_id;
-}
-
-void SaveItem::SetTotalBytes(int64 total_bytes) {
- DCHECK(total_bytes_ == 0);
- total_bytes_ = total_bytes;
-}
diff --git a/chrome/browser/download/save_item.h b/chrome/browser/download/save_item.h
deleted file mode 100644
index 724441a..0000000
--- a/chrome/browser/download/save_item.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2010 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.
-//
-#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_ITEM_H__
-#define CHROME_BROWSER_DOWNLOAD_SAVE_ITEM_H__
-#pragma once
-
-#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "chrome/browser/download/save_types.h"
-#include "googleurl/src/gurl.h"
-
-class SavePackage;
-
-// One SaveItem per save file. This is the model class that stores all the
-// state for one save file.
-class SaveItem {
- public:
- enum SaveState {
- WAIT_START,
- IN_PROGRESS,
- COMPLETE,
- CANCELED
- };
-
- SaveItem(const GURL& url,
- const GURL& referrer,
- SavePackage* package,
- SaveFileCreateInfo::SaveFileSource save_source);
-
- ~SaveItem();
-
- void Start();
-
- // Received a new chunk of data.
- void Update(int64 bytes_so_far);
-
- // Cancel saving item.
- void Cancel();
-
- // Saving operation completed.
- void Finish(int64 size, bool is_success);
-
- // Rough percent complete, -1 means we don't know (since we didn't receive a
- // total size).
- int PercentComplete() const;
-
- // Update path for SaveItem, the actual file is renamed on the file thread.
- void Rename(const FilePath& full_path);
-
- void SetSaveId(int32 save_id);
-
- void SetTotalBytes(int64 total_bytes);
-
- // Accessors.
- SaveState state() const { return state_; }
- const FilePath& full_path() const { return full_path_; }
- const FilePath& file_name() const { return file_name_; }
- const GURL& url() const { return url_; }
- const GURL& referrer() const { return referrer_; }
- int64 total_bytes() const { return total_bytes_; }
- int64 received_bytes() const { return received_bytes_; }
- int32 save_id() const { return save_id_; }
- bool has_final_name() const { return has_final_name_; }
- bool success() const { return is_success_; }
- SaveFileCreateInfo::SaveFileSource save_source() const {
- return save_source_;
- }
- SavePackage* package() const { return package_; }
-
- private:
- // Internal helper for maintaining consistent received and total sizes.
- void UpdateSize(int64 size);
-
- // Request ID assigned by the ResourceDispatcherHost.
- int32 save_id_;
-
- // Full path to the save item file.
- FilePath full_path_;
-
- // Short display version of the file.
- FilePath file_name_;
-
- // The URL for this save item.
- GURL url_;
- GURL referrer_;
-
- // Total bytes expected.
- int64 total_bytes_;
-
- // Current received bytes.
- int64 received_bytes_;
-
- // The current state of this save item.
- SaveState state_;
-
- // Specifies if this name is a final or not.
- bool has_final_name_;
-
- // Flag indicates whether SaveItem has error while in saving process.
- bool is_success_;
-
- SaveFileCreateInfo::SaveFileSource save_source_;
-
- // Our owning object.
- SavePackage* package_;
-
- DISALLOW_COPY_AND_ASSIGN(SaveItem);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_SAVE_ITEM_H__
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
deleted file mode 100644
index 8e37206..0000000
--- a/chrome/browser/download/save_package.cc
+++ /dev/null
@@ -1,1476 +0,0 @@
-// 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.
-
-#include "chrome/browser/download/save_package.h"
-
-#include <algorithm>
-
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/i18n/file_util_icu.h"
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/stl_util-inl.h"
-#include "base/string_piece.h"
-#include "base/string_split.h"
-#include "base/sys_string_conversions.h"
-#include "base/task.h"
-#include "base/threading/thread.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/download/download_item.h"
-#include "chrome/browser/download/download_item_model.h"
-#include "chrome/browser/download/download_manager.h"
-#include "chrome/browser/download/download_prefs.h"
-#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/download/save_file.h"
-#include "chrome/browser/download/save_file_manager.h"
-#include "chrome/browser/download/save_item.h"
-#include "chrome/browser/net/url_fixer_upper.h"
-#include "chrome/browser/platform_util.h"
-#include "chrome/browser/prefs/pref_member.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/ui/download/download_tab_helper.h"
-#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/common/render_messages.h"
-#include "chrome/common/url_constants.h"
-#include "content/browser/browser_thread.h"
-#include "content/browser/renderer_host/render_process_host.h"
-#include "content/browser/renderer_host/render_view_host.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
-#include "content/browser/renderer_host/resource_dispatcher_host.h"
-#include "content/browser/tab_contents/tab_contents.h"
-#include "content/common/notification_service.h"
-#include "grit/generated_resources.h"
-#include "net/base/io_buffer.h"
-#include "net/base/mime_util.h"
-#include "net/base/net_util.h"
-#include "net/url_request/url_request_context.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebPageSerializerClient.h"
-#include "ui/base/l10n/l10n_util.h"
-
-using base::Time;
-using WebKit::WebPageSerializerClient;
-
-namespace {
-
-// A counter for uniquely identifying each save package.
-int g_save_package_id = 0;
-
-// Default name which will be used when we can not get proper name from
-// resource URL.
-const char kDefaultSaveName[] = "saved_resource";
-
-const FilePath::CharType kDefaultHtmlExtension[] =
-#if defined(OS_WIN)
- FILE_PATH_LITERAL("htm");
-#else
- FILE_PATH_LITERAL("html");
-#endif
-
-// Maximum number of file ordinal number. I think it's big enough for resolving
-// name-conflict files which has same base file name.
-const int32 kMaxFileOrdinalNumber = 9999;
-
-// Maximum length for file path. Since Windows have MAX_PATH limitation for
-// file path, we need to make sure length of file path of every saved file
-// is less than MAX_PATH
-#if defined(OS_WIN)
-const uint32 kMaxFilePathLength = MAX_PATH - 1;
-#elif defined(OS_POSIX)
-const uint32 kMaxFilePathLength = PATH_MAX - 1;
-#endif
-
-// Maximum length for file ordinal number part. Since we only support the
-// maximum 9999 for ordinal number, which means maximum file ordinal number part
-// should be "(9998)", so the value is 6.
-const uint32 kMaxFileOrdinalNumberPartLength = 6;
-
-// If false, we don't prompt the user as to where to save the file. This
-// exists only for testing.
-bool g_should_prompt_for_filename = true;
-
-// Indexes used for specifying which element in the extensions dropdown
-// the user chooses when picking a save type.
-const int kSelectFileHtmlOnlyIndex = 1;
-const int kSelectFileCompleteIndex = 2;
-
-// Used for mapping between SavePackageType constants and the indexes above.
-const SavePackage::SavePackageType kIndexToSaveType[] = {
- SavePackage::SAVE_TYPE_UNKNOWN,
- SavePackage::SAVE_AS_ONLY_HTML,
- SavePackage::SAVE_AS_COMPLETE_HTML,
-};
-
-// Used for mapping between the IDS_ string identifiers and the indexes above.
-const int kIndexToIDS[] = {
- 0, IDS_SAVE_PAGE_DESC_HTML_ONLY, IDS_SAVE_PAGE_DESC_COMPLETE,
-};
-
-int SavePackageTypeToIndex(SavePackage::SavePackageType type) {
- for (size_t i = 0; i < arraysize(kIndexToSaveType); ++i) {
- if (kIndexToSaveType[i] == type)
- return i;
- }
- NOTREACHED();
- return -1;
-}
-
-// Strip current ordinal number, if any. Should only be used on pure
-// file names, i.e. those stripped of their extensions.
-// TODO(estade): improve this to not choke on alternate encodings.
-FilePath::StringType StripOrdinalNumber(
- const FilePath::StringType& pure_file_name) {
- FilePath::StringType::size_type r_paren_index =
- pure_file_name.rfind(FILE_PATH_LITERAL(')'));
- FilePath::StringType::size_type l_paren_index =
- pure_file_name.rfind(FILE_PATH_LITERAL('('));
- if (l_paren_index >= r_paren_index)
- return pure_file_name;
-
- for (FilePath::StringType::size_type i = l_paren_index + 1;
- i != r_paren_index; ++i) {
- if (!IsAsciiDigit(pure_file_name[i]))
- return pure_file_name;
- }
-
- return pure_file_name.substr(0, l_paren_index);
-}
-
-// Check whether we can save page as complete-HTML for the contents which
-// have specified a MIME type. Now only contents which have the MIME type
-// "text/html" can be saved as complete-HTML.
-bool CanSaveAsComplete(const std::string& contents_mime_type) {
- return contents_mime_type == "text/html" ||
- contents_mime_type == "application/xhtml+xml";
-}
-
-} // namespace
-
-SavePackage::SavePackage(TabContentsWrapper* wrapper,
- SavePackageType save_type,
- const FilePath& file_full_path,
- const FilePath& directory_full_path)
- : TabContentsObserver(wrapper->tab_contents()),
- wrapper_(wrapper),
- file_manager_(NULL),
- download_(NULL),
- page_url_(GetUrlToBeSaved()),
- saved_main_file_path_(file_full_path),
- saved_main_directory_path_(directory_full_path),
- title_(tab_contents()->GetTitle()),
- finished_(false),
- user_canceled_(false),
- disk_error_occurred_(false),
- save_type_(save_type),
- all_save_items_count_(0),
- wait_state_(INITIALIZE),
- tab_id_(tab_contents()->GetRenderProcessHost()->id()),
- unique_id_(g_save_package_id++),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
- DCHECK(page_url_.is_valid());
- DCHECK(save_type_ == SAVE_AS_ONLY_HTML ||
- save_type_ == SAVE_AS_COMPLETE_HTML);
- DCHECK(!saved_main_file_path_.empty() &&
- saved_main_file_path_.value().length() <= kMaxFilePathLength);
- DCHECK(!saved_main_directory_path_.empty() &&
- saved_main_directory_path_.value().length() < kMaxFilePathLength);
- InternalInit();
-}
-
-SavePackage::SavePackage(TabContentsWrapper* wrapper)
- : TabContentsObserver(wrapper->tab_contents()),
- wrapper_(wrapper),
- file_manager_(NULL),
- download_(NULL),
- page_url_(GetUrlToBeSaved()),
- title_(tab_contents()->GetTitle()),
- finished_(false),
- user_canceled_(false),
- disk_error_occurred_(false),
- save_type_(SAVE_TYPE_UNKNOWN),
- all_save_items_count_(0),
- wait_state_(INITIALIZE),
- tab_id_(tab_contents()->GetRenderProcessHost()->id()),
- unique_id_(g_save_package_id++),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
- DCHECK(page_url_.is_valid());
- InternalInit();
-}
-
-// This is for testing use. Set |finished_| as true because we don't want
-// method Cancel to be be called in destructor in test mode.
-// We also don't call InternalInit().
-SavePackage::SavePackage(TabContentsWrapper* wrapper,
- const FilePath& file_full_path,
- const FilePath& directory_full_path)
- : TabContentsObserver(wrapper->tab_contents()),
- wrapper_(wrapper),
- file_manager_(NULL),
- download_(NULL),
- saved_main_file_path_(file_full_path),
- saved_main_directory_path_(directory_full_path),
- finished_(true),
- user_canceled_(false),
- disk_error_occurred_(false),
- save_type_(SAVE_TYPE_UNKNOWN),
- all_save_items_count_(0),
- wait_state_(INITIALIZE),
- tab_id_(0),
- unique_id_(g_save_package_id++),
- ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
-}
-
-SavePackage::~SavePackage() {
- // Stop receiving saving job's updates
- if (!finished_ && !canceled()) {
- // Unexpected quit.
- Cancel(true);
- }
-
- DCHECK(all_save_items_count_ == (waiting_item_queue_.size() +
- completed_count() +
- in_process_count()));
- // Free all SaveItems.
- while (!waiting_item_queue_.empty()) {
- // We still have some items which are waiting for start to save.
- SaveItem* save_item = waiting_item_queue_.front();
- waiting_item_queue_.pop();
- delete save_item;
- }
-
- STLDeleteValues(&saved_success_items_);
- STLDeleteValues(&in_progress_items_);
- STLDeleteValues(&saved_failed_items_);
-
- // The DownloadItem is owned by DownloadManager.
- download_ = NULL;
-
- file_manager_ = NULL;
-
- // If there's an outstanding save dialog, make sure it doesn't call us back
- // now that we're gone.
- if (select_file_dialog_.get())
- select_file_dialog_->ListenerDestroyed();
-}
-
-// Retrieves the URL to be saved from tab_contents_ variable.
-GURL SavePackage::GetUrlToBeSaved() {
- // Instead of using tab_contents_.GetURL here, we use url()
- // (which is the "real" url of the page)
- // from the NavigationEntry because it reflects its' origin
- // rather than the displayed one (returned by GetURL) which may be
- // different (like having "view-source:" on the front).
- NavigationEntry* active_entry =
- tab_contents()->controller().GetActiveEntry();
- return active_entry->url();
-}
-
-// Cancel all in progress request, might be called by user or internal error.
-void SavePackage::Cancel(bool user_action) {
- if (!canceled()) {
- if (user_action)
- user_canceled_ = true;
- else
- disk_error_occurred_ = true;
- Stop();
- }
-}
-
-// Init() can be called directly, or indirectly via GetSaveInfo(). In both
-// cases, we need file_manager_ to be initialized, so we do this first.
-void SavePackage::InternalInit() {
- ResourceDispatcherHost* rdh = g_browser_process->resource_dispatcher_host();
- if (!rdh) {
- NOTREACHED();
- return;
- }
-
- file_manager_ = rdh->save_file_manager();
- if (!file_manager_) {
- NOTREACHED();
- return;
- }
-}
-
-// Initialize the SavePackage.
-bool SavePackage::Init() {
- // Set proper running state.
- if (wait_state_ != INITIALIZE)
- return false;
-
- wait_state_ = START_PROCESS;
-
- // Initialize the request context and resource dispatcher.
- Profile* profile = tab_contents()->profile();
- if (!profile) {
- NOTREACHED();
- return false;
- }
-
- // Create the fake DownloadItem and display the view.
- DownloadManager* download_manager =
- tab_contents()->profile()->GetDownloadManager();
- download_ = new DownloadItem(download_manager,
- saved_main_file_path_,
- page_url_,
- profile->IsOffTheRecord());
-
- // Transfer the ownership to the download manager. We need the DownloadItem
- // to be alive as long as the Profile is alive.
- download_manager->SavePageAsDownloadStarted(download_);
-
- wrapper_->download_tab_helper()->OnStartDownload(download_);
-
- // Check save type and process the save page job.
- if (save_type_ == SAVE_AS_COMPLETE_HTML) {
- // Get directory
- DCHECK(!saved_main_directory_path_.empty());
- GetAllSavableResourceLinksForCurrentPage();
- } else {
- wait_state_ = NET_FILES;
- SaveFileCreateInfo::SaveFileSource save_source = page_url_.SchemeIsFile() ?
- SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
- SaveFileCreateInfo::SAVE_FILE_FROM_NET;
- SaveItem* save_item = new SaveItem(page_url_,
- GURL(),
- this,
- save_source);
- // Add this item to waiting list.
- waiting_item_queue_.push(save_item);
- all_save_items_count_ = 1;
- download_->set_total_bytes(1);
-
- DoSavingProcess();
- }
-
- return true;
-}
-
-// On POSIX, the length of |pure_file_name| + |file_name_ext| is further
-// restricted by NAME_MAX. The maximum allowed path looks like:
-// '/path/to/save_dir' + '/' + NAME_MAX.
-uint32 SavePackage::GetMaxPathLengthForDirectory(const FilePath& base_dir) {
-#if defined(OS_POSIX)
- return std::min(kMaxFilePathLength,
- static_cast<uint32>(base_dir.value().length()) +
- NAME_MAX + 1);
-#else
- return kMaxFilePathLength;
-#endif
-}
-
-// File name is considered being consist of pure file name, dot and file
-// extension name. File name might has no dot and file extension, or has
-// multiple dot inside file name. The dot, which separates the pure file
-// name and file extension name, is last dot in the whole file name.
-// This function is for making sure the length of specified file path is not
-// great than the specified maximum length of file path and getting safe pure
-// file name part if the input pure file name is too long.
-// The parameter |dir_path| specifies directory part of the specified
-// file path. The parameter |file_name_ext| specifies file extension
-// name part of the specified file path (including start dot). The parameter
-// |max_file_path_len| specifies maximum length of the specified file path.
-// The parameter |pure_file_name| input pure file name part of the specified
-// file path. If the length of specified file path is great than
-// |max_file_path_len|, the |pure_file_name| will output new pure file name
-// part for making sure the length of specified file path is less than
-// specified maximum length of file path. Return false if the function can
-// not get a safe pure file name, otherwise it returns true.
-bool SavePackage::GetSafePureFileName(const FilePath& dir_path,
- const FilePath::StringType& file_name_ext,
- uint32 max_file_path_len,
- FilePath::StringType* pure_file_name) {
- DCHECK(!pure_file_name->empty());
- int available_length = static_cast<int>(max_file_path_len -
- dir_path.value().length() -
- file_name_ext.length());
- // Need an extra space for the separator.
- if (!file_util::EndsWithSeparator(dir_path))
- --available_length;
-
- // Plenty of room.
- if (static_cast<int>(pure_file_name->length()) <= available_length)
- return true;
-
- // Limited room. Truncate |pure_file_name| to fit.
- if (available_length > 0) {
- *pure_file_name = pure_file_name->substr(0, available_length);
- return true;
- }
-
- // Not enough room to even use a shortened |pure_file_name|.
- pure_file_name->clear();
- return false;
-}
-
-// Generate name for saving resource.
-bool SavePackage::GenerateFileName(const std::string& disposition,
- const GURL& url,
- bool need_html_ext,
- FilePath::StringType* generated_name) {
- // TODO(jungshik): Figure out the referrer charset when having one
- // makes sense and pass it to GetSuggestedFilename.
- string16 suggested_name =
- net::GetSuggestedFilename(url, disposition, "", "",
- ASCIIToUTF16(kDefaultSaveName));
-
- // TODO(evan): this code is totally wrong -- we should just generate
- // Unicode filenames and do all this encoding switching at the end.
- // However, I'm just shuffling wrong code around, at least not adding
- // to it.
-#if defined(OS_WIN)
- FilePath file_path = FilePath(suggested_name);
-#else
- FilePath file_path = FilePath(
- base::SysWideToNativeMB(UTF16ToWide(suggested_name)));
-#endif
-
- DCHECK(!file_path.empty());
- FilePath::StringType pure_file_name =
- file_path.RemoveExtension().BaseName().value();
- FilePath::StringType file_name_ext = file_path.Extension();
-
- // If it is HTML resource, use ".htm{l,}" as its extension.
- if (need_html_ext) {
- file_name_ext = FILE_PATH_LITERAL(".");
- file_name_ext.append(kDefaultHtmlExtension);
- }
-
- // Need to make sure the suggested file name is not too long.
- uint32 max_path = GetMaxPathLengthForDirectory(saved_main_directory_path_);
-
- // Get safe pure file name.
- if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext,
- max_path, &pure_file_name))
- return false;
-
- FilePath::StringType file_name = pure_file_name + file_name_ext;
-
- // Check whether we already have same name.
- if (file_name_set_.find(file_name) == file_name_set_.end()) {
- file_name_set_.insert(file_name);
- } else {
- // Found same name, increase the ordinal number for the file name.
- FilePath::StringType base_file_name = StripOrdinalNumber(pure_file_name);
-
- // We need to make sure the length of base file name plus maximum ordinal
- // number path will be less than or equal to kMaxFilePathLength.
- if (!GetSafePureFileName(saved_main_directory_path_, file_name_ext,
- max_path - kMaxFileOrdinalNumberPartLength, &base_file_name))
- return false;
-
- // Prepare the new ordinal number.
- uint32 ordinal_number;
- FileNameCountMap::iterator it = file_name_count_map_.find(base_file_name);
- if (it == file_name_count_map_.end()) {
- // First base-name-conflict resolving, use 1 as initial ordinal number.
- file_name_count_map_[base_file_name] = 1;
- ordinal_number = 1;
- } else {
- // We have met same base-name conflict, use latest ordinal number.
- ordinal_number = it->second;
- }
-
- if (ordinal_number > (kMaxFileOrdinalNumber - 1)) {
- // Use a random file from temporary file.
- FilePath temp_file;
- file_util::CreateTemporaryFile(&temp_file);
- file_name = temp_file.RemoveExtension().BaseName().value();
- // Get safe pure file name.
- if (!GetSafePureFileName(saved_main_directory_path_,
- FilePath::StringType(),
- max_path, &file_name))
- return false;
- } else {
- for (int i = ordinal_number; i < kMaxFileOrdinalNumber; ++i) {
- FilePath::StringType new_name = base_file_name +
- StringPrintf(FILE_PATH_LITERAL("(%d)"), i) + file_name_ext;
- if (file_name_set_.find(new_name) == file_name_set_.end()) {
- // Resolved name conflict.
- file_name = new_name;
- file_name_count_map_[base_file_name] = ++i;
- break;
- }
- }
- }
-
- file_name_set_.insert(file_name);
- }
-
- DCHECK(!file_name.empty());
- generated_name->assign(file_name);
-
- return true;
-}
-
-// We have received a message from SaveFileManager about a new saving job. We
-// create a SaveItem and store it in our in_progress list.
-void SavePackage::StartSave(const SaveFileCreateInfo* info) {
- DCHECK(info && !info->url.is_empty());
-
- SaveUrlItemMap::iterator it = in_progress_items_.find(info->url.spec());
- if (it == in_progress_items_.end()) {
- // If not found, we must have cancel action.
- DCHECK(canceled());
- return;
- }
- SaveItem* save_item = it->second;
-
- DCHECK(!saved_main_file_path_.empty());
-
- save_item->SetSaveId(info->save_id);
- save_item->SetTotalBytes(info->total_bytes);
-
- // Determine the proper path for a saving job, by choosing either the default
- // save directory, or prompting the user.
- DCHECK(!save_item->has_final_name());
- if (info->url != page_url_) {
- FilePath::StringType generated_name;
- // For HTML resource file, make sure it will have .htm as extension name,
- // otherwise, when you open the saved page in Chrome again, download
- // file manager will treat it as downloadable resource, and download it
- // instead of opening it as HTML.
- bool need_html_ext =
- info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_DOM;
- if (!GenerateFileName(info->content_disposition,
- GURL(info->url),
- need_html_ext,
- &generated_name)) {
- // We can not generate file name for this SaveItem, so we cancel the
- // saving page job if the save source is from serialized DOM data.
- // Otherwise, it means this SaveItem is sub-resource type, we treat it
- // as an error happened on saving. We can ignore this type error for
- // sub-resource links which will be resolved as absolute links instead
- // of local links in final saved contents.
- if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_DOM)
- Cancel(true);
- else
- SaveFinished(save_item->save_id(), 0, false);
- return;
- }
-
- // When saving page as only-HTML, we only have a SaveItem whose url
- // must be page_url_.
- DCHECK(save_type_ == SAVE_AS_COMPLETE_HTML);
- DCHECK(!saved_main_directory_path_.empty());
-
- // Now we get final name retrieved from GenerateFileName, we will use it
- // rename the SaveItem.
- FilePath final_name = saved_main_directory_path_.Append(generated_name);
- save_item->Rename(final_name);
- } else {
- // It is the main HTML file, use the name chosen by the user.
- save_item->Rename(saved_main_file_path_);
- }
-
- // If the save source is from file system, inform SaveFileManager to copy
- // corresponding file to the file path which this SaveItem specifies.
- if (info->save_source == SaveFileCreateInfo::SAVE_FILE_FROM_FILE) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::SaveLocalFile,
- save_item->url(),
- save_item->save_id(),
- tab_id()));
- return;
- }
-
- // Check whether we begin to require serialized HTML data.
- if (save_type_ == SAVE_AS_COMPLETE_HTML && wait_state_ == HTML_DATA) {
- // Inform backend to serialize the all frames' DOM and send serialized
- // HTML data back.
- GetSerializedHtmlDataForCurrentPageWithLocalLinks();
- }
-}
-
-// Look up SaveItem by save id from in progress map.
-SaveItem* SavePackage::LookupItemInProcessBySaveId(int32 save_id) {
- if (in_process_count()) {
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- SaveItem* save_item = it->second;
- DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
- if (save_item->save_id() == save_id)
- return save_item;
- }
- }
- return NULL;
-}
-
-// Remove SaveItem from in progress map and put it to saved map.
-void SavePackage::PutInProgressItemToSavedMap(SaveItem* save_item) {
- SaveUrlItemMap::iterator it = in_progress_items_.find(
- save_item->url().spec());
- DCHECK(it != in_progress_items_.end());
- DCHECK(save_item == it->second);
- in_progress_items_.erase(it);
-
- if (save_item->success()) {
- // Add it to saved_success_items_.
- DCHECK(saved_success_items_.find(save_item->save_id()) ==
- saved_success_items_.end());
- saved_success_items_[save_item->save_id()] = save_item;
- } else {
- // Add it to saved_failed_items_.
- DCHECK(saved_failed_items_.find(save_item->url().spec()) ==
- saved_failed_items_.end());
- saved_failed_items_[save_item->url().spec()] = save_item;
- }
-}
-
-// Called for updating saving state.
-bool SavePackage::UpdateSaveProgress(int32 save_id,
- int64 size,
- bool write_success) {
- // Because we might have canceled this saving job before,
- // so we might not find corresponding SaveItem.
- SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
- if (!save_item)
- return false;
-
- save_item->Update(size);
-
- // If we got disk error, cancel whole save page job.
- if (!write_success) {
- // Cancel job with reason of disk error.
- Cancel(false);
- }
- return true;
-}
-
-// Stop all page saving jobs that are in progress and instruct the file thread
-// to delete all saved files.
-void SavePackage::Stop() {
- // If we haven't moved out of the initial state, there's nothing to cancel and
- // there won't be valid pointers for file_manager_ or download_.
- if (wait_state_ == INITIALIZE)
- return;
-
- // When stopping, if it still has some items in in_progress, cancel them.
- DCHECK(canceled());
- if (in_process_count()) {
- SaveUrlItemMap::iterator it = in_progress_items_.begin();
- for (; it != in_progress_items_.end(); ++it) {
- SaveItem* save_item = it->second;
- DCHECK(save_item->state() == SaveItem::IN_PROGRESS);
- save_item->Cancel();
- }
- // Remove all in progress item to saved map. For failed items, they will
- // be put into saved_failed_items_, for successful item, they will be put
- // into saved_success_items_.
- while (in_process_count())
- PutInProgressItemToSavedMap(in_progress_items_.begin()->second);
- }
-
- // This vector contains the save ids of the save files which SaveFileManager
- // needs to remove from its save_file_map_.
- SaveIDList save_ids;
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it)
- save_ids.push_back(it->first);
- for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
- it != saved_failed_items_.end(); ++it)
- save_ids.push_back(it->second->save_id());
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::RemoveSavedFileFromFileMap,
- save_ids));
-
- finished_ = true;
- wait_state_ = FAILED;
-
- // Inform the DownloadItem we have canceled whole save page job.
- download_->Cancel(false);
-}
-
-void SavePackage::CheckFinish() {
- if (in_process_count() || finished_)
- return;
-
- FilePath dir = (save_type_ == SAVE_AS_COMPLETE_HTML &&
- saved_success_items_.size() > 1) ?
- saved_main_directory_path_ : FilePath();
-
- // This vector contains the final names of all the successfully saved files
- // along with their save ids. It will be passed to SaveFileManager to do the
- // renaming job.
- FinalNameList final_names;
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it)
- final_names.push_back(std::make_pair(it->first,
- it->second->full_path()));
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::RenameAllFiles,
- final_names,
- dir,
- tab_contents()->GetRenderProcessHost()->id(),
- tab_contents()->render_view_host()->routing_id(),
- id()));
-}
-
-// Successfully finished all items of this SavePackage.
-void SavePackage::Finish() {
- // User may cancel the job when we're moving files to the final directory.
- if (canceled())
- return;
-
- wait_state_ = SUCCESSFUL;
- finished_ = true;
-
- // This vector contains the save ids of the save files which SaveFileManager
- // needs to remove from its save_file_map_.
- SaveIDList save_ids;
- for (SaveUrlItemMap::iterator it = saved_failed_items_.begin();
- it != saved_failed_items_.end(); ++it)
- save_ids.push_back(it->second->save_id());
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::RemoveSavedFileFromFileMap,
- save_ids));
-
- download_->OnAllDataSaved(all_save_items_count_);
- download_->MarkAsComplete();
-
- NotificationService::current()->Notify(
- chrome::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- Source<SavePackage>(this),
- Details<GURL>(&page_url_));
-}
-
-// Called for updating end state.
-void SavePackage::SaveFinished(int32 save_id, int64 size, bool is_success) {
- // Because we might have canceled this saving job before,
- // so we might not find corresponding SaveItem. Just ignore it.
- SaveItem* save_item = LookupItemInProcessBySaveId(save_id);
- if (!save_item)
- return;
-
- // Let SaveItem set end state.
- save_item->Finish(size, is_success);
- // Remove the associated save id and SavePackage.
- file_manager_->RemoveSaveFile(save_id, save_item->url(), this);
-
- PutInProgressItemToSavedMap(save_item);
-
- // Inform the DownloadItem to update UI.
- // We use the received bytes as number of saved files.
- download_->Update(completed_count());
-
- if (save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM &&
- save_item->url() == page_url_ && !save_item->received_bytes()) {
- // If size of main HTML page is 0, treat it as disk error.
- Cancel(false);
- return;
- }
-
- if (canceled()) {
- DCHECK(finished_);
- return;
- }
-
- // Continue processing the save page job.
- DoSavingProcess();
-
- // Check whether we can successfully finish whole job.
- CheckFinish();
-}
-
-// Sometimes, the net io will only call SaveFileManager::SaveFinished with
-// save id -1 when it encounters error. Since in this case, save id will be
-// -1, so we can only use URL to find which SaveItem is associated with
-// this error.
-// Saving an item failed. If it's a sub-resource, ignore it. If the error comes
-// from serializing HTML data, then cancel saving page.
-void SavePackage::SaveFailed(const GURL& save_url) {
- SaveUrlItemMap::iterator it = in_progress_items_.find(save_url.spec());
- if (it == in_progress_items_.end()) {
- NOTREACHED(); // Should not exist!
- return;
- }
- SaveItem* save_item = it->second;
-
- save_item->Finish(0, false);
-
- PutInProgressItemToSavedMap(save_item);
-
- // Inform the DownloadItem to update UI.
- // We use the received bytes as number of saved files.
- download_->Update(completed_count());
-
- if (save_type_ == SAVE_AS_ONLY_HTML ||
- save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
- // We got error when saving page. Treat it as disk error.
- Cancel(true);
- }
-
- if (canceled()) {
- DCHECK(finished_);
- return;
- }
-
- // Continue processing the save page job.
- DoSavingProcess();
-
- CheckFinish();
-}
-
-void SavePackage::SaveCanceled(SaveItem* save_item) {
- // Call the RemoveSaveFile in UI thread.
- file_manager_->RemoveSaveFile(save_item->save_id(),
- save_item->url(),
- this);
- if (save_item->save_id() != -1)
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::CancelSave,
- save_item->save_id()));
-}
-
-// Initiate a saving job of a specific URL. We send the request to
-// SaveFileManager, which will dispatch it to different approach according to
-// the save source. Parameter process_all_remaining_items indicates whether
-// we need to save all remaining items.
-void SavePackage::SaveNextFile(bool process_all_remaining_items) {
- DCHECK(tab_contents());
- DCHECK(waiting_item_queue_.size());
-
- do {
- // Pop SaveItem from waiting list.
- SaveItem* save_item = waiting_item_queue_.front();
- waiting_item_queue_.pop();
-
- // Add the item to in_progress_items_.
- SaveUrlItemMap::iterator it = in_progress_items_.find(
- save_item->url().spec());
- DCHECK(it == in_progress_items_.end());
- in_progress_items_[save_item->url().spec()] = save_item;
- save_item->Start();
- file_manager_->SaveURL(save_item->url(),
- save_item->referrer(),
- tab_contents()->GetRenderProcessHost()->id(),
- routing_id(),
- save_item->save_source(),
- save_item->full_path(),
- tab_contents()->profile()->GetResourceContext(),
- this);
- } while (process_all_remaining_items && waiting_item_queue_.size());
-}
-
-
-// Open download page in windows explorer on file thread, to avoid blocking the
-// user interface.
-void SavePackage::ShowDownloadInShell() {
- DCHECK(file_manager_);
- DCHECK(finished_ && !canceled() && !saved_main_file_path_.empty());
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-#if defined(OS_MACOSX)
- // Mac OS X requires opening downloads on the UI thread.
- platform_util::ShowItemInFolder(saved_main_file_path_);
-#else
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::OnShowSavedFileInShell,
- saved_main_file_path_));
-#endif
-}
-
-// Calculate the percentage of whole save page job.
-int SavePackage::PercentComplete() {
- if (!all_save_items_count_)
- return 0;
- else if (!in_process_count())
- return 100;
- else
- return completed_count() / all_save_items_count_;
-}
-
-// Continue processing the save page job after one SaveItem has been
-// finished.
-void SavePackage::DoSavingProcess() {
- if (save_type_ == SAVE_AS_COMPLETE_HTML) {
- // We guarantee that images and JavaScripts must be downloaded first.
- // So when finishing all those sub-resources, we will know which
- // sub-resource's link can be replaced with local file path, which
- // sub-resource's link need to be replaced with absolute URL which
- // point to its internet address because it got error when saving its data.
- SaveItem* save_item = NULL;
- // Start a new SaveItem job if we still have job in waiting queue.
- if (waiting_item_queue_.size()) {
- DCHECK(wait_state_ == NET_FILES);
- save_item = waiting_item_queue_.front();
- if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
- SaveNextFile(false);
- } else if (!in_process_count()) {
- // If there is no in-process SaveItem, it means all sub-resources
- // have been processed. Now we need to start serializing HTML DOM
- // for the current page to get the generated HTML data.
- wait_state_ = HTML_DATA;
- // All non-HTML resources have been finished, start all remaining
- // HTML files.
- SaveNextFile(true);
- }
- } else if (in_process_count()) {
- // Continue asking for HTML data.
- DCHECK(wait_state_ == HTML_DATA);
- }
- } else {
- // Save as HTML only.
- DCHECK(wait_state_ == NET_FILES);
- DCHECK(save_type_ == SAVE_AS_ONLY_HTML);
- if (waiting_item_queue_.size()) {
- DCHECK(all_save_items_count_ == waiting_item_queue_.size());
- SaveNextFile(false);
- }
- }
-}
-
-bool SavePackage::OnMessageReceived(const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(SavePackage, message)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SendCurrentPageAllSavableResourceLinks,
- OnReceivedSavableResourceLinksForCurrentPage)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SendSerializedHtmlData,
- OnReceivedSerializedHtmlData)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-// After finishing all SaveItems which need to get data from net.
-// We collect all URLs which have local storage and send the
-// map:(originalURL:currentLocalPath) to render process (backend).
-// Then render process will serialize DOM and send data to us.
-void SavePackage::GetSerializedHtmlDataForCurrentPageWithLocalLinks() {
- if (wait_state_ != HTML_DATA)
- return;
- std::vector<GURL> saved_links;
- std::vector<FilePath> saved_file_paths;
- int successful_started_items_count = 0;
-
- // Collect all saved items which have local storage.
- // First collect the status of all the resource files and check whether they
- // have created local files although they have not been completely saved.
- // If yes, the file can be saved. Otherwise, there is a disk error, so we
- // need to cancel the page saving job.
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- DCHECK(it->second->save_source() ==
- SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
- if (it->second->has_final_name())
- successful_started_items_count++;
- saved_links.push_back(it->second->url());
- saved_file_paths.push_back(it->second->file_name());
- }
-
- // If not all file of HTML resource have been started, then wait.
- if (successful_started_items_count != in_process_count())
- return;
-
- // Collect all saved success items.
- for (SavedItemMap::iterator it = saved_success_items_.begin();
- it != saved_success_items_.end(); ++it) {
- DCHECK(it->second->has_final_name());
- saved_links.push_back(it->second->url());
- saved_file_paths.push_back(it->second->file_name());
- }
-
- // Get the relative directory name.
- FilePath relative_dir_name = saved_main_directory_path_.BaseName();
-
- Send(new ViewMsg_GetSerializedHtmlDataForCurrentPageWithLocalLinks(
- routing_id(), saved_links, saved_file_paths, relative_dir_name));
-}
-
-// Process the serialized HTML content data of a specified web page
-// retrieved from render process.
-void SavePackage::OnReceivedSerializedHtmlData(const GURL& frame_url,
- const std::string& data,
- int32 status) {
- WebPageSerializerClient::PageSerializationStatus flag =
- static_cast<WebPageSerializerClient::PageSerializationStatus>(status);
- // Check current state.
- if (wait_state_ != HTML_DATA)
- return;
-
- int id = tab_id();
- // If the all frames are finished saving, we need to close the
- // remaining SaveItems.
- if (flag == WebPageSerializerClient::AllFramesAreFinished) {
- for (SaveUrlItemMap::iterator it = in_progress_items_.begin();
- it != in_progress_items_.end(); ++it) {
- VLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << it->second->save_id()
- << " url = \"" << it->second->url().spec() << "\"";
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::SaveFinished,
- it->second->save_id(),
- it->second->url(),
- id,
- true));
- }
- return;
- }
-
- SaveUrlItemMap::iterator it = in_progress_items_.find(frame_url.spec());
- if (it == in_progress_items_.end())
- return;
- SaveItem* save_item = it->second;
- DCHECK(save_item->save_source() == SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
-
- if (!data.empty()) {
- // Prepare buffer for saving HTML data.
- scoped_refptr<net::IOBuffer> new_data(new net::IOBuffer(data.size()));
- memcpy(new_data->data(), data.data(), data.size());
-
- // Call write file functionality in file thread.
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::UpdateSaveProgress,
- save_item->save_id(),
- new_data,
- static_cast<int>(data.size())));
- }
-
- // Current frame is completed saving, call finish in file thread.
- if (flag == WebPageSerializerClient::CurrentFrameIsFinished) {
- VLOG(20) << " " << __FUNCTION__ << "()"
- << " save_id = " << save_item->save_id()
- << " url = \"" << save_item->url().spec() << "\"";
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(file_manager_,
- &SaveFileManager::SaveFinished,
- save_item->save_id(),
- save_item->url(),
- id,
- true));
- }
-}
-
-// Ask for all savable resource links from backend, include main frame and
-// sub-frame.
-void SavePackage::GetAllSavableResourceLinksForCurrentPage() {
- if (wait_state_ != START_PROCESS)
- return;
-
- wait_state_ = RESOURCES_LIST;
- Send(new ViewMsg_GetAllSavableResourceLinksForCurrentPage(routing_id(),
- page_url_));
-}
-
-// Give backend the lists which contain all resource links that have local
-// storage, after which, render process will serialize DOM for generating
-// HTML data.
-void SavePackage::OnReceivedSavableResourceLinksForCurrentPage(
- const std::vector<GURL>& resources_list,
- const std::vector<GURL>& referrers_list,
- const std::vector<GURL>& frames_list) {
- if (wait_state_ != RESOURCES_LIST)
- return;
-
- DCHECK(resources_list.size() == referrers_list.size());
- all_save_items_count_ = static_cast<int>(resources_list.size()) +
- static_cast<int>(frames_list.size());
-
- // We use total bytes as the total number of files we want to save.
- download_->set_total_bytes(all_save_items_count_);
-
- if (all_save_items_count_) {
- // Put all sub-resources to wait list.
- for (int i = 0; i < static_cast<int>(resources_list.size()); ++i) {
- const GURL& u = resources_list[i];
- DCHECK(u.is_valid());
- SaveFileCreateInfo::SaveFileSource save_source = u.SchemeIsFile() ?
- SaveFileCreateInfo::SAVE_FILE_FROM_FILE :
- SaveFileCreateInfo::SAVE_FILE_FROM_NET;
- SaveItem* save_item = new SaveItem(u, referrers_list[i],
- this, save_source);
- waiting_item_queue_.push(save_item);
- }
- // Put all HTML resources to wait list.
- for (int i = 0; i < static_cast<int>(frames_list.size()); ++i) {
- const GURL& u = frames_list[i];
- DCHECK(u.is_valid());
- SaveItem* save_item = new SaveItem(u, GURL(),
- this, SaveFileCreateInfo::SAVE_FILE_FROM_DOM);
- waiting_item_queue_.push(save_item);
- }
- wait_state_ = NET_FILES;
- DoSavingProcess();
- } else {
- // No resource files need to be saved, treat it as user cancel.
- Cancel(true);
- }
-}
-
-void SavePackage::SetShouldPromptUser(bool should_prompt) {
- g_should_prompt_for_filename = should_prompt;
-}
-
-FilePath SavePackage::GetSuggestedNameForSaveAs(
- bool can_save_as_complete,
- const std::string& contents_mime_type) {
- FilePath name_with_proper_ext =
- FilePath::FromWStringHack(UTF16ToWideHack(title_));
-
- // If the page's title matches its URL, use the URL. Try to use the last path
- // component or if there is none, the domain as the file name.
- // Normally we want to base the filename on the page title, or if it doesn't
- // exist, on the URL. It's not easy to tell if the page has no title, because
- // if the page has no title, TabContents::GetTitle() will return the page's
- // URL (adjusted for display purposes). Therefore, we convert the "title"
- // back to a URL, and if it matches the original page URL, we know the page
- // had no title (or had a title equal to its URL, which is fine to treat
- // similarly).
- GURL fixed_up_title_url =
- URLFixerUpper::FixupURL(UTF16ToUTF8(title_), std::string());
-
- if (page_url_ == fixed_up_title_url) {
- std::string url_path;
- std::vector<std::string> url_parts;
- base::SplitString(page_url_.path(), '/', &url_parts);
- if (!url_parts.empty()) {
- for (int i = static_cast<int>(url_parts.size()) - 1; i >= 0; --i) {
- url_path = url_parts[i];
- if (!url_path.empty())
- break;
- }
- }
- if (url_path.empty())
- url_path = page_url_.host();
- name_with_proper_ext = FilePath::FromWStringHack(UTF8ToWide(url_path));
- }
-
- // Ask user for getting final saving name.
- name_with_proper_ext = EnsureMimeExtension(name_with_proper_ext,
- contents_mime_type);
- // Adjust extension for complete types.
- if (can_save_as_complete)
- name_with_proper_ext = EnsureHtmlExtension(name_with_proper_ext);
-
- FilePath::StringType file_name = name_with_proper_ext.value();
- file_util::ReplaceIllegalCharactersInPath(&file_name, ' ');
- return FilePath(file_name);
-}
-
-FilePath SavePackage::EnsureHtmlExtension(const FilePath& name) {
- // If the file name doesn't have an extension suitable for HTML files,
- // append one.
- FilePath::StringType ext = name.Extension();
- if (!ext.empty())
- ext.erase(ext.begin()); // Erase preceding '.'.
- std::string mime_type;
- if (!net::GetMimeTypeFromExtension(ext, &mime_type) ||
- !CanSaveAsComplete(mime_type)) {
- return FilePath(name.value() + FILE_PATH_LITERAL(".") +
- kDefaultHtmlExtension);
- }
- return name;
-}
-
-FilePath SavePackage::EnsureMimeExtension(const FilePath& name,
- const std::string& contents_mime_type) {
- // Start extension at 1 to skip over period if non-empty.
- FilePath::StringType ext = name.Extension().length() ?
- name.Extension().substr(1) : name.Extension();
- FilePath::StringType suggested_extension =
- ExtensionForMimeType(contents_mime_type);
- std::string mime_type;
- if (!suggested_extension.empty() &&
- (!net::GetMimeTypeFromExtension(ext, &mime_type) ||
- !IsSavableContents(mime_type))) {
- // Extension is absent or needs to be updated.
- return FilePath(name.value() + FILE_PATH_LITERAL(".") +
- suggested_extension);
- }
- return name;
-}
-
-const FilePath::CharType* SavePackage::ExtensionForMimeType(
- const std::string& contents_mime_type) {
- static const struct {
- const FilePath::CharType *mime_type;
- const FilePath::CharType *suggested_extension;
- } extensions[] = {
- { FILE_PATH_LITERAL("text/html"), kDefaultHtmlExtension },
- { FILE_PATH_LITERAL("text/xml"), FILE_PATH_LITERAL("xml") },
- { FILE_PATH_LITERAL("application/xhtml+xml"), FILE_PATH_LITERAL("xhtml") },
- { FILE_PATH_LITERAL("text/plain"), FILE_PATH_LITERAL("txt") },
- { FILE_PATH_LITERAL("text/css"), FILE_PATH_LITERAL("css") },
- };
-#if defined(OS_POSIX)
- FilePath::StringType mime_type(contents_mime_type);
-#elif defined(OS_WIN)
- FilePath::StringType mime_type(UTF8ToWide(contents_mime_type));
-#endif // OS_WIN
- for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(extensions); ++i) {
- if (mime_type == extensions[i].mime_type)
- return extensions[i].suggested_extension;
- }
- return FILE_PATH_LITERAL("");
-}
-
-
-
-// static.
-// Check whether the preference has the preferred directory for saving file. If
-// not, initialize it with default directory.
-FilePath SavePackage::GetSaveDirPreference(PrefService* prefs) {
- DCHECK(prefs);
-
- if (!prefs->FindPreference(prefs::kSaveFileDefaultDirectory)) {
- DCHECK(prefs->FindPreference(prefs::kDownloadDefaultDirectory));
- FilePath default_save_path = prefs->GetFilePath(
- prefs::kDownloadDefaultDirectory);
- prefs->RegisterFilePathPref(prefs::kSaveFileDefaultDirectory,
- default_save_path,
- PrefService::UNSYNCABLE_PREF);
- }
-
- // Get the directory from preference.
- FilePath save_file_path = prefs->GetFilePath(
- prefs::kSaveFileDefaultDirectory);
- DCHECK(!save_file_path.empty());
-
- return save_file_path;
-}
-
-void SavePackage::GetSaveInfo() {
- // Can't use tab_contents_ in the file thread, so get the data that we need
- // before calling to it.
- PrefService* prefs = tab_contents()->profile()->GetPrefs();
- FilePath website_save_dir = GetSaveDirPreference(prefs);
- FilePath download_save_dir = prefs->GetFilePath(
- prefs::kDownloadDefaultDirectory);
- std::string mime_type = tab_contents()->contents_mime_type();
-
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(this, &SavePackage::CreateDirectoryOnFileThread,
- website_save_dir, download_save_dir, mime_type));
-}
-
-void SavePackage::CreateDirectoryOnFileThread(
- const FilePath& website_save_dir,
- const FilePath& download_save_dir,
- const std::string& mime_type) {
- FilePath save_dir;
- // If the default html/websites save folder doesn't exist...
- if (!file_util::DirectoryExists(website_save_dir)) {
- // If the default download dir doesn't exist, create it.
- if (!file_util::DirectoryExists(download_save_dir))
- file_util::CreateDirectory(download_save_dir);
- save_dir = download_save_dir;
- } else {
- // If it does exist, use the default save dir param.
- save_dir = website_save_dir;
- }
-
- bool can_save_as_complete = CanSaveAsComplete(mime_type);
- FilePath suggested_filename = GetSuggestedNameForSaveAs(can_save_as_complete,
- mime_type);
- FilePath::StringType pure_file_name =
- suggested_filename.RemoveExtension().BaseName().value();
- FilePath::StringType file_name_ext = suggested_filename.Extension();
-
- // Need to make sure the suggested file name is not too long.
- uint32 max_path = GetMaxPathLengthForDirectory(save_dir);
-
- if (GetSafePureFileName(save_dir, file_name_ext, max_path, &pure_file_name)) {
- save_dir = save_dir.Append(pure_file_name + file_name_ext);
- } else {
- // Cannot create a shorter filename. This will cause the save as operation
- // to fail unless the user pick a shorter name. Continuing even though it
- // will fail because returning means no save as popup for the user, which
- // is even more confusing. This case should be rare though.
- save_dir = save_dir.Append(suggested_filename);
- }
-
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &SavePackage::ContinueGetSaveInfo, save_dir,
- can_save_as_complete));
-}
-
-void SavePackage::ContinueGetSaveInfo(const FilePath& suggested_path,
- bool can_save_as_complete) {
- // The TabContents which owns this SavePackage may have disappeared during
- // the UI->FILE->UI thread hop of
- // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo.
- if (!tab_contents())
- return;
- DownloadPrefs* download_prefs =
- tab_contents()->profile()->GetDownloadManager()->download_prefs();
- int file_type_index =
- SavePackageTypeToIndex(
- static_cast<SavePackageType>(download_prefs->save_file_type()));
- DCHECK_NE(-1, file_type_index);
-
- SelectFileDialog::FileTypeInfo file_type_info;
- FilePath::StringType default_extension;
-
- // If the contents can not be saved as complete-HTML, do not show the
- // file filters.
- if (can_save_as_complete) {
- bool add_extra_extension = false;
- FilePath::StringType extra_extension;
- if (!suggested_path.Extension().empty() &&
- suggested_path.Extension().compare(FILE_PATH_LITERAL("htm")) &&
- suggested_path.Extension().compare(FILE_PATH_LITERAL("html"))) {
- add_extra_extension = true;
- extra_extension = suggested_path.Extension().substr(1);
- }
-
- file_type_info.extensions.resize(2);
- file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
- FILE_PATH_LITERAL("htm"));
- file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
- FILE_PATH_LITERAL("html"));
-
- if (add_extra_extension) {
- file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
- extra_extension);
- }
-
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex - 1]));
- file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
- FILE_PATH_LITERAL("htm"));
- file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
- FILE_PATH_LITERAL("html"));
-
- if (add_extra_extension) {
- file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
- extra_extension);
- }
-
- file_type_info.extension_description_overrides.push_back(
- l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex]));
- file_type_info.include_all_files = false;
- default_extension = kDefaultHtmlExtension;
- } else {
- file_type_info.extensions.resize(1);
- file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
- suggested_path.Extension());
-
- if (!file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].empty()) {
- // Drop the .
- file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].erase(0, 1);
- }
-
- file_type_info.include_all_files = true;
- file_type_index = 1;
- }
-
- if (g_should_prompt_for_filename) {
- if (!select_file_dialog_.get())
- select_file_dialog_ = SelectFileDialog::Create(this);
- select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
- string16(),
- suggested_path,
- &file_type_info,
- file_type_index,
- default_extension,
- tab_contents(),
- platform_util::GetTopLevel(
- tab_contents()->GetNativeView()),
- NULL);
- } else {
- // Just use 'suggested_path' instead of opening the dialog prompt.
- ContinueSave(suggested_path, file_type_index);
- }
-}
-
-// Called after the save file dialog box returns.
-void SavePackage::ContinueSave(const FilePath& final_name,
- int index) {
- // Ensure the filename is safe.
- saved_main_file_path_ = final_name;
- download_util::GenerateSafeFileName(tab_contents()->contents_mime_type(),
- &saved_main_file_path_);
-
- // The option index is not zero-based.
- DCHECK(index >= kSelectFileHtmlOnlyIndex &&
- index <= kSelectFileCompleteIndex);
-
- saved_main_directory_path_ = saved_main_file_path_.DirName();
-
- PrefService* prefs = tab_contents()->profile()->GetPrefs();
- StringPrefMember save_file_path;
- save_file_path.Init(prefs::kSaveFileDefaultDirectory, prefs, NULL);
-#if defined(OS_POSIX)
- std::string path_string = saved_main_directory_path_.value();
-#elif defined(OS_WIN)
- std::string path_string = WideToUTF8(saved_main_directory_path_.value());
-#endif
- // If user change the default saving directory, we will remember it just
- // like IE and FireFox.
- if (!tab_contents()->profile()->IsOffTheRecord() &&
- save_file_path.GetValue() != path_string) {
- save_file_path.SetValue(path_string);
- }
-
- save_type_ = kIndexToSaveType[index];
-
- prefs->SetInteger(prefs::kSaveFileType, save_type_);
-
- if (save_type_ == SavePackage::SAVE_AS_COMPLETE_HTML) {
- // Make new directory for saving complete file.
- saved_main_directory_path_ = saved_main_directory_path_.Append(
- saved_main_file_path_.RemoveExtension().BaseName().value() +
- FILE_PATH_LITERAL("_files"));
- }
-
- Init();
-}
-
-// Static
-bool SavePackage::IsSavableURL(const GURL& url) {
- for (int i = 0; chrome::kSavableSchemes[i] != NULL; ++i) {
- if (url.SchemeIs(chrome::kSavableSchemes[i])) {
- return true;
- }
- }
- return false;
-}
-
-// Static
-bool SavePackage::IsSavableContents(const std::string& contents_mime_type) {
- // WebKit creates Document object when MIME type is application/xhtml+xml,
- // so we also support this MIME type.
- return contents_mime_type == "text/html" ||
- contents_mime_type == "text/xml" ||
- contents_mime_type == "application/xhtml+xml" ||
- contents_mime_type == "text/plain" ||
- contents_mime_type == "text/css" ||
- net::IsSupportedJavascriptMimeType(contents_mime_type.c_str());
-}
-
-// SelectFileDialog::Listener interface.
-void SavePackage::FileSelected(const FilePath& path,
- int index, void* params) {
- ContinueSave(path, index);
-}
-
-void SavePackage::FileSelectionCanceled(void* params) {
-}
diff --git a/chrome/browser/download/save_package.h b/chrome/browser/download/save_package.h
deleted file mode 100644
index 74f5526..0000000
--- a/chrome/browser/download/save_package.h
+++ /dev/null
@@ -1,327 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_H_
-#define CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_H_
-#pragma once
-
-#include <queue>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/hash_tables.h"
-#include "base/memory/ref_counted.h"
-#include "base/task.h"
-#include "chrome/browser/ui/shell_dialogs.h"
-#include "content/browser/tab_contents/tab_contents_observer.h"
-#include "googleurl/src/gurl.h"
-
-class DownloadItem;
-class DownloadManager;
-class GURL;
-class MessageLoop;
-class PrefService;
-class Profile;
-struct SaveFileCreateInfo;
-class SaveFileManager;
-class SaveItem;
-class SavePackage;
-struct SavePackageParam;
-class TabContentsWrapper;
-
-namespace base {
-class Thread;
-class Time;
-}
-
-
-// The SavePackage object manages the process of saving a page as only-html or
-// complete-html and providing the information for displaying saving status.
-// Saving page as only-html means means that we save web page to a single HTML
-// file regardless internal sub resources and sub frames.
-// Saving page as complete-html page means we save not only the main html file
-// the user told it to save but also a directory for the auxiliary files such
-// as all sub-frame html files, image files, css files and js files.
-//
-// Each page saving job may include one or multiple files which need to be
-// saved. Each file is represented by a SaveItem, and all SaveItems are owned
-// by the SavePackage. SaveItems are created when a user initiates a page
-// saving job, and exist for the duration of one tab's life time.
-class SavePackage : public base::RefCountedThreadSafe<SavePackage>,
- public TabContentsObserver,
- public SelectFileDialog::Listener {
- public:
- enum SavePackageType {
- // The value of the save type before its set by the user.
- SAVE_TYPE_UNKNOWN = -1,
- // User chose to save only the HTML of the page.
- SAVE_AS_ONLY_HTML = 0,
- // User chose to save complete-html page.
- SAVE_AS_COMPLETE_HTML = 1
- };
-
- enum WaitState {
- // State when created but not initialized.
- INITIALIZE = 0,
- // State when after initializing, but not yet saving.
- START_PROCESS,
- // Waiting on a list of savable resources from the backend.
- RESOURCES_LIST,
- // Waiting for data sent from net IO or from file system.
- NET_FILES,
- // Waiting for html DOM data sent from render process.
- HTML_DATA,
- // Saving page finished successfully.
- SUCCESSFUL,
- // Failed to save page.
- FAILED
- };
-
- // Constructor for user initiated page saving. This constructor results in a
- // SavePackage that will generate and sanitize a suggested name for the user
- // in the "Save As" dialog box.
- explicit SavePackage(TabContentsWrapper* wrapper);
-
- // This contructor is used only for testing. We can bypass the file and
- // directory name generation / sanitization by providing well known paths
- // better suited for tests.
- SavePackage(TabContentsWrapper* wrapper,
- SavePackageType save_type,
- const FilePath& file_full_path,
- const FilePath& directory_full_path);
-
- // Initialize the SavePackage. Returns true if it initializes properly.
- // Need to make sure that this method must be called in the UI thread because
- // using g_browser_process on a non-UI thread can cause crashes during
- // shutdown.
- bool Init();
-
- void Cancel(bool user_action);
-
- void Finish();
-
- // Notifications sent from the file thread to the UI thread.
- void StartSave(const SaveFileCreateInfo* info);
- bool UpdateSaveProgress(int32 save_id, int64 size, bool write_success);
- void SaveFinished(int32 save_id, int64 size, bool is_success);
- void SaveFailed(const GURL& save_url);
- void SaveCanceled(SaveItem* save_item);
-
- // Rough percent complete, -1 means we don't know (since we didn't receive a
- // total size).
- int PercentComplete();
-
- // Show or Open a saved page via the Windows shell.
- void ShowDownloadInShell();
-
- bool canceled() const { return user_canceled_ || disk_error_occurred_; }
- bool finished() const { return finished_; }
- SavePackageType save_type() const { return save_type_; }
- int tab_id() const { return tab_id_; }
- int id() const { return unique_id_; }
-
- void GetSaveInfo();
-
- // Statics -------------------------------------------------------------------
-
- // Used to disable prompting the user for a directory/filename of the saved
- // web page. This is available for testing.
- static void SetShouldPromptUser(bool should_prompt);
-
- // Check whether we can do the saving page operation for the specified URL.
- static bool IsSavableURL(const GURL& url);
-
- // Check whether we can do the saving page operation for the contents which
- // have the specified MIME type.
- static bool IsSavableContents(const std::string& contents_mime_type);
-
- // SelectFileDialog::Listener ------------------------------------------------
- virtual void FileSelected(const FilePath& path, int index, void* params);
- virtual void FileSelectionCanceled(void* params);
-
- private:
- friend class base::RefCountedThreadSafe<SavePackage>;
-
- // For testing only.
- SavePackage(TabContentsWrapper* wrapper,
- const FilePath& file_full_path,
- const FilePath& directory_full_path);
-
- virtual ~SavePackage();
-
- // Notes from Init() above applies here as well.
- void InternalInit();
-
- void Stop();
- void CheckFinish();
- void SaveNextFile(bool process_all_remainder_items);
- void DoSavingProcess();
-
- // TabContentsObserver implementation.
- virtual bool OnMessageReceived(const IPC::Message& message);
-
- // Return max length of a path for a specific base directory.
- // This is needed on POSIX, which restrict the length of file names in
- // addition to the restriction on the length of path names.
- // |base_dir| is assumed to be a directory name with no trailing slash.
- static uint32 GetMaxPathLengthForDirectory(const FilePath& base_dir);
-
- static bool GetSafePureFileName(const FilePath& dir_path,
- const FilePath::StringType& file_name_ext,
- uint32 max_file_path_len,
- FilePath::StringType* pure_file_name);
-
- // Create a file name based on the response from the server.
- bool GenerateFileName(const std::string& disposition,
- const GURL& url,
- bool need_html_ext,
- FilePath::StringType* generated_name);
-
- // Get all savable resource links from current web page, include main
- // frame and sub-frame.
- void GetAllSavableResourceLinksForCurrentPage();
- // Get html data by serializing all frames of current page with lists
- // which contain all resource links that have local copy.
- void GetSerializedHtmlDataForCurrentPageWithLocalLinks();
-
- SaveItem* LookupItemInProcessBySaveId(int32 save_id);
- void PutInProgressItemToSavedMap(SaveItem* save_item);
-
- // Retrieves the URL to be saved from tab_contents_ variable.
- GURL GetUrlToBeSaved();
-
- void CreateDirectoryOnFileThread(const FilePath& website_save_dir,
- const FilePath& download_save_dir,
- const std::string& mime_type);
- void ContinueGetSaveInfo(const FilePath& suggested_path,
- bool can_save_as_complete);
- void ContinueSave(const FilePath& final_name, int index);
-
- void OnReceivedSavableResourceLinksForCurrentPage(
- const std::vector<GURL>& resources_list,
- const std::vector<GURL>& referrers_list,
- const std::vector<GURL>& frames_list);
-
- void OnReceivedSerializedHtmlData(const GURL& frame_url,
- const std::string& data,
- int32 status);
-
-
- typedef base::hash_map<std::string, SaveItem*> SaveUrlItemMap;
- // in_progress_items_ is map of all saving job in in-progress state.
- SaveUrlItemMap in_progress_items_;
- // saved_failed_items_ is map of all saving job which are failed.
- SaveUrlItemMap saved_failed_items_;
-
- // The number of in process SaveItems.
- int in_process_count() const {
- return static_cast<int>(in_progress_items_.size());
- }
-
- // The number of all SaveItems which have completed, including success items
- // and failed items.
- int completed_count() const {
- return static_cast<int>(saved_success_items_.size() +
- saved_failed_items_.size());
- }
-
- // Retrieve the preference for the directory to save pages to.
- static FilePath GetSaveDirPreference(PrefService* prefs);
-
- // Helper function for preparing suggested name for the SaveAs Dialog. The
- // suggested name is determined by the web document's title.
- FilePath GetSuggestedNameForSaveAs(
- bool can_save_as_complete,
- const std::string& contents_mime_type);
-
- // Ensures that the file name has a proper extension for HTML by adding ".htm"
- // if necessary.
- static FilePath EnsureHtmlExtension(const FilePath& name);
-
- // Ensures that the file name has a proper extension for supported formats
- // if necessary.
- static FilePath EnsureMimeExtension(const FilePath& name,
- const std::string& contents_mime_type);
-
- // Returns extension for supported MIME types (for example, for "text/plain"
- // it returns "txt").
- static const FilePath::CharType* ExtensionForMimeType(
- const std::string& contents_mime_type);
-
- // Owning TabContentsWrapper.
- TabContentsWrapper* wrapper_;
-
- typedef std::queue<SaveItem*> SaveItemQueue;
- // A queue for items we are about to start saving.
- SaveItemQueue waiting_item_queue_;
-
- typedef base::hash_map<int32, SaveItem*> SavedItemMap;
- // saved_success_items_ is map of all saving job which are successfully saved.
- SavedItemMap saved_success_items_;
-
- // Non-owning pointer for handling file writing on the file thread.
- SaveFileManager* file_manager_;
-
- // We use a fake DownloadItem here in order to reuse the DownloadItemView.
- // This class owns the pointer.
- DownloadItem* download_;
-
- // The URL of the page the user wants to save.
- GURL page_url_;
- FilePath saved_main_file_path_;
- FilePath saved_main_directory_path_;
-
- // The title of the page the user wants to save.
- string16 title_;
-
- // Indicates whether the actual saving job is finishing or not.
- bool finished_;
-
- // Indicates whether user canceled the saving job.
- bool user_canceled_;
-
- // Indicates whether user get disk error.
- bool disk_error_occurred_;
-
- // Type about saving page as only-html or complete-html.
- SavePackageType save_type_;
-
- // Number of all need to be saved resources.
- size_t all_save_items_count_;
-
- typedef base::hash_set<FilePath::StringType> FileNameSet;
- // This set is used to eliminate duplicated file names in saving directory.
- FileNameSet file_name_set_;
-
- typedef base::hash_map<FilePath::StringType, uint32> FileNameCountMap;
- // This map is used to track serial number for specified filename.
- FileNameCountMap file_name_count_map_;
-
- // Indicates current waiting state when SavePackage try to get something
- // from outside.
- WaitState wait_state_;
-
- // Since for one tab, it can only have one SavePackage in same time.
- // Now we actually use render_process_id as tab's unique id.
- const int tab_id_;
-
- // Unique ID for this SavePackage.
- const int unique_id_;
-
- // For managing select file dialogs.
- scoped_refptr<SelectFileDialog> select_file_dialog_;
-
- friend class SavePackageTest;
- FRIEND_TEST_ALL_PREFIXES(SavePackageTest, TestSuggestedSaveNames);
- FRIEND_TEST_ALL_PREFIXES(SavePackageTest, TestLongSafePureFilename);
-
- ScopedRunnableMethodFactory<SavePackage> method_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(SavePackage);
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_H_
diff --git a/chrome/browser/download/save_package_file_picker.cc b/chrome/browser/download/save_package_file_picker.cc
new file mode 100644
index 0000000..1c32aec
--- /dev/null
+++ b/chrome/browser/download/save_package_file_picker.cc
@@ -0,0 +1,165 @@
+// 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.
+
+#include "chrome/browser/download/save_package_file_picker.h"
+
+#include "chrome/browser/download/download_manager.h"
+#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "content/browser/download/save_package.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace {
+
+// If false, we don't prompt the user as to where to save the file. This
+// exists only for testing.
+bool g_should_prompt_for_filename = true;
+
+// Used for mapping between SavePackageType constants and the indexes above.
+const SavePackage::SavePackageType kIndexToSaveType[] = {
+ SavePackage::SAVE_TYPE_UNKNOWN,
+ SavePackage::SAVE_AS_ONLY_HTML,
+ SavePackage::SAVE_AS_COMPLETE_HTML,
+};
+
+int SavePackageTypeToIndex(SavePackage::SavePackageType type) {
+ for (size_t i = 0; i < arraysize(kIndexToSaveType); ++i) {
+ if (kIndexToSaveType[i] == type)
+ return i;
+ }
+ NOTREACHED();
+ return -1;
+}
+
+// Indexes used for specifying which element in the extensions dropdown
+// the user chooses when picking a save type.
+const int kSelectFileHtmlOnlyIndex = 1;
+const int kSelectFileCompleteIndex = 2;
+
+// Used for mapping between the IDS_ string identifiers and the indexes above.
+const int kIndexToIDS[] = {
+ 0, IDS_SAVE_PAGE_DESC_HTML_ONLY, IDS_SAVE_PAGE_DESC_COMPLETE,
+};
+
+}
+
+SavePackageFilePicker::SavePackageFilePicker(SavePackage* save_package,
+ const FilePath& suggested_path,
+ bool can_save_as_complete)
+ : save_package_(save_package) {
+ // The TabContents which owns this SavePackage may have disappeared during
+ // the UI->FILE->UI thread hop of
+ // GetSaveInfo->CreateDirectoryOnFileThread->ContinueGetSaveInfo.
+ TabContents* tab_contents = save_package->tab_contents();
+ if (!tab_contents) {
+ delete this;
+ return;
+ }
+
+ DownloadPrefs* download_prefs =
+ tab_contents->profile()->GetDownloadManager()->download_prefs();
+ int file_type_index = SavePackageTypeToIndex(
+ static_cast<SavePackage::SavePackageType>(
+ download_prefs->save_file_type()));
+ DCHECK_NE(-1, file_type_index);
+
+ SelectFileDialog::FileTypeInfo file_type_info;
+ FilePath::StringType default_extension;
+
+ // If the contents can not be saved as complete-HTML, do not show the
+ // file filters.
+ if (can_save_as_complete) {
+ bool add_extra_extension = false;
+ FilePath::StringType extra_extension;
+ if (!suggested_path.Extension().empty() &&
+ suggested_path.Extension().compare(FILE_PATH_LITERAL("htm")) &&
+ suggested_path.Extension().compare(FILE_PATH_LITERAL("html"))) {
+ add_extra_extension = true;
+ extra_extension = suggested_path.Extension().substr(1);
+ }
+
+ file_type_info.extensions.resize(2);
+ file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
+ FILE_PATH_LITERAL("htm"));
+ file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
+ FILE_PATH_LITERAL("html"));
+
+ if (add_extra_extension) {
+ file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
+ extra_extension);
+ }
+
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex - 1]));
+ file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
+ FILE_PATH_LITERAL("htm"));
+ file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
+ FILE_PATH_LITERAL("html"));
+
+ if (add_extra_extension) {
+ file_type_info.extensions[kSelectFileCompleteIndex - 1].push_back(
+ extra_extension);
+ }
+
+ file_type_info.extension_description_overrides.push_back(
+ l10n_util::GetStringUTF16(kIndexToIDS[kSelectFileCompleteIndex]));
+ file_type_info.include_all_files = false;
+ default_extension = SavePackage::kDefaultHtmlExtension;
+ } else {
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1].push_back(
+ suggested_path.Extension());
+
+ if (!file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].empty()) {
+ // Drop the .
+ file_type_info.extensions[kSelectFileHtmlOnlyIndex - 1][0].erase(0, 1);
+ }
+
+ file_type_info.include_all_files = true;
+ file_type_index = 1;
+ }
+
+ if (g_should_prompt_for_filename) {
+ select_file_dialog_ = SelectFileDialog::Create(this);
+ select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
+ string16(),
+ suggested_path,
+ &file_type_info,
+ file_type_index,
+ default_extension,
+ tab_contents,
+ platform_util::GetTopLevel(
+ tab_contents->GetNativeView()),
+ NULL);
+ } else {
+ // Just use 'suggested_path' instead of opening the dialog prompt.
+ save_package_->OnPathPicked(
+ suggested_path, kIndexToSaveType[file_type_index]);
+ }
+}
+
+SavePackageFilePicker::~SavePackageFilePicker() {
+}
+
+void SavePackageFilePicker::SetShouldPromptUser(bool should_prompt) {
+ g_should_prompt_for_filename = should_prompt;
+}
+
+void SavePackageFilePicker::FileSelected(const FilePath& path,
+ int index,
+ void* params) {
+ // The option index is not zero-based.
+ DCHECK(index >= kSelectFileHtmlOnlyIndex &&
+ index <= kSelectFileCompleteIndex);
+
+ save_package_->OnPathPicked(path, kIndexToSaveType[index]);
+ delete this;
+}
+
+void SavePackageFilePicker::FileSelectionCanceled(void* params) {
+ delete this;
+}
diff --git a/chrome/browser/download/save_package_file_picker.h b/chrome/browser/download/save_package_file_picker.h
new file mode 100644
index 0000000..638f151
--- /dev/null
+++ b/chrome/browser/download/save_package_file_picker.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_FILE_PICKER_H_
+#define CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_FILE_PICKER_H_
+#pragma once
+
+#include "base/memory/ref_counted.h"
+#include "chrome/browser/ui/shell_dialogs.h"
+
+class FilePath;
+class SavePackage;
+
+// Handles showing a dialog to the user to ask for the filename to save a page.
+class SavePackageFilePicker : public SelectFileDialog::Listener {
+ public:
+ SavePackageFilePicker(SavePackage* save_package,
+ const FilePath& suggested_path,
+ bool can_save_as_complete);
+ ~SavePackageFilePicker();
+
+ // Used to disable prompting the user for a directory/filename of the saved
+ // web page. This is available for testing.
+ static void SetShouldPromptUser(bool should_prompt);
+
+ private:
+ // SelectFileDialog::Listener implementation.
+ virtual void FileSelected(const FilePath& path, int index, void* params);
+ virtual void FileSelectionCanceled(void* params);
+
+ scoped_refptr<SavePackage> save_package_;
+
+ // For managing select file dialogs.
+ scoped_refptr<SelectFileDialog> select_file_dialog_;
+
+ DISALLOW_COPY_AND_ASSIGN(SavePackageFilePicker);
+};
+
+#endif // CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_FILE_PICKER_H_
diff --git a/chrome/browser/download/save_package_unittest.cc b/chrome/browser/download/save_package_unittest.cc
deleted file mode 100644
index ac250fe..0000000
--- a/chrome/browser/download/save_package_unittest.cc
+++ /dev/null
@@ -1,426 +0,0 @@
-// 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.
-
-#include <string>
-
-#include "base/file_path.h"
-#include "base/path_service.h"
-#include "base/scoped_temp_dir.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/download/save_package.h"
-#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
-#include "content/browser/browser_thread.h"
-#include "content/browser/net/url_request_mock_http_job.h"
-#include "content/browser/tab_contents/test_tab_contents.h"
-#include "googleurl/src/gurl.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#define FPL FILE_PATH_LITERAL
-#if defined(OS_WIN)
-#define HTML_EXTENSION ".htm"
-// This second define is needed because MSVC is broken.
-#define FPL_HTML_EXTENSION L".htm"
-#else
-#define HTML_EXTENSION ".html"
-#define FPL_HTML_EXTENSION ".html"
-#endif
-
-namespace {
-
-// This constant copied from save_package.cc.
-#if defined(OS_WIN)
-const uint32 kMaxFilePathLength = MAX_PATH - 1;
-const uint32 kMaxFileNameLength = MAX_PATH - 1;
-#elif defined(OS_POSIX)
-const uint32 kMaxFilePathLength = PATH_MAX - 1;
-const uint32 kMaxFileNameLength = NAME_MAX;
-#endif
-
-// Used to make long filenames.
-std::string long_file_name(
- "EFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz01234567"
- "89ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz012345"
- "6789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz0123"
- "456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789a");
-
-bool HasOrdinalNumber(const FilePath::StringType& filename) {
- FilePath::StringType::size_type r_paren_index = filename.rfind(FPL(')'));
- FilePath::StringType::size_type l_paren_index = filename.rfind(FPL('('));
- if (l_paren_index >= r_paren_index)
- return false;
-
- for (FilePath::StringType::size_type i = l_paren_index + 1;
- i != r_paren_index; ++i) {
- if (!IsAsciiDigit(filename[i]))
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-class SavePackageTest : public TabContentsWrapperTestHarness {
- public:
- SavePackageTest() : browser_thread_(BrowserThread::UI, &message_loop_) {
- }
-
- bool GetGeneratedFilename(bool need_success_generate_filename,
- const std::string& disposition,
- const std::string& url,
- bool need_htm_ext,
- FilePath::StringType* generated_name) {
- SavePackage* save_package;
- if (need_success_generate_filename)
- save_package = save_package_success_.get();
- else
- save_package = save_package_fail_.get();
- return save_package->GenerateFileName(disposition, GURL(url), need_htm_ext,
- generated_name);
- }
-
- FilePath EnsureHtmlExtension(const FilePath& name) {
- return SavePackage::EnsureHtmlExtension(name);
- }
-
- FilePath EnsureMimeExtension(const FilePath& name,
- const std::string& content_mime_type) {
- return SavePackage::EnsureMimeExtension(name, content_mime_type);
- }
-
- GURL GetUrlToBeSaved() {
- return save_package_success_->GetUrlToBeSaved();
- }
-
- protected:
- virtual void SetUp() {
- TabContentsWrapperTestHarness::SetUp();
-
- // Do the initialization in SetUp so contents() is initialized by
- // TabContentsWrapperTestHarness::SetUp.
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-
- save_package_success_ = new SavePackage(contents_wrapper(),
- temp_dir_.path().AppendASCII("testfile" HTML_EXTENSION),
- temp_dir_.path().AppendASCII("testfile_files"));
-
- // We need to construct a path that is *almost* kMaxFilePathLength long
- long_file_name.resize(kMaxFilePathLength + long_file_name.length());
- while (long_file_name.length() < kMaxFilePathLength)
- long_file_name += long_file_name;
- long_file_name.resize(
- kMaxFilePathLength - 9 - temp_dir_.path().value().length());
-
- save_package_fail_ = new SavePackage(contents_wrapper(),
- temp_dir_.path().AppendASCII(long_file_name + HTML_EXTENSION),
- temp_dir_.path().AppendASCII(long_file_name + "_files"));
- }
-
- private:
- BrowserThread browser_thread_;
-
- // SavePackage for successfully generating file name.
- scoped_refptr<SavePackage> save_package_success_;
- // SavePackage for failed generating file name.
- scoped_refptr<SavePackage> save_package_fail_;
-
- ScopedTempDir temp_dir_;
-
- DISALLOW_COPY_AND_ASSIGN(SavePackageTest);
-};
-
-static const struct {
- const char* disposition;
- const char* url;
- const FilePath::CharType* expected_name;
- bool need_htm_ext;
-} kGeneratedFiles[] = {
- // We mainly focus on testing duplicated names here, since retrieving file
- // name from disposition and url has been tested in DownloadManagerTest.
-
- // No useful information in disposition or URL, use default.
- {"1.html", "http://www.savepage.com/",
- FPL("saved_resource") FPL_HTML_EXTENSION, true},
-
- // No duplicate occurs.
- {"filename=1.css", "http://www.savepage.com", FPL("1.css"), false},
-
- // No duplicate occurs.
- {"filename=1.js", "http://www.savepage.com", FPL("1.js"), false},
-
- // Append numbers for duplicated names.
- {"filename=1.css", "http://www.savepage.com", FPL("1(1).css"), false},
-
- // No duplicate occurs.
- {"filename=1(1).js", "http://www.savepage.com", FPL("1(1).js"), false},
-
- // Append numbers for duplicated names.
- {"filename=1.css", "http://www.savepage.com", FPL("1(2).css"), false},
-
- // Change number for duplicated names.
- {"filename=1(1).css", "http://www.savepage.com", FPL("1(3).css"), false},
-
- // No duplicate occurs.
- {"filename=1(11).css", "http://www.savepage.com", FPL("1(11).css"), false},
-};
-
-TEST_F(SavePackageTest, TestSuccessfullyGenerateSavePackageFilename) {
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGeneratedFiles); ++i) {
- FilePath::StringType file_name;
- bool ok = GetGeneratedFilename(true,
- kGeneratedFiles[i].disposition,
- kGeneratedFiles[i].url,
- kGeneratedFiles[i].need_htm_ext,
- &file_name);
- ASSERT_TRUE(ok);
- EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name);
- }
-}
-
-TEST_F(SavePackageTest, TestUnSuccessfullyGenerateSavePackageFilename) {
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGeneratedFiles); ++i) {
- FilePath::StringType file_name;
- bool ok = GetGeneratedFilename(false,
- kGeneratedFiles[i].disposition,
- kGeneratedFiles[i].url,
- kGeneratedFiles[i].need_htm_ext,
- &file_name);
- ASSERT_FALSE(ok);
- }
-}
-
-// Crashing on Windows, see http://crbug.com/79365
-#if defined(OS_WIN)
-#define MAYBE_TestLongSavePackageFilename DISABLED_TestLongSavePackageFilename
-#else
-#define MAYBE_TestLongSavePackageFilename TestLongSavePackageFilename
-#endif
-TEST_F(SavePackageTest, MAYBE_TestLongSavePackageFilename) {
- const std::string base_url("http://www.google.com/");
- const std::string long_file = long_file_name + ".css";
- const std::string url = base_url + long_file;
-
- FilePath::StringType filename;
- // Test that the filename is successfully shortened to fit.
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
- EXPECT_TRUE(filename.length() < long_file.length());
- EXPECT_FALSE(HasOrdinalNumber(filename));
-
- // Test that the filename is successfully shortened to fit, and gets an
- // an ordinal appended.
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename));
- EXPECT_TRUE(filename.length() < long_file.length());
- EXPECT_TRUE(HasOrdinalNumber(filename));
-
- // Test that the filename is successfully shortened to fit, and gets a
- // different ordinal appended.
- FilePath::StringType filename2;
- ASSERT_TRUE(GetGeneratedFilename(true, "", url, false, &filename2));
- EXPECT_TRUE(filename2.length() < long_file.length());
- EXPECT_TRUE(HasOrdinalNumber(filename2));
- EXPECT_NE(filename, filename2);
-}
-
-// Crashing on Windows, see http://crbug.com/79365
-#if defined(OS_WIN)
-#define MAYBE_TestLongSafePureFilename DISABLED_TestLongSafePureFilename
-#else
-#define MAYBE_TestLongSafePureFilename TestLongSafePureFilename
-#endif
-TEST_F(SavePackageTest, MAYBE_TestLongSafePureFilename) {
- const FilePath save_dir(FPL("test_dir"));
- const FilePath::StringType ext(FPL_HTML_EXTENSION);
- FilePath::StringType filename =
-#if defined(OS_WIN)
- ASCIIToWide(long_file_name);
-#else
- long_file_name;
-#endif
-
- // Test that the filename + extension doesn't exceed kMaxFileNameLength
- uint32 max_path = SavePackage::GetMaxPathLengthForDirectory(save_dir);
- ASSERT_TRUE(SavePackage::GetSafePureFileName(save_dir, ext, max_path,
- &filename));
- EXPECT_TRUE(filename.length() <= kMaxFileNameLength-ext.length());
-}
-
-static const struct {
- const FilePath::CharType* page_title;
- const FilePath::CharType* expected_name;
-} kExtensionTestCases[] = {
- // Extension is preserved if it is already proper for HTML.
- {FPL("filename.html"), FPL("filename.html")},
- {FPL("filename.HTML"), FPL("filename.HTML")},
- {FPL("filename.XHTML"), FPL("filename.XHTML")},
- {FPL("filename.xhtml"), FPL("filename.xhtml")},
- {FPL("filename.htm"), FPL("filename.htm")},
- // ".htm" is added if the extension is improper for HTML.
- {FPL("hello.world"), FPL("hello.world") FPL_HTML_EXTENSION},
- {FPL("hello.txt"), FPL("hello.txt") FPL_HTML_EXTENSION},
- {FPL("is.html.good"), FPL("is.html.good") FPL_HTML_EXTENSION},
- // ".htm" is added if the name doesn't have an extension.
- {FPL("helloworld"), FPL("helloworld") FPL_HTML_EXTENSION},
- {FPL("helloworld."), FPL("helloworld.") FPL_HTML_EXTENSION},
-};
-
-// Crashing on Windows, see http://crbug.com/79365
-#if defined(OS_WIN)
-#define MAYBE_TestEnsureHtmlExtension DISABLED_TestEnsureHtmlExtension
-#else
-#define MAYBE_TestEnsureHtmlExtension TestEnsureHtmlExtension
-#endif
-TEST_F(SavePackageTest, MAYBE_TestEnsureHtmlExtension) {
- for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kExtensionTestCases); ++i) {
- FilePath original = FilePath(kExtensionTestCases[i].page_title);
- FilePath expected = FilePath(kExtensionTestCases[i].expected_name);
- FilePath actual = EnsureHtmlExtension(original);
- EXPECT_EQ(expected.value(), actual.value()) << "Failed for page title: " <<
- kExtensionTestCases[i].page_title;
- }
-}
-
-// Crashing on Windows, see http://crbug.com/79365
-#if defined(OS_WIN)
-#define MAYBE_TestEnsureMimeExtension DISABLED_TestEnsureMimeExtension
-#else
-#define MAYBE_TestEnsureMimeExtension TestEnsureMimeExtension
-#endif
-TEST_F(SavePackageTest, MAYBE_TestEnsureMimeExtension) {
- static const struct {
- const FilePath::CharType* page_title;
- const FilePath::CharType* expected_name;
- const char* contents_mime_type;
- } kExtensionTests[] = {
- { FPL("filename.html"), FPL("filename.html"), "text/html" },
- { FPL("filename.htm"), FPL("filename.htm"), "text/html" },
- { FPL("filename.xhtml"), FPL("filename.xhtml"), "text/html" },
-#if defined(OS_WIN)
- { FPL("filename"), FPL("filename.htm"), "text/html" },
-#else // defined(OS_WIN)
- { FPL("filename"), FPL("filename.html"), "text/html" },
-#endif // defined(OS_WIN)
- { FPL("filename.html"), FPL("filename.html"), "text/xml" },
- { FPL("filename.xml"), FPL("filename.xml"), "text/xml" },
- { FPL("filename"), FPL("filename.xml"), "text/xml" },
- { FPL("filename.xhtml"), FPL("filename.xhtml"),
- "application/xhtml+xml" },
- { FPL("filename.html"), FPL("filename.html"),
- "application/xhtml+xml" },
- { FPL("filename"), FPL("filename.xhtml"), "application/xhtml+xml" },
- { FPL("filename.txt"), FPL("filename.txt"), "text/plain" },
- { FPL("filename"), FPL("filename.txt"), "text/plain" },
- { FPL("filename.css"), FPL("filename.css"), "text/css" },
- { FPL("filename"), FPL("filename.css"), "text/css" },
- { FPL("filename.abc"), FPL("filename.abc"), "unknown/unknown" },
- { FPL("filename"), FPL("filename"), "unknown/unknown" },
- };
- for (uint32 i = 0; i < ARRAYSIZE_UNSAFE(kExtensionTests); ++i) {
- FilePath original = FilePath(kExtensionTests[i].page_title);
- FilePath expected = FilePath(kExtensionTests[i].expected_name);
- std::string mime_type(kExtensionTests[i].contents_mime_type);
- FilePath actual = EnsureMimeExtension(original, mime_type);
- EXPECT_EQ(expected.value(), actual.value()) << "Failed for page title: " <<
- kExtensionTests[i].page_title << " MIME:" << mime_type;
- }
-}
-
-// Test that the suggested names generated by SavePackage are reasonable:
-// If the name is a URL, retrieve only the path component since the path name
-// generation code will turn the entire URL into the file name leading to bad
-// extension names. For example, a page with no title and a URL:
-// http://www.foo.com/a/path/name.txt will turn into file:
-// "http www.foo.com a path name.txt", when we want to save it as "name.txt".
-
-static const struct SuggestedSaveNameTestCase {
- const char* page_url;
- const string16 page_title;
- const FilePath::CharType* expected_name;
- bool ensure_html_extension;
-} kSuggestedSaveNames[] = {
- // Title overrides the URL.
- { "http://foo.com",
- ASCIIToUTF16("A page title"),
- FPL("A page title") FPL_HTML_EXTENSION,
- true
- },
- // Extension is preserved.
- { "http://foo.com",
- ASCIIToUTF16("A page title with.ext"),
- FPL("A page title with.ext"),
- false
- },
- // If the title matches the URL, use the last component of the URL.
- { "http://foo.com/bar",
- ASCIIToUTF16("http://foo.com/bar"),
- FPL("bar"),
- false
- },
- // If the title matches the URL, but there is no "filename" component,
- // use the domain.
- { "http://foo.com",
- ASCIIToUTF16("http://foo.com"),
- FPL("foo.com"),
- false
- },
- // Make sure fuzzy matching works.
- { "http://foo.com/bar",
- ASCIIToUTF16("foo.com/bar"),
- FPL("bar"),
- false
- },
- // A URL-like title that does not match the title is respected in full.
- { "http://foo.com",
- ASCIIToUTF16("http://www.foo.com/path/title.txt"),
- FPL("http www.foo.com path title.txt"),
- false
- },
-};
-
-// Crashing on Windows, see http://crbug.com/79365
-#if defined(OS_WIN)
-#define MAYBE_TestSuggestedSaveNames DISABLED_TestSuggestedSaveNames
-#else
-#define MAYBE_TestSuggestedSaveNames TestSuggestedSaveNames
-#endif
-TEST_F(SavePackageTest, MAYBE_TestSuggestedSaveNames) {
- for (size_t i = 0; i < arraysize(kSuggestedSaveNames); ++i) {
- scoped_refptr<SavePackage> save_package(
- new SavePackage(contents_wrapper(), FilePath(), FilePath()));
- save_package->page_url_ = GURL(kSuggestedSaveNames[i].page_url);
- save_package->title_ = kSuggestedSaveNames[i].page_title;
-
- FilePath save_name = save_package->GetSuggestedNameForSaveAs(
- kSuggestedSaveNames[i].ensure_html_extension,
- std::string());
- EXPECT_EQ(kSuggestedSaveNames[i].expected_name, save_name.value()) <<
- "Test case " << i;
- }
-}
-
-static const FilePath::CharType* kTestDir = FILE_PATH_LITERAL("save_page");
-
-// GetUrlToBeSaved method should return correct url to be saved.
-TEST_F(SavePackageTest, TestGetUrlToBeSaved) {
- FilePath file_name(FILE_PATH_LITERAL("a.htm"));
- GURL url = URLRequestMockHTTPJob::GetMockUrl(
- FilePath(kTestDir).Append(file_name));
- NavigateAndCommit(url);
- EXPECT_EQ(url, GetUrlToBeSaved());
-}
-
-// GetUrlToBeSaved method sould return actual url to be saved,
-// instead of the displayed url used to view source of a page.
-// Ex:GetUrlToBeSaved method should return http://www.google.com
-// when user types view-source:http://www.google.com
-TEST_F(SavePackageTest, TestGetUrlToBeSavedViewSource) {
- FilePath file_name(FILE_PATH_LITERAL("a.htm"));
- GURL view_source_url = URLRequestMockHTTPJob::GetMockViewSourceUrl(
- FilePath(kTestDir).Append(file_name));
- GURL actual_url = URLRequestMockHTTPJob::GetMockUrl(
- FilePath(kTestDir).Append(file_name));
- NavigateAndCommit(view_source_url);
- EXPECT_EQ(actual_url, GetUrlToBeSaved());
- EXPECT_EQ(view_source_url, contents()->GetURL());
-}
diff --git a/chrome/browser/download/save_page_uitest.cc b/chrome/browser/download/save_page_uitest.cc
index 0126c6a..9f5f9cc 100644
--- a/chrome/browser/download/save_page_uitest.cc
+++ b/chrome/browser/download/save_page_uitest.cc
@@ -7,13 +7,13 @@
#include "base/string_util.h"
#include "base/test/test_file_util.h"
#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/automation/automation_proxy.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "chrome/test/ui_test_utils.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/net/url_request_mock_http_job.h"
#include "net/url_request/url_request_test_util.h"
diff --git a/chrome/browser/download/save_types.cc b/chrome/browser/download/save_types.cc
deleted file mode 100644
index d65b4d7..0000000
--- a/chrome/browser/download/save_types.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2010 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.
-
-#include "chrome/browser/download/save_types.h"
-
-
-SaveFileCreateInfo::SaveFileCreateInfo(const FilePath& path,
- const GURL& url,
- SaveFileSource save_source,
- int32 save_id)
- : path(path),
- url(url),
- save_id(save_id),
- render_process_id(-1),
- render_view_id(-1),
- request_id(-1),
- total_bytes(0),
- save_source(save_source) {
-}
-
-SaveFileCreateInfo::SaveFileCreateInfo()
- : save_id(-1),
- render_process_id(-1),
- render_view_id(-1),
- request_id(-1),
- total_bytes(0),
- save_source(SAVE_FILE_FROM_UNKNOWN) {
-}
-
-SaveFileCreateInfo::~SaveFileCreateInfo() {}
diff --git a/chrome/browser/download/save_types.h b/chrome/browser/download/save_types.h
deleted file mode 100644
index 8295106..0000000
--- a/chrome/browser/download/save_types.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2010 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.
-
-#ifndef CHROME_BROWSER_DOWNLOAD_SAVE_TYPES_H_
-#define CHROME_BROWSER_DOWNLOAD_SAVE_TYPES_H_
-#pragma once
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/file_path.h"
-#include "googleurl/src/gurl.h"
-
-typedef std::vector<std::pair<int, FilePath> > FinalNameList;
-typedef std::vector<int> SaveIDList;
-
-// This structure is used to handle and deliver some info
-// when processing each save item job.
-struct SaveFileCreateInfo {
- enum SaveFileSource {
- // This type indicates the source is not set.
- SAVE_FILE_FROM_UNKNOWN = -1,
- // This type indicates the save item needs to be retrieved from the network.
- SAVE_FILE_FROM_NET = 0,
- // This type indicates the save item needs to be retrieved from serializing
- // DOM.
- SAVE_FILE_FROM_DOM,
- // This type indicates the save item needs to be retrieved from local file
- // system.
- SAVE_FILE_FROM_FILE
- };
-
- SaveFileCreateInfo(const FilePath& path,
- const GURL& url,
- SaveFileSource save_source,
- int32 save_id);
-
- SaveFileCreateInfo();
-
- ~SaveFileCreateInfo();
-
- // SaveItem fields.
- // The local file path of saved file.
- FilePath path;
- // Original URL of the saved resource.
- GURL url;
- // Final URL of the saved resource since some URL might be redirected.
- GURL final_url;
- // The unique identifier for saving job, assigned at creation by
- // the SaveFileManager for its internal record keeping.
- int save_id;
- // IDs for looking up the tab we are associated with.
- int render_process_id;
- int render_view_id;
- // Handle for informing the ResourceDispatcherHost of a UI based cancel.
- int request_id;
- // Disposition info from HTTP response.
- std::string content_disposition;
- // Total bytes of saved file.
- int64 total_bytes;
- // Source type of saved file.
- SaveFileSource save_source;
-};
-
-#endif // CHROME_BROWSER_DOWNLOAD_SAVE_TYPES_H_
diff --git a/chrome/browser/renderer_host/DEPS b/chrome/browser/renderer_host/DEPS
index 1c0609d5..549ec50 100644
--- a/chrome/browser/renderer_host/DEPS
+++ b/chrome/browser/renderer_host/DEPS
@@ -1,9 +1,7 @@
include_rules = [
# DO NOT ALLOW tab_contents INCLUDES FROM THIS DIRECTORY! The renderer_host
# layer should be usable in contexts other than inside TabContents. Instead,
- # you should call upward through the RenderViewHostDelegate interface. If
- # your test needs some TabContents code, you can put it in renderer_host/test
- # which can include more stuff for testing purposes.
+ # you should call upward through the RenderViewHostDelegate interface.
#
# If somebody adds an include and you're fixing the build, please revert them
# instead of commenting out this rule.
diff --git a/chrome/browser/renderer_host/save_file_resource_handler.cc b/chrome/browser/renderer_host/save_file_resource_handler.cc
deleted file mode 100644
index 6f374b5..0000000
--- a/chrome/browser/renderer_host/save_file_resource_handler.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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.
-
-#include "chrome/browser/renderer_host/save_file_resource_handler.h"
-
-#include "base/logging.h"
-#include "base/message_loop.h"
-#include "base/string_number_conversions.h"
-#include "chrome/browser/download/save_file_manager.h"
-#include "content/browser/browser_thread.h"
-#include "net/base/io_buffer.h"
-#include "net/url_request/url_request_status.h"
-
-SaveFileResourceHandler::SaveFileResourceHandler(int render_process_host_id,
- int render_view_id,
- const GURL& url,
- SaveFileManager* manager)
- : save_id_(-1),
- render_process_id_(render_process_host_id),
- render_view_id_(render_view_id),
- url_(url),
- content_length_(0),
- save_manager_(manager) {
-}
-
-bool SaveFileResourceHandler::OnUploadProgress(int request_id,
- uint64 position,
- uint64 size) {
- return true;
-}
-
-bool SaveFileResourceHandler::OnRequestRedirected(int request_id,
- const GURL& url,
- ResourceResponse* response,
- bool* defer) {
- final_url_ = url;
- return true;
-}
-
-bool SaveFileResourceHandler::OnResponseStarted(int request_id,
- ResourceResponse* response) {
- save_id_ = save_manager_->GetNextId();
- // |save_manager_| consumes (deletes):
- SaveFileCreateInfo* info = new SaveFileCreateInfo;
- info->url = url_;
- info->final_url = final_url_;
- info->total_bytes = content_length_;
- info->save_id = save_id_;
- info->render_process_id = render_process_id_;
- info->render_view_id = render_view_id_;
- info->request_id = request_id;
- info->content_disposition = content_disposition_;
- info->save_source = SaveFileCreateInfo::SAVE_FILE_FROM_NET;
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(save_manager_,
- &SaveFileManager::StartSave,
- info));
- return true;
-}
-
-bool SaveFileResourceHandler::OnWillStart(int request_id,
- const GURL& url,
- bool* defer) {
- return true;
-}
-
-bool SaveFileResourceHandler::OnWillRead(int request_id, net::IOBuffer** buf,
- int* buf_size, int min_size) {
- DCHECK(buf && buf_size);
- if (!read_buffer_) {
- *buf_size = min_size < 0 ? kReadBufSize : min_size;
- read_buffer_ = new net::IOBuffer(*buf_size);
- }
- *buf = read_buffer_.get();
- return true;
-}
-
-bool SaveFileResourceHandler::OnReadCompleted(int request_id, int* bytes_read) {
- DCHECK(read_buffer_);
- // We are passing ownership of this buffer to the save file manager.
- scoped_refptr<net::IOBuffer> buffer;
- read_buffer_.swap(buffer);
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(save_manager_,
- &SaveFileManager::UpdateSaveProgress,
- save_id_,
- buffer,
- *bytes_read));
- return true;
-}
-
-bool SaveFileResourceHandler::OnResponseCompleted(
- int request_id,
- const net::URLRequestStatus& status,
- const std::string& security_info) {
- BrowserThread::PostTask(
- BrowserThread::FILE, FROM_HERE,
- NewRunnableMethod(save_manager_,
- &SaveFileManager::SaveFinished,
- save_id_,
- url_,
- render_process_id_,
- status.is_success() && !status.is_io_pending()));
- read_buffer_ = NULL;
- return true;
-}
-
-void SaveFileResourceHandler::OnRequestClosed() {
-}
-
-void SaveFileResourceHandler::set_content_length(
- const std::string& content_length) {
- base::StringToInt64(content_length, &content_length_);
-}
-
-SaveFileResourceHandler::~SaveFileResourceHandler() {}
diff --git a/chrome/browser/renderer_host/save_file_resource_handler.h b/chrome/browser/renderer_host/save_file_resource_handler.h
deleted file mode 100644
index a112b33..0000000
--- a/chrome/browser/renderer_host/save_file_resource_handler.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_RENDERER_HOST_SAVE_FILE_RESOURCE_HANDLER_H_
-#define CHROME_BROWSER_RENDERER_HOST_SAVE_FILE_RESOURCE_HANDLER_H_
-#pragma once
-
-#include <string>
-
-#include "content/browser/renderer_host/resource_handler.h"
-#include "googleurl/src/gurl.h"
-
-class SaveFileManager;
-
-// Forwards data to the save thread.
-class SaveFileResourceHandler : public ResourceHandler {
- public:
- SaveFileResourceHandler(int render_process_host_id,
- int render_view_id,
- const GURL& url,
- SaveFileManager* manager);
-
- // ResourceHandler Implementation:
- virtual bool OnUploadProgress(int request_id, uint64 position, uint64 size);
-
- // Saves the redirected URL to final_url_, we need to use the original
- // URL to match original request.
- virtual bool OnRequestRedirected(int request_id, const GURL& url,
- ResourceResponse* response, bool* defer);
-
- // Sends the download creation information to the download thread.
- virtual bool OnResponseStarted(int request_id, ResourceResponse* response);
-
- // Pass-through implementation.
- virtual bool OnWillStart(int request_id, const GURL& url, bool* defer);
-
- // Creates a new buffer, which will be handed to the download thread for file
- // writing and deletion.
- virtual bool OnWillRead(int request_id, net::IOBuffer** buf, int* buf_size,
- int min_size);
-
- // Passes the buffer to the download file writer.
- virtual bool OnReadCompleted(int request_id, int* bytes_read);
-
- virtual bool OnResponseCompleted(int request_id,
- const net::URLRequestStatus& status,
- const std::string& security_info);
-
- virtual void OnRequestClosed();
-
- // If the content-length header is not present (or contains something other
- // than numbers), StringToInt64 returns 0, which indicates 'unknown size' and
- // is handled correctly by the SaveManager.
- void set_content_length(const std::string& content_length);
-
- void set_content_disposition(const std::string& content_disposition) {
- content_disposition_ = content_disposition;
- }
-
- private:
- virtual ~SaveFileResourceHandler();
-
- int save_id_;
- int render_process_id_;
- int render_view_id_;
- scoped_refptr<net::IOBuffer> read_buffer_;
- std::string content_disposition_;
- GURL url_;
- GURL final_url_;
- int64 content_length_;
- SaveFileManager* save_manager_;
-
- static const int kReadBufSize = 32768; // bytes
-
- DISALLOW_COPY_AND_ASSIGN(SaveFileResourceHandler);
-};
-
-#endif // CHROME_BROWSER_RENDERER_HOST_SAVE_FILE_RESOURCE_HANDLER_H_
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index 0121bcd..b3d0d5e 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -21,7 +21,6 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/extension_event_router.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/net/browser_url_util.h"
@@ -52,6 +51,7 @@
#include "chrome/common/url_constants.h"
#include "content/browser/child_process_security_policy.h"
#include "content/browser/debugger/devtools_window.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/navigation_entry.h"
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index f21df63..294d5d1 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -34,7 +34,6 @@
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/download/download_started_animation.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
@@ -110,6 +109,7 @@
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/devtools_toggle_action.h"
#include "content/browser/debugger/devtools_window.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/host_zoom_map.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/site_instance.h"
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
index f233d5a..cdbf030 100644
--- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
+++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -9,13 +9,13 @@
#import "base/memory/scoped_nsobject.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/download/save_package.h"
#include "chrome/browser/sessions/restore_tab_helper.h"
#include "chrome/browser/sessions/session_id.h"
#include "chrome/browser/ui/cocoa/applescript/error_applescript.h"
#include "chrome/browser/ui/download/download_tab_helper.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/common/url_constants.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/navigation_entry.h"
diff --git a/chrome/browser/ui/download/download_tab_helper.h b/chrome/browser/ui/download/download_tab_helper.h
index ac55913..e6c613c 100644
--- a/chrome/browser/ui/download/download_tab_helper.h
+++ b/chrome/browser/ui/download/download_tab_helper.h
@@ -7,7 +7,7 @@
#pragma once
#include "base/basictypes.h"
-#include "chrome/browser/download/save_package.h"
+#include "content/browser/download/save_package.h"
#include "content/browser/tab_contents/tab_contents_observer.h"
class DownloadItem;