diff options
60 files changed, 856 insertions, 829 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index c4747d9..9e7b48c 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -160,6 +160,9 @@ const char *kAllAboutPaths[] = { #endif }; +// Points to the singleton AboutSource object, if any. +ChromeURLDataManager::DataSource* about_source = NULL; + // When you type about:memory, it actually loads an intermediate URL that // redirects you to the final page. This avoids the problem where typing // "about:memory" on the new tab page or any other page where a process @@ -689,9 +692,21 @@ std::string VersionNumberToString(uint32 value) { AboutSource::AboutSource() : DataSource(chrome::kAboutScheme, MessageLoop::current()) { + // This should be a singleton. + DCHECK(!about_source); + about_source = this; + + // Add us to the global URL handler on the IO thread. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(this))); } AboutSource::~AboutSource() { + about_source = NULL; } void AboutSource::StartDataRequest(const std::string& path_raw, @@ -1039,7 +1054,7 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { return false; // Anything else requires our special handler; make sure it's initialized. - InitializeAboutDataSource(profile); + InitializeAboutDataSource(); // Special case about:memory to go through a redirect before ending up on // the final page. See GetAboutMemoryRedirectResponse above for why. @@ -1057,8 +1072,14 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { return true; } -void InitializeAboutDataSource(Profile* profile) { - profile->GetChromeURLDataManager()->AddDataSource(new AboutSource()); +void InitializeAboutDataSource() { + // We only need to register the AboutSource once and it is kept globally. + // There is currently no way to remove a data source. + static bool initialized = false; + if (!initialized) { + about_source = new AboutSource(); + initialized = true; + } } // This function gets called with the fixed-up chrome: URLs, so we have to diff --git a/chrome/browser/browser_about_handler.h b/chrome/browser/browser_about_handler.h index e5e31c9f..46ae100 100644 --- a/chrome/browser/browser_about_handler.h +++ b/chrome/browser/browser_about_handler.h @@ -28,7 +28,7 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile); // Register the data source for chrome://about URLs. // Safe to call multiple times. -void InitializeAboutDataSource(Profile* profile); +void InitializeAboutDataSource(); // We have a few magic commands that don't cause navigations, but rather pop up // dialogs. This function handles those cases, and returns true if so. In this diff --git a/chrome/browser/browser_about_handler_unittest.cc b/chrome/browser/browser_about_handler_unittest.cc index 16fface..6b3bd40 100644 --- a/chrome/browser/browser_about_handler_unittest.cc +++ b/chrome/browser/browser_about_handler_unittest.cc @@ -5,10 +5,8 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "chrome/browser/browser_about_handler.h" -#include "chrome/browser/browser_thread.h" #include "chrome/common/about_handler.h" #include "chrome/common/url_constants.h" -#include "chrome/test/testing_profile.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -98,16 +96,13 @@ TEST(BrowserAboutHandlerTest, WillHandleBrowserAboutURL) { true }, }; - MessageLoopForUI message_loop; - BrowserThread ui_thread(BrowserThread::UI, &message_loop); - TestingProfile profile; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_data); ++i) { GURL url(test_data[i].test_url); EXPECT_EQ(test_data[i].about_handled, chrome_about_handler::WillHandle(url)); EXPECT_EQ(test_data[i].browser_handled, - WillHandleBrowserAboutURL(&url, &profile)); + WillHandleBrowserAboutURL(&url, NULL)); EXPECT_EQ(test_data[i].result_url, url); } diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index b0f3954..0819289 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -36,7 +36,7 @@ #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/extensions/extension_protocols.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extensions_startup.h" @@ -1548,7 +1548,7 @@ int BrowserMain(const MainFunctionParams& parameters) { // Register our global network handler for chrome:// and // chrome-extension:// URLs. - ChromeURLDataManagerBackend::Register(); + RegisterURLRequestChromeJob(); RegisterExtensionProtocols(); RegisterMetadataURLRequestHandler(); RegisterBlobURLRequestJobFactory(); diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index 198a75c..7858c8f 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc @@ -257,11 +257,16 @@ void Shutdown() { file_util::WriteFile(shutdown_ms_file, shutdown_ms.c_str(), len); } + UnregisterURLRequestChromeJob(); + #if defined(OS_CHROMEOS) BrowserList::NotifyAndTerminate(false); #endif - ChromeURLDataManager::DeleteDataSources(); + // Clean up data sources before the UI thread is removed. + ChromeURLDataManager* data_manager = ChromeURLDataManager::GetInstance(); + if (data_manager) + data_manager->RemoveAllDataSources(); } void ReadLastShutdownFile( diff --git a/chrome/browser/browser_signin.cc b/chrome/browser/browser_signin.cc index f077d0c..1c2c051 100644 --- a/chrome/browser/browser_signin.cc +++ b/chrome/browser/browser_signin.cc @@ -215,11 +215,12 @@ BrowserSignin::BrowserSignin(Profile* profile) : profile_(profile), delegate_(NULL), html_dialog_ui_delegate_(NULL) { - // profile is NULL during testing. - if (profile) { - BrowserSigninResourcesSource* source = new BrowserSigninResourcesSource(); - profile->GetChromeURLDataManager()->AddDataSource(source); - } + BrowserSigninResourcesSource* source = new BrowserSigninResourcesSource(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(source))); } BrowserSignin::~BrowserSignin() { diff --git a/chrome/browser/chromeos/dom_ui/imageburner_ui.cc b/chrome/browser/chromeos/dom_ui/imageburner_ui.cc index 8aaa576..758b47b 100644 --- a/chrome/browser/chromeos/dom_ui/imageburner_ui.cc +++ b/chrome/browser/chromeos/dom_ui/imageburner_ui.cc @@ -649,5 +649,10 @@ ImageBurnUI::ImageBurnUI(TabContents* contents) : DOMUI(contents) { ImageBurnHandler* handler = new ImageBurnHandler(contents); AddMessageHandler((handler)->Attach(this)); ImageBurnUIHTMLSource* html_source = new ImageBurnUIHTMLSource(); - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc b/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc index fb84ee2..8f41996 100644 --- a/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc +++ b/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc @@ -12,8 +12,6 @@ #include "chrome/browser/chromeos/cros/input_method_library.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" @@ -296,5 +294,10 @@ KeyboardOverlayUI::KeyboardOverlayUI(TabContents* contents) KeyboardOverlayUIHTMLSource* html_source = new KeyboardOverlayUIHTMLSource(); // Set up the chrome://keyboardoverlay/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/chromeos/dom_ui/login/login_ui.cc b/chrome/browser/chromeos/dom_ui/login/login_ui.cc index a1ba4e0..845bf4b 100644 --- a/chrome/browser/chromeos/dom_ui/login/login_ui.cc +++ b/chrome/browser/chromeos/dom_ui/login/login_ui.cc @@ -14,8 +14,6 @@ #include "chrome/browser/chromeos/dom_ui/login/authenticator_facade_cros.h" #include "chrome/browser/chromeos/dom_ui/login/login_ui.h" #include "chrome/browser/chromeos/dom_ui/login/login_ui_helpers.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/common/url_constants.h" @@ -157,7 +155,12 @@ LoginUI::LoginUI(TabContents* contents) LoginUIHTMLSource* html_source = new LoginUIHTMLSource(MessageLoop::current()); - contents->profile->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } } // namespace chromeos diff --git a/chrome/browser/chromeos/dom_ui/menu_ui.cc b/chrome/browser/chromeos/dom_ui/menu_ui.cc index 04adde5..741961a 100644 --- a/chrome/browser/chromeos/dom_ui/menu_ui.cc +++ b/chrome/browser/chromeos/dom_ui/menu_ui.cc @@ -20,7 +20,6 @@ #include "chrome/browser/chromeos/views/native_menu_webui.h" #include "chrome/browser/chromeos/views/webui_menu_widget.h" #include "chrome/browser/dom_ui/web_ui_util.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_delegate.h" #include "chrome/common/url_constants.h" @@ -532,8 +531,12 @@ MenuUI::MenuUI(TabContents* contents) : DOMUI(contents) { MenuHandler* handler = new MenuHandler(); AddMessageHandler((handler)->Attach(this)); - contents->profile()->GetChromeURLDataManager()->AddDataSource( - CreateDataSource()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(CreateDataSource()))); } MenuUI::MenuUI(TabContents* contents, ChromeURLDataManager::DataSource* source) @@ -541,7 +544,12 @@ MenuUI::MenuUI(TabContents* contents, ChromeURLDataManager::DataSource* source) MenuHandler* handler = new MenuHandler(); AddMessageHandler((handler)->Attach(this)); - contents->profile()->GetChromeURLDataManager()->AddDataSource(source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(source))); } void MenuUI::ModelUpdated(const ui::MenuModel* model) { diff --git a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc index ac3688e..a6365cd 100644 --- a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc +++ b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc @@ -1323,5 +1323,10 @@ MobileSetupUI::MobileSetupUI(TabContents* contents) : DOMUI(contents) { new MobileSetupUIHTMLSource(service_path); // Set up the chrome://mobilesetup/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/chromeos/dom_ui/network_menu_ui.cc b/chrome/browser/chromeos/dom_ui/network_menu_ui.cc index 8e0defd..cea000d 100644 --- a/chrome/browser/chromeos/dom_ui/network_menu_ui.cc +++ b/chrome/browser/chromeos/dom_ui/network_menu_ui.cc @@ -13,7 +13,6 @@ #include "chrome/browser/chromeos/views/native_menu_webui.h" #include "chrome/browser/chromeos/views/webui_menu_widget.h" #include "chrome/browser/dom_ui/web_ui_theme_source.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" @@ -118,8 +117,13 @@ NetworkMenuUI::NetworkMenuUI(TabContents* contents) AddMessageHandler((handler)->Attach(this)); // Set up chrome://theme/ source. - WebUIThemeSource* theme = new WebUIThemeSource(contents->profile()); - contents->profile()->GetChromeURLDataManager()->AddDataSource(theme); + WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(theme))); } bool NetworkMenuUI::ModelAction(const ui::MenuModel* model, diff --git a/chrome/browser/chromeos/dom_ui/register_page_ui.cc b/chrome/browser/chromeos/dom_ui/register_page_ui.cc index f3e4453..2434c03 100644 --- a/chrome/browser/chromeos/dom_ui/register_page_ui.cc +++ b/chrome/browser/chromeos/dom_ui/register_page_ui.cc @@ -21,7 +21,6 @@ #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/version_loader.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" @@ -324,5 +323,10 @@ RegisterPageUI::RegisterPageUI(TabContents* contents) : DOMUI(contents){ RegisterPageUIHTMLSource* html_source = new RegisterPageUIHTMLSource(); // Set up the chrome://register/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/chromeos/dom_ui/system_info_ui.cc b/chrome/browser/chromeos/dom_ui/system_info_ui.cc index 93b8456..87f01d2 100644 --- a/chrome/browser/chromeos/dom_ui/system_info_ui.cc +++ b/chrome/browser/chromeos/dom_ui/system_info_ui.cc @@ -18,8 +18,6 @@ #include "chrome/browser/chromeos/cros/cros_library.h" #include "chrome/browser/chromeos/cros/syslogs_library.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" @@ -181,5 +179,10 @@ SystemInfoUI::SystemInfoUI(TabContents* contents) : DOMUI(contents) { SystemInfoUIHTMLSource* html_source = new SystemInfoUIHTMLSource(); // Set up the chrome://system/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/bookmarks_ui.cc b/chrome/browser/dom_ui/bookmarks_ui.cc index 490b102..b615168 100644 --- a/chrome/browser/dom_ui/bookmarks_ui.cc +++ b/chrome/browser/dom_ui/bookmarks_ui.cc @@ -8,9 +8,7 @@ #include "base/ref_counted_memory.h" #include "base/singleton.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/url_constants.h" #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -50,7 +48,12 @@ BookmarksUI::BookmarksUI(TabContents* contents) : DOMUI(contents) { BookmarksUIHTMLSource* html_source = new BookmarksUIHTMLSource(); // Set up the chrome://bookmarks/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc index d7cbd42..d64a100 100644 --- a/chrome/browser/dom_ui/bug_report_ui.cc +++ b/chrome/browser/dom_ui/bug_report_ui.cc @@ -21,7 +21,6 @@ #include "chrome/browser/bug_report_data.h" #include "chrome/browser/bug_report_util.h" #include "chrome/browser/dom_ui/web_ui_screenshot_source.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -433,9 +432,9 @@ void BugReportData::SendReport() { // //////////////////////////////////////////////////////////////////////////////// BugReportHandler::BugReportHandler(TabContents* tab) - : tab_(tab), - screenshot_source_(NULL), - bug_report_(NULL) + : tab_(tab) + , screenshot_source_(NULL) + , bug_report_(NULL) #if defined(OS_CHROMEOS) , syslogs_handle_(0) #endif @@ -455,8 +454,12 @@ void BugReportHandler::ClobberScreenshotsSource() { // Re-create our screenshots data source (this clobbers the last source) // setting the screenshot to NULL, effectively disabling the source // TODO(rkc): Once there is a method to 'remove' a source, change this code - tab_->profile()->GetChromeURLDataManager()->AddDataSource( - new WebUIScreenshotSource(NULL)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIScreenshotSource(NULL)))); // clobber last screenshot if (browser::last_screenshot_png) @@ -470,7 +473,12 @@ void BugReportHandler::SetupScreenshotsSource() { browser::last_screenshot_png); // Add the source to the data manager. - tab_->profile()->GetChromeURLDataManager()->AddDataSource(screenshot_source_); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(screenshot_source_))); } WebUIMessageHandler* BugReportHandler::Attach(DOMUI* dom_ui) { @@ -741,5 +749,10 @@ BugReportUI::BugReportUI(TabContents* tab) : HtmlDialogUI(tab) { BugReportUIHTMLSource* html_source = new BugReportUIHTMLSource(handler->Init()); // Set up the chrome://bugreport/ source. - tab->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.cc b/chrome/browser/dom_ui/chrome_url_data_manager.cc index 703a5af..c5c38c7 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.cc +++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc @@ -4,113 +4,332 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include <vector> - +#include "base/file_util.h" #include "base/i18n/rtl.h" #include "base/message_loop.h" +#include "base/path_service.h" #include "base/ref_counted_memory.h" +#include "base/singleton.h" +#include "base/stl_util-inl.h" #include "base/string_util.h" -#include "base/synchronization/lock.h" +#include "base/threading/thread.h" #include "base/values.h" +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif +#include "chrome/browser/appcache/view_appcache_internals_job_factory.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.h" +#include "chrome/browser/dom_ui/shared_resources_data_source.h" #include "chrome/browser/net/chrome_url_request_context.h" -#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/net/view_blob_internals_job_factory.h" +#include "chrome/browser/net/view_http_cache_job_factory.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/ref_counted_util.h" +#include "chrome/common/url_constants.h" +#include "googleurl/src/url_util.h" #include "grit/platform_locale_settings.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_file_job.h" +#include "net/url_request/url_request_job.h" #include "ui/base/l10n/l10n_util.h" -#if defined(OS_WIN) -#include "base/win/windows_version.h" -#endif +// URLRequestChromeJob is a net::URLRequestJob that manages running +// chrome-internal resource requests asynchronously. +// It hands off URL requests to ChromeURLDataManager, which asynchronously +// calls back once the data is available. +class URLRequestChromeJob : public net::URLRequestJob { + public: + explicit URLRequestChromeJob(net::URLRequest* request); -// static -base::Lock ChromeURLDataManager::delete_lock_; + // net::URLRequestJob implementation. + virtual void Start(); + virtual void Kill(); + virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); + virtual bool GetMimeType(std::string* mime_type) const; + + // Called by ChromeURLDataManager to notify us that the data blob is ready + // for us. + void DataAvailable(RefCountedMemory* bytes); + + void SetMimeType(const std::string& mime_type) { + mime_type_ = mime_type; + } + + private: + virtual ~URLRequestChromeJob(); + + // Helper for Start(), to let us start asynchronously. + // (This pattern is shared by most net::URLRequestJob implementations.) + void StartAsync(); + + // Do the actual copy from data_ (the data we're serving) into |buf|. + // Separate from ReadRawData so we can handle async I/O. + void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read); + + // The actual data we're serving. NULL until it's been fetched. + scoped_refptr<RefCountedMemory> data_; + // The current offset into the data that we're handing off to our + // callers via the Read interfaces. + int data_offset_; + + // For async reads, we keep around a pointer to the buffer that + // we're reading into. + scoped_refptr<net::IOBuffer> pending_buf_; + int pending_buf_size_; + std::string mime_type_; + + DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); +}; + +// URLRequestChromeFileJob is a net::URLRequestJob that acts like a file:// URL +class URLRequestChromeFileJob : public net::URLRequestFileJob { + public: + URLRequestChromeFileJob(net::URLRequest* request, const FilePath& path); + + private: + virtual ~URLRequestChromeFileJob(); + + DISALLOW_COPY_AND_ASSIGN(URLRequestChromeFileJob); +}; + +void RegisterURLRequestChromeJob() { + FilePath inspector_dir; + if (PathService::Get(chrome::DIR_INSPECTOR, &inspector_dir)) { + ChromeURLDataManager::GetInstance()->AddFileSource( + chrome::kChromeUIDevToolsHost, inspector_dir); + } + + SharedResourcesDataSource::Register(); + net::URLRequest::RegisterProtocolFactory(chrome::kChromeDevToolsScheme, + &ChromeURLDataManager::Factory); + net::URLRequest::RegisterProtocolFactory(chrome::kChromeUIScheme, + &ChromeURLDataManager::Factory); +} + +void UnregisterURLRequestChromeJob() { + FilePath inspector_dir; + if (PathService::Get(chrome::DIR_INSPECTOR, &inspector_dir)) { + ChromeURLDataManager::GetInstance()->RemoveFileSource( + chrome::kChromeUIDevToolsHost); + } +} // static -ChromeURLDataManager::DataSources* ChromeURLDataManager::data_sources_ = NULL; +void ChromeURLDataManager::URLToRequest(const GURL& url, + std::string* source_name, + std::string* path) { + DCHECK(url.SchemeIs(chrome::kChromeDevToolsScheme) || + url.SchemeIs(chrome::kChromeUIScheme)); + + if (!url.is_valid()) { + NOTREACHED(); + return; + } -// Invoked on the IO thread to do the actual adding of the DataSource. -static void AddDataSourceOnIOThread( - scoped_refptr<URLRequestContextGetter> context_getter, - scoped_refptr<ChromeURLDataManager::DataSource> data_source) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - static_cast<ChromeURLRequestContext*>( - context_getter->GetURLRequestContext())-> - GetChromeURLDataManagerBackend()->AddDataSource(data_source.get()); + // Our input looks like: chrome://source_name/extra_bits?foo . + // So the url's "host" is our source, and everything after the host is + // the path. + source_name->assign(url.host()); + + const std::string& spec = url.possibly_invalid_spec(); + const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); + // + 1 to skip the slash at the beginning of the path. + int offset = parsed.CountCharactersBefore(url_parse::Parsed::PATH, false) + 1; + + if (offset < static_cast<int>(spec.size())) + path->assign(spec.substr(offset)); } -ChromeURLDataManager::ChromeURLDataManager(Profile* profile) - : profile_(profile) { +// static +bool ChromeURLDataManager::URLToFilePath(const GURL& url, + FilePath* file_path) { + // Parse the URL into a request for a source and path. + std::string source_name; + std::string relative_path; + + // Remove Query and Ref from URL. + GURL stripped_url; + GURL::Replacements replacements; + replacements.ClearQuery(); + replacements.ClearRef(); + stripped_url = url.ReplaceComponents(replacements); + + URLToRequest(stripped_url, &source_name, &relative_path); + + FileSourceMap::const_iterator i( + ChromeURLDataManager::GetInstance()->file_sources_.find(source_name)); + if (i == ChromeURLDataManager::GetInstance()->file_sources_.end()) + return false; + + // Check that |relative_path| is not an absolute path (otherwise AppendASCII() + // will DCHECK). The awkward use of StringType is because on some systems + // FilePath expects a std::string, but on others a std::wstring. + FilePath p(FilePath::StringType(relative_path.begin(), relative_path.end())); + if (p.IsAbsolute()) + return false; + + *file_path = i->second.AppendASCII(relative_path); + + return true; } +ChromeURLDataManager::ChromeURLDataManager() : next_request_id_(0) { } + ChromeURLDataManager::~ChromeURLDataManager() { + // This is used as a Singleton, so it is only called at exit cleanup time. + // This means it is called on the main (UI) thread. + // + // It will break if it is called at shutdown time on a different thread, as + // it will attempt to call the destructors for its |data_source_|s on the + // UI thread, but the UI thread's message loop will be not be running + // -- so the destructor calls will be dropped and we will leak the objects. } -void ChromeURLDataManager::AddDataSource(DataSource* source) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableFunction(AddDataSourceOnIOThread, - make_scoped_refptr(profile_->GetRequestContext()), - make_scoped_refptr(source))); +// static +ChromeURLDataManager* ChromeURLDataManager::GetInstance() { + return Singleton<ChromeURLDataManager>::get(); } -// static -void ChromeURLDataManager::DeleteDataSources() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DataSources sources; - { - base::AutoLock lock(delete_lock_); - data_sources_->swap(sources); - } - for (size_t i = 0; i < sources.size(); ++i) - delete sources[i]; +void ChromeURLDataManager::AddDataSource(scoped_refptr<DataSource> source) { + // Some |DataSource|-derived classes, notably |FileIconSource| and + // |WebUIFavIconSource|, have members that will DCHECK if they are not + // destructed in the same thread as they are constructed (the UI thread). + // + // If |AddDataSource| is called more than once, it will destruct the object + // that it had before, as it is the only thing still holding a reference to + // that object. |DataSource| uses the |DeleteOnUIThread| trait to insure + // that the destructor is called on the UI thread. + // + // TODO(jackson): A new data source with same name should not clobber the + // existing one. + data_sources_[source->source_name()] = source; } -// static -void ChromeURLDataManager::DeleteDataSource(const DataSource* data_source) { - // Invoked when a DataSource is no longer referenced and needs to be deleted. - if (BrowserThread::CurrentlyOn(BrowserThread::UI)) { - // We're on the UI thread, delete right away. - delete data_source; +void ChromeURLDataManager::RemoveDataSourceForTest(const char* source_name) { + DataSourceMap::iterator i = data_sources_.find(source_name); + if (i == data_sources_.end()) return; + (*i).second = NULL; // Calls Release(). + data_sources_.erase(i); +} + +void ChromeURLDataManager::RemoveAllDataSources() { + for (DataSourceMap::iterator i = data_sources_.begin(); + i != data_sources_.end(); + i = data_sources_.begin()) { + (*i).second = NULL; // Calls Release(). + data_sources_.erase(i); + } +} + +void ChromeURLDataManager::AddFileSource(const std::string& source_name, + const FilePath& file_path) { + DCHECK(file_sources_.count(source_name) == 0); + file_sources_[source_name] = file_path; +} + +void ChromeURLDataManager::RemoveFileSource(const std::string& source_name) { + DCHECK(file_sources_.count(source_name) == 1); + file_sources_.erase(source_name); +} + +bool ChromeURLDataManager::HasPendingJob(URLRequestChromeJob* job) const { + for (PendingRequestMap::const_iterator i = pending_requests_.begin(); + i != pending_requests_.end(); ++i) { + if (i->second == job) + return true; + } + + return false; +} + +bool ChromeURLDataManager::StartRequest(const GURL& url, + URLRequestChromeJob* job) { + // Parse the URL into a request for a source and path. + std::string source_name; + std::string path; + URLToRequest(url, &source_name, &path); + + // Look up the data source for the request. + DataSourceMap::iterator i = data_sources_.find(source_name); + if (i == data_sources_.end()) + return false; + DataSource* source = i->second; + + // Save this request so we know where to send the data. + RequestID request_id = next_request_id_++; + pending_requests_.insert(std::make_pair(request_id, job)); + + // TODO(eroman): would be nicer if the mimetype were set at the same time + // as the data blob. For now do it here, since NotifyHeadersComplete() is + // going to get called once we return. + job->SetMimeType(source->GetMimeType(path)); + + ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( + job->request()->context()); + + // Forward along the request to the data source. + MessageLoop* target_message_loop = source->MessageLoopForRequestPath(path); + if (!target_message_loop) { + // The DataSource is agnostic to which thread StartDataRequest is called + // on for this path. Call directly into it from this thread, the IO + // thread. + source->StartDataRequest(path, context->is_off_the_record(), request_id); + } else { + // The DataSource wants StartDataRequest to be called on a specific thread, + // usually the UI thread, for this path. + target_message_loop->PostTask(FROM_HERE, + NewRunnableMethod(source, &DataSource::StartDataRequest, + path, context->is_off_the_record(), request_id)); } + return true; +} - // We're not on the UI thread, add the DataSource to the list of DataSources - // to delete. - bool schedule_delete = false; - { - base::AutoLock lock(delete_lock_); - if (!data_sources_) - data_sources_ = new DataSources(); - schedule_delete = data_sources_->empty(); - data_sources_->push_back(data_source); +void ChromeURLDataManager::RemoveRequest(URLRequestChromeJob* job) { + // Remove the request from our list of pending requests. + // If/when the source sends the data that was requested, the data will just + // be thrown away. + for (PendingRequestMap::iterator i = pending_requests_.begin(); + i != pending_requests_.end(); ++i) { + if (i->second == job) { + pending_requests_.erase(i); + return; + } } - if (schedule_delete) { - // Schedule a task to delete the DataSource back on the UI thread. - BrowserThread::PostTask(BrowserThread::UI, - FROM_HERE, - NewRunnableFunction( - &ChromeURLDataManager::DeleteDataSources)); +} + +void ChromeURLDataManager::DataAvailable( + RequestID request_id, + scoped_refptr<RefCountedMemory> bytes) { + // Forward this data on to the pending net::URLRequest, if it exists. + PendingRequestMap::iterator i = pending_requests_.find(request_id); + if (i != pending_requests_.end()) { + // We acquire a reference to the job so that it doesn't disappear under the + // feet of any method invoked here (we could trigger a callback). + scoped_refptr<URLRequestChromeJob> job(i->second); + pending_requests_.erase(i); + job->DataAvailable(bytes); } } ChromeURLDataManager::DataSource::DataSource(const std::string& source_name, MessageLoop* message_loop) - : source_name_(source_name), - message_loop_(message_loop), - backend_(NULL) { + : source_name_(source_name), message_loop_(message_loop) { } ChromeURLDataManager::DataSource::~DataSource() { } -void ChromeURLDataManager::DataSource::SendResponse(int request_id, - RefCountedMemory* bytes) { +void ChromeURLDataManager::DataSource::SendResponse( + RequestID request_id, + RefCountedMemory* bytes) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - NewRunnableMethod(this, &DataSource::SendResponseOnIOThread, - request_id, make_scoped_refptr(bytes))); + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::DataAvailable, + request_id, scoped_refptr<RefCountedMemory>(bytes))); } MessageLoop* ChromeURLDataManager::DataSource::MessageLoopForRequestPath( @@ -138,10 +357,120 @@ void ChromeURLDataManager::DataSource::SetFontAndTextDirection( base::i18n::IsRTL() ? "rtl" : "ltr"); } -void ChromeURLDataManager::DataSource::SendResponseOnIOThread( - int request_id, - scoped_refptr<RefCountedMemory> bytes) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (backend_) - backend_->DataAvailable(request_id, bytes); +net::URLRequestJob* ChromeURLDataManager::Factory(net::URLRequest* request, + const std::string& scheme) { + // Try first with a file handler + FilePath path; + if (ChromeURLDataManager::URLToFilePath(request->url(), &path)) + return new URLRequestChromeFileJob(request, path); + + // Next check for chrome://view-http-cache/*, which uses its own job type. + if (ViewHttpCacheJobFactory::IsSupportedURL(request->url())) + return ViewHttpCacheJobFactory::CreateJobForRequest(request); + + // Next check for chrome://appcache-internals/, which uses its own job type. + if (ViewAppCacheInternalsJobFactory::IsSupportedURL(request->url())) + return ViewAppCacheInternalsJobFactory::CreateJobForRequest(request); + + // Next check for chrome://blob-internals/, which uses its own job type. + if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) + return ViewBlobInternalsJobFactory::CreateJobForRequest(request); + + // Fall back to using a custom handler + return new URLRequestChromeJob(request); +} + +URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request) + : net::URLRequestJob(request), + data_offset_(0), + pending_buf_size_(0) { +} + +URLRequestChromeJob::~URLRequestChromeJob() { + CHECK(!ChromeURLDataManager::GetInstance()->HasPendingJob(this)); } + +void URLRequestChromeJob::Start() { + // Start reading asynchronously so that all error reporting and data + // callbacks happen as they would for network requests. + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( + this, &URLRequestChromeJob::StartAsync)); +} + +void URLRequestChromeJob::Kill() { + ChromeURLDataManager::GetInstance()->RemoveRequest(this); +} + +bool URLRequestChromeJob::GetMimeType(std::string* mime_type) const { + *mime_type = mime_type_; + return !mime_type_.empty(); +} + +void URLRequestChromeJob::DataAvailable(RefCountedMemory* bytes) { + if (bytes) { + // The request completed, and we have all the data. + // Clear any IO pending status. + SetStatus(net::URLRequestStatus()); + + data_ = bytes; + int bytes_read; + if (pending_buf_.get()) { + CHECK(pending_buf_->data()); + CompleteRead(pending_buf_, pending_buf_size_, &bytes_read); + pending_buf_ = NULL; + NotifyReadComplete(bytes_read); + } + } else { + // The request failed. + NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_FAILED)); + } +} + +bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size, + int* bytes_read) { + if (!data_.get()) { + SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); + DCHECK(!pending_buf_.get()); + CHECK(buf->data()); + pending_buf_ = buf; + pending_buf_size_ = buf_size; + return false; // Tell the caller we're still waiting for data. + } + + // Otherwise, the data is available. + CompleteRead(buf, buf_size, bytes_read); + return true; +} + +void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size, + int* bytes_read) { + int remaining = static_cast<int>(data_->size()) - data_offset_; + if (buf_size > remaining) + buf_size = remaining; + if (buf_size > 0) { + memcpy(buf->data(), data_->front() + data_offset_, buf_size); + data_offset_ += buf_size; + } + *bytes_read = buf_size; +} + +void URLRequestChromeJob::StartAsync() { + if (!request_) + return; + + if (ChromeURLDataManager::GetInstance()->StartRequest(request_->url(), + this)) { + NotifyHeadersComplete(); + } else { + NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, + net::ERR_INVALID_URL)); + } +} + +URLRequestChromeFileJob::URLRequestChromeFileJob(net::URLRequest* request, + const FilePath& path) + : net::URLRequestFileJob(request, path) { +} + +URLRequestChromeFileJob::~URLRequestChromeFileJob() { } diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.h b/chrome/browser/dom_ui/chrome_url_data_manager.h index 163edf7..0717498 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.h +++ b/chrome/browser/dom_ui/chrome_url_data_manager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,45 +9,35 @@ #include <map> #include <string> +#include "base/singleton.h" #include "base/task.h" #include "base/ref_counted.h" #include "chrome/browser/browser_thread.h" -class ChromeURLDataManagerBackend; class DictionaryValue; class FilePath; +class GURL; class MessageLoop; -class Profile; class RefCountedMemory; +class URLRequestChromeJob; + +namespace net { +class URLRequest; +class URLRequestJob; +} // namespace net // To serve dynamic data off of chrome: URLs, implement the // ChromeURLDataManager::DataSource interface and register your handler -// with AddDataSource. DataSources must be added on the UI thread (they are also -// deleted on the UI thread). Internally the DataSources are maintained by -// ChromeURLDataManagerBackend, see it for details. +// with AddDataSource. + +// ChromeURLDataManager lives on the IO thread, so any interfacing with +// it from the UI thread needs to go through an InvokeLater. class ChromeURLDataManager { public: - class DataSource; + // Returns the singleton instance. + static ChromeURLDataManager* GetInstance(); - // Trait used to handle deleting a DataSource. Deletion happens on the UI - // thread. - // - // Implementation note: the normal shutdown sequence is for the UI loop to - // stop pumping events then the IO loop and thread are stopped. When the - // DataSources are no longer referenced (which happens when IO thread stops) - // they get added to the UI message loop for deletion. But because the UI loop - // has stopped by the time this happens the DataSources would be leaked. - // - // To make sure DataSources are properly deleted ChromeURLDataManager manages - // deletion of the DataSources. When a DataSource is no longer referenced it - // is added to |data_sources_| and a task is posted to the UI thread to handle - // the actual deletion. During shutdown |DeleteDataSources| is invoked so that - // all pending DataSources are properly deleted. - struct DeleteDataSource { - static void Destruct(const DataSource* data_source) { - ChromeURLDataManager::DeleteDataSource(data_source); - } - }; + typedef int RequestID; // A DataSource is an object that can answer requests for data // asynchronously. DataSources are collectively owned with refcounting smart @@ -59,10 +49,11 @@ class ChromeURLDataManager { // StartDataRequest() by starting its (implementation-specific) asynchronous // request for the data, then call SendResponse() to notify. class DataSource : public base::RefCountedThreadSafe< - DataSource, DeleteDataSource> { + DataSource, BrowserThread::DeleteOnUIThread> { public: // See source_name_ and message_loop_ below for docs on these parameters. - DataSource(const std::string& source_name, MessageLoop* message_loop); + DataSource(const std::string& source_name, + MessageLoop* message_loop); // Sent by the DataManager to request data at |path|. The source should // call SendResponse() when the data is available or if the request could @@ -97,18 +88,13 @@ class ChromeURLDataManager { static void SetFontAndTextDirection(DictionaryValue* localized_strings); protected: - virtual ~DataSource(); - - private: - friend class ChromeURLDataManagerBackend; - friend class ChromeURLDataManager; + friend class base::RefCountedThreadSafe<DataSource>; + friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; friend class DeleteTask<DataSource>; - // SendResponse invokes this on the IO thread. Notifies the backend to - // handle the actual work of sending the data. - virtual void SendResponseOnIOThread(int request_id, - scoped_refptr<RefCountedMemory> bytes); + virtual ~DataSource(); + private: // The name of this source. // E.g., for favicons, this could be "favicon", which results in paths for // specific resources like "favicon/34" getting sent to this source. @@ -117,53 +103,89 @@ class ChromeURLDataManager { // The MessageLoop for the thread where this DataSource lives. // Used to send messages to the DataSource. MessageLoop* message_loop_; - - // This field is set and maintained by ChromeURLDataManagerBackend. It is - // set when the DataSource is added, and unset if the DataSource is removed. - // A DataSource can be removed in two ways: the ChromeURLDataManagerBackend - // is deleted, or another DataSource is registered with the same - // name. backend_ should only be accessed on the IO thread. - // This reference can't be via a scoped_refptr else there would be a cycle - // between the backend and data source. - ChromeURLDataManagerBackend* backend_; }; - explicit ChromeURLDataManager(Profile* profile); - ~ChromeURLDataManager(); - - // Adds a DataSource to the collection of data sources. This *must* be invoked - // on the UI thread. - // - // If |AddDataSource| is called more than once for a particular name it will - // release the old |DataSource|, most likely resulting in it getting deleted - // as there are no other references to it. |DataSource| uses the - // |DeleteOnUIThread| trait to insure that the destructor is called on the UI - // thread. This is necessary as some |DataSource|s notably |FileIconSource| - // and |WebUIFavIconSource|, have members that will DCHECK if they are not - // destructed in the same thread as they are constructed (the UI thread). - void AddDataSource(DataSource* source); - - // Deletes any data sources no longer referenced. This is normally invoked - // for you, but can be invoked to force deletion (such as during shutdown). - static void DeleteDataSources(); + // Add a DataSource to the collection of data sources. + // Because we don't track users of a given path, we can't know when it's + // safe to remove them, so the added source effectively leaks. + // This could be improved in the future but currently the users of this + // interface are conceptually permanent registration anyway. + // Adding a second DataSource with the same name clobbers the first. + // NOTE: Calling this from threads other the IO thread must be done via + // InvokeLater. + void AddDataSource(scoped_refptr<DataSource> source); + // Called during shutdown, before destruction of |BrowserThread|. + void RemoveDataSourceForTest(const char* source_name); // For unit tests. + void RemoveAllDataSources(); // For the browser. + + // Add/remove a path from the collection of file sources. + // A file source acts like a file:// URL to the specified path. + // Calling this from threads other the IO thread must be done via + // InvokeLater. + void AddFileSource(const std::string& source_name, const FilePath& path); + void RemoveFileSource(const std::string& source_name); + + static net::URLRequestJob* Factory(net::URLRequest* request, + const std::string& scheme); private: - typedef std::vector<const ChromeURLDataManager::DataSource*> DataSources; + friend class URLRequestChromeJob; + friend struct DefaultSingletonTraits<ChromeURLDataManager>; - // If invoked on the UI thread the DataSource is deleted immediatlye, - // otherwise it is added to |data_sources_| and a task is scheduled to handle - // deletion on the UI thread. See note abouve DeleteDataSource for more info. - static void DeleteDataSource(const DataSource* data_source); + ChromeURLDataManager(); + ~ChromeURLDataManager(); - Profile* profile_; + // Parse a URL into the components used to resolve its request. + static void URLToRequest(const GURL& url, + std::string* source, + std::string* path); + + // Translate a chrome resource URL into a local file path if there is one. + // Returns false if there is no file handler for this URL + static bool URLToFilePath(const GURL& url, FilePath* file_path); + + // Called by the job when it's starting up. + // Returns false if |url| is not a URL managed by this object. + bool StartRequest(const GURL& url, URLRequestChromeJob* job); + // Remove a request from the list of pending requests. + void RemoveRequest(URLRequestChromeJob* job); + + // Returns true if the job exists in |pending_requests_|. False otherwise. + // Called by ~URLRequestChromeJob to verify that |pending_requests_| is kept + // up to date. + bool HasPendingJob(URLRequestChromeJob* job) const; + + // Sent by Request::SendResponse. + void DataAvailable(RequestID request_id, + scoped_refptr<RefCountedMemory> bytes); + + // File sources of data, keyed by source name (e.g. "inspector"). + typedef std::map<std::string, FilePath> FileSourceMap; + FileSourceMap file_sources_; + + // Custom sources of data, keyed by source path (e.g. "favicon"). + typedef std::map<std::string, scoped_refptr<DataSource> > DataSourceMap; + DataSourceMap data_sources_; + + // All pending URLRequestChromeJobs, keyed by ID of the request. + // URLRequestChromeJob calls into this object when it's constructed and + // destructed to ensure that the pointers in this map remain valid. + typedef std::map<RequestID, URLRequestChromeJob*> PendingRequestMap; + PendingRequestMap pending_requests_; + + // The ID we'll use for the next request we receive. + RequestID next_request_id_; +}; - // Lock used when accessing |data_sources_|. - static base::Lock delete_lock_; +// Since we have a single global ChromeURLDataManager, we don't need to +// grab a reference to it when creating Tasks involving it. +DISABLE_RUNNABLE_METHOD_REFCOUNT(ChromeURLDataManager); - // |data_sources_| that are no longer referenced and scheduled for deletion. - static DataSources* data_sources_; +// Register our special URL handler under our special URL scheme. +// Must be done once at startup. +void RegisterURLRequestChromeJob(); - DISALLOW_COPY_AND_ASSIGN(ChromeURLDataManager); -}; +// Undoes the registration done by RegisterURLRequestChromeJob. +void UnregisterURLRequestChromeJob(); #endif // CHROME_BROWSER_DOM_UI_CHROME_URL_DATA_MANAGER_H_ diff --git a/chrome/browser/dom_ui/chrome_url_data_manager_backend.cc b/chrome/browser/dom_ui/chrome_url_data_manager_backend.cc deleted file mode 100644 index 0048828..0000000 --- a/chrome/browser/dom_ui/chrome_url_data_manager_backend.cc +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.h" - -#include "base/file_util.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/ref_counted_memory.h" -#include "base/string_util.h" -#include "chrome/browser/appcache/view_appcache_internals_job_factory.h" -#include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/shared_resources_data_source.h" -#include "chrome/browser/net/chrome_url_request_context.h" -#include "chrome/browser/net/view_blob_internals_job_factory.h" -#include "chrome/browser/net/view_http_cache_job_factory.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/url_constants.h" -#include "googleurl/src/url_util.h" -#include "grit/platform_locale_settings.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/url_request/url_request.h" -#include "net/url_request/url_request_file_job.h" -#include "net/url_request/url_request_job.h" - -static ChromeURLDataManagerBackend* GetBackend(net::URLRequest* request) { - return static_cast<ChromeURLRequestContext*>(request->context())-> - GetChromeURLDataManagerBackend(); -} - -// URLRequestChromeJob is a net::URLRequestJob that manages running -// chrome-internal resource requests asynchronously. -// It hands off URL requests to ChromeURLDataManager, which asynchronously -// calls back once the data is available. -class URLRequestChromeJob : public net::URLRequestJob { - public: - explicit URLRequestChromeJob(net::URLRequest* request); - - // net::URLRequestJob implementation. - virtual void Start(); - virtual void Kill(); - virtual bool ReadRawData(net::IOBuffer* buf, int buf_size, int *bytes_read); - virtual bool GetMimeType(std::string* mime_type) const; - - // Called by ChromeURLDataManager to notify us that the data blob is ready - // for us. - void DataAvailable(RefCountedMemory* bytes); - - void SetMimeType(const std::string& mime_type) { - mime_type_ = mime_type; - } - - private: - virtual ~URLRequestChromeJob(); - - // Helper for Start(), to let us start asynchronously. - // (This pattern is shared by most net::URLRequestJob implementations.) - void StartAsync(); - - // Do the actual copy from data_ (the data we're serving) into |buf|. - // Separate from ReadRawData so we can handle async I/O. - void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read); - - // The actual data we're serving. NULL until it's been fetched. - scoped_refptr<RefCountedMemory> data_; - // The current offset into the data that we're handing off to our - // callers via the Read interfaces. - int data_offset_; - - // For async reads, we keep around a pointer to the buffer that - // we're reading into. - scoped_refptr<net::IOBuffer> pending_buf_; - int pending_buf_size_; - std::string mime_type_; - - // The backend is owned by ChromeURLRequestContext and always outlives us. - ChromeURLDataManagerBackend* backend_; - - DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); -}; - -// URLRequestChromeFileJob is a net::URLRequestJob that acts like a file:// URL -class URLRequestChromeFileJob : public net::URLRequestFileJob { - public: - URLRequestChromeFileJob(net::URLRequest* request, const FilePath& path); - - private: - virtual ~URLRequestChromeFileJob(); - - DISALLOW_COPY_AND_ASSIGN(URLRequestChromeFileJob); -}; - -void ChromeURLDataManagerBackend::URLToRequest(const GURL& url, - std::string* source_name, - std::string* path) { - DCHECK(url.SchemeIs(chrome::kChromeDevToolsScheme) || - url.SchemeIs(chrome::kChromeUIScheme)); - - if (!url.is_valid()) { - NOTREACHED(); - return; - } - - // Our input looks like: chrome://source_name/extra_bits?foo . - // So the url's "host" is our source, and everything after the host is - // the path. - source_name->assign(url.host()); - - const std::string& spec = url.possibly_invalid_spec(); - const url_parse::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); - // + 1 to skip the slash at the beginning of the path. - int offset = parsed.CountCharactersBefore(url_parse::Parsed::PATH, false) + 1; - - if (offset < static_cast<int>(spec.size())) - path->assign(spec.substr(offset)); -} - -bool ChromeURLDataManagerBackend::URLToFilePath(const GURL& url, - FilePath* file_path) { - // Parse the URL into a request for a source and path. - std::string source_name; - std::string relative_path; - - // Remove Query and Ref from URL. - GURL stripped_url; - GURL::Replacements replacements; - replacements.ClearQuery(); - replacements.ClearRef(); - stripped_url = url.ReplaceComponents(replacements); - - URLToRequest(stripped_url, &source_name, &relative_path); - - FileSourceMap::const_iterator i(file_sources_.find(source_name)); - if (i == file_sources_.end()) - return false; - - // Check that |relative_path| is not an absolute path (otherwise AppendASCII() - // will DCHECK). The awkward use of StringType is because on some systems - // FilePath expects a std::string, but on others a std::wstring. - FilePath p(FilePath::StringType(relative_path.begin(), relative_path.end())); - if (p.IsAbsolute()) - return false; - - *file_path = i->second.AppendASCII(relative_path); - - return true; -} - -ChromeURLDataManagerBackend::ChromeURLDataManagerBackend() - : next_request_id_(0) { - FilePath inspector_dir; - if (PathService::Get(chrome::DIR_INSPECTOR, &inspector_dir)) - AddFileSource(chrome::kChromeUIDevToolsHost, inspector_dir); - AddDataSource(new SharedResourcesDataSource()); -} - -ChromeURLDataManagerBackend::~ChromeURLDataManagerBackend() { - for (DataSourceMap::iterator i = data_sources_.begin(); - i != data_sources_.end(); ++i) { - i->second->backend_ = NULL; - } - data_sources_.clear(); -} - -// static -void ChromeURLDataManagerBackend::Register() { - net::URLRequest::RegisterProtocolFactory( - chrome::kChromeDevToolsScheme, - &ChromeURLDataManagerBackend::Factory); - net::URLRequest::RegisterProtocolFactory( - chrome::kChromeUIScheme, - &ChromeURLDataManagerBackend::Factory); -} - -void ChromeURLDataManagerBackend::AddDataSource( - ChromeURLDataManager::DataSource* source) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DataSourceMap::iterator i = data_sources_.find(source->source_name()); - if (i != data_sources_.end()) - i->second->backend_ = NULL; - data_sources_[source->source_name()] = source; - source->backend_ = this; -} - -void ChromeURLDataManagerBackend::AddFileSource(const std::string& source_name, - const FilePath& file_path) { - DCHECK(file_sources_.count(source_name) == 0); - file_sources_[source_name] = file_path; -} - -bool ChromeURLDataManagerBackend::HasPendingJob( - URLRequestChromeJob* job) const { - for (PendingRequestMap::const_iterator i = pending_requests_.begin(); - i != pending_requests_.end(); ++i) { - if (i->second == job) - return true; - } - return false; -} - -bool ChromeURLDataManagerBackend::StartRequest(const GURL& url, - URLRequestChromeJob* job) { - // Parse the URL into a request for a source and path. - std::string source_name; - std::string path; - URLToRequest(url, &source_name, &path); - - // Look up the data source for the request. - DataSourceMap::iterator i = data_sources_.find(source_name); - if (i == data_sources_.end()) - return false; - - ChromeURLDataManager::DataSource* source = i->second; - - // Save this request so we know where to send the data. - RequestID request_id = next_request_id_++; - pending_requests_.insert(std::make_pair(request_id, job)); - - // TODO(eroman): would be nicer if the mimetype were set at the same time - // as the data blob. For now do it here, since NotifyHeadersComplete() is - // going to get called once we return. - job->SetMimeType(source->GetMimeType(path)); - - ChromeURLRequestContext* context = static_cast<ChromeURLRequestContext*>( - job->request()->context()); - - // Forward along the request to the data source. - MessageLoop* target_message_loop = source->MessageLoopForRequestPath(path); - if (!target_message_loop) { - // The DataSource is agnostic to which thread StartDataRequest is called - // on for this path. Call directly into it from this thread, the IO - // thread. - source->StartDataRequest(path, context->is_off_the_record(), request_id); - } else { - // The DataSource wants StartDataRequest to be called on a specific thread, - // usually the UI thread, for this path. - target_message_loop->PostTask( - FROM_HERE, - NewRunnableMethod(source, - &ChromeURLDataManager::DataSource::StartDataRequest, - path, context->is_off_the_record(), request_id)); - } - return true; -} - -void ChromeURLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) { - // Remove the request from our list of pending requests. - // If/when the source sends the data that was requested, the data will just - // be thrown away. - for (PendingRequestMap::iterator i = pending_requests_.begin(); - i != pending_requests_.end(); ++i) { - if (i->second == job) { - pending_requests_.erase(i); - return; - } - } -} - -void ChromeURLDataManagerBackend::DataAvailable(RequestID request_id, - RefCountedMemory* bytes) { - // Forward this data on to the pending net::URLRequest, if it exists. - PendingRequestMap::iterator i = pending_requests_.find(request_id); - if (i != pending_requests_.end()) { - // We acquire a reference to the job so that it doesn't disappear under the - // feet of any method invoked here (we could trigger a callback). - scoped_refptr<URLRequestChromeJob> job(i->second); - pending_requests_.erase(i); - job->DataAvailable(bytes); - } -} - -// static -net::URLRequestJob* ChromeURLDataManagerBackend::Factory( - net::URLRequest* request, - const std::string& scheme) { - // Try first with a file handler - FilePath path; - ChromeURLDataManagerBackend* backend = GetBackend(request); - if (backend->URLToFilePath(request->url(), &path)) - return new URLRequestChromeFileJob(request, path); - - // Next check for chrome://view-http-cache/*, which uses its own job type. - if (ViewHttpCacheJobFactory::IsSupportedURL(request->url())) - return ViewHttpCacheJobFactory::CreateJobForRequest(request); - - // Next check for chrome://appcache-internals/, which uses its own job type. - if (ViewAppCacheInternalsJobFactory::IsSupportedURL(request->url())) - return ViewAppCacheInternalsJobFactory::CreateJobForRequest(request); - - // Next check for chrome://blob-internals/, which uses its own job type. - if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) - return ViewBlobInternalsJobFactory::CreateJobForRequest(request); - - // Fall back to using a custom handler - return new URLRequestChromeJob(request); -} - -URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request) - : net::URLRequestJob(request), - data_offset_(0), - pending_buf_size_(0), - backend_(GetBackend(request)) { -} - -URLRequestChromeJob::~URLRequestChromeJob() { - CHECK(!backend_->HasPendingJob(this)); -} - -void URLRequestChromeJob::Start() { - // Start reading asynchronously so that all error reporting and data - // callbacks happen as they would for network requests. - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - this, &URLRequestChromeJob::StartAsync)); -} - -void URLRequestChromeJob::Kill() { - backend_->RemoveRequest(this); -} - -bool URLRequestChromeJob::GetMimeType(std::string* mime_type) const { - *mime_type = mime_type_; - return !mime_type_.empty(); -} - -void URLRequestChromeJob::DataAvailable(RefCountedMemory* bytes) { - if (bytes) { - // The request completed, and we have all the data. - // Clear any IO pending status. - SetStatus(net::URLRequestStatus()); - - data_ = bytes; - int bytes_read; - if (pending_buf_.get()) { - CHECK(pending_buf_->data()); - CompleteRead(pending_buf_, pending_buf_size_, &bytes_read); - pending_buf_ = NULL; - NotifyReadComplete(bytes_read); - } - } else { - // The request failed. - NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_FAILED)); - } -} - -bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size, - int* bytes_read) { - if (!data_.get()) { - SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); - DCHECK(!pending_buf_.get()); - CHECK(buf->data()); - pending_buf_ = buf; - pending_buf_size_ = buf_size; - return false; // Tell the caller we're still waiting for data. - } - - // Otherwise, the data is available. - CompleteRead(buf, buf_size, bytes_read); - return true; -} - -void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size, - int* bytes_read) { - int remaining = static_cast<int>(data_->size()) - data_offset_; - if (buf_size > remaining) - buf_size = remaining; - if (buf_size > 0) { - memcpy(buf->data(), data_->front() + data_offset_, buf_size); - data_offset_ += buf_size; - } - *bytes_read = buf_size; -} - -void URLRequestChromeJob::StartAsync() { - if (!request_) - return; - - if (backend_->StartRequest(request_->url(), this)) { - NotifyHeadersComplete(); - } else { - NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, - net::ERR_INVALID_URL)); - } -} - -URLRequestChromeFileJob::URLRequestChromeFileJob(net::URLRequest* request, - const FilePath& path) - : net::URLRequestFileJob(request, path) { -} - -URLRequestChromeFileJob::~URLRequestChromeFileJob() {} diff --git a/chrome/browser/dom_ui/chrome_url_data_manager_backend.h b/chrome/browser/dom_ui/chrome_url_data_manager_backend.h deleted file mode 100644 index fe900bc..0000000 --- a/chrome/browser/dom_ui/chrome_url_data_manager_backend.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_DOM_UI_CHROME_URL_DATA_MANAGER_BACKEND_H_ -#define CHROME_BROWSER_DOM_UI_CHROME_URL_DATA_MANAGER_BACKEND_H_ -#pragma once - -#include "base/basictypes.h" -#include "base/ref_counted.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager.h" - -#include <map> -#include <string> -#include <vector> - -class FilePath; -class GURL; -class URLRequestChromeJob; - -namespace net { -class URLRequest; -class URLRequestJob; -} - -// ChromeURLDataManagerBackend is used internally by ChromeURLDataManager on the -// IO thread. In most cases you can use the API in ChromeURLDataManager and -// ignore this class. ChromeURLDataManagerBackend is owned by -// ChromeURLRequestContext. -class ChromeURLDataManagerBackend { - public: - typedef int RequestID; - - ChromeURLDataManagerBackend(); - ~ChromeURLDataManagerBackend(); - - // Invoked to register the protocol factories. - static void Register(); - - // Adds a DataSource to the collection of data sources. - void AddDataSource(ChromeURLDataManager::DataSource* source); - - // Add/remove a path from the collection of file sources. - // A file source acts like a file:// URL to the specified path. - // Calling this from threads other the IO thread must be done via - // InvokeLater. - void AddFileSource(const std::string& source_name, const FilePath& path); - - // DataSource invokes this. Sends the data to the URLRequest. - void DataAvailable(RequestID request_id, RefCountedMemory* bytes); - - static net::URLRequestJob* Factory(net::URLRequest* request, - const std::string& scheme); - - private: - friend class URLRequestChromeJob; - - typedef std::map<std::string, - scoped_refptr<ChromeURLDataManager::DataSource> > DataSourceMap; - typedef std::map<std::string, FilePath> FileSourceMap; - typedef std::map<RequestID, URLRequestChromeJob*> PendingRequestMap; - - // Parse a URL into the components used to resolve its request. - void URLToRequest(const GURL& url, std::string* source, std::string* path); - - // Translate a chrome resource URL into a local file path if there is one. - // Returns false if there is no file handler for this URL - bool URLToFilePath(const GURL& url, FilePath* file_path); - - // Called by the job when it's starting up. - // Returns false if |url| is not a URL managed by this object. - bool StartRequest(const GURL& url, URLRequestChromeJob* job); - - // Remove a request from the list of pending requests. - void RemoveRequest(URLRequestChromeJob* job); - - // Returns true if the job exists in |pending_requests_|. False otherwise. - // Called by ~URLRequestChromeJob to verify that |pending_requests_| is kept - // up to date. - bool HasPendingJob(URLRequestChromeJob* job) const; - - // File sources of data, keyed by source name (e.g. "inspector"). - FileSourceMap file_sources_; - - // Custom sources of data, keyed by source path (e.g. "favicon"). - DataSourceMap data_sources_; - - // All pending URLRequestChromeJobs, keyed by ID of the request. - // URLRequestChromeJob calls into this object when it's constructed and - // destructed to ensure that the pointers in this map remain valid. - PendingRequestMap pending_requests_; - - // The ID we'll use for the next request we receive. - RequestID next_request_id_; - - DISALLOW_COPY_AND_ASSIGN(ChromeURLDataManagerBackend); -}; - -#endif // CHROME_BROWSER_DOM_UI_CHROME_URL_DATA_MANAGER_BACKEND_H_ diff --git a/chrome/browser/dom_ui/conflicts_ui.cc b/chrome/browser/dom_ui/conflicts_ui.cc index 4e21b29..8631c8d 100644 --- a/chrome/browser/dom_ui/conflicts_ui.cc +++ b/chrome/browser/dom_ui/conflicts_ui.cc @@ -14,7 +14,6 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/enumerate_modules_model_win.h" #include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/notification_observer.h" @@ -203,7 +202,11 @@ ConflictsUI::ConflictsUI(TabContents* contents) : DOMUI(contents) { ConflictsUIHTMLSource* html_source = new ConflictsUIHTMLSource(); // Set up the about:conflicts source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/downloads_dom_handler.cc b/chrome/browser/dom_ui/downloads_dom_handler.cc index 82badc9..c6a22ec 100644 --- a/chrome/browser/dom_ui/downloads_dom_handler.cc +++ b/chrome/browser/dom_ui/downloads_dom_handler.cc @@ -22,7 +22,6 @@ #include "chrome/browser/download/download_item.h" #include "chrome/browser/download/download_util.h" #include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" @@ -52,8 +51,12 @@ DownloadsDOMHandler::DownloadsDOMHandler(DownloadManager* dlm) download_manager_(dlm), callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { // Create our fileicon data source. - dlm->profile()->GetChromeURLDataManager()->AddDataSource( - new FileIconSource()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new FileIconSource()))); } DownloadsDOMHandler::~DownloadsDOMHandler() { diff --git a/chrome/browser/dom_ui/downloads_ui.cc b/chrome/browser/dom_ui/downloads_ui.cc index 2fadd47..63b1b153 100644 --- a/chrome/browser/dom_ui/downloads_ui.cc +++ b/chrome/browser/dom_ui/downloads_ui.cc @@ -14,7 +14,6 @@ #include "chrome/browser/dom_ui/downloads_dom_handler.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" @@ -135,7 +134,11 @@ DownloadsUI::DownloadsUI(TabContents* contents) : DOMUI(contents) { DownloadsUIHTMLSource* html_source = new DownloadsUIHTMLSource(); // Set up the chrome://downloads/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index 81dddb2..08dceb3 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -422,9 +422,13 @@ FilebrowseHandler::~FilebrowseHandler() { WebUIMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) { // Create our favicon data source. + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(dom_ui->GetProfile())))); profile_ = dom_ui->GetProfile(); - profile_->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile_)); tab_contents_ = dom_ui->tab_contents(); return WebUIMessageHandler::Attach(dom_ui); } @@ -1135,7 +1139,12 @@ FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) { FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource(); // Set up the chrome://filebrowse/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/flags_ui.cc b/chrome/browser/dom_ui/flags_ui.cc index b301673..d57dc3b 100644 --- a/chrome/browser/dom_ui/flags_ui.cc +++ b/chrome/browser/dom_ui/flags_ui.cc @@ -14,8 +14,6 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" @@ -182,7 +180,11 @@ FlagsUI::FlagsUI(TabContents* contents) : DOMUI(contents) { FlagsUIHTMLSource* html_source = new FlagsUIHTMLSource(); // Set up the about:flags source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/gpu_internals_ui.cc b/chrome/browser/dom_ui/gpu_internals_ui.cc index 9948264..c37a071 100644 --- a/chrome/browser/dom_ui/gpu_internals_ui.cc +++ b/chrome/browser/dom_ui/gpu_internals_ui.cc @@ -29,8 +29,6 @@ #include "chrome/browser/net/passive_log_collector.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/platform_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/jstemplate_builder.h" @@ -309,9 +307,9 @@ DictionaryValue* GpuInfoToDict(const GPUInfo& gpu_info) { if (gpu_info.level() == GPUInfo::kPartial) { info->SetString("level", "partial"); } else if (gpu_info.level() == GPUInfo::kCompleting) { - info->SetString("level", "completing"); + info->SetString("level", "completing"); } else if (gpu_info.level() == GPUInfo::kComplete) { - info->SetString("level", "complete"); + info->SetString("level", "complete"); } else { DCHECK(false) << "Unrecognized GPUInfo::Level value"; info->SetString("level", ""); @@ -367,6 +365,11 @@ GpuInternalsUI::GpuInternalsUI(TabContents* contents) : DOMUI(contents) { GpuHTMLSource* html_source = new GpuHTMLSource(); // Set up the chrome://gpu/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/history2_ui.cc b/chrome/browser/dom_ui/history2_ui.cc index aaf7fdc..bdfe536 100644 --- a/chrome/browser/dom_ui/history2_ui.cc +++ b/chrome/browser/dom_ui/history2_ui.cc @@ -129,9 +129,12 @@ BrowsingHistoryHandler2::~BrowsingHistoryHandler2() { WebUIMessageHandler* BrowsingHistoryHandler2::Attach(DOMUI* dom_ui) { // Create our favicon data source. - Profile* profile = dom_ui->GetProfile(); - profile->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(dom_ui->GetProfile())))); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, @@ -397,7 +400,12 @@ HistoryUI2::HistoryUI2(TabContents* contents) : DOMUI(contents) { HistoryUIHTMLSource2* html_source = new HistoryUIHTMLSource2(); // Set up the chrome://history2/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/history_ui.cc b/chrome/browser/dom_ui/history_ui.cc index 80be7d3..2013256 100644 --- a/chrome/browser/dom_ui/history_ui.cc +++ b/chrome/browser/dom_ui/history_ui.cc @@ -129,13 +129,16 @@ BrowsingHistoryHandler::~BrowsingHistoryHandler() { WebUIMessageHandler* BrowsingHistoryHandler::Attach(DOMUI* dom_ui) { // Create our favicon data source. - Profile* profile = dom_ui->GetProfile(); - profile->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(dom_ui->GetProfile())))); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(profile->GetOriginalProfile())); + Source<Profile>(dom_ui->GetProfile()->GetOriginalProfile())); return WebUIMessageHandler::Attach(dom_ui); } @@ -385,7 +388,12 @@ HistoryUI::HistoryUI(TabContents* contents) : DOMUI(contents) { HistoryUIHTMLSource* html_source = new HistoryUIHTMLSource(); // Set up the chrome://history/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/dom_ui/keyboard_ui.cc b/chrome/browser/dom_ui/keyboard_ui.cc index 375acd1..413cb0d 100644 --- a/chrome/browser/dom_ui/keyboard_ui.cc +++ b/chrome/browser/dom_ui/keyboard_ui.cc @@ -9,7 +9,6 @@ #include "base/string_piece.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -20,7 +19,12 @@ KeyboardUI::KeyboardUI(TabContents* contents) : DOMUI(contents) { KeyboardHTMLSource* html_source = new KeyboardHTMLSource(); - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } KeyboardUI::~KeyboardUI() { diff --git a/chrome/browser/dom_ui/mediaplayer_ui.cc b/chrome/browser/dom_ui/mediaplayer_ui.cc index 858d6d8..8b2b300 100644 --- a/chrome/browser/dom_ui/mediaplayer_ui.cc +++ b/chrome/browser/dom_ui/mediaplayer_ui.cc @@ -209,9 +209,12 @@ MediaplayerHandler::~MediaplayerHandler() { WebUIMessageHandler* MediaplayerHandler::Attach(DOMUI* dom_ui) { // Create our favicon data source. - Profile* profile = dom_ui->GetProfile(); - profile->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(dom_ui->GetProfile())))); return WebUIMessageHandler::Attach(dom_ui); } @@ -609,5 +612,10 @@ MediaplayerUI::MediaplayerUI(TabContents* contents) : DOMUI(contents) { new MediaplayerUIHTMLSource(is_playlist); // Set up the chrome://mediaplayer/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/most_visited_handler.cc b/chrome/browser/dom_ui/most_visited_handler.cc index 7e9e61e..9bf80c2 100644 --- a/chrome/browser/dom_ui/most_visited_handler.cc +++ b/chrome/browser/dom_ui/most_visited_handler.cc @@ -64,21 +64,30 @@ MostVisitedHandler::~MostVisitedHandler() { } WebUIMessageHandler* MostVisitedHandler::Attach(DOMUI* dom_ui) { - Profile* profile = dom_ui->GetProfile(); - url_blacklist_ = profile->GetPrefs()->GetMutableDictionary( - prefs::kNTPMostVisitedURLsBlacklist); - pinned_urls_ = profile->GetPrefs()->GetMutableDictionary( - prefs::kNTPMostVisitedPinnedURLs); + url_blacklist_ = dom_ui->GetProfile()->GetPrefs()-> + GetMutableDictionary(prefs::kNTPMostVisitedURLsBlacklist); + pinned_urls_ = dom_ui->GetProfile()->GetPrefs()-> + GetMutableDictionary(prefs::kNTPMostVisitedPinnedURLs); // Set up our sources for thumbnail and favicon data. - WebUIThumbnailSource* thumbnail_src = new WebUIThumbnailSource(profile); - profile->GetChromeURLDataManager()->AddDataSource(thumbnail_src); - - WebUIFavIconSource* favicon_src = new WebUIFavIconSource(profile); - profile->GetChromeURLDataManager()->AddDataSource(favicon_src); + WebUIThumbnailSource* thumbnail_src = + new WebUIThumbnailSource(dom_ui->GetProfile()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(thumbnail_src))); + + WebUIFavIconSource* favicon_src = + new WebUIFavIconSource(dom_ui->GetProfile()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(favicon_src))); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(profile)); + Source<Profile>(dom_ui->GetProfile())); WebUIMessageHandler* result = WebUIMessageHandler::Attach(dom_ui); diff --git a/chrome/browser/dom_ui/net_internals_ui.cc b/chrome/browser/dom_ui/net_internals_ui.cc index 00e4ce3..8296623 100644 --- a/chrome/browser/dom_ui/net_internals_ui.cc +++ b/chrome/browser/dom_ui/net_internals_ui.cc @@ -210,10 +210,10 @@ class NetInternalsMessageHandler::IOThreadImpl typedef void (IOThreadImpl::*MessageHandler)(const ListValue*); // Creates a proxy for |handler| that will live on the IO thread. - // |handler| is a weak pointer, since it is possible for the - // WebUIMessageHandler to be deleted on the UI thread while we were executing - // on the IO thread. |io_thread| is the global IOThread (it is passed in as - // an argument since we need to grab it from the UI thread). + // |handler| is a weak pointer, since it is possible for the WebUIMessageHandler + // to be deleted on the UI thread while we were executing on the IO thread. + // |io_thread| is the global IOThread (it is passed in as an argument since + // we need to grab it from the UI thread). IOThreadImpl( const base::WeakPtr<NetInternalsMessageHandler>& handler, IOThread* io_thread, @@ -1162,5 +1162,10 @@ NetInternalsUI::NetInternalsUI(TabContents* contents) : DOMUI(contents) { NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource(); // Set up the chrome://net-internals/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index d4f6174..ad95bca 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -332,7 +332,12 @@ NewTabUI::NewTabUI(TabContents* contents) InitializeCSSCaches(); NewTabHTMLSource* html_source = new NewTabHTMLSource(GetProfile()->GetOriginalProfile()); - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); // Listen for theme installation. registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, @@ -417,9 +422,13 @@ void NewTabUI::Observe(NotificationType type, } void NewTabUI::InitializeCSSCaches() { - Profile* profile = GetProfile(); - WebUIThemeSource* theme = new WebUIThemeSource(profile); - profile->GetChromeURLDataManager()->AddDataSource(theme); + WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(theme))); } // static diff --git a/chrome/browser/dom_ui/options/browser_options_handler.cc b/chrome/browser/dom_ui/options/browser_options_handler.cc index b8b1cb5..83d5223 100644 --- a/chrome/browser/dom_ui/options/browser_options_handler.cc +++ b/chrome/browser/dom_ui/options/browser_options_handler.cc @@ -126,8 +126,12 @@ void BrowserOptionsHandler::Initialize() { Profile* profile = dom_ui_->GetProfile(); // Create our favicon data source. - profile->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(profile)))); homepage_.Init(prefs::kHomePage, profile->GetPrefs(), NULL); default_browser_policy_.Init(prefs::kDefaultBrowserSettingEnabled, diff --git a/chrome/browser/dom_ui/options/options_ui.cc b/chrome/browser/dom_ui/options/options_ui.cc index 24e83d9..2ae3772 100644 --- a/chrome/browser/dom_ui/options/options_ui.cc +++ b/chrome/browser/dom_ui/options/options_ui.cc @@ -193,15 +193,25 @@ OptionsUI::OptionsUI(TabContents* contents) new OptionsUIHTMLSource(localized_strings); // Set up the chrome://settings/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); // Set up the chrome://theme/ source. - WebUIThemeSource* theme = new WebUIThemeSource(contents->profile()); - contents->profile()->GetChromeURLDataManager()->AddDataSource(theme); + WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(theme))); // Initialize the chrome://about/ source in case the user clicks the credits // link. - InitializeAboutDataSource(contents->profile()); + InitializeAboutDataSource(); } OptionsUI::~OptionsUI() { diff --git a/chrome/browser/dom_ui/plugins_ui.cc b/chrome/browser/dom_ui/plugins_ui.cc index b67397b..74980cb 100644 --- a/chrome/browser/dom_ui/plugins_ui.cc +++ b/chrome/browser/dom_ui/plugins_ui.cc @@ -349,7 +349,11 @@ PluginsUI::PluginsUI(TabContents* contents) : DOMUI(contents) { PluginsUIHTMLSource* html_source = new PluginsUIHTMLSource(); // Set up the chrome://plugins/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/print_preview_ui.cc b/chrome/browser/dom_ui/print_preview_ui.cc index a52d173..fd3476c 100644 --- a/chrome/browser/dom_ui/print_preview_ui.cc +++ b/chrome/browser/dom_ui/print_preview_ui.cc @@ -8,8 +8,6 @@ #include "chrome/browser/browser_thread.h" #include "chrome/browser/dom_ui/print_preview_handler.h" #include "chrome/browser/dom_ui/print_preview_ui_html_source.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" PrintPreviewUI::PrintPreviewUI(TabContents* contents) : DOMUI(contents), @@ -19,7 +17,12 @@ PrintPreviewUI::PrintPreviewUI(TabContents* contents) AddMessageHandler(handler->Attach(this)); // Set up the chrome://print/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source_); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + html_source_)); } PrintPreviewUI::~PrintPreviewUI() { diff --git a/chrome/browser/dom_ui/remoting_ui.cc b/chrome/browser/dom_ui/remoting_ui.cc index 648b857..f3e0899 100644 --- a/chrome/browser/dom_ui/remoting_ui.cc +++ b/chrome/browser/dom_ui/remoting_ui.cc @@ -7,8 +7,6 @@ #include "base/singleton.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/url_constants.h" #include "grit/theme_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -66,7 +64,11 @@ RemotingUI::RemotingUI(TabContents* contents) : DOMUI(contents) { RemotingUIHTMLSource* html_source = new RemotingUIHTMLSource(); // Set up the chrome://remoting source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/shared_resources_data_source.cc b/chrome/browser/dom_ui/shared_resources_data_source.cc index 167a67a..4922f1e 100644 --- a/chrome/browser/dom_ui/shared_resources_data_source.cc +++ b/chrome/browser/dom_ui/shared_resources_data_source.cc @@ -53,6 +53,17 @@ int PathToIDR(const std::string& path) { } // namespace +// static +void SharedResourcesDataSource::Register() { + SharedResourcesDataSource* source = new SharedResourcesDataSource(); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(source))); +} + SharedResourcesDataSource::SharedResourcesDataSource() : DataSource(chrome::kChromeUIResourcesHost, NULL) { } diff --git a/chrome/browser/dom_ui/shared_resources_data_source.h b/chrome/browser/dom_ui/shared_resources_data_source.h index 1aec881..a162b43 100644 --- a/chrome/browser/dom_ui/shared_resources_data_source.h +++ b/chrome/browser/dom_ui/shared_resources_data_source.h @@ -18,7 +18,8 @@ class GURL; // A DataSource for chrome://resources/ URLs. class SharedResourcesDataSource : public ChromeURLDataManager::DataSource { public: - SharedResourcesDataSource(); + // Registers an instance of this data source with the ChromeUrlDataManager. + static void Register(); // Overridden from ChromeURLDataManager::DataSource: virtual void StartDataRequest(const std::string& path, @@ -27,6 +28,7 @@ class SharedResourcesDataSource : public ChromeURLDataManager::DataSource { virtual std::string GetMimeType(const std::string&) const; private: + SharedResourcesDataSource(); ~SharedResourcesDataSource(); DISALLOW_COPY_AND_ASSIGN(SharedResourcesDataSource); diff --git a/chrome/browser/dom_ui/slideshow_ui.cc b/chrome/browser/dom_ui/slideshow_ui.cc index 105fd79..78a3965 100644 --- a/chrome/browser/dom_ui/slideshow_ui.cc +++ b/chrome/browser/dom_ui/slideshow_ui.cc @@ -148,10 +148,14 @@ SlideshowHandler::~SlideshowHandler() { } WebUIMessageHandler* SlideshowHandler::Attach(DOMUI* dom_ui) { - profile_ = dom_ui->GetProfile(); // Create our favicon data source. - profile_->GetChromeURLDataManager()->AddDataSource( - new WebUIFavIconSource(profile_)); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new WebUIFavIconSource(dom_ui->GetProfile())))); + profile_ = dom_ui->GetProfile(); return WebUIMessageHandler::Attach(dom_ui); } @@ -280,5 +284,10 @@ SlideshowUI::SlideshowUI(TabContents* contents) : DOMUI(contents) { SlideshowUIHTMLSource* html_source = new SlideshowUIHTMLSource(); // Set up the chrome://slideshow/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/dom_ui/sync_internals_ui.cc b/chrome/browser/dom_ui/sync_internals_ui.cc index bf36c5f..0af9f0c 100644 --- a/chrome/browser/dom_ui/sync_internals_ui.cc +++ b/chrome/browser/dom_ui/sync_internals_ui.cc @@ -30,8 +30,12 @@ SyncInternalsUI::SyncInternalsUI(TabContents* contents) // If this PostTask() call fails, it's most likely because this is // being run from a unit test. The created objects will be cleaned // up, anyway. - contents->profile()->GetChromeURLDataManager()->AddDataSource( - new SyncInternalsHTMLSource()); + (void)BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new SyncInternalsHTMLSource()))); } SyncInternalsUI::~SyncInternalsUI() { diff --git a/chrome/browser/dom_ui/textfields_ui.cc b/chrome/browser/dom_ui/textfields_ui.cc index cca22c9..7d75aaa 100644 --- a/chrome/browser/dom_ui/textfields_ui.cc +++ b/chrome/browser/dom_ui/textfields_ui.cc @@ -11,8 +11,6 @@ #include "base/string_piece.h" #include "base/values.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" @@ -70,5 +68,9 @@ TextfieldsUI::TextfieldsUI(TabContents* contents) : DOMUI(contents) { TextfieldsUIHTMLSource* html_source = new TextfieldsUIHTMLSource(); // Set up the chrome://textfields/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 3d6f4d4..839b341 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -391,7 +391,11 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( // ChromeURLDataManager. if (extension->HasHostPermission(GURL(chrome::kChromeUIFavIconURL))) { WebUIFavIconSource* favicon_source = new WebUIFavIconSource(profile_); - profile_->GetChromeURLDataManager()->AddDataSource(favicon_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(favicon_source))); } // Update the extension permissions. Doing this each time we create an EFD diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index c0406dd..087102c 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -959,7 +959,12 @@ ExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) { ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource(); // Set up the chrome://extensions/ source. - contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod( + ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); } // static diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 573ffdc..e42ae2d 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -11,7 +11,6 @@ #include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/io_thread.h" @@ -733,13 +732,6 @@ ChromeURLRequestContext::ChromeURLRequestContext() CheckCurrentlyOnIOThread(); } -ChromeURLDataManagerBackend* - ChromeURLRequestContext::GetChromeURLDataManagerBackend() { - if (!chrome_url_data_manager_backend_.get()) - chrome_url_data_manager_backend_.reset(new ChromeURLDataManagerBackend()); - return chrome_url_data_manager_backend_.get(); -} - ChromeURLRequestContext::~ChromeURLRequestContext() { CheckCurrentlyOnIOThread(); diff --git a/chrome/browser/net/chrome_url_request_context.h b/chrome/browser/net/chrome_url_request_context.h index 943b0fd..5d57b46 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -40,7 +40,6 @@ class DnsCertProvenanceChecker; class NetworkDelegate; } -class ChromeURLDataManagerBackend; class ChromeURLRequestContext; class ChromeURLRequestContextFactory; @@ -103,8 +102,6 @@ class ChromeURLRequestContext : public net::URLRequestContext { return prerender_manager_.get(); } - ChromeURLDataManagerBackend* GetChromeURLDataManagerBackend(); - protected: virtual ~ChromeURLRequestContext(); @@ -194,7 +191,6 @@ class ChromeURLRequestContext : public net::URLRequestContext { scoped_refptr<ExtensionInfoMap> extension_info_map_; scoped_refptr<ExtensionIOEventRouter> extension_io_event_router_; scoped_refptr<PrerenderManager> prerender_manager_; - scoped_ptr<ChromeURLDataManagerBackend> chrome_url_data_manager_backend_; bool is_off_the_record_; diff --git a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc index 0e2f79d..52e4739 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc +++ b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc @@ -88,8 +88,11 @@ CloudPrintSetupFlow::CloudPrintSetupFlow(const std::string& args, delegate_(delegate) { // TODO(hclam): The data source should be added once. profile_ = profile; - profile->GetChromeURLDataManager()->AddDataSource( - new CloudPrintSetupSource()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new CloudPrintSetupSource()))); } CloudPrintSetupFlow::~CloudPrintSetupFlow() { diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 0c59310..85c71ad 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -17,7 +17,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/chrome_blob_storage_context.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_pref_store.h" @@ -631,12 +630,6 @@ class OffTheRecordProfileImpl : public Profile, return NULL; } - virtual ChromeURLDataManager* GetChromeURLDataManager() { - if (!chrome_url_data_manager_.get()) - chrome_url_data_manager_.reset(new ChromeURLDataManager(this)); - return chrome_url_data_manager_.get(); - } - virtual PromoCounter* GetInstantPromoCounter() { return NULL; } @@ -726,8 +719,6 @@ class OffTheRecordProfileImpl : public Profile, scoped_refptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; - scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; - DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileImpl); }; diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 2f09b1c..976eacd 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -50,7 +50,7 @@ class BrowserSignin; class BrowserThemeProvider; class ChromeAppCacheService; class ChromeBlobStorageContext; -class ChromeURLDataManager; +class ChromeURLRequestContextGetter; class CloudPrintProxyService; class DesktopNotificationService; class DownloadManager; @@ -497,9 +497,6 @@ class Profile { // Gets the policy context associated with this profile. virtual policy::ProfilePolicyContext* GetPolicyContext() = 0; - // Returns the ChromeURLDataManager for this profile. - virtual ChromeURLDataManager* GetChromeURLDataManager() = 0; - #if defined(OS_CHROMEOS) enum AppLocaleChangedVia { // Caused by chrome://settings change. diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index d3c633d..aa8fabf 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -26,7 +26,6 @@ #include "chrome/browser/chrome_blob_storage_context.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/defaults.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/ntp_resource_cache.h" #include "chrome/browser/download/download_manager.h" #include "chrome/browser/extensions/default_apps.h" @@ -1373,12 +1372,6 @@ policy::ProfilePolicyContext* ProfileImpl::GetPolicyContext() { return profile_policy_context_.get(); } -ChromeURLDataManager* ProfileImpl::GetChromeURLDataManager() { - if (!chrome_url_data_manager_.get()) - chrome_url_data_manager_.reset(new ChromeURLDataManager(this)); - return chrome_url_data_manager_.get(); -} - PromoCounter* ProfileImpl::GetInstantPromoCounter() { #if defined(OS_WIN) // TODO: enable this when we're ready to turn on the promo. diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index d65e7b6..acc0d5b 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -131,7 +131,6 @@ class ProfileImpl : public Profile, virtual PromoCounter* GetInstantPromoCounter(); virtual BrowserSignin* GetBrowserSignin(); virtual policy::ProfilePolicyContext* GetPolicyContext(); - virtual ChromeURLDataManager* GetChromeURLDataManager(); #if defined(OS_CHROMEOS) virtual void ChangeAppLocale(const std::string& locale, AppLocaleChangedVia); @@ -307,8 +306,6 @@ class ProfileImpl : public Profile, scoped_refptr<PrerenderManager> prerender_manager_; - scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; - DISALLOW_COPY_AND_ASSIGN(ProfileImpl); }; diff --git a/chrome/browser/remoting/setup_flow.cc b/chrome/browser/remoting/setup_flow.cc index 918855a..2d5811d 100644 --- a/chrome/browser/remoting/setup_flow.cc +++ b/chrome/browser/remoting/setup_flow.cc @@ -115,16 +115,18 @@ void SetupFlowDoneStep::DoStart() { SetupFlowContext::SetupFlowContext() { } SetupFlowContext::~SetupFlowContext() { } -SetupFlow::SetupFlow(const std::string& args, - Profile* profile, +SetupFlow::SetupFlow(const std::string& args, Profile* profile, SetupFlowStep* first_step) : dom_ui_(NULL), dialog_start_args_(args), profile_(profile), current_step_(first_step) { // TODO(hclam): The data source should be added once. - profile->GetChromeURLDataManager()->AddDataSource( - new RemotingResourcesSource()); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new RemotingResourcesSource()))); } SetupFlow::~SetupFlow() { } diff --git a/chrome/browser/sync/profile_sync_service_mock.cc b/chrome/browser/sync/profile_sync_service_mock.cc index 99e9ede..f843159 100644 --- a/chrome/browser/sync/profile_sync_service_mock.cc +++ b/chrome/browser/sync/profile_sync_service_mock.cc @@ -9,4 +9,6 @@ ProfileSyncServiceMock::ProfileSyncServiceMock() {} ProfileSyncServiceMock::~ProfileSyncServiceMock() { + ChromeURLDataManager::GetInstance()->RemoveDataSourceForTest( + chrome::kChromeUISyncResourcesHost); } diff --git a/chrome/browser/sync/sync_setup_wizard.cc b/chrome/browser/sync/sync_setup_wizard.cc index 632d60d..2cb6b7e 100644 --- a/chrome/browser/sync/sync_setup_wizard.cc +++ b/chrome/browser/sync/sync_setup_wizard.cc @@ -260,14 +260,19 @@ SyncSetupWizard::SyncSetupWizard(ProfileSyncService* service) : service_(service), flow_container_(new SyncSetupFlowContainer()), parent_window_(NULL) { - // If we're in a unit test, we may not have an IO thread or profile. Avoid + // If we're in a unit test, we may not have an IO thread. Avoid // creating a SyncResourcesSource since we may leak it (since it's // DeleteOnUIThread). - if (BrowserThread::IsMessageLoopValid(BrowserThread::IO) && - service_->profile()) { + if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { // Add our network layer data source for 'cloudy' URLs. SyncResourcesSource* sync_source = new SyncResourcesSource(); - service_->profile()->GetChromeURLDataManager()->AddDataSource(sync_source); + bool posted = + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + NewRunnableMethod(ChromeURLDataManager::GetInstance(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(sync_source))); + DCHECK(posted); } } diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc index 96dd2c909..7122170 100644 --- a/chrome/browser/sync/sync_ui_util_unittest.cc +++ b/chrome/browser/sync/sync_ui_util_unittest.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/basictypes.h" -#include "chrome/browser/browser_thread.h" #include "chrome/browser/sync/sync_ui_util.h" #include "chrome/browser/sync/profile_sync_service_mock.h" #include "testing/gmock/include/gmock/gmock.h" @@ -13,8 +12,6 @@ using ::testing::Return; using ::testing::NiceMock; TEST(SyncUIUtilTest, ConstructAboutInformationWithUnrecoverableErrorTest) { - MessageLoopForUI message_loop; - BrowserThread ui_thread(BrowserThread::UI, &message_loop); NiceMock<ProfileSyncServiceMock> service; DictionaryValue strings; diff --git a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc index 2113459..a2df005 100644 --- a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc +++ b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc @@ -275,7 +275,6 @@ TEST_F(RenderViewHostManagerTest, DOMUI) { // still swap processes if ShouldSwapProcessesForNavigation is true. // Regression test for bug 46290. TEST_F(RenderViewHostManagerTest, NonDOMUIChromeURLs) { - BrowserThread thread(BrowserThread::UI, &message_loop_); SiteInstance* instance = SiteInstance::CreateSiteInstance(profile_.get()); TestTabContents tab_contents(profile_.get(), instance); RenderViewHostManager manager(&tab_contents, &tab_contents); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index ea4e102..fac8d4f 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -855,8 +855,6 @@ 'browser/dom_ui/bookmarks_ui.h', 'browser/dom_ui/bug_report_ui.cc', 'browser/dom_ui/bug_report_ui.h', - 'browser/dom_ui/chrome_url_data_manager_backend.cc', - 'browser/dom_ui/chrome_url_data_manager_backend.h', 'browser/dom_ui/chrome_url_data_manager.cc', 'browser/dom_ui/chrome_url_data_manager.h', 'browser/dom_ui/constrained_html_ui.cc', diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index 6cfec31..e7102df 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -16,7 +16,6 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser_thread.h" #include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/ntp_resource_cache.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_pref_value_map.h" @@ -50,7 +49,6 @@ #include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "webkit/database/database_tracker.h" - #if defined(OS_LINUX) && !defined(TOOLKIT_VIEWS) #include "chrome/browser/ui/gtk/gtk_theme_provider.h" #endif @@ -761,12 +759,6 @@ policy::ProfilePolicyContext* TestingProfile::GetPolicyContext() { return NULL; } -ChromeURLDataManager* TestingProfile::GetChromeURLDataManager() { - if (!chrome_url_data_manager_.get()) - chrome_url_data_manager_.reset(new ChromeURLDataManager(this)); - return chrome_url_data_manager_.get(); -} - PrerenderManager* TestingProfile::GetPrerenderManager() { return NULL; } diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h index c32b44e..ee16eb6 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -273,7 +273,6 @@ class TestingProfile : public Profile { virtual ExtensionInfoMap* GetExtensionInfoMap(); virtual PromoCounter* GetInstantPromoCounter(); virtual policy::ProfilePolicyContext* GetPolicyContext(); - virtual ChromeURLDataManager* GetChromeURLDataManager(); virtual PrerenderManager* GetPrerenderManager(); virtual PrefService* GetOffTheRecordPrefs(); @@ -382,8 +381,6 @@ class TestingProfile : public Profile { // We use a temporary directory to store testing profile data. ScopedTempDir temp_dir_; - - scoped_ptr<ChromeURLDataManager> chrome_url_data_manager_; }; // A profile that derives from another profile. This does not actually |