diff options
Diffstat (limited to 'chrome/browser')
21 files changed, 177 insertions, 77 deletions
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc index 1e4428d..5edee1a 100644 --- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc +++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc @@ -188,6 +188,8 @@ void KioskModeScreensaver::ScreensaverPathCallback( Extension::COMPONENT, Extension::NO_FLAGS, extensions_dir, + content::BrowserThread::GetMessageLoopProxyForThread( + content::BrowserThread::FILE), new ScreensaverUnpackerClient( screensaver_crx, base::Bind( diff --git a/chrome/browser/component_updater/component_updater_service.cc b/chrome/browser/component_updater/component_updater_service.cc index b141a42..654b9cb 100644 --- a/chrome/browser/component_updater/component_updater_service.cc +++ b/chrome/browser/component_updater/component_updater_service.cc @@ -605,7 +605,8 @@ void CrxUpdateService::ParseManifest(const std::string& xml) { } } else { UtilityProcessHost* host = UtilityProcessHost::Create( - new ManifestParserBridge(this), BrowserThread::UI); + new ManifestParserBridge(this), + base::MessageLoopProxy::current()); host->EnableZygote(); host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml)); } diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc index 58ec543..d934b99 100644 --- a/chrome/browser/extensions/api/management/management_api.cc +++ b/chrome/browser/extensions/api/management/management_api.cc @@ -290,7 +290,9 @@ class SafeManifestJSONParser : public UtilityProcessHostClient { void StartWorkOnIOThread() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); UtilityProcessHost* host = - UtilityProcessHost::Create(this, BrowserThread::IO); + UtilityProcessHost::Create( + this, + base::MessageLoopProxy::current()); host->EnableZygote(); host->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); } diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 0ee089b..3c8354c 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -13,10 +13,12 @@ #include "base/metrics/histogram.h" #include "base/path_service.h" #include "base/scoped_temp_dir.h" +#include "base/sequenced_task_runner.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/time.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/utf_string_conversions.h" #include "base/version.h" #include "chrome/browser/browser_process.h" @@ -105,6 +107,7 @@ CrxInstaller::CrxInstaller( requirements_checker_(new extensions::RequirementsChecker()), has_requirement_errors_(false), install_wait_for_idle_(true) { + installer_task_runner_ = frontend_weak->GetFileTaskRunner(); if (!approval) return; @@ -128,19 +131,6 @@ CrxInstaller::CrxInstaller( } CrxInstaller::~CrxInstaller() { - // Delete the temp directory and crx file as necessary. Note that the - // destructor might be called on any thread, so we post a task to the file - // thread to make sure the delete happens there. This is a best effort - // operation since the browser can be shutting down so there might not - // be a file thread to post to. - if (!temp_dir_.value().empty()) { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::Bind(&extension_file_util::DeleteFile, temp_dir_, true)); - } - if (delete_source_) { - BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, - base::Bind(&extension_file_util::DeleteFile, source_file_, false)); - } // Make sure the UI is deleted on the ui thread. if (client_) { BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, client_); @@ -158,10 +148,11 @@ void CrxInstaller::InstallCrx(const FilePath& source_file) { install_source_, creation_flags_, install_directory_, + installer_task_runner_, this)); - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!installer_task_runner_->PostTask( + FROM_HERE, base::Bind(&SandboxedUnpacker::Start, unpacker.get()))) NOTREACHED(); } @@ -173,8 +164,8 @@ void CrxInstaller::InstallUserScript(const FilePath& source_file, source_file_ = source_file; download_url_ = download_url; - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!installer_task_runner_->PostTask( + FROM_HERE, base::Bind(&CrxInstaller::ConvertUserScriptOnFileThread, this))) NOTREACHED(); } @@ -192,8 +183,8 @@ void CrxInstaller::ConvertUserScriptOnFileThread() { } void CrxInstaller::InstallWebApp(const WebApplicationInfo& web_app) { - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!installer_task_runner_->PostTask( + FROM_HERE, base::Bind(&CrxInstaller::ConvertWebAppOnFileThread, this, web_app, @@ -218,7 +209,7 @@ void CrxInstaller::ConvertWebAppOnFileThread( } CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); // Make sure the expected ID matches if one was supplied or if we want to // bypass the prompt. @@ -347,7 +338,7 @@ CrxInstallerError CrxInstaller::AllowInstall(const Extension* extension) { } void CrxInstaller::OnUnpackFailure(const string16& error_message) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackFailureInstallSource", install_source(), Extension::NUM_LOCATIONS); @@ -363,7 +354,7 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, const FilePath& extension_dir, const DictionaryValue* original_manifest, const Extension* extension) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); UMA_HISTOGRAM_ENUMERATION("Extensions.UnpackSuccessInstallSource", install_source(), Extension::NUM_LOCATIONS); @@ -462,8 +453,8 @@ void CrxInstaller::ConfirmInstall() { AddRef(); // Balanced in Proceed() and Abort(). client_->ConfirmInstall(this, extension_.get(), show_dialog_callback_); } else { - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!installer_task_runner_->PostTask( + FROM_HERE, base::Bind(&CrxInstaller::CompleteInstall, this))) NOTREACHED(); } @@ -471,8 +462,8 @@ void CrxInstaller::ConfirmInstall() { } void CrxInstaller::InstallUIProceed() { - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!installer_task_runner_->PostTask( + FROM_HERE, base::Bind(&CrxInstaller::CompleteInstall, this))) NOTREACHED(); @@ -502,7 +493,7 @@ void CrxInstaller::InstallUIAbort(bool user_initiated) { } void CrxInstaller::CompleteInstall() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); if (!current_version_.empty()) { Version current_version(current_version_); @@ -561,7 +552,7 @@ void CrxInstaller::CompleteInstall() { } void CrxInstaller::ReportFailureFromFileThread(const CrxInstallerError& error) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); if (!BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(&CrxInstaller::ReportFailureFromUIThread, this, error))) { @@ -590,10 +581,13 @@ void CrxInstaller::ReportFailureFromUIThread(const CrxInstallerError& error) { client_->OnInstallFailure(error); NotifyCrxInstallComplete(NULL); + + // Delete temporary files. + CleanupTempFiles(); } void CrxInstaller::ReportSuccessFromFileThread() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + DCHECK(installer_task_runner_->RunsTasksOnCurrentThread()); // Tracking number of extensions installed by users if (install_cause() == extension_misc::INSTALL_CAUSE_USER_DOWNLOAD) @@ -603,6 +597,9 @@ void CrxInstaller::ReportSuccessFromFileThread() { BrowserThread::UI, FROM_HERE, base::Bind(&CrxInstaller::ReportSuccessFromUIThread, this))) NOTREACHED(); + + // Delete temporary files. + CleanupTempFiles(); } void CrxInstaller::ReportSuccessFromUIThread() { @@ -654,4 +651,26 @@ void CrxInstaller::NotifyCrxInstallComplete(const Extension* extension) { content::Details<const Extension>(extension)); } +void CrxInstaller::CleanupTempFiles() { + if (!installer_task_runner_->RunsTasksOnCurrentThread()) { + if (!installer_task_runner_->PostTask( + FROM_HERE, + base::Bind(&CrxInstaller::CleanupTempFiles, this))) { + NOTREACHED(); + } + return; + } + + // Delete the temp directory and crx file as necessary. + if (!temp_dir_.value().empty()) { + extension_file_util::DeleteFile(temp_dir_, true); + temp_dir_ = FilePath(); + } + + if (delete_source_ && !source_file_.value().empty()) { + extension_file_util::DeleteFile(source_file_, false); + source_file_ = FilePath(); + } +} + } // namespace extensions diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 5d2d195..0f0019f 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -21,8 +21,13 @@ #include "sync/api/string_ordinal.h" class ExtensionService; +class ExtensionServiceTest; class SkBitmap; +namespace base { +class SequencedTaskRunner; +} + namespace extensions { class ExtensionUpdaterTest; class RequirementsChecker; @@ -184,6 +189,7 @@ class CrxInstaller Profile* profile() { return profile_; } private: + friend class ::ExtensionServiceTest; friend class ExtensionUpdaterTest; friend class ExtensionCrxInstallerTest; @@ -235,6 +241,12 @@ class CrxInstaller void ReportSuccessFromUIThread(); void NotifyCrxInstallComplete(const Extension* extension); + // Deletes temporary directory and crx file if needed. + void CleanupTempFiles(); + + // Creates sequenced task runner for extension install file I/O operations. + scoped_refptr<base::SequencedTaskRunner> CreateSequencedTaskRunner(); + // The file we're installing. FilePath source_file_; @@ -371,6 +383,9 @@ class CrxInstaller bool install_wait_for_idle_; + // Sequenced task runner where file I/O operations will be performed. + scoped_refptr<base::SequencedTaskRunner> installer_task_runner_; + // Used to show the install dialog. ExtensionInstallPrompt::ShowDialogCallback show_dialog_callback_; diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 9499f21..4063742 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -19,6 +19,7 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/stringprintf.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" #include "base/time.h" #include "base/utf_string_conversions.h" @@ -243,6 +244,11 @@ void ExtensionService::CheckExternalUninstall(const std::string& id) { UninstallExtension(id, true, NULL); } +void ExtensionService::SetFileTaskRunnerForTesting( + base::SequencedTaskRunner* task_runner) { + file_task_runner_ = task_runner; +} + void ExtensionService::ClearProvidersForTesting() { external_extension_providers_.clear(); } @@ -634,8 +640,8 @@ bool ExtensionService::UpdateExtension(const std::string& id, << " because it is not installed or pending"; // Delete extension_path since we're not creating a CrxInstaller // that would do it for us. - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!GetFileTaskRunner()->PostTask( + FROM_HERE, base::Bind( &extension_file_util::DeleteFile, extension_path, false))) NOTREACHED(); @@ -826,8 +832,8 @@ bool ExtensionService::UninstallExtension( // Tell the backend to start deleting installed extensions on the file thread. if (Extension::LOAD != extension->location()) { - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!GetFileTaskRunner()->PostTask( + FROM_HERE, base::Bind( &extension_file_util::UninstallExtension, install_directory_, @@ -1238,6 +1244,22 @@ bool ExtensionService::is_ready() { return ready_; } +base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { + if (file_task_runner_) + return file_task_runner_; + + // We should be able to interrupt any part of extension install process during + // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks + // will be ignored/deleted while we will block on started tasks. + std::string token("ext_install-"); + token.append(profile_->GetPath().AsUTF8Unsafe()); + file_task_runner_ = BrowserThread::GetBlockingPool()-> + GetSequencedTaskRunnerWithShutdownBehavior( + BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); + return file_task_runner_; +} + extensions::ExtensionUpdater* ExtensionService::updater() { return updater_.get(); } @@ -1982,8 +2004,8 @@ void ExtensionService::GarbageCollectExtensions() { extension_paths.insert(std::make_pair(info->at(i)->extension_id, info->at(i)->extension_path)); - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!GetFileTaskRunner()->PostTask( + FROM_HERE, base::Bind( &extension_file_util::GarbageCollectExtensions, install_directory_, @@ -2284,8 +2306,8 @@ void ExtensionService::OnExtensionInstalled( // Delete the extension directory since we're not going to // load it. - if (!BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + if (!GetFileTaskRunner()->PostTask( + FROM_HERE, base::Bind(&extension_file_util::DeleteFile, extension->path(), true))) { NOTREACHED(); diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 23ef9aa..23542e9 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -50,6 +50,10 @@ class GURL; class Profile; class Version; +namespace base { +class SequencedTaskRunner; +} + namespace chromeos { class ExtensionInputMethodEventRouter; } @@ -132,6 +136,9 @@ class ExtensionServiceInterface : public syncer::SyncableService { const extensions::Extension& extension) = 0; virtual bool is_ready() = 0; + + // Returns task runner for crx installation file I/O operations. + virtual base::SequencedTaskRunner* GetFileTaskRunner() = 0; }; // Manages installed and running Chromium extensions. @@ -509,6 +516,8 @@ class ExtensionService // Whether the extension service is ready. virtual bool is_ready() OVERRIDE; + virtual base::SequencedTaskRunner* GetFileTaskRunner() OVERRIDE; + extensions::ComponentLoader* component_loader() { return component_loader_.get(); } @@ -561,6 +570,9 @@ class ExtensionService // externally managed extension. If so, uninstall it. void CheckExternalUninstall(const std::string& id); + // Changes sequenced task runner for crx installation tasks to |task_runner|. + void SetFileTaskRunnerForTesting(base::SequencedTaskRunner* task_runner); + // Clear all ExternalProviders. void ClearProvidersForTesting(); @@ -955,6 +967,8 @@ class ExtensionService extensions::AppShortcutManager app_shortcut_manager_; scoped_ptr<ExtensionErrorUI> extension_error_ui_; + // Sequenced task runner for extension related file operations. + scoped_refptr<base::SequencedTaskRunner> file_task_runner_; #if defined(ENABLE_EXTENSIONS) scoped_ptr<extensions::ExtensionActionStorageManager> diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 007dcd3..0793270 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -436,6 +436,7 @@ void ExtensionServiceTestBase::InitializeExtensionService( CommandLine::ForCurrentProcess(), extensions_install_dir, autoupdate_enabled); + service_->SetFileTaskRunnerForTesting(loop_.message_loop_proxy()); service_->set_extensions_enabled(true); service_->set_show_extensions_prompts(false); service_->set_install_updates_when_idle_for_test(false); @@ -679,7 +680,6 @@ class ExtensionServiceTest << "Path does not exist: "<< crx_path.value().c_str(); // no client (silent install) scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL)); - installer->set_install_source(install_location); installer->InstallCrx(crx_path); @@ -5814,7 +5814,7 @@ TEST_F(ExtensionServiceTest, WipeOutExtension) { data_dir_.AppendASCII("good.crx")); service_->CheckForExternalUpdates(); - loop_.RunAllPending(); + loop_.RunUntilIdle(); EXPECT_FALSE(extensions::HasExternalInstallError(service_)); EXPECT_FALSE(service_->IsExtensionEnabled(good_crx)); EXPECT_TRUE(service_->IsExtensionEnabled(page_action)); diff --git a/chrome/browser/extensions/sandboxed_unpacker.cc b/chrome/browser/extensions/sandboxed_unpacker.cc index a9a9179..f1d4c88 100644 --- a/chrome/browser/extensions/sandboxed_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_unpacker.cc @@ -16,6 +16,7 @@ #include "base/message_loop.h" #include "base/metrics/histogram.h" #include "base/path_service.h" +#include "base/sequenced_task_runner.h" #include "base/utf_string_conversions.h" // TODO(viettrungluu): delete me. #include "chrome/browser/extensions/crx_file.h" #include "chrome/browser/extensions/extension_service.h" @@ -177,19 +178,20 @@ SandboxedUnpacker::SandboxedUnpacker( Extension::Location location, int creation_flags, const FilePath& extensions_dir, + base::SequencedTaskRunner* unpacker_io_task_runner, SandboxedUnpackerClient* client) : crx_path_(crx_path), - thread_identifier_(BrowserThread::ID_COUNT), run_out_of_process_(run_out_of_process), client_(client), extensions_dir_(extensions_dir), got_response_(false), location_(location), - creation_flags_(creation_flags) { + creation_flags_(creation_flags), + unpacker_io_task_runner_(unpacker_io_task_runner) { } bool SandboxedUnpacker::CreateTempDirectory() { - CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_)); + CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); FilePath temp_dir; if (!FindWritableTempLocation(extensions_dir_, &temp_dir)) { @@ -216,7 +218,7 @@ bool SandboxedUnpacker::CreateTempDirectory() { void SandboxedUnpacker::Start() { // We assume that we are started on the thread that the client wants us to do // file IO on. - CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_identifier_)); + CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); unpack_start_time_ = base::TimeTicks::Now(); @@ -293,9 +295,6 @@ void SandboxedUnpacker::Start() { } SandboxedUnpacker::~SandboxedUnpacker() { - base::FileUtilProxy::Delete( - BrowserThread::GetMessageLoopProxyForThread(thread_identifier_), - temp_dir_.Take(), true, base::FileUtilProxy::StatusCallback()); } bool SandboxedUnpacker::OnMessageReceived(const IPC::Message& message) { @@ -325,7 +324,7 @@ void SandboxedUnpacker::OnProcessCrashed(int exit_code) { void SandboxedUnpacker::StartProcessOnIOThread(const FilePath& temp_crx_path) { UtilityProcessHost* host = UtilityProcessHost::Create( - this, thread_identifier_); + this, unpacker_io_task_runner_); // Grant the subprocess access to the entire subdir the extension file is // in, so that it can unpack to that dir. host->SetExposedDir(temp_crx_path.DirName()); @@ -336,9 +335,7 @@ void SandboxedUnpacker::StartProcessOnIOThread(const FilePath& temp_crx_path) { void SandboxedUnpacker::OnUnpackExtensionSucceeded( const DictionaryValue& manifest) { - // Skip check for unittests. - if (thread_identifier_ != BrowserThread::ID_COUNT) - CHECK(BrowserThread::CurrentlyOn(thread_identifier_)); + CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); got_response_ = true; scoped_ptr<DictionaryValue> final_manifest(RewriteManifestFile(manifest)); @@ -391,7 +388,7 @@ void SandboxedUnpacker::OnUnpackExtensionSucceeded( } void SandboxedUnpacker::OnUnpackExtensionFailed(const string16& error) { - CHECK(BrowserThread::CurrentlyOn(thread_identifier_)); + CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); got_response_ = true; ReportFailure( UNPACKER_CLIENT_FAILED, @@ -569,7 +566,7 @@ void SandboxedUnpacker::ReportFailure(FailureReason reason, reason, NUM_FAILURE_REASONS); UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", base::TimeTicks::Now() - unpack_start_time_); - + Cleanup(); client_->OnUnpackFailure(error); } @@ -792,4 +789,12 @@ bool SandboxedUnpacker::RewriteCatalogFiles() { return true; } +void SandboxedUnpacker::Cleanup() { + DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); + if (!temp_dir_.Delete()) { + LOG(WARNING) << "Can not delete temp directory at " + << temp_dir_.path().value(); + } +} + } // namespace extensions diff --git a/chrome/browser/extensions/sandboxed_unpacker.h b/chrome/browser/extensions/sandboxed_unpacker.h index 22abb5f..67af256 100644 --- a/chrome/browser/extensions/sandboxed_unpacker.h +++ b/chrome/browser/extensions/sandboxed_unpacker.h @@ -16,6 +16,7 @@ namespace base { class DictionaryValue; +class SequencedTaskRunner; } namespace extensions { @@ -77,6 +78,7 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient { Extension::Location location, int creation_flags, const FilePath& extensions_dir, + base::SequencedTaskRunner* unpacker_io_task_runner, SandboxedUnpackerClient* client); // Start unpacking the extension. The client is called with the results. @@ -187,12 +189,12 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient { bool RewriteImageFiles(); bool RewriteCatalogFiles(); + // Cleans up temp directory artifacts. + void Cleanup(); + // The path to the CRX to unpack. FilePath crx_path_; - // Our client's thread. This is the thread we respond on. - content::BrowserThread::ID thread_identifier_; - // True if unpacking should be done by the utility process. bool run_out_of_process_; @@ -230,6 +232,9 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient { // Creation flags to use for the extension. These flags will be used // when calling Extenion::Create() by the crx installer. int creation_flags_; + + // Sequenced task runner where file I/O operations will be performed at. + scoped_refptr<base::SequencedTaskRunner> unpacker_io_task_runner_; }; } // namespace extensions diff --git a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc index c16f325..11c4dd1 100644 --- a/chrome/browser/extensions/sandboxed_unpacker_unittest.cc +++ b/chrome/browser/extensions/sandboxed_unpacker_unittest.cc @@ -104,13 +104,12 @@ class SandboxedUnpackerTest : public testing::Test { ASSERT_TRUE(file_util::CreateDirectory(temp_path_)); sandboxed_unpacker_ = - new SandboxedUnpacker(crx_path, false, Extension::INTERNAL, - Extension::NO_FLAGS, extensions_dir_.path(), - client_); + new SandboxedUnpacker( + crx_path, false, Extension::INTERNAL, Extension::NO_FLAGS, + extensions_dir_.path(), + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), + client_); - // Hack since SandboxedUnpacker gets its background thread id from - // the Start call, but we don't call it here. - sandboxed_unpacker_->thread_identifier_ = BrowserThread::FILE; EXPECT_TRUE(PrepareUnpackerEnv()); } diff --git a/chrome/browser/extensions/test_extension_service.cc b/chrome/browser/extensions/test_extension_service.cc index 16d5bc2..46871cd 100644 --- a/chrome/browser/extensions/test_extension_service.cc +++ b/chrome/browser/extensions/test_extension_service.cc @@ -105,6 +105,11 @@ bool TestExtensionService::is_ready() { return false; } +base::SequencedTaskRunner* TestExtensionService::GetFileTaskRunner() { + ADD_FAILURE(); + return NULL; +} + void TestExtensionService::AddExtension(const Extension* extension) { ADD_FAILURE(); } diff --git a/chrome/browser/extensions/test_extension_service.h b/chrome/browser/extensions/test_extension_service.h index 0c0b27f..11b95e2 100644 --- a/chrome/browser/extensions/test_extension_service.h +++ b/chrome/browser/extensions/test_extension_service.h @@ -65,6 +65,8 @@ class TestExtensionService : public ExtensionServiceInterface { virtual bool is_ready() OVERRIDE; + virtual base::SequencedTaskRunner* GetFileTaskRunner() OVERRIDE; + virtual void AddExtension(const extensions::Extension* extension) OVERRIDE; virtual void UnloadExtension( diff --git a/chrome/browser/extensions/updater/safe_manifest_parser.cc b/chrome/browser/extensions/updater/safe_manifest_parser.cc index 7287122..920a2ff 100644 --- a/chrome/browser/extensions/updater/safe_manifest_parser.cc +++ b/chrome/browser/extensions/updater/safe_manifest_parser.cc @@ -51,7 +51,7 @@ void SafeManifestParser::ParseInSandbox() { !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); if (use_utility_process) { content::UtilityProcessHost* host = content::UtilityProcessHost::Create( - this, BrowserThread::UI); + this, BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI)); host->EnableZygote(); host->Send(new ChromeUtilityMsg_ParseUpdateManifest(xml_)); } else { diff --git a/chrome/browser/extensions/webstore_install_helper.cc b/chrome/browser/extensions/webstore_install_helper.cc index 950fbb6..2b27dd5 100644 --- a/chrome/browser/extensions/webstore_install_helper.cc +++ b/chrome/browser/extensions/webstore_install_helper.cc @@ -74,7 +74,8 @@ void WebstoreInstallHelper::Start() { void WebstoreInstallHelper::StartWorkOnIOThread() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); utility_host_ = - UtilityProcessHost::Create(this, BrowserThread::IO)->AsWeakPtr(); + UtilityProcessHost::Create( + this, base::MessageLoopProxy::current())->AsWeakPtr(); utility_host_->EnableZygote(); utility_host_->StartBatchMode(); diff --git a/chrome/browser/extensions/webstore_standalone_installer.cc b/chrome/browser/extensions/webstore_standalone_installer.cc index bb3e38b..7686908 100644 --- a/chrome/browser/extensions/webstore_standalone_installer.cc +++ b/chrome/browser/extensions/webstore_standalone_installer.cc @@ -81,7 +81,8 @@ class SafeWebstoreResponseParser : public UtilityProcessHostClient { void StartWorkOnIOThread() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); UtilityProcessHost* host = - UtilityProcessHost::Create(this, BrowserThread::IO); + UtilityProcessHost::Create( + this, base::MessageLoopProxy::current()); host->EnableZygote(); host->Send(new ChromeUtilityMsg_ParseJSON(webstore_data_)); } diff --git a/chrome/browser/image_decoder.cc b/chrome/browser/image_decoder.cc index 1f456ee..6d7b948 100644 --- a/chrome/browser/image_decoder.cc +++ b/chrome/browser/image_decoder.cc @@ -62,7 +62,7 @@ void ImageDecoder::DecodeImageInSandbox( const std::vector<unsigned char>& image_data) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); UtilityProcessHost* utility_process_host = UtilityProcessHost::Create( - this, target_thread_id_); + this, BrowserThread::GetMessageLoopProxyForThread(target_thread_id_)); utility_process_host->EnableZygote(); if (image_codec_ == ROBUST_JPEG_CODEC) { utility_process_host->Send( diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc index 36dc21d..bcec842 100644 --- a/chrome/browser/importer/external_process_importer_client.cc +++ b/chrome/browser/importer/external_process_importer_client.cc @@ -261,7 +261,9 @@ void ExternalProcessImporterClient::NotifyItemFinishedOnIOThread( void ExternalProcessImporterClient::StartProcessOnIOThread( BrowserThread::ID thread_id) { utility_process_host_ = - UtilityProcessHost::Create(this, thread_id)->AsWeakPtr(); + UtilityProcessHost::Create( + this, + BrowserThread::GetMessageLoopProxyForThread(thread_id))->AsWeakPtr(); utility_process_host_->DisableSandbox(); #if defined(OS_MACOSX) diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index c6dd5ad..3a47e65 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc @@ -10,6 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "base/string_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" #include "base/utf_string_conversions.h" #include "base/values.h" @@ -516,7 +517,6 @@ scoped_refptr<BrowserThemePack> BrowserThemePack::BuildFromDataPack( } bool BrowserThemePack::WriteToDisk(const FilePath& path) const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); // Add resources for each of the property arrays. RawDataForWriting resources; resources[kHeaderID] = base::StringPiece( @@ -1100,9 +1100,6 @@ void BrowserThemePack::CreateTabBackgroundImages(ImageCache* images) const { void BrowserThemePack::RepackImages(const ImageCache& images, RawImages* reencoded_images) const { - - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); - typedef std::vector<ui::ScaleFactor> ScaleFactors; for (ImageCache::const_iterator it = images.begin(); it != images.end(); ++it) { @@ -1150,7 +1147,6 @@ void BrowserThemePack::CopyImagesTo(const ImageCache& source, void BrowserThemePack::AddRawImagesTo(const RawImages& images, RawDataForWriting* out) const { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); for (RawImages::const_iterator it = images.begin(); it != images.end(); ++it) { (*out)[it->first] = base::StringPiece( diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index e1f660d..027315d 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc @@ -6,10 +6,12 @@ #include "base/bind.h" #include "base/memory/ref_counted_memory.h" +#include "base/sequenced_task_runner.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_system.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/browser_theme_pack.h" @@ -194,7 +196,8 @@ const int kToolbarButtonIDs[] = { }; // Writes the theme pack to disk on a separate thread. -void WritePackToDiskCallback(BrowserThemePack* pack, const FilePath& path) { +void WritePackToDiskCallback(BrowserThemePack* pack, + const FilePath& path) { if (!pack->WriteToDisk(path)) NOTREACHED() << "Could not write theme pack to disk"; } @@ -682,10 +685,15 @@ void ThemeService::BuildFromExtension(const Extension* extension) { return; } + ExtensionService* service = + extensions::ExtensionSystem::Get(profile_)->extension_service(); + if (!service) + return; + // Write the packed file to disk. FilePath pack_path = extension->path().Append(chrome::kThemePackFilename); - BrowserThread::PostTask( - BrowserThread::FILE, FROM_HERE, + service->GetFileTaskRunner()->PostTask( + FROM_HERE, base::Bind(&WritePackToDiskCallback, pack, pack_path)); SavePackName(pack_path); diff --git a/chrome/browser/web_resource/json_asynchronous_unpacker.cc b/chrome/browser/web_resource/json_asynchronous_unpacker.cc index f797a2f..44dcbbc 100644 --- a/chrome/browser/web_resource/json_asynchronous_unpacker.cc +++ b/chrome/browser/web_resource/json_asynchronous_unpacker.cc @@ -105,7 +105,8 @@ class JSONAsynchronousUnpackerImpl void StartProcessOnIOThread(BrowserThread::ID thread_id, const std::string& json_data) { - UtilityProcessHost* host = UtilityProcessHost::Create(this, thread_id); + UtilityProcessHost* host = UtilityProcessHost::Create( + this, BrowserThread::GetMessageLoopProxyForThread(thread_id)); host->EnableZygote(); // TODO(mrc): get proper file path when we start using web resources // that need to be unpacked. |