diff options
68 files changed, 506 insertions, 333 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 109c05c..eb5d1e0 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -29,9 +29,6 @@ include_rules = [ # TODO(jam): this needs to be removed, and only use content/public. BUG=98716 "+content/browser", - "-content/browser/download/download_manager_impl.h", - "-content/browser/download/download_resource_handler.h", - "-content/browser/download/save_file_manager.h", "-content/browser/notification_service_impl.h", "-content/browser/tab_contents/navigation_controller_impl.h", "-content/browser/tab_contents/navigation_entry_impl.h", diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 27ec3064..c683820 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -83,9 +83,6 @@ class BrowserProcess { BrowserProcess(); virtual ~BrowserProcess(); - // Called when the ResourceDispatcherHost object is created by content. - virtual void ResourceDispatcherHostCreated() = 0; - // Invoked when the user is logging out/shutting down. When logging off we may // not have enough time to do a normal shutdown. This method is invoked prior // to normal shutdown and saves any state that must be saved before we are @@ -93,6 +90,8 @@ class BrowserProcess { virtual void EndSession() = 0; // Services: any of these getters may return NULL + virtual ResourceDispatcherHost* resource_dispatcher_host() = 0; + virtual MetricsService* metrics_service() = 0; virtual ProfileManager* profile_manager() = 0; virtual PrefService* local_state() = 0; diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index f68f0f2..27a458a 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -68,8 +68,10 @@ #include "chrome/installer/util/google_update_constants.h" #include "content/browser/browser_child_process_host.h" #include "content/browser/child_process_security_policy.h" +#include "content/browser/download/download_file_manager.h" #include "content/browser/download/download_status_updater.h" #include "content/browser/download/mhtml_generation_manager.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/renderer_host/resource_dispatcher_host.h" @@ -119,7 +121,8 @@ using content::BrowserThread; using content::PluginService; BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line) - : created_metrics_service_(false), + : created_resource_dispatcher_host_(false), + created_metrics_service_(false), created_watchdog_thread_(false), created_profile_manager_(false), created_local_state_(false), @@ -152,6 +155,10 @@ BrowserProcessImpl::BrowserProcessImpl(const CommandLine& command_line) } BrowserProcessImpl::~BrowserProcessImpl() { + // See StartTearDown and PreStopThread functions below, this is where + // most destruction happens so that it can be interleaved with threads + // going away. + // Wait for the pending print jobs to finish. print_job_manager_->OnQuit(); print_job_manager_.reset(); @@ -212,6 +219,11 @@ void BrowserProcessImpl::StartTearDown() { // Debugger must be cleaned up before IO thread and NotificationService. remote_debugging_server_.reset(); + if (resource_dispatcher_host_.get()) { + // Cancel pending requests and prevent new requests. + resource_dispatcher_host()->Shutdown(); + } + ExtensionTabIdMap::GetInstance()->Shutdown(); // The policy providers managed by |browser_policy_connector_| need to shut @@ -228,18 +240,60 @@ void BrowserProcessImpl::StartTearDown() { watchdog_thread_.reset(); } -void BrowserProcessImpl::PostDestroyThreads() { - // With the file_thread_ flushed, we can release any icon resources. - icon_manager_.reset(); +void BrowserProcessImpl::PreStartThread(BrowserThread::ID thread_id) { + switch (thread_id) { + case BrowserThread::IO: + CreateIOThreadState(); + break; - // Reset associated state right after actual thread is stopped, - // as io_thread_.global_ cleanup happens in CleanUp on the IO - // thread, i.e. as the thread exits its message loop. - // - // This is important also because in various places, the - // IOThread object being NULL is considered synonymous with the - // IO thread having stopped. - io_thread_.reset(); + default: + break; + } +} + +void BrowserProcessImpl::PostStartThread(BrowserThread::ID thread_id) { +} + +void BrowserProcessImpl::PreStopThread(BrowserThread::ID thread_id) { + switch (thread_id) { + case BrowserThread::FILE: + // Clean up state that lives on or uses the file_thread_ before + // it goes away. + if (resource_dispatcher_host_.get()) { + resource_dispatcher_host()->download_file_manager()->Shutdown(); + resource_dispatcher_host()->save_file_manager()->Shutdown(); + } + break; + case BrowserThread::WEBKIT_DEPRECATED: + // Need to destroy ResourceDispatcherHost before PluginService + // and SafeBrowsingService, since it caches a pointer to + // it. + resource_dispatcher_host_.reset(); + break; + default: + break; + } +} + +void BrowserProcessImpl::PostStopThread(BrowserThread::ID thread_id) { + switch (thread_id) { + case BrowserThread::FILE: + // With the file_thread_ flushed, we can release any icon resources. + icon_manager_.reset(); + break; + case BrowserThread::IO: + // Reset associated state right after actual thread is stopped, + // as io_thread_.global_ cleanup happens in CleanUp on the IO + // thread, i.e. as the thread exits its message loop. + // + // This is important also because in various places, the + // IOThread object being NULL is considered synonymous with the + // IO thread having stopped. + io_thread_.reset(); + break; + default: + break; + } } #if defined(OS_WIN) @@ -338,6 +392,13 @@ void BrowserProcessImpl::EndSession() { #endif } +ResourceDispatcherHost* BrowserProcessImpl::resource_dispatcher_host() { + DCHECK(CalledOnValidThread()); + if (!created_resource_dispatcher_host_) + CreateResourceDispatcherHost(); + return resource_dispatcher_host_.get(); +} + MetricsService* BrowserProcessImpl::metrics_service() { DCHECK(CalledOnValidThread()); if (!created_metrics_service_) @@ -636,15 +697,25 @@ AudioManager* BrowserProcessImpl::audio_manager() { return audio_manager_; } -void BrowserProcessImpl::ResourceDispatcherHostCreated() { +void BrowserProcessImpl::CreateResourceDispatcherHost() { + DCHECK(!created_resource_dispatcher_host_ && + resource_dispatcher_host_.get() == NULL); + created_resource_dispatcher_host_ = true; + // UserScriptListener and NetworkDelayListener will delete themselves. - ResourceDispatcherHost* rdh = ResourceDispatcherHost::Get(); - rdh->AddResourceQueueDelegate(new UserScriptListener()); - rdh->AddResourceQueueDelegate(new NetworkDelayListener()); + ResourceQueue::DelegateSet resource_queue_delegates; + resource_queue_delegates.insert(new UserScriptListener()); + resource_queue_delegates.insert(new NetworkDelayListener()); + + resource_dispatcher_host_.reset( + new ResourceDispatcherHost(resource_queue_delegates)); + resource_dispatcher_host_->Initialize(); resource_dispatcher_host_delegate_.reset( - new ChromeResourceDispatcherHostDelegate(rdh, prerender_tracker())); - rdh->set_delegate(resource_dispatcher_host_delegate_.get()); + new ChromeResourceDispatcherHostDelegate(resource_dispatcher_host_.get(), + prerender_tracker())); + resource_dispatcher_host_->set_delegate( + resource_dispatcher_host_delegate_.get()); pref_change_registrar_.Add(prefs::kAllowCrossOriginAuthPrompt, this); ApplyAllowCrossOriginAuthPromptPolicy(); @@ -657,6 +728,38 @@ void BrowserProcessImpl::CreateMetricsService() { metrics_service_.reset(new MetricsService); } +void BrowserProcessImpl::CreateIOThreadState() { + // Prior to any processing happening on the io thread, we create the + // plugin service as it is predominantly used from the io thread, + // but must be created on the main thread. The service ctor is + // inexpensive and does not invoke the io_thread() accessor. + PluginService* plugin_service = PluginService::GetInstance(); + plugin_service->Init(); + plugin_service->SetFilter(ChromePluginServiceFilter::GetInstance()); + plugin_service->StartWatchingPlugins(); + + // Register the internal Flash if available. + FilePath path; + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableInternalFlash) && + PathService::Get(chrome::FILE_FLASH_PLUGIN, &path)) { + plugin_service->AddExtraPluginPath(path); + } + +#if defined(OS_POSIX) + // Also find plugins in a user-specific plugins dir, + // e.g. ~/.config/chromium/Plugins. + FilePath user_data_dir; + if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { + plugin_service->AddExtraPluginPath(user_data_dir.Append("Plugins")); + } +#endif + + scoped_ptr<IOThread> thread(new IOThread( + local_state(), net_log_.get(), extension_event_router_forwarder_.get())); + io_thread_.swap(thread); +} + void BrowserProcessImpl::CreateWatchdogThread() { DCHECK(!created_watchdog_thread_ && watchdog_thread_.get() == NULL); created_watchdog_thread_ = true; @@ -723,33 +826,7 @@ void BrowserProcessImpl::CreateLocalState() { local_state_->RegisterBooleanPref(prefs::kAllowCrossOriginAuthPrompt, false); } -void BrowserProcessImpl::PreCreateThreads() { - io_thread_.reset(new IOThread( - local_state(), net_log_.get(), extension_event_router_forwarder_.get())); -} - void BrowserProcessImpl::PreMainMessageLoopRun() { - PluginService* plugin_service = PluginService::GetInstance(); - plugin_service->SetFilter(ChromePluginServiceFilter::GetInstance()); - plugin_service->StartWatchingPlugins(); - - // Register the internal Flash if available. - FilePath path; - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableInternalFlash) && - PathService::Get(chrome::FILE_FLASH_PLUGIN, &path)) { - plugin_service->AddExtraPluginPath(path); - } - -#if defined(OS_POSIX) - // Also find plugins in a user-specific plugins dir, - // e.g. ~/.config/chromium/Plugins. - FilePath user_data_dir; - if (PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)) { - plugin_service->AddExtraPluginPath(user_data_dir.Append("Plugins")); - } -#endif - if (local_state_->IsManagedPreference(prefs::kDefaultBrowserSettingEnabled)) ApplyDefaultBrowserPolicy(); } @@ -839,7 +916,7 @@ void BrowserProcessImpl::ApplyDefaultBrowserPolicy() { void BrowserProcessImpl::ApplyAllowCrossOriginAuthPromptPolicy() { bool value = local_state()->GetBoolean(prefs::kAllowCrossOriginAuthPrompt); - ResourceDispatcherHost::Get()->set_allow_cross_origin_auth_prompt(value); + resource_dispatcher_host()->set_allow_cross_origin_auth_prompt(value); } // Mac is currently not supported. diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 8c03cbb..54e926f 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -45,8 +45,10 @@ class BrowserProcessImpl : public BrowserProcess, explicit BrowserProcessImpl(const CommandLine& command_line); virtual ~BrowserProcessImpl(); - // Called before the browser threads are created. - void PreCreateThreads(); + // Some of our startup is interleaved with thread creation, driven + // by these functions. + void PreStartThread(content::BrowserThread::ID identifier); + void PostStartThread(content::BrowserThread::ID identifier); // Called after the threads have been created but before the message loops // starts running. Allows the browser process to do any initialization that @@ -58,11 +60,12 @@ class BrowserProcessImpl : public BrowserProcess, // framework, rather than in the destructor, so that we can // interleave cleanup with threads being stopped. void StartTearDown(); - void PostDestroyThreads(); + void PreStopThread(content::BrowserThread::ID identifier); + void PostStopThread(content::BrowserThread::ID identifier); // BrowserProcess methods - virtual void ResourceDispatcherHostCreated() OVERRIDE; virtual void EndSession() OVERRIDE; + virtual ResourceDispatcherHost* resource_dispatcher_host() OVERRIDE; virtual MetricsService* metrics_service() OVERRIDE; virtual IOThread* io_thread() OVERRIDE; virtual WatchDogThread* watchdog_thread() OVERRIDE; @@ -124,7 +127,12 @@ class BrowserProcessImpl : public BrowserProcess, virtual AudioManager* audio_manager() OVERRIDE; private: + // Must be called right before the IO thread is started. + void CreateIOThreadState(); + + void CreateResourceDispatcherHost(); void CreateMetricsService(); + void CreateWatchdogThread(); #if defined(OS_CHROMEOS) void InitializeWebSocketProxyThread(); @@ -151,6 +159,9 @@ class BrowserProcessImpl : public BrowserProcess, void ApplyAllowCrossOriginAuthPromptPolicy(); void ApplyDefaultBrowserPolicy(); + bool created_resource_dispatcher_host_; + scoped_ptr<ResourceDispatcherHost> resource_dispatcher_host_; + bool created_metrics_service_; scoped_ptr<MetricsService> metrics_service_; diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 2c9e976..9ef1382 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc @@ -1156,8 +1156,6 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() { tracked_objects::ThreadData::InitializeAndSetTrackingStatus(enabled); } - browser_process_->PreCreateThreads(); - // This forces the TabCloseableStateWatcher to be created and, on chromeos, // register for the notifications it needs to track the closeable state of // tabs. @@ -1314,6 +1312,38 @@ int ChromeBrowserMainParts::PreCreateThreadsImpl() { return content::RESULT_CODE_NORMAL_EXIT; } +void ChromeBrowserMainParts::PreStartThread( + content::BrowserThread::ID thread_id) { + browser_process_->PreStartThread(thread_id); +} + +void ChromeBrowserMainParts::PostStartThread( + content::BrowserThread::ID thread_id) { + browser_process_->PostStartThread(thread_id); + switch (thread_id) { + case BrowserThread::FILE: + // Now the command line has been mutated based on about:flags, + // and the file thread has been started, we can set up metrics + // and initialize field trials. + metrics_ = SetupMetricsAndFieldTrials(local_state_); + +#if defined(USE_LINUX_BREAKPAD) + // Needs to be called after we have chrome::DIR_USER_DATA and + // g_browser_process. This happens in PreCreateThreads. + BrowserThread::PostTask(BrowserThread::FILE, + FROM_HERE, + base::Bind(&GetLinuxDistroCallback)); + + if (IsCrashReportingEnabled(local_state_)) + InitCrashReporter(); +#endif + break; + + default: + break; + } +} + void ChromeBrowserMainParts::PreMainMessageLoopRun() { result_code_ = PreMainMessageLoopRunImpl(); @@ -1353,22 +1383,6 @@ void ChromeBrowserMainParts::PostBrowserStart() { } int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { - // Now the command line has been mutated based on about:flags, - // and the file thread has been started, we can set up metrics - // and initialize field trials. - metrics_ = SetupMetricsAndFieldTrials(local_state_); - -#if defined(USE_LINUX_BREAKPAD) - // Needs to be called after we have chrome::DIR_USER_DATA and - // g_browser_process. This happens in PreCreateThreads. - BrowserThread::PostTask(BrowserThread::FILE, - FROM_HERE, - base::Bind(&GetLinuxDistroCallback)); - - if (IsCrashReportingEnabled(local_state_)) - InitCrashReporter(); -#endif - // Create watchdog thread after creating all other threads because it will // watch the other threads and they must be running. browser_process_->watchdog_thread(); @@ -1380,7 +1394,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() { #if defined(USE_WEBKIT_COMPOSITOR) // We need to ensure WebKit has been initialized before we start the WebKit // compositor. This is done by the ResourceDispatcherHost on creation. - ResourceDispatcherHost::Get(); + browser_process_->resource_dispatcher_host(); #endif // Record last shutdown time into a histogram. @@ -1916,8 +1930,15 @@ void ChromeBrowserMainParts::PostMainMessageLoopRun() { browser_process_->StartTearDown(); } +void ChromeBrowserMainParts::PreStopThread(BrowserThread::ID identifier) { + browser_process_->PreStopThread(identifier); +} + +void ChromeBrowserMainParts::PostStopThread(BrowserThread::ID identifier) { + browser_process_->PostStopThread(identifier); +} + void ChromeBrowserMainParts::PostDestroyThreads() { - browser_process_->PostDestroyThreads(); // browser_shutdown takes care of deleting browser_process, so we need to // release it. ignore_result(browser_process_.release()); diff --git a/chrome/browser/chrome_browser_main.h b/chrome/browser/chrome_browser_main.h index 4940232..d4a4d05 100644 --- a/chrome/browser/chrome_browser_main.h +++ b/chrome/browser/chrome_browser_main.h @@ -65,9 +65,13 @@ class ChromeBrowserMainParts : public content::BrowserMainParts { virtual void PreMainMessageLoopStart() OVERRIDE; virtual void PostMainMessageLoopStart() OVERRIDE; virtual void PreCreateThreads() OVERRIDE; + virtual void PreStartThread(content::BrowserThread::ID identifier) OVERRIDE; + virtual void PostStartThread(content::BrowserThread::ID identifier) OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; virtual void PostMainMessageLoopRun() OVERRIDE; + virtual void PreStopThread(content::BrowserThread::ID identifier) OVERRIDE; + virtual void PostStopThread(content::BrowserThread::ID identifier) OVERRIDE; virtual void PostDestroyThreads() OVERRIDE; // Additional stages for ChromeBrowserMainExtraParts. These stages are called diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index e3c2be4..0d46782 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -72,7 +72,6 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/plugin_process_host.h" #include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/resource_context.h" #include "content/browser/site_instance.h" #include "content/browser/ssl/ssl_cert_error_handler.h" @@ -1089,8 +1088,9 @@ std::string ChromeContentBrowserClient::GetWorkerProcessTitle( return extension ? extension->name() : std::string(); } -void ChromeContentBrowserClient::ResourceDispatcherHostCreated() { - return g_browser_process->ResourceDispatcherHostCreated(); +ResourceDispatcherHost* + ChromeContentBrowserClient::GetResourceDispatcherHost() { + return g_browser_process->resource_dispatcher_host(); } ui::Clipboard* ChromeContentBrowserClient::GetClipboard() { diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 2eda665..adfe863 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -118,7 +118,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; - virtual void ResourceDispatcherHostCreated() OVERRIDE; + virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; virtual ui::Clipboard* GetClipboard() OVERRIDE; virtual MHTMLGenerationManager* GetMHTMLGenerationManager() OVERRIDE; virtual net::NetLog* GetNetLog() OVERRIDE; diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 22ffa5c..b0828e1 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc @@ -97,7 +97,9 @@ class CancelTestDataCollector : public base::RefCountedThreadSafe<CancelTestDataCollector> { public: CancelTestDataCollector() - : slow_download_job_pending_requests_(0), + : resource_dispatcher_host_( + g_browser_process->resource_dispatcher_host()), + slow_download_job_pending_requests_(0), dfm_pending_downloads_(0) { } void WaitForDataCollected() { @@ -122,8 +124,7 @@ class CancelTestDataCollector private: void IOInfoCollector() { - download_file_manager_ = - ResourceDispatcherHost::Get()->download_file_manager(); + download_file_manager_ = resource_dispatcher_host_->download_file_manager(); slow_download_job_pending_requests_ = URLRequestSlowDownloadJob::NumberOutstandingRequests(); BrowserThread::PostTask( @@ -137,6 +138,7 @@ class CancelTestDataCollector BrowserThread::UI, FROM_HERE, MessageLoop::QuitClosure()); } + ResourceDispatcherHost* resource_dispatcher_host_; DownloadFileManager* download_file_manager_; int slow_download_job_pending_requests_; int dfm_pending_downloads_; diff --git a/chrome/browser/download/download_extension_api.cc b/chrome/browser/download/download_extension_api.cc index 3a38259..7f9effc 100644 --- a/chrome/browser/download/download_extension_api.cc +++ b/chrome/browser/download/download_extension_api.cc @@ -33,6 +33,7 @@ #include "chrome/browser/renderer_host/chrome_render_message_filter.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/webui/web_ui_util.h" +#include "content/browser/download/download_file_manager.h" #include "content/browser/download/download_id.h" #include "content/browser/download/download_state_info.h" #include "content/browser/download/download_types.h" @@ -232,7 +233,7 @@ bool DownloadsDownloadFunction::ParseArgs() { } } } - iodata_->rdh = ResourceDispatcherHost::Get(); + iodata_->rdh = g_browser_process->resource_dispatcher_host(); iodata_->resource_context = &profile()->GetResourceContext(); iodata_->render_process_host_id = render_view_host()->process()->GetID(); iodata_->render_view_host_routing_id = render_view_host()->routing_id(); diff --git a/chrome/browser/download/download_manager_unittest.cc b/chrome/browser/download/download_manager_unittest.cc index 3f2c669..42e6a2c 100644 --- a/chrome/browser/download/download_manager_unittest.cc +++ b/chrome/browser/download/download_manager_unittest.cc @@ -29,13 +29,13 @@ #include "content/browser/download/download_file_impl.h" #include "content/browser/download/download_file_manager.h" #include "content/browser/download/download_id_factory.h" +#include "content/browser/download/download_manager_impl.h" #include "content/browser/download/download_request_handle.h" #include "content/browser/download/download_status_updater.h" #include "content/browser/download/interrupt_reasons.h" #include "content/browser/download/mock_download_file.h" #include "content/browser/download/mock_download_manager.h" #include "content/public/browser/download_item.h" -#include "content/public/browser/download_manager.h" #include "content/test/test_browser_thread.h" #include "grit/generated_resources.h" #include "net/base/io_buffer.h" @@ -167,7 +167,7 @@ class DownloadManagerTest : public testing::Test { download_manager_delegate_(new TestDownloadManagerDelegate( profile_.get())), id_factory_(new DownloadIdFactory(kValidIdDomain)), - download_manager_(DownloadManager::Create( + download_manager_(new DownloadManagerImpl( download_manager_delegate_, id_factory_, &download_status_updater_)), diff --git a/chrome/browser/download/download_service.cc b/chrome/browser/download/download_service.cc index 98031ec..833949a 100644 --- a/chrome/browser/download/download_service.cc +++ b/chrome/browser/download/download_service.cc @@ -11,7 +11,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "content/browser/download/download_id_factory.h" -#include "content/public/browser/download_manager.h" +#include "content/browser/download/download_manager_impl.h" using content::DownloadManager; @@ -47,7 +47,7 @@ DownloadManager* DownloadService::GetDownloadManager() { // SetDownloadManagerDelegateForTesting. if (!manager_delegate_.get()) manager_delegate_ = new ChromeDownloadManagerDelegate(profile_); - manager_ = DownloadManager::Create( + manager_ = new DownloadManagerImpl( manager_delegate_.get(), id_factory_.get(), g_browser_process->download_status_updater()); diff --git a/chrome/browser/download/download_throttling_resource_handler.cc b/chrome/browser/download/download_throttling_resource_handler.cc index 98a9fb5..7f4ba73 100644 --- a/chrome/browser/download/download_throttling_resource_handler.cc +++ b/chrome/browser/download/download_throttling_resource_handler.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "content/browser/download/download_id.h" +#include "content/browser/download/download_resource_handler.h" #include "content/browser/download/download_stats.h" #include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 4051afe..f904df07 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -33,7 +33,6 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_file_util.h" -#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/user_metrics.h" @@ -142,8 +141,7 @@ CrxInstaller::CrxInstaller(base::WeakPtr<ExtensionService> frontend_weak, apps_require_extension_mime_type_(false), allow_silent_install_(false), install_cause_(extension_misc::INSTALL_CAUSE_UNSET), - creation_flags_(Extension::NO_FLAGS), - use_utility_process_(true) { + creation_flags_(Extension::NO_FLAGS) { } CrxInstaller::~CrxInstaller() { @@ -171,10 +169,10 @@ void CrxInstaller::InstallCrx(const FilePath& source_file) { scoped_refptr<SandboxedExtensionUnpacker> unpacker( new SandboxedExtensionUnpacker( source_file, + g_browser_process->resource_dispatcher_host(), install_source_, creation_flags_, this)); - unpacker->set_use_utility_process(use_utility_process_); if (!BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index 5419e8d..8f6584a 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -184,8 +184,6 @@ class CrxInstaller Profile* profile() { return profile_; } - void set_use_utility_process(bool value) { use_utility_process_ = value; } - private: friend class ExtensionUpdaterTest; @@ -331,9 +329,6 @@ class CrxInstaller // when calling Extenion::Create() by the crx installer. int creation_flags_; - // True if the utility process is used, false otherwise (i.e. for tests). - bool use_utility_process_; - DISALLOW_COPY_AND_ASSIGN(CrxInstaller); }; diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 597188f..655a80e 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc @@ -92,7 +92,6 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "content/browser/plugin_process_host.h" -#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_agent_host_registry.h" #include "content/public/browser/devtools_manager.h" @@ -390,8 +389,7 @@ ExtensionService::ExtensionService(Profile* profile, event_routers_initialized_(false), extension_warnings_(profile), socket_controller_(NULL), - tracker_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - use_utility_process_(true) { + tracker_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Figure out if extension installation should be enabled. @@ -568,7 +566,7 @@ void ExtensionService::Init() { // Hack: we need to ensure the ResourceDispatcherHost is ready before we load // the first extension, because its members listen for loaded notifications. - ResourceDispatcherHost::Get(); + g_browser_process->resource_dispatcher_host(); component_loader_->LoadAll(); extensions::InstalledLoader(this).LoadAllExtensions(); @@ -628,7 +626,6 @@ bool ExtensionService::UpdateExtension( NULL : new ExtensionInstallUI(profile_); scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(this, client)); - installer->set_use_utility_process(use_utility_process_); installer->set_expected_id(id); if (is_pending_extension) installer->set_install_source(pending_extension_info.install_source()); @@ -2325,7 +2322,6 @@ void ExtensionService::OnExternalExtensionFileFound( // no client (silent install) scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(this, NULL)); - installer->set_use_utility_process(use_utility_process_); installer->set_install_source(location); installer->set_expected_id(id); installer->set_expected_version(*version); diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 554cd0b..9922976 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h @@ -510,12 +510,13 @@ class ExtensionService const FilePath& path, Extension::Location location, int creation_flags, - bool mark_acknowledged) OVERRIDE; + bool mark_acknowledged) + OVERRIDE; - virtual void OnExternalExtensionUpdateUrlFound( - const std::string& id, - const GURL& update_url, - Extension::Location location) OVERRIDE; + virtual void OnExternalExtensionUpdateUrlFound(const std::string& id, + const GURL& update_url, + Extension::Location location) + OVERRIDE; virtual void OnExternalProviderReady( const ExternalExtensionProviderInterface* provider) OVERRIDE; @@ -581,11 +582,6 @@ class ExtensionService virtual void OnImageLoaded(SkBitmap* image, const ExtensionResource& resource, int index) OVERRIDE; - - void set_use_utility_process_for_testing(bool value) { - use_utility_process_ = value; - } - private: // Bundle of type (app or extension)-specific sync stuff. struct SyncBundle { @@ -847,9 +843,6 @@ class ExtensionService ShellIntegration::ShortcutInfo shortcut_info_; ImageLoadingTracker tracker_; - // True if the utility process is used, false otherwise (i.e. for tests). - bool use_utility_process_; - FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, InstallAppsWithUnlimtedStorage); FRIEND_TEST_ALL_PREFIXES(ExtensionServiceTest, diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 8217b13..7494b0a 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -431,7 +431,6 @@ void ExtensionServiceTestBase::InitializeExtensionService( autoupdate_enabled); service_->set_extensions_enabled(true); service_->set_show_extensions_prompts(false); - service_->set_use_utility_process_for_testing(false); profile->set_extensions_service(service_); // When we start up, we want to make sure there is no external provider, @@ -598,7 +597,6 @@ class ExtensionServiceTest ASSERT_TRUE(file_util::PathExists(crx_path)) << "Path does not exist: "<< crx_path.value().c_str(); scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL)); - installer->set_use_utility_process(false); installer->set_allow_silent_install(true); installer->set_is_gallery_install(from_webstore); installer->InstallCrx(crx_path); @@ -647,7 +645,6 @@ class ExtensionServiceTest // no client (silent install) scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL)); - installer->set_use_utility_process(false); installer->set_install_source(install_location); installer->InstallCrx(crx_path); @@ -1430,7 +1427,6 @@ TEST_F(ExtensionServiceTest, InstallUserScript) { ASSERT_TRUE(file_util::PathExists(path)); scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL)); - installer->set_use_utility_process(false); installer->set_allow_silent_install(true); installer->InstallUserScript( path, diff --git a/chrome/browser/extensions/extension_updater.cc b/chrome/browser/extensions/extension_updater.cc index 858ad885..930b232 100644 --- a/chrome/browser/extensions/extension_updater.cc +++ b/chrome/browser/extensions/extension_updater.cc @@ -482,8 +482,7 @@ ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, service_(service), frequency_seconds_(frequency_seconds), will_check_soon_(false), extension_prefs_(extension_prefs), prefs_(prefs), profile_(profile), blacklist_checks_enabled_(true), - crx_install_is_running_(false), - use_utility_process_(true) { + crx_install_is_running_(false) { Init(); } @@ -623,11 +622,8 @@ class SafeManifestParser : public UtilityProcessHost::Client { public: // Takes ownership of |fetch_data|. SafeManifestParser(const std::string& xml, ManifestFetchData* fetch_data, - base::WeakPtr<ExtensionUpdater> updater, - bool use_utility_process) - : xml_(xml), - updater_(updater), - use_utility_process_(use_utility_process) { + base::WeakPtr<ExtensionUpdater> updater) + : xml_(xml), updater_(updater) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); fetch_data_.reset(fetch_data); } @@ -639,18 +635,19 @@ class SafeManifestParser : public UtilityProcessHost::Client { if (!BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind( - &SafeManifestParser::ParseInSandbox, this))) { + &SafeManifestParser::ParseInSandbox, this, + g_browser_process->resource_dispatcher_host()))) { NOTREACHED(); } } // Creates the sandboxed utility process and tells it to start parsing. - void ParseInSandbox() { + void ParseInSandbox(ResourceDispatcherHost* rdh) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // TODO(asargent) we shouldn't need to do this branch here - instead // UtilityProcessHost should handle it for us. (http://crbug.com/19192) - bool use_utility_process = use_utility_process_ && + bool use_utility_process = rdh && !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); if (use_utility_process) { UtilityProcessHost* host = new UtilityProcessHost( @@ -724,7 +721,6 @@ class SafeManifestParser : public UtilityProcessHost::Client { // Should be accessed only on UI thread. scoped_ptr<ManifestFetchData> fetch_data_; base::WeakPtr<ExtensionUpdater> updater_; - bool use_utility_process_; }; @@ -740,8 +736,7 @@ void ExtensionUpdater::OnManifestFetchComplete( VLOG(2) << "beginning manifest parse for " << url; scoped_refptr<SafeManifestParser> safe_parser( new SafeManifestParser(data, current_manifest_fetch_.release(), - weak_ptr_factory_.GetWeakPtr(), - use_utility_process_)); + weak_ptr_factory_.GetWeakPtr())); safe_parser->Start(); } else { // TODO(asargent) Do exponential backoff here. (http://crbug.com/12546). diff --git a/chrome/browser/extensions/extension_updater.h b/chrome/browser/extensions/extension_updater.h index 548e27c..d77f4a49 100644 --- a/chrome/browser/extensions/extension_updater.h +++ b/chrome/browser/extensions/extension_updater.h @@ -208,10 +208,6 @@ class ExtensionUpdater : public content::URLFetcherDelegate, // code should just call CheckSoon(). bool WillCheckSoon() const; - void set_use_utility_process_for_testing(bool value) { - use_utility_process_ = value; - } - private: friend class ExtensionUpdaterTest; friend class ExtensionUpdaterFileHandler; @@ -387,9 +383,6 @@ class ExtensionUpdater : public content::URLFetcherDelegate, // to keep more than one install from running at once. bool crx_install_is_running_; - // True if the utility process is used, false otherwise (i.e. for tests). - bool use_utility_process_; - // Fetched CRX files waiting to be installed. std::stack<FetchedCRXFile> fetched_crx_files_; diff --git a/chrome/browser/extensions/extension_updater_unittest.cc b/chrome/browser/extensions/extension_updater_unittest.cc index 2a6c2bf..e475feb 100644 --- a/chrome/browser/extensions/extension_updater_unittest.cc +++ b/chrome/browser/extensions/extension_updater_unittest.cc @@ -339,7 +339,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), 60*60*24); - updater.set_use_utility_process_for_testing(false); updater.Start(); // Disable blacklist checks (tested elsewhere) so that we only see the // update HTTP request. @@ -392,7 +391,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), 60*60*24); - updater.set_use_utility_process_for_testing(false); updater.Start(); // Tell the updater that it's time to do update checks. @@ -505,7 +503,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); // Check passing an empty list of parse results to DetermineUpdates @@ -547,7 +544,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); ManifestFetchData fetch_data(GURL("http://localhost/foo")); @@ -586,7 +582,6 @@ class ExtensionUpdaterTest : public testing::Test { service->pref_service(), service->profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); GURL url1("http://localhost/manifest1"); @@ -665,7 +660,6 @@ class ExtensionUpdaterTest : public testing::Test { service->pref_service(), service->profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); GURL test_url("http://localhost/extension.crx"); @@ -730,7 +724,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); GURL test_url("http://localhost/extension.crx"); @@ -782,7 +775,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); EXPECT_FALSE(updater.crx_install_is_running_); @@ -984,7 +976,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); updater.set_blacklist_checks_enabled(false); @@ -1072,7 +1063,6 @@ class ExtensionUpdaterTest : public testing::Test { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); GURL update_url("http://www.google.com/manifest"); @@ -1229,7 +1219,6 @@ TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); updater.Start(); updater.StartUpdateCheck(new ManifestFetchData(GURL())); // This should delete the newly-created ManifestFetchData. @@ -1251,7 +1240,6 @@ TEST_F(ExtensionUpdaterTest, TestCheckSoon) { ExtensionUpdater updater( &service, service.extension_prefs(), service.pref_service(), service.profile(), kUpdateFrequencySecs); - updater.set_use_utility_process_for_testing(false); EXPECT_FALSE(updater.WillCheckSoon()); updater.Start(); EXPECT_FALSE(updater.WillCheckSoon()); diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc index e00409d..35414b4 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc @@ -163,16 +163,14 @@ bool FindWritableTempLocation(FilePath* temp_dir) { SandboxedExtensionUnpacker::SandboxedExtensionUnpacker( const FilePath& crx_path, + ResourceDispatcherHost* rdh, Extension::Location location, int creation_flags, SandboxedExtensionUnpackerClient* client) : crx_path_(crx_path), thread_identifier_(BrowserThread::ID_COUNT), - client_(client), - got_response_(false), - location_(location), - creation_flags_(creation_flags), - use_utility_process_(true) { + rdh_(rdh), client_(client), got_response_(false), + location_(location), creation_flags_(creation_flags) { } bool SandboxedExtensionUnpacker::CreateTempDirectory() { @@ -241,7 +239,7 @@ void SandboxedExtensionUnpacker::Start() { // // TODO(asargent) we shouldn't need to do this branch here - instead // UtilityProcessHost should handle it for us. (http://crbug.com/19192) - bool use_utility_process = use_utility_process_ && + bool use_utility_process = rdh_ && !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); if (use_utility_process) { // The utility process will have access to the directory passed to diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h index c788553..2fdc59f 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.h +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h @@ -15,6 +15,7 @@ #include "content/browser/utility_process_host.h" class Extension; +class ResourceDispatcherHost; namespace base { class DictionaryValue; @@ -97,8 +98,10 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { static const uint32 kCurrentVersion = 2; // Unpacks the extension in |crx_path| into a temporary directory and calls - // |client| with the result. + // |client| with the result. If |rdh| is provided, unpacking is done in a + // sandboxed subprocess. Otherwise, it is done in-process. SandboxedExtensionUnpacker(const FilePath& crx_path, + ResourceDispatcherHost* rdh, Extension::Location location, int creation_flags, SandboxedExtensionUnpackerClient* client); @@ -106,8 +109,6 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // Start unpacking the extension. The client is called with the results. void Start(); - void set_use_utility_process(bool value) { use_utility_process_ = value; } - private: class ProcessHostClient; @@ -219,6 +220,9 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // Our client's thread. This is the thread we respond on. content::BrowserThread::ID thread_identifier_; + // ResourceDispatcherHost to pass to the utility process. + ResourceDispatcherHost* rdh_; + // Our client. scoped_refptr<SandboxedExtensionUnpackerClient> client_; @@ -246,9 +250,6 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // Creation flags to use for the extension. These flags will be used // when calling Extenion::Create() by the crx installer. int creation_flags_; - - // True if the utility process is used, false otherwise (i.e. for tests). - bool use_utility_process_; }; #endif // CHROME_BROWSER_EXTENSIONS_SANDBOXED_EXTENSION_UNPACKER_H_ diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc index d7cfc24..68bc2e9 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker_unittest.cc @@ -100,9 +100,8 @@ class SandboxedExtensionUnpackerTest : public testing::Test { ASSERT_TRUE(file_util::CreateDirectory(temp_path_)); sandboxed_unpacker_ = - new SandboxedExtensionUnpacker(crx_path, Extension::INTERNAL, + new SandboxedExtensionUnpacker(crx_path, NULL, Extension::INTERNAL, Extension::NO_FLAGS, client_); - sandboxed_unpacker_->set_use_utility_process(true); // Hack since SandboxedExtensionUnpacker gets its background thread id from // the Start call, but we don't call it here. diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index d1b9f30..59f0c71 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -11,6 +11,7 @@ #include "base/bind_helpers.h" #include "base/debug/leak_tracker.h" #include "base/logging.h" +#include "base/metrics/field_trial.h" #include "base/stl_util.h" #include "base/string_number_conversions.h" #include "base/string_split.h" @@ -120,6 +121,43 @@ net::HostResolver* CreateGlobalHostResolver(net::NetLog* net_log) { } else { LOG(ERROR) << "Invalid switch for host resolver parallelism: " << s; } + } else { + // Set up a field trial to see what impact the total number of concurrent + // resolutions have on DNS resolutions. + base::FieldTrial::Probability kDivisor = 1000; + // For each option (i.e., non-default), we have a fixed probability. + base::FieldTrial::Probability kProbabilityPerGroup = 100; // 10%. + + // After June 30, 2011 builds, it will always be in default group + // (parallel_default). + scoped_refptr<base::FieldTrial> trial( + new base::FieldTrial( + "DnsParallelism", kDivisor, "parallel_default", 2011, 6, 30)); + + // List options with different counts. + // Firefox limits total to 8 in parallel, and default is currently 50. + int parallel_6 = trial->AppendGroup("parallel_6", kProbabilityPerGroup); + int parallel_7 = trial->AppendGroup("parallel_7", kProbabilityPerGroup); + int parallel_8 = trial->AppendGroup("parallel_8", kProbabilityPerGroup); + int parallel_9 = trial->AppendGroup("parallel_9", kProbabilityPerGroup); + int parallel_10 = trial->AppendGroup("parallel_10", kProbabilityPerGroup); + int parallel_14 = trial->AppendGroup("parallel_14", kProbabilityPerGroup); + int parallel_20 = trial->AppendGroup("parallel_20", kProbabilityPerGroup); + + if (trial->group() == parallel_6) + parallelism = 6; + else if (trial->group() == parallel_7) + parallelism = 7; + else if (trial->group() == parallel_8) + parallelism = 8; + else if (trial->group() == parallel_9) + parallelism = 9; + else if (trial->group() == parallel_10) + parallelism = 10; + else if (trial->group() == parallel_14) + parallelism = 14; + else if (trial->group() == parallel_20) + parallelism = 20; } size_t retry_attempts = net::HostResolver::kDefaultRetryAttempts; diff --git a/chrome/browser/prerender/prerender_tracker.cc b/chrome/browser/prerender/prerender_tracker.cc index 9224f15..a1c908a 100644 --- a/chrome/browser/prerender/prerender_tracker.cc +++ b/chrome/browser/prerender/prerender_tracker.cc @@ -20,14 +20,18 @@ namespace prerender { namespace { -void CancelDeferredRequestOnIOThread(int child_id, int request_id) { +void CancelDeferredRequestOnIOThread( + ResourceDispatcherHost* resource_dispatcher_host, + int child_id, int request_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ResourceDispatcherHost::Get()->CancelRequest(child_id, request_id, false); + resource_dispatcher_host->CancelRequest(child_id, request_id, false); } -void StartDeferredRequestOnIOThread(int child_id, int request_id) { +void StartDeferredRequestOnIOThread( + ResourceDispatcherHost* resource_dispatcher_host, + int child_id, int request_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - ResourceDispatcherHost::Get()->StartDeferredRequest(child_id, request_id); + resource_dispatcher_host->StartDeferredRequest(child_id, request_id); } bool ShouldCancelRequest( @@ -55,14 +59,19 @@ void HandleDelayedRequestOnUIThread( int route_id, int request_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + ResourceDispatcherHost* resource_dispatcher_host = + g_browser_process->resource_dispatcher_host(); + CHECK(resource_dispatcher_host); if (ShouldCancelRequest(child_id, route_id)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&CancelDeferredRequestOnIOThread, child_id, request_id)); + base::Bind(&CancelDeferredRequestOnIOThread, resource_dispatcher_host, + child_id, request_id)); } else { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&StartDeferredRequestOnIOThread, child_id, request_id)); + base::Bind(&StartDeferredRequestOnIOThread, resource_dispatcher_host, + child_id, request_id)); } } diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 514f42d..5968e86 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -547,7 +547,7 @@ void ProfileIOData::ShutdownOnUIThread() { BrowserThread::IO, FROM_HERE, base::Bind( &ResourceDispatcherHost::CancelRequestsForContext, - base::Unretained(ResourceDispatcherHost::Get()), + base::Unretained(g_browser_process->resource_dispatcher_host()), &resource_context_)); bool posted = BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, this); if (!posted) diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index 536cf4d..72fae3f 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -42,6 +42,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_child_process_host.h" +#include "content/browser/renderer_host/render_message_filter.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" diff --git a/chrome/browser/web_resource/promo_resource_service_unittest.cc b/chrome/browser/web_resource/promo_resource_service_unittest.cc index c1ba3e1..149a592 100644 --- a/chrome/browser/web_resource/promo_resource_service_unittest.cc +++ b/chrome/browser/web_resource/promo_resource_service_unittest.cc @@ -29,7 +29,6 @@ class PromoResourceServiceTest : public testing::Test { PromoResourceServiceTest() : local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)), web_resource_service_(new PromoResourceService(&profile_)) { - web_resource_service_->set_use_utility_process_for_testing(false); } protected: diff --git a/chrome/browser/web_resource/web_resource_service.cc b/chrome/browser/web_resource/web_resource_service.cc index 7688c19..403836f 100644 --- a/chrome/browser/web_resource/web_resource_service.cc +++ b/chrome/browser/web_resource/web_resource_service.cc @@ -30,18 +30,21 @@ using content::BrowserThread; // the WebResourceService. class WebResourceService::UnpackerClient : public UtilityProcessHost::Client { public: - UnpackerClient(WebResourceService* web_resource_service, - bool use_utility_process) + explicit UnpackerClient(WebResourceService* web_resource_service) : web_resource_service_(web_resource_service), - use_utility_process_(use_utility_process), + resource_dispatcher_host_(g_browser_process->resource_dispatcher_host()), got_response_(false) { } void Start(const std::string& json_data) { AddRef(); // balanced in Cleanup. + // TODO(willchan): Look for a better signal of whether we're in a unit test + // or not. Using |resource_dispatcher_host_| for this is pretty lame. + // If we don't have a resource_dispatcher_host_, assume we're in + // a test and run the unpacker directly in-process. bool use_utility_process = - use_utility_process_ && + resource_dispatcher_host_ != NULL && !CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess); if (use_utility_process) { BrowserThread::ID thread_id; @@ -115,7 +118,8 @@ class WebResourceService::UnpackerClient : public UtilityProcessHost::Client { scoped_refptr<WebResourceService> web_resource_service_; - bool use_utility_process_; + // Owned by the global browser process. + ResourceDispatcherHost* resource_dispatcher_host_; // True if we got a response from the utility process and have cleaned up // already. @@ -136,8 +140,7 @@ WebResourceService::WebResourceService( apply_locale_to_url_(apply_locale_to_url), last_update_time_pref_name_(last_update_time_pref_name), start_fetch_delay_ms_(start_fetch_delay_ms), - cache_update_delay_ms_(cache_update_delay_ms), - use_utility_process_(true) { + cache_update_delay_ms_(cache_update_delay_ms) { DCHECK(prefs); } @@ -228,7 +231,7 @@ void WebResourceService::OnURLFetchComplete(const content::URLFetcher* source) { source->GetResponseAsString(&data); // UnpackerClient releases itself. - UnpackerClient* client = new UnpackerClient(this, use_utility_process_); + UnpackerClient* client = new UnpackerClient(this); client->Start(data); Release(); diff --git a/chrome/browser/web_resource/web_resource_service.h b/chrome/browser/web_resource/web_resource_service.h index 077cec5..2dc28d7 100644 --- a/chrome/browser/web_resource/web_resource_service.h +++ b/chrome/browser/web_resource/web_resource_service.h @@ -38,10 +38,6 @@ class WebResourceService // Then begin updating resources. void StartAfterDelay(); - void set_use_utility_process_for_testing(bool value) { - use_utility_process_ = value; - } - protected: virtual ~WebResourceService(); @@ -93,9 +89,6 @@ class WebResourceService // different for different builds of Chrome. int cache_update_delay_ms_; - // Used by unittests to skip the utility process. - bool use_utility_process_; - DISALLOW_COPY_AND_ASSIGN(WebResourceService); }; diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index ef97f73..4866ad3 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -30,10 +30,11 @@ TestingBrowserProcess::~TestingBrowserProcess() { EXPECT_FALSE(local_state_); } -void TestingBrowserProcess::ResourceDispatcherHostCreated() { +void TestingBrowserProcess::EndSession() { } -void TestingBrowserProcess::EndSession() { +ResourceDispatcherHost* TestingBrowserProcess::resource_dispatcher_host() { + return NULL; } MetricsService* TestingBrowserProcess::metrics_service() { diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index db62178..4f0fc10 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -47,8 +47,8 @@ class TestingBrowserProcess : public BrowserProcess { TestingBrowserProcess(); virtual ~TestingBrowserProcess(); - virtual void ResourceDispatcherHostCreated() OVERRIDE; virtual void EndSession() OVERRIDE; + virtual ResourceDispatcherHost* resource_dispatcher_host() OVERRIDE; virtual MetricsService* metrics_service() OVERRIDE; virtual IOThread* io_thread() OVERRIDE; virtual WatchDogThread* watchdog_thread() OVERRIDE; diff --git a/chrome_frame/test/net/fake_external_tab.cc b/chrome_frame/test/net/fake_external_tab.cc index 20b3e04..d4d00a1 100644 --- a/chrome_frame/test/net/fake_external_tab.cc +++ b/chrome_frame/test/net/fake_external_tab.cc @@ -605,7 +605,16 @@ void CFUrlRequestUnittestRunner::PreCreateThreads() { StartChromeFrameInHostBrowser(); } +void CFUrlRequestUnittestRunner::PreStartThread(BrowserThread::ID identifier) { + fake_chrome_->browser_process()->PreStartThread(identifier); +} + +void CFUrlRequestUnittestRunner::PostStartThread(BrowserThread::ID identifier) { + fake_chrome_->browser_process()->PostStartThread(identifier); +} + void CFUrlRequestUnittestRunner::PreMainMessageLoopRun() { + fake_chrome_->InitializePostThreadsCreated(); } bool CFUrlRequestUnittestRunner::MainMessageLoopRun(int* result_code) { @@ -632,6 +641,16 @@ void CFUrlRequestUnittestRunner::PostMainMessageLoopRun() { base::KillProcesses(chrome_frame_test::kIEBrokerImageName, 0, NULL); } +void CFUrlRequestUnittestRunner::PreStopThread( + content::BrowserThread::ID identifier) { + fake_chrome_->browser_process()->PreStopThread(identifier); +} + +void CFUrlRequestUnittestRunner::PostStopThread( + content::BrowserThread::ID identifier) { + fake_chrome_->browser_process()->PostStopThread(identifier); +} + void CFUrlRequestUnittestRunner::PostDestroyThreads() { fake_chrome_->Shutdown(); fake_chrome_.reset(); diff --git a/chrome_frame/test/net/fake_external_tab.h b/chrome_frame/test/net/fake_external_tab.h index 8a1a190..b0089a8 100644 --- a/chrome_frame/test/net/fake_external_tab.h +++ b/chrome_frame/test/net/fake_external_tab.h @@ -105,9 +105,14 @@ class CFUrlRequestUnittestRunner virtual void PostMainMessageLoopStart() OVERRIDE {} virtual void ToolkitInitialized() OVERRIDE {} virtual void PreCreateThreads() OVERRIDE; + virtual void PreStartThread(content::BrowserThread::ID identifier) OVERRIDE; + virtual void PostStartThread( + content::BrowserThread::ID identifier) OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; virtual void PostMainMessageLoopRun() OVERRIDE; + virtual void PreStopThread(content::BrowserThread::ID identifier) OVERRIDE; + virtual void PostStopThread(content::BrowserThread::ID identifier) OVERRIDE; virtual void PostDestroyThreads() OVERRIDE; protected: diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index e49acb2..bfd23b4 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc @@ -13,11 +13,7 @@ #include "base/metrics/histogram.h" #include "base/threading/thread_restrictions.h" #include "content/browser/browser_thread_impl.h" -#include "content/browser/download/download_file_manager.h" -#include "content/browser/download/save_file_manager.h" #include "content/browser/in_process_webkit/webkit_thread.h" -#include "content/browser/plugin_service_impl.h" -#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/browser/trace_controller.h" #include "content/common/hi_res_timer_manager.h" #include "content/common/sandbox_policy.h" @@ -294,12 +290,6 @@ void BrowserMainLoop::MainMessageLoopStart() { system_message_window_.reset(new SystemMessageWindowWin); #endif - // Prior to any processing happening on the io thread, we create the - // plugin service as it is predominantly used from the io thread, - // but must be created on the main thread. The service ctor is - // inexpensive and does not invoke the io_thread() accessor. - PluginService::GetInstance()->Init(); - if (parts_.get()) parts_->PostMainMessageLoopStart(); } @@ -368,6 +358,9 @@ void BrowserMainLoop::RunMainMessageLoopParts( BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); + if (parts_.get()) + parts_->PreStartThread(id); + if (thread_id == BrowserThread::WEBKIT_DEPRECATED) { webkit_thread_.reset(new WebKitThread); webkit_thread_->Initialize(); @@ -377,6 +370,9 @@ void BrowserMainLoop::RunMainMessageLoopParts( } else { NOTREACHED(); } + + if (parts_.get()) + parts_->PostStartThread(id); } if (parts_.get()) @@ -414,12 +410,6 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { if (parts_.get()) parts_->PostMainMessageLoopRun(); - // Cancel pending requests and prevent new requests. - ResourceDispatcherHost* rdh = ResourceDispatcherHost::IsCreated() ? - ResourceDispatcherHost::Get() : NULL; - if (rdh) - rdh->Shutdown(); - // Must be size_t so we can subtract from it. for (size_t thread_id = BrowserThread::ID_COUNT - 1; thread_id >= (BrowserThread::UI + 1); @@ -455,24 +445,12 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { case BrowserThread::WEBKIT_DEPRECATED: // Special case as WebKitThread is a separate // type. |thread_to_stop| is not used in this case. - - // Need to destroy ResourceDispatcherHost before PluginService - // and since it caches a pointer to it. - if (rdh) - delete rdh; break; case BrowserThread::FILE_USER_BLOCKING: thread_to_stop = &file_user_blocking_thread_; break; case BrowserThread::FILE: thread_to_stop = &file_thread_; - - // Clean up state that lives on or uses the file_thread_ before - // it goes away. - if (rdh) { - rdh->download_file_manager()->Shutdown(); - rdh->save_file_manager()->Shutdown(); - } break; case BrowserThread::PROCESS_LAUNCHER: thread_to_stop = &process_launcher_thread_; @@ -492,6 +470,9 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { BrowserThread::ID id = static_cast<BrowserThread::ID>(thread_id); + if (parts_.get()) + parts_->PreStopThread(id); + if (id == BrowserThread::WEBKIT_DEPRECATED) { webkit_thread_.reset(); } else if (thread_to_stop) { @@ -499,6 +480,9 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() { } else { NOTREACHED(); } + + if (parts_.get()) + parts_->PostStopThread(id); } if (parts_.get()) diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index f3bb3b0..1487b19 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc @@ -86,18 +86,6 @@ void BeginDownload(const URLParams& url_params, } // namespace -namespace content { - -// static -DownloadManager* DownloadManager::Create( - content::DownloadManagerDelegate* delegate, - DownloadIdFactory* id_factory, - DownloadStatusUpdater* status_updater) { - return new DownloadManagerImpl(delegate, id_factory, status_updater); -} - -} // namespace content - DownloadManagerImpl::DownloadManagerImpl( content::DownloadManagerDelegate* delegate, DownloadIdFactory* id_factory, @@ -259,8 +247,15 @@ bool DownloadManagerImpl::Init(content::BrowserContext* browser_context) { browser_context_ = browser_context; - file_manager_ = ResourceDispatcherHost::Get()->download_file_manager(); - DCHECK(file_manager_); + // In test mode, there may be no ResourceDispatcherHost. In this case it's + // safe to avoid setting |file_manager_| because we only call a small set of + // functions, none of which need it. + ResourceDispatcherHost* rdh = + content::GetContentClient()->browser()->GetResourceDispatcherHost(); + if (rdh) { + file_manager_ = rdh->download_file_manager(); + DCHECK(file_manager_); + } return true; } @@ -786,7 +781,7 @@ void DownloadManagerImpl::DownloadUrlToFile(const GURL& url, const DownloadSaveInfo& save_info, WebContents* web_contents) { ResourceDispatcherHost* resource_dispatcher_host = - ResourceDispatcherHost::Get(); + content::GetContentClient()->browser()->GetResourceDispatcherHost(); // We send a pointer to content::ResourceContext, instead of the usual // reference, so that a copy of the object isn't made. diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h index 50fdf58..07bba75 100644 --- a/content/browser/download/download_manager_impl.h +++ b/content/browser/download/download_manager_impl.h @@ -7,6 +7,8 @@ #define CONTENT_BROWSER_DOWNLOAD_DOWNLOAD_MANAGER_IMPL_H_ #pragma once +#include "content/public/browser/download_manager.h" + #include <map> #include <set> @@ -20,7 +22,6 @@ #include "content/browser/download/download_item_impl.h" #include "content/browser/download/download_status_updater_delegate.h" #include "content/common/content_export.h" -#include "content/public/browser/download_manager.h" class DownloadIdFactory; class DownloadStatusUpdater; diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index 6095738..1ce1f21 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc @@ -241,7 +241,14 @@ void SavePackage::Cancel(bool user_action) { // 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() { - file_manager_ = ResourceDispatcherHost::Get()->save_file_manager(); + ResourceDispatcherHost* rdh = + content::GetContentClient()->browser()->GetResourceDispatcherHost(); + if (!rdh) { + NOTREACHED(); + return; + } + + file_manager_ = rdh->save_file_manager(); DCHECK(file_manager_); download_manager_ = web_contents()->GetBrowserContext()->GetDownloadManager(); diff --git a/content/browser/mock_content_browser_client.cc b/content/browser/mock_content_browser_client.cc index 0476f7d..a4ad86d 100644 --- a/content/browser/mock_content_browser_client.cc +++ b/content/browser/mock_content_browser_client.cc @@ -236,7 +236,8 @@ std::string MockContentBrowserClient::GetWorkerProcessTitle( return std::string(); } -void MockContentBrowserClient::ResourceDispatcherHostCreated() { +ResourceDispatcherHost* MockContentBrowserClient::GetResourceDispatcherHost() { + return NULL; } ui::Clipboard* MockContentBrowserClient::GetClipboard() { diff --git a/content/browser/mock_content_browser_client.h b/content/browser/mock_content_browser_client.h index 6e47710..14e9d4e17 100644 --- a/content/browser/mock_content_browser_client.h +++ b/content/browser/mock_content_browser_client.h @@ -125,7 +125,7 @@ class MockContentBrowserClient : public ContentBrowserClient { int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; - virtual void ResourceDispatcherHostCreated() OVERRIDE; + virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; virtual ui::Clipboard* GetClipboard() OVERRIDE; virtual MHTMLGenerationManager* GetMHTMLGenerationManager() OVERRIDE; virtual net::NetLog* GetNetLog() OVERRIDE; diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index dcfe740..a695441 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -164,7 +164,8 @@ PluginProcessHost::~PluginProcessHost() { CancelRequests(); } -bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { +bool PluginProcessHost::Init(const webkit::WebPluginInfo& info, + const std::string& locale) { info_ = info; set_name(info_.name); @@ -230,8 +231,6 @@ bool PluginProcessHost::Init(const webkit::WebPluginInfo& info) { if (!plugin_launcher.empty()) cmd_line->PrependWrapper(plugin_launcher); - std::string locale = - content::GetContentClient()->browser()->GetApplicationLocale(); if (!locale.empty()) { // Pass on the locale so the null plugin will use the right language in the // prompt to install the desired plugin. diff --git a/content/browser/plugin_process_host.h b/content/browser/plugin_process_host.h index 2fabe64..6ce5f08 100644 --- a/content/browser/plugin_process_host.h +++ b/content/browser/plugin_process_host.h @@ -67,7 +67,7 @@ class CONTENT_EXPORT PluginProcessHost : public BrowserChildProcessHost { // Initialize the new plugin process, returning true on success. This must // be called before the object can be used. - bool Init(const webkit::WebPluginInfo& info); + bool Init(const webkit::WebPluginInfo& info, const std::string& locale); // Force the plugin process to shutdown (cleanly). void ForceShutdown(); diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index 4dcc47c..8cd4cbc 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -135,7 +135,10 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() { } PluginServiceImpl::PluginServiceImpl() - : plugin_list_(NULL), filter_(NULL) { + : plugin_list_(NULL), + ui_locale_( + content::GetContentClient()->browser()->GetApplicationLocale()), + filter_(NULL) { } PluginServiceImpl::~PluginServiceImpl() { @@ -229,6 +232,10 @@ void PluginServiceImpl::StartWatchingPlugins() { #endif } +const std::string& PluginServiceImpl::GetUILocale() { + return ui_locale_; +} + PluginProcessHost* PluginServiceImpl::FindNpapiPluginProcess( const FilePath& plugin_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -290,7 +297,7 @@ PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( // This plugin isn't loaded by any plugin process, so create a new process. scoped_ptr<PluginProcessHost> new_host(new PluginProcessHost()); - if (!new_host->Init(info)) { + if (!new_host->Init(info, ui_locale_)) { NOTREACHED(); // Init is not expected to fail. return NULL; } diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index a9aee11..4a2c203 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -106,6 +106,9 @@ class CONTENT_EXPORT PluginServiceImpl virtual void SetPluginListForTesting( webkit::npapi::PluginList* plugin_list) OVERRIDE; + // Gets the browser's UI locale. + const std::string& GetUILocale(); + // Like FindNpapiPluginProcess but for Pepper. PpapiPluginProcessHost* FindPpapiPluginProcess(const FilePath& plugin_path); PpapiPluginProcessHost* FindPpapiBrokerProcess(const FilePath& broker_path); @@ -197,6 +200,9 @@ class CONTENT_EXPORT PluginServiceImpl // The plugin list instance. webkit::npapi::PluginList* plugin_list_; + // The browser's UI locale. + const std::string ui_locale_; + content::NotificationRegistrar registrar_; #if defined(OS_WIN) diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 113fcae..37bc99e 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -271,7 +271,8 @@ RenderMessageFilter::RenderMessageFilter( content::BrowserContext* browser_context, net::URLRequestContextGetter* request_context, RenderWidgetHelper* render_widget_helper) - : resource_dispatcher_host_(ResourceDispatcherHost::Get()), + : resource_dispatcher_host_( + content::GetContentClient()->browser()->GetResourceDispatcherHost()), plugin_service_(plugin_service), browser_context_(browser_context), request_context_(request_context), diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 319e9b9..1765526 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -85,6 +85,9 @@ class RenderMessageFilter : public content::BrowserMessageFilter { bool OffTheRecord() const; int render_process_id() const { return render_process_id_; } + ResourceDispatcherHost* resource_dispatcher_host() { + return resource_dispatcher_host_; + } // Returns the correct net::URLRequestContext depending on what type of url is // given. diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index e969c06..1e4124e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -454,8 +454,10 @@ void RenderProcessHostImpl::CreateMessageFilters() { &browser_context->GetResourceContext(); ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( - GetID(), content::PROCESS_TYPE_RENDERER, resource_context, - new RendererURLRequestContextSelector(browser_context, GetID())); + GetID(), content::PROCESS_TYPE_RENDERER, + resource_context, + new RendererURLRequestContextSelector(browser_context, GetID()), + content::GetContentClient()->browser()->GetResourceDispatcherHost()); channel_->AddFilter(resource_message_filter); channel_->AddFilter(new AudioInputRendererHost(resource_context)); @@ -501,6 +503,7 @@ void RenderProcessHostImpl::CreateMessageFilters() { channel_->AddFilter(socket_stream_dispatcher_host); channel_->AddFilter(new WorkerMessageFilter(GetID(), resource_context, + content::GetContentClient()->browser()->GetResourceDispatcherHost(), base::Bind(&RenderWidgetHelper::GetNextRoutingID, base::Unretained(widget_helper_.get())))); diff --git a/content/browser/renderer_host/resource_dispatcher_host.cc b/content/browser/renderer_host/resource_dispatcher_host.cc index c44c7c2..748f589 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.cc +++ b/content/browser/renderer_host/resource_dispatcher_host.cc @@ -95,8 +95,6 @@ using webkit_blob::DeletableFileReference; namespace { -static ResourceDispatcherHost* g_resource_dispatcher_host; - // The interval for calls to ResourceDispatcherHost::UpdateLoadStates const int kUpdateLoadStatesIntervalMsec = 100; @@ -296,20 +294,9 @@ void OnSwapOutACKHelper(int render_process_id, int render_view_id) { } // namespace -ResourceDispatcherHost* ResourceDispatcherHost::Get() { - if (!g_resource_dispatcher_host) - new ResourceDispatcherHost(); - DCHECK(g_resource_dispatcher_host); - return g_resource_dispatcher_host; -} - -bool ResourceDispatcherHost::IsCreated() { - return !!g_resource_dispatcher_host; -} - -ResourceDispatcherHost::ResourceDispatcherHost() - : temporarily_delegate_set_(NULL), - ALLOW_THIS_IN_INITIALIZER_LIST( +ResourceDispatcherHost::ResourceDispatcherHost( + const ResourceQueue::DelegateSet& resource_queue_delegates) + : ALLOW_THIS_IN_INITIALIZER_LIST( download_file_manager_(new DownloadFileManager(this, NULL))), ALLOW_THIS_IN_INITIALIZER_LIST( save_file_manager_(new SaveFileManager(this))), @@ -321,27 +308,14 @@ ResourceDispatcherHost::ResourceDispatcherHost() filter_(NULL), delegate_(NULL), allow_cross_origin_auth_prompt_(false) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - g_resource_dispatcher_host = this; - - ResourceQueue::DelegateSet resource_queue_delegates; - temporarily_delegate_set_ = &resource_queue_delegates; - content::GetContentClient()->browser()->ResourceDispatcherHostCreated(); resource_queue_.Initialize(resource_queue_delegates); - temporarily_delegate_set_ = NULL; ANNOTATE_BENIGN_RACE( &last_user_gesture_time_, "We don't care about the precise value, see http://crbug.com/92889"); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind(&appcache::AppCacheInterceptor::EnsureRegistered)); } ResourceDispatcherHost::~ResourceDispatcherHost() { - DCHECK(g_resource_dispatcher_host); - g_resource_dispatcher_host = NULL; AsyncResourceHandler::GlobalCleanup(); for (PendingRequestList::const_iterator i = pending_requests_.begin(); i != pending_requests_.end(); ++i) { @@ -351,6 +325,13 @@ ResourceDispatcherHost::~ResourceDispatcherHost() { DCHECK(transferred_navigations_.empty()); } +void ResourceDispatcherHost::Initialize() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&appcache::AppCacheInterceptor::EnsureRegistered)); +} + void ResourceDispatcherHost::Shutdown() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); BrowserThread::PostTask(BrowserThread::IO, @@ -359,11 +340,6 @@ void ResourceDispatcherHost::Shutdown() { base::Unretained(this))); } -void ResourceDispatcherHost::AddResourceQueueDelegate( - ResourceQueueDelegate* delegate) { - temporarily_delegate_set_->insert(delegate); -} - void ResourceDispatcherHost::SetRequestInfo( net::URLRequest* request, ResourceDispatcherHostRequestInfo* info) { diff --git a/content/browser/renderer_host/resource_dispatcher_host.h b/content/browser/renderer_host/resource_dispatcher_host.h index 535a68b..94f7fb5 100644 --- a/content/browser/renderer_host/resource_dispatcher_host.h +++ b/content/browser/renderer_host/resource_dispatcher_host.h @@ -59,29 +59,16 @@ class DeletableFileReference; class CONTENT_EXPORT ResourceDispatcherHost : public net::URLRequest::Delegate { public: - ResourceDispatcherHost(); + explicit ResourceDispatcherHost( + const ResourceQueue::DelegateSet& resource_queue_delegates); virtual ~ResourceDispatcherHost(); - // Returns the current ResourceDispatcherHost, creating it if necessary. The - // first time this is called must be on the UI thread, but after that it can - // be called from the IO thread as well. - static ResourceDispatcherHost* Get(); - - // Returns true if the ResourceDispatcherHost has been created (i.e. Get() has - // been called). - static bool IsCreated(); + void Initialize(); // Puts the resource dispatcher host in an inactive state (unable to begin // new requests). Cancels all pending requests. void Shutdown(); - // Destructs the current ResourceDispatcherHost. - void Destruct(); - - // Adds a delegate that can delay requests. This should be called early, i.e. - // in the ContentBrowserClient::ResourceDispatcherHostCreated callback. - void AddResourceQueueDelegate(ResourceQueueDelegate* delegate); - // Returns true if the message was a resource message that was processed. // If it was, message_was_ok will be false iff the message was corrupt. bool OnMessageReceived(const IPC::Message& message, @@ -475,9 +462,6 @@ class CONTENT_EXPORT ResourceDispatcherHost : public net::URLRequest::Delegate { // Handles the resource requests from the moment we want to start them. ResourceQueue resource_queue_; - // Used temporarily during construction. - ResourceQueue::DelegateSet* temporarily_delegate_set_; - // We own the download file writing thread and manager scoped_refptr<DownloadFileManager> download_file_manager_; diff --git a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc index 08f54d5..53cc63f 100644 --- a/content/browser/renderer_host/resource_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/resource_dispatcher_host_unittest.cc @@ -174,7 +174,8 @@ class ForwardingFilter : public ResourceMessageFilter { content::PROCESS_TYPE_RENDERER, content::MockResourceContext::GetInstance(), new MockURLRequestContextSelector( - content::MockResourceContext::GetInstance()->request_context())), + content::MockResourceContext::GetInstance()->request_context()), + NULL), dest_(dest) { OnChannelConnected(base::GetCurrentProcId()); } @@ -276,6 +277,7 @@ class ResourceDispatcherHostTest : public testing::Test, : ui_thread_(BrowserThread::UI, &message_loop_), io_thread_(BrowserThread::IO, &message_loop_), ALLOW_THIS_IN_INITIALIZER_LIST(filter_(new ForwardingFilter(this))), + host_(ResourceQueue::DelegateSet()), old_factory_(NULL), resource_type_(ResourceType::SUB_RESOURCE) { } diff --git a/content/browser/renderer_host/resource_message_filter.cc b/content/browser/renderer_host/resource_message_filter.cc index 7c8497f..771008c 100644 --- a/content/browser/renderer_host/resource_message_filter.cc +++ b/content/browser/renderer_host/resource_message_filter.cc @@ -14,11 +14,13 @@ ResourceMessageFilter::ResourceMessageFilter( int child_id, content::ProcessType process_type, const content::ResourceContext* resource_context, - URLRequestContextSelector* url_request_context_selector) + URLRequestContextSelector* url_request_context_selector, + ResourceDispatcherHost* resource_dispatcher_host) : child_id_(child_id), process_type_(process_type), resource_context_(resource_context), - url_request_context_selector_(url_request_context_selector) { + url_request_context_selector_(url_request_context_selector), + resource_dispatcher_host_(resource_dispatcher_host) { DCHECK(resource_context); DCHECK(url_request_context_selector); } @@ -31,12 +33,12 @@ void ResourceMessageFilter::OnChannelClosing() { // Unhook us from all pending network requests so they don't get sent to a // deleted object. - ResourceDispatcherHost::Get()->CancelRequestsForProcess(child_id_); + resource_dispatcher_host_->CancelRequestsForProcess(child_id_); } bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message, bool* message_was_ok) { - return ResourceDispatcherHost::Get()->OnMessageReceived( + return resource_dispatcher_host_->OnMessageReceived( message, this, message_was_ok); } diff --git a/content/browser/renderer_host/resource_message_filter.h b/content/browser/renderer_host/resource_message_filter.h index c9f6d0d..96ef977 100644 --- a/content/browser/renderer_host/resource_message_filter.h +++ b/content/browser/renderer_host/resource_message_filter.h @@ -11,6 +11,8 @@ #include "content/public/common/process_type.h" #include "webkit/glue/resource_type.h" +class ResourceDispatcherHost; + namespace content { class ResourceContext; } // namespace content @@ -40,11 +42,11 @@ class CONTENT_EXPORT ResourceMessageFilter DISALLOW_COPY_AND_ASSIGN(URLRequestContextSelector); }; - ResourceMessageFilter( - int child_id, - content::ProcessType process_type, - const content::ResourceContext* resource_context, - URLRequestContextSelector* url_request_context_selector); + ResourceMessageFilter(int child_id, + content::ProcessType process_type, + const content::ResourceContext* resource_context, + URLRequestContextSelector* url_request_context_selector, + ResourceDispatcherHost* resource_dispatcher_host); // content::BrowserMessageFilter implementation. virtual void OnChannelClosing() OVERRIDE; @@ -77,6 +79,9 @@ class CONTENT_EXPORT ResourceMessageFilter const scoped_ptr<URLRequestContextSelector> url_request_context_selector_; + // Owned by BrowserProcess, which is guaranteed to outlive us. + ResourceDispatcherHost* resource_dispatcher_host_; + DISALLOW_IMPLICIT_CONSTRUCTORS(ResourceMessageFilter); }; diff --git a/content/browser/tab_contents/interstitial_page.cc b/content/browser/tab_contents/interstitial_page.cc index 60e2c6d..c3e53b5 100644 --- a/content/browser/tab_contents/interstitial_page.cc +++ b/content/browser/tab_contents/interstitial_page.cc @@ -569,17 +569,21 @@ void InterstitialPage::TakeActionOnResourceDispatcher( // The tab might not have a render_view_host if it was closed (in which case, // we have taken care of the blocked requests when processing // NOTIFY_RENDER_WIDGET_HOST_DESTROYED. + // Also we need to test there is a ResourceDispatcherHost, as when unit-tests + // we don't have one. RenderViewHost* rvh = RenderViewHost::FromID(original_child_id_, original_rvh_id_); - if (!rvh) + if (!rvh || + !content::GetContentClient()->browser()->GetResourceDispatcherHost()) { return; + } BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind( &ResourceRequestHelper, - ResourceDispatcherHost::Get(), + content::GetContentClient()->browser()->GetResourceDispatcherHost(), original_child_id_, original_rvh_id_, action)); diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index ce3abd1..56946f2 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -2059,7 +2059,10 @@ void TabContents::OnUserGesture() { // Notify observers. FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetUserGesture()); - ResourceDispatcherHost::Get()->OnUserGesture(this); + ResourceDispatcherHost* rdh = + content::GetContentClient()->browser()->GetResourceDispatcherHost(); + if (rdh) // NULL in unittests. + rdh->OnUserGesture(this); } void TabContents::OnIgnoredUIEvent() { diff --git a/content/browser/worker_host/worker_message_filter.cc b/content/browser/worker_host/worker_message_filter.cc index f543eaa..3dc750a 100644 --- a/content/browser/worker_host/worker_message_filter.cc +++ b/content/browser/worker_host/worker_message_filter.cc @@ -17,9 +17,11 @@ using content::WorkerServiceImpl; WorkerMessageFilter::WorkerMessageFilter( int render_process_id, const content::ResourceContext* resource_context, + ResourceDispatcherHost* resource_dispatcher_host, const NextRoutingIDCallback& callback) : render_process_id_(render_process_id), resource_context_(resource_context), + resource_dispatcher_host_(resource_dispatcher_host), next_routing_id_(callback) { DCHECK(resource_context); } diff --git a/content/browser/worker_host/worker_message_filter.h b/content/browser/worker_host/worker_message_filter.h index c2dac0f..39bb567 100644 --- a/content/browser/worker_host/worker_message_filter.h +++ b/content/browser/worker_host/worker_message_filter.h @@ -25,6 +25,7 @@ class WorkerMessageFilter : public content::BrowserMessageFilter { WorkerMessageFilter( int render_process_id, const content::ResourceContext* resource_context, + ResourceDispatcherHost* resource_dispatcher_host, const NextRoutingIDCallback& callback); // content::BrowserMessageFilter implementation. @@ -34,6 +35,9 @@ class WorkerMessageFilter : public content::BrowserMessageFilter { int GetNextRoutingID(); int render_process_id() const { return render_process_id_; } + ResourceDispatcherHost* resource_dispatcher_host() const { + return resource_dispatcher_host_; + } private: virtual ~WorkerMessageFilter(); @@ -51,6 +55,7 @@ class WorkerMessageFilter : public content::BrowserMessageFilter { int render_process_id_; const content::ResourceContext* const resource_context_; + ResourceDispatcherHost* resource_dispatcher_host_; // This is guaranteed to be valid until OnChannelClosing is closed, and it's // not used after. diff --git a/content/browser/worker_host/worker_process_host.cc b/content/browser/worker_host/worker_process_host.cc index be99858..4988172 100644 --- a/content/browser/worker_host/worker_process_host.cc +++ b/content/browser/worker_host/worker_process_host.cc @@ -85,9 +85,11 @@ void WorkerCrashCallback(int render_process_unique_id, int render_view_id) { } WorkerProcessHost::WorkerProcessHost( - const content::ResourceContext* resource_context) + const content::ResourceContext* resource_context, + ResourceDispatcherHost* resource_dispatcher_host) : BrowserChildProcessHost(content::PROCESS_TYPE_WORKER), - resource_context_(resource_context) { + resource_context_(resource_context), + resource_dispatcher_host_(resource_dispatcher_host) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(resource_context); } @@ -237,11 +239,12 @@ void WorkerProcessHost::CreateMessageFilters(int render_process_id) { ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( id(), content::PROCESS_TYPE_WORKER, resource_context_, - new URLRequestContextSelector(request_context)); + new URLRequestContextSelector(request_context), + resource_dispatcher_host_); child_process_host()->AddFilter(resource_message_filter); worker_message_filter_ = new WorkerMessageFilter( - render_process_id, resource_context_, + render_process_id, resource_context_, resource_dispatcher_host_, base::Bind(&WorkerServiceImpl::next_worker_route_id, base::Unretained(WorkerServiceImpl::GetInstance()))); child_process_host()->AddFilter(worker_message_filter_); diff --git a/content/browser/worker_host/worker_process_host.h b/content/browser/worker_host/worker_process_host.h index 6ccc137..3ec544aa 100644 --- a/content/browser/worker_host/worker_process_host.h +++ b/content/browser/worker_host/worker_process_host.h @@ -16,6 +16,8 @@ #include "content/browser/worker_host/worker_document_set.h" #include "googleurl/src/gurl.h" +class ResourceDispatcherHost; + namespace content { class ResourceContext; class WorkerServiceImpl; @@ -107,7 +109,9 @@ class WorkerProcessHost : public BrowserChildProcessHost { const content::ResourceContext* const resource_context_; }; - explicit WorkerProcessHost(const content::ResourceContext* resource_context); + WorkerProcessHost( + const content::ResourceContext* resource_context, + ResourceDispatcherHost* resource_dispatcher_host); virtual ~WorkerProcessHost(); // Starts the process. Returns true iff it succeeded. @@ -186,6 +190,8 @@ class WorkerProcessHost : public BrowserChildProcessHost { // process. scoped_refptr<WorkerMessageFilter> worker_message_filter_; + ResourceDispatcherHost* const resource_dispatcher_host_; + DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost); }; diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc index 4818fc9d..3d5acb3 100644 --- a/content/browser/worker_host/worker_service_impl.cc +++ b/content/browser/worker_host/worker_service_impl.cc @@ -284,7 +284,9 @@ bool WorkerServiceImpl::CreateWorkerFromInstance( if (!worker) { WorkerMessageFilter* first_filter = instance.filters().begin()->first; - worker = new WorkerProcessHost(instance.resource_context()); + worker = new WorkerProcessHost( + instance.resource_context(), + first_filter->resource_dispatcher_host()); // TODO(atwilson): This won't work if the message is from a worker process. // We don't support that yet though (this message is only sent from // renderers) but when we do, we'll need to add code to pass in the current diff --git a/content/public/browser/browser_main_parts.h b/content/public/browser/browser_main_parts.h index 09cf20a..4bce3cf 100644 --- a/content/public/browser/browser_main_parts.h +++ b/content/public/browser/browser_main_parts.h @@ -72,6 +72,15 @@ class CONTENT_EXPORT BrowserMainParts { // been run), and the toolkit has been initialized. virtual void PreCreateThreads() = 0; + // Called once for each thread owned by the content framework just + // before and just after the thread object is created and started. + // This happens in the order of the threads' appearence in the + // BrowserThread::ID enumeration. Note that there will be no such + // call for BrowserThread::UI, since it is the main thread of the + // application. + virtual void PreStartThread(BrowserThread::ID identifier) = 0; + virtual void PostStartThread(BrowserThread::ID identifier) = 0; + // This is called just before the main message loop is run. The // various browser threads have all been created at this point virtual void PreMainMessageLoopRun() = 0; @@ -85,6 +94,14 @@ class CONTENT_EXPORT BrowserMainParts { // threads are stopped. virtual void PostMainMessageLoopRun() = 0; + // Called once for each thread owned by the content framework just + // before and just after it is torn down. This is in reverse order + // of the threads' appearance in the BrowserThread::ID enumeration. + // Note that you will not receive such a call for BrowserThread::UI, + // since it is the main thread of the application. + virtual void PreStopThread(BrowserThread::ID identifier) = 0; + virtual void PostStopThread(BrowserThread::ID identifier) = 0; + // Called as the very last part of shutdown, after threads have been // stopped and destroyed. virtual void PostDestroyThreads() = 0; diff --git a/content/public/browser/browser_shutdown.h b/content/public/browser/browser_shutdown.h index abefc26..72a4ce0 100644 --- a/content/public/browser/browser_shutdown.h +++ b/content/public/browser/browser_shutdown.h @@ -17,7 +17,8 @@ namespace content { // This causes the shutdown sequence embodied by // BrowserMainParts::PostMainMessageLoopRun through // BrowserMainParts::PostDestroyThreads to occur, i.e. we pretend the -// message loop finished, all threads are stopped in sequence and then +// message loop finished, all threads are stopped in sequence and +// PreStopThread/PostStopThread gets called, and at least, // PostDestroyThreads is called. // // As this violates the normal order of shutdown, likely leaving the diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 9a9fda1..87900d3 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -291,11 +291,8 @@ class ContentBrowserClient { virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) = 0; - // Notifies the embedder that the ResourceDispatcherHost has been created. - // This is when it can optionally add a delegate or ResourceQueueDelegates. - virtual void ResourceDispatcherHostCreated() = 0; - // Getters for common objects. + virtual ResourceDispatcherHost* GetResourceDispatcherHost() = 0; virtual ui::Clipboard* GetClipboard() = 0; virtual MHTMLGenerationManager* GetMHTMLGenerationManager() = 0; virtual net::NetLog* GetNetLog() = 0; diff --git a/content/public/browser/download_manager.h b/content/public/browser/download_manager.h index 13e717a5..41de9b2 100644 --- a/content/public/browser/download_manager.h +++ b/content/public/browser/download_manager.h @@ -43,10 +43,8 @@ #include "net/base/net_errors.h" class DownloadFileManager; -class DownloadIdFactory; class DownloadManagerTest; class DownloadRequestHandle; -class DownloadStatusUpdater; class GURL; class TabContents; struct DownloadCreateInfo; @@ -63,11 +61,6 @@ class CONTENT_EXPORT DownloadManager public: virtual ~DownloadManager() {} - static DownloadManager* Create( - DownloadManagerDelegate* delegate, - DownloadIdFactory* id_factory, - DownloadStatusUpdater* status_updater); - // Shutdown the download manager. Must be called before destruction. virtual void Shutdown() = 0; diff --git a/content/shell/shell_browser_main.cc b/content/shell/shell_browser_main.cc index 311b6a0..24d7149 100644 --- a/content/shell/shell_browser_main.cc +++ b/content/shell/shell_browser_main.cc @@ -13,6 +13,7 @@ #include "content/browser/download/download_file_manager.h" #include "content/browser/download/save_file_manager.h" #include "content/browser/plugin_service_impl.h" +#include "content/browser/renderer_host/resource_dispatcher_host.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_content_browser_client.h" @@ -47,6 +48,7 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() { Shell::PlatformInitialize(); net::NetModule::SetResourceProvider(Shell::PlatformResourceProvider); + PluginService::GetInstance()->Init(); Shell::CreateNewWindow(browser_context_.get(), GetStartupURL(), @@ -57,12 +59,32 @@ void ShellBrowserMainParts::PreMainMessageLoopRun() { void ShellBrowserMainParts::PostMainMessageLoopRun() { browser_context_.reset(); + + resource_dispatcher_host_->download_file_manager()->Shutdown(); + resource_dispatcher_host_->save_file_manager()->Shutdown(); + resource_dispatcher_host_->Shutdown(); +} + +void ShellBrowserMainParts::PreStopThread(BrowserThread::ID id) { + if (id == BrowserThread::WEBKIT_DEPRECATED) { + resource_dispatcher_host_.reset(); + } } bool ShellBrowserMainParts::MainMessageLoopRun(int* result_code) { return false; } +ResourceDispatcherHost* ShellBrowserMainParts::GetResourceDispatcherHost() { + if (!resource_dispatcher_host_.get()) { + ResourceQueue::DelegateSet resource_queue_delegates; + resource_dispatcher_host_.reset( + new ResourceDispatcherHost(resource_queue_delegates)); + resource_dispatcher_host_->Initialize(); + } + return resource_dispatcher_host_.get(); +} + ui::Clipboard* ShellBrowserMainParts::GetClipboard() { if (!clipboard_.get()) clipboard_.reset(new ui::Clipboard()); diff --git a/content/shell/shell_browser_main.h b/content/shell/shell_browser_main.h index 2451761..e842e21 100644 --- a/content/shell/shell_browser_main.h +++ b/content/shell/shell_browser_main.h @@ -10,6 +10,8 @@ #include "base/memory/scoped_ptr.h" #include "content/public/browser/browser_main_parts.h" +class ResourceDispatcherHost; + namespace base { class Thread; } @@ -34,16 +36,22 @@ class ShellBrowserMainParts : public BrowserMainParts { virtual void ToolkitInitialized() OVERRIDE {} virtual void PostMainMessageLoopStart() OVERRIDE {} virtual void PreCreateThreads() OVERRIDE {} + virtual void PreStartThread(BrowserThread::ID id) OVERRIDE {} + virtual void PostStartThread(BrowserThread::ID id) OVERRIDE {} virtual void PreMainMessageLoopRun() OVERRIDE; virtual bool MainMessageLoopRun(int* result_code) OVERRIDE; virtual void PostMainMessageLoopRun() OVERRIDE; + virtual void PreStopThread(BrowserThread::ID id) OVERRIDE; + virtual void PostStopThread(BrowserThread::ID) OVERRIDE {} virtual void PostDestroyThreads() OVERRIDE {} + ResourceDispatcherHost* GetResourceDispatcherHost(); ui::Clipboard* GetClipboard(); private: scoped_ptr<ShellBrowserContext> browser_context_; + scoped_ptr<ResourceDispatcherHost> resource_dispatcher_host_; scoped_ptr<ui::Clipboard> clipboard_; DISALLOW_COPY_AND_ASSIGN(ShellBrowserMainParts); diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index 904e9ff..73e8a5c 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -245,7 +245,8 @@ std::string ShellContentBrowserClient::GetWorkerProcessTitle( return std::string(); } -void ShellContentBrowserClient::ResourceDispatcherHostCreated() { +ResourceDispatcherHost* ShellContentBrowserClient::GetResourceDispatcherHost() { + return shell_browser_main_parts_->GetResourceDispatcherHost(); } ui::Clipboard* ShellContentBrowserClient::GetClipboard() { diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index a81c445..44ee7c7 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -138,7 +138,7 @@ class ShellContentBrowserClient : public ContentBrowserClient int render_process_id) OVERRIDE; virtual std::string GetWorkerProcessTitle( const GURL& url, const content::ResourceContext& context) OVERRIDE; - virtual void ResourceDispatcherHostCreated() OVERRIDE; + virtual ResourceDispatcherHost* GetResourceDispatcherHost() OVERRIDE; virtual ui::Clipboard* GetClipboard() OVERRIDE; virtual MHTMLGenerationManager* GetMHTMLGenerationManager() OVERRIDE; virtual net::NetLog* GetNetLog() OVERRIDE; |