diff options
60 files changed, 829 insertions, 856 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 9e7b48c..c4747d9 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -160,9 +160,6 @@ 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 @@ -692,21 +689,9 @@ 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, @@ -1054,7 +1039,7 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { return false; // Anything else requires our special handler; make sure it's initialized. - InitializeAboutDataSource(); + InitializeAboutDataSource(profile); // Special case about:memory to go through a redirect before ending up on // the final page. See GetAboutMemoryRedirectResponse above for why. @@ -1072,14 +1057,8 @@ bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { return true; } -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; - } +void InitializeAboutDataSource(Profile* profile) { + profile->GetChromeURLDataManager()->AddDataSource(new AboutSource()); } // 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 46ae100..e5e31c9f 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(); +void InitializeAboutDataSource(Profile* profile); // 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 6b3bd40..16fface 100644 --- a/chrome/browser/browser_about_handler_unittest.cc +++ b/chrome/browser/browser_about_handler_unittest.cc @@ -5,8 +5,10 @@ #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" @@ -96,13 +98,16 @@ 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, NULL)); + WillHandleBrowserAboutURL(&url, &profile)); EXPECT_EQ(test_data[i].result_url, url); } diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 0819289..b0f3954 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.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.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. - RegisterURLRequestChromeJob(); + ChromeURLDataManagerBackend::Register(); RegisterExtensionProtocols(); RegisterMetadataURLRequestHandler(); RegisterBlobURLRequestJobFactory(); diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index 7858c8f..198a75c 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc @@ -257,16 +257,11 @@ void Shutdown() { file_util::WriteFile(shutdown_ms_file, shutdown_ms.c_str(), len); } - UnregisterURLRequestChromeJob(); - #if defined(OS_CHROMEOS) BrowserList::NotifyAndTerminate(false); #endif - // Clean up data sources before the UI thread is removed. - ChromeURLDataManager* data_manager = ChromeURLDataManager::GetInstance(); - if (data_manager) - data_manager->RemoveAllDataSources(); + ChromeURLDataManager::DeleteDataSources(); } void ReadLastShutdownFile( diff --git a/chrome/browser/browser_signin.cc b/chrome/browser/browser_signin.cc index 1c2c051..f077d0c 100644 --- a/chrome/browser/browser_signin.cc +++ b/chrome/browser/browser_signin.cc @@ -215,12 +215,11 @@ BrowserSignin::BrowserSignin(Profile* profile) : profile_(profile), delegate_(NULL), html_dialog_ui_delegate_(NULL) { - BrowserSigninResourcesSource* source = new BrowserSigninResourcesSource(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(source))); + // profile is NULL during testing. + if (profile) { + BrowserSigninResourcesSource* source = new BrowserSigninResourcesSource(); + profile->GetChromeURLDataManager()->AddDataSource(source); + } } BrowserSignin::~BrowserSignin() { diff --git a/chrome/browser/chromeos/dom_ui/imageburner_ui.cc b/chrome/browser/chromeos/dom_ui/imageburner_ui.cc index 758b47b..8aaa576 100644 --- a/chrome/browser/chromeos/dom_ui/imageburner_ui.cc +++ b/chrome/browser/chromeos/dom_ui/imageburner_ui.cc @@ -649,10 +649,5 @@ ImageBurnUI::ImageBurnUI(TabContents* contents) : DOMUI(contents) { ImageBurnHandler* handler = new ImageBurnHandler(contents); AddMessageHandler((handler)->Attach(this)); ImageBurnUIHTMLSource* html_source = new ImageBurnUIHTMLSource(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 8f41996..fb84ee2 100644 --- a/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc +++ b/chrome/browser/chromeos/dom_ui/keyboard_overlay_ui.cc @@ -12,6 +12,8 @@ #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" @@ -294,10 +296,5 @@ KeyboardOverlayUI::KeyboardOverlayUI(TabContents* contents) KeyboardOverlayUIHTMLSource* html_source = new KeyboardOverlayUIHTMLSource(); // Set up the chrome://keyboardoverlay/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 845bf4b..a1ba4e0 100644 --- a/chrome/browser/chromeos/dom_ui/login/login_ui.cc +++ b/chrome/browser/chromeos/dom_ui/login/login_ui.cc @@ -14,6 +14,8 @@ #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" @@ -155,12 +157,7 @@ LoginUI::LoginUI(TabContents* contents) LoginUIHTMLSource* html_source = new LoginUIHTMLSource(MessageLoop::current()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile->GetChromeURLDataManager()->AddDataSource(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 741961a..04adde5 100644 --- a/chrome/browser/chromeos/dom_ui/menu_ui.cc +++ b/chrome/browser/chromeos/dom_ui/menu_ui.cc @@ -20,6 +20,7 @@ #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" @@ -531,12 +532,8 @@ MenuUI::MenuUI(TabContents* contents) : DOMUI(contents) { MenuHandler* handler = new MenuHandler(); AddMessageHandler((handler)->Attach(this)); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(CreateDataSource()))); + contents->profile()->GetChromeURLDataManager()->AddDataSource( + CreateDataSource()); } MenuUI::MenuUI(TabContents* contents, ChromeURLDataManager::DataSource* source) @@ -544,12 +541,7 @@ MenuUI::MenuUI(TabContents* contents, ChromeURLDataManager::DataSource* source) MenuHandler* handler = new MenuHandler(); AddMessageHandler((handler)->Attach(this)); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 a6365cd..ac3688e 100644 --- a/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc +++ b/chrome/browser/chromeos/dom_ui/mobile_setup_ui.cc @@ -1323,10 +1323,5 @@ MobileSetupUI::MobileSetupUI(TabContents* contents) : DOMUI(contents) { new MobileSetupUIHTMLSource(service_path); // Set up the chrome://mobilesetup/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 cea000d..8e0defd 100644 --- a/chrome/browser/chromeos/dom_ui/network_menu_ui.cc +++ b/chrome/browser/chromeos/dom_ui/network_menu_ui.cc @@ -13,6 +13,7 @@ #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" @@ -117,13 +118,8 @@ NetworkMenuUI::NetworkMenuUI(TabContents* contents) AddMessageHandler((handler)->Attach(this)); // Set up chrome://theme/ source. - WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(theme))); + WebUIThemeSource* theme = new WebUIThemeSource(contents->profile()); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 2434c03..f3e4453 100644 --- a/chrome/browser/chromeos/dom_ui/register_page_ui.cc +++ b/chrome/browser/chromeos/dom_ui/register_page_ui.cc @@ -21,6 +21,7 @@ #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" @@ -323,10 +324,5 @@ RegisterPageUI::RegisterPageUI(TabContents* contents) : DOMUI(contents){ RegisterPageUIHTMLSource* html_source = new RegisterPageUIHTMLSource(); // Set up the chrome://register/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 87f01d2..93b8456 100644 --- a/chrome/browser/chromeos/dom_ui/system_info_ui.cc +++ b/chrome/browser/chromeos/dom_ui/system_info_ui.cc @@ -18,6 +18,8 @@ #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" @@ -179,10 +181,5 @@ SystemInfoUI::SystemInfoUI(TabContents* contents) : DOMUI(contents) { SystemInfoUIHTMLSource* html_source = new SystemInfoUIHTMLSource(); // Set up the chrome://system/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/bookmarks_ui.cc b/chrome/browser/dom_ui/bookmarks_ui.cc index b615168..490b102 100644 --- a/chrome/browser/dom_ui/bookmarks_ui.cc +++ b/chrome/browser/dom_ui/bookmarks_ui.cc @@ -8,7 +8,9 @@ #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" @@ -48,12 +50,7 @@ BookmarksUI::BookmarksUI(TabContents* contents) : DOMUI(contents) { BookmarksUIHTMLSource* html_source = new BookmarksUIHTMLSource(); // Set up the chrome://bookmarks/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/bug_report_ui.cc b/chrome/browser/dom_ui/bug_report_ui.cc index d64a100..d7cbd42 100644 --- a/chrome/browser/dom_ui/bug_report_ui.cc +++ b/chrome/browser/dom_ui/bug_report_ui.cc @@ -21,6 +21,7 @@ #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" @@ -432,9 +433,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 @@ -454,12 +455,8 @@ 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 - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new WebUIScreenshotSource(NULL)))); + tab_->profile()->GetChromeURLDataManager()->AddDataSource( + new WebUIScreenshotSource(NULL)); // clobber last screenshot if (browser::last_screenshot_png) @@ -473,12 +470,7 @@ void BugReportHandler::SetupScreenshotsSource() { browser::last_screenshot_png); // Add the source to the data manager. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(screenshot_source_))); + tab_->profile()->GetChromeURLDataManager()->AddDataSource(screenshot_source_); } WebUIMessageHandler* BugReportHandler::Attach(DOMUI* dom_ui) { @@ -749,10 +741,5 @@ BugReportUI::BugReportUI(TabContents* tab) : HtmlDialogUI(tab) { BugReportUIHTMLSource* html_source = new BugReportUIHTMLSource(handler->Init()); // Set up the chrome://bugreport/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + tab->profile()->GetChromeURLDataManager()->AddDataSource(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 c5c38c7..703a5af 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.cc +++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc @@ -4,332 +4,113 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "base/file_util.h" +#include <vector> + #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/threading/thread.h" +#include "base/synchronization/lock.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/shared_resources_data_source.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager_backend.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/ref_counted_util.h" -#include "chrome/common/url_constants.h" -#include "googleurl/src/url_util.h" +#include "chrome/browser/profiles/profile.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" -// 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_; - - 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 -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; - } - - // 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)); -} +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif // 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. -} +base::Lock ChromeURLDataManager::delete_lock_; // static -ChromeURLDataManager* ChromeURLDataManager::GetInstance() { - return Singleton<ChromeURLDataManager>::get(); -} +ChromeURLDataManager::DataSources* ChromeURLDataManager::data_sources_ = NULL; -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; -} - -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); +// 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()); } -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); - } +ChromeURLDataManager::ChromeURLDataManager(Profile* profile) + : profile_(profile) { } -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; +ChromeURLDataManager::~ChromeURLDataManager() { } -void ChromeURLDataManager::RemoveFileSource(const std::string& source_name) { - DCHECK(file_sources_.count(source_name) == 1); - file_sources_.erase(source_name); +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))); } -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; +// static +void ChromeURLDataManager::DeleteDataSources() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DataSources sources; + { + base::AutoLock lock(delete_lock_); + data_sources_->swap(sources); } - - return false; + for (size_t i = 0; i < sources.size(); ++i) + delete sources[i]; } -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)); +// 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; + return; } - return true; -} -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; - } + // 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::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); + if (schedule_delete) { + // Schedule a task to delete the DataSource back on the UI thread. + BrowserThread::PostTask(BrowserThread::UI, + FROM_HERE, + NewRunnableFunction( + &ChromeURLDataManager::DeleteDataSources)); } } ChromeURLDataManager::DataSource::DataSource(const std::string& source_name, MessageLoop* message_loop) - : source_name_(source_name), message_loop_(message_loop) { + : source_name_(source_name), + message_loop_(message_loop), + backend_(NULL) { } ChromeURLDataManager::DataSource::~DataSource() { } -void ChromeURLDataManager::DataSource::SendResponse( - RequestID request_id, - RefCountedMemory* bytes) { +void ChromeURLDataManager::DataSource::SendResponse(int request_id, + RefCountedMemory* bytes) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::DataAvailable, - request_id, scoped_refptr<RefCountedMemory>(bytes))); + NewRunnableMethod(this, &DataSource::SendResponseOnIOThread, + request_id, make_scoped_refptr(bytes))); } MessageLoop* ChromeURLDataManager::DataSource::MessageLoopForRequestPath( @@ -357,120 +138,10 @@ void ChromeURLDataManager::DataSource::SetFontAndTextDirection( base::i18n::IsRTL() ? "rtl" : "ltr"); } -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) { +void ChromeURLDataManager::DataSource::SendResponseOnIOThread( + int request_id, + scoped_refptr<RefCountedMemory> bytes) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (backend_) + backend_->DataAvailable(request_id, bytes); } - -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 0717498..163edf7 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) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -9,35 +9,45 @@ #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. - -// ChromeURLDataManager lives on the IO thread, so any interfacing with -// it from the UI thread needs to go through an InvokeLater. +// 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. class ChromeURLDataManager { public: - // Returns the singleton instance. - static ChromeURLDataManager* GetInstance(); + class DataSource; - typedef int RequestID; + // 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); + } + }; // A DataSource is an object that can answer requests for data // asynchronously. DataSources are collectively owned with refcounting smart @@ -49,11 +59,10 @@ class ChromeURLDataManager { // StartDataRequest() by starting its (implementation-specific) asynchronous // request for the data, then call SendResponse() to notify. class DataSource : public base::RefCountedThreadSafe< - DataSource, BrowserThread::DeleteOnUIThread> { + DataSource, DeleteDataSource> { 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 @@ -88,13 +97,18 @@ class ChromeURLDataManager { static void SetFontAndTextDirection(DictionaryValue* localized_strings); protected: - friend class base::RefCountedThreadSafe<DataSource>; - friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; - friend class DeleteTask<DataSource>; - virtual ~DataSource(); private: + friend class ChromeURLDataManagerBackend; + friend class ChromeURLDataManager; + 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); + // 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. @@ -103,89 +117,53 @@ 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_; }; - // 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); + 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(); private: - friend class URLRequestChromeJob; - friend struct DefaultSingletonTraits<ChromeURLDataManager>; + typedef std::vector<const ChromeURLDataManager::DataSource*> DataSources; - ChromeURLDataManager(); - ~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); - // 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_; -}; + Profile* profile_; -// 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); + // Lock used when accessing |data_sources_|. + static base::Lock delete_lock_; -// Register our special URL handler under our special URL scheme. -// Must be done once at startup. -void RegisterURLRequestChromeJob(); + // |data_sources_| that are no longer referenced and scheduled for deletion. + static DataSources* data_sources_; -// Undoes the registration done by RegisterURLRequestChromeJob. -void UnregisterURLRequestChromeJob(); + DISALLOW_COPY_AND_ASSIGN(ChromeURLDataManager); +}; #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 new file mode 100644 index 0000000..0048828 --- /dev/null +++ b/chrome/browser/dom_ui/chrome_url_data_manager_backend.cc @@ -0,0 +1,393 @@ +// 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 new file mode 100644 index 0000000..fe900bc --- /dev/null +++ b/chrome/browser/dom_ui/chrome_url_data_manager_backend.h @@ -0,0 +1,99 @@ +// 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 8631c8d..4e21b29 100644 --- a/chrome/browser/dom_ui/conflicts_ui.cc +++ b/chrome/browser/dom_ui/conflicts_ui.cc @@ -14,6 +14,7 @@ #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" @@ -202,11 +203,7 @@ ConflictsUI::ConflictsUI(TabContents* contents) : DOMUI(contents) { ConflictsUIHTMLSource* html_source = new ConflictsUIHTMLSource(); // Set up the about:conflicts source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/downloads_dom_handler.cc b/chrome/browser/dom_ui/downloads_dom_handler.cc index c6a22ec..82badc9 100644 --- a/chrome/browser/dom_ui/downloads_dom_handler.cc +++ b/chrome/browser/dom_ui/downloads_dom_handler.cc @@ -22,6 +22,7 @@ #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" @@ -51,12 +52,8 @@ DownloadsDOMHandler::DownloadsDOMHandler(DownloadManager* dlm) download_manager_(dlm), callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { // Create our fileicon data source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new FileIconSource()))); + dlm->profile()->GetChromeURLDataManager()->AddDataSource( + new FileIconSource()); } DownloadsDOMHandler::~DownloadsDOMHandler() { diff --git a/chrome/browser/dom_ui/downloads_ui.cc b/chrome/browser/dom_ui/downloads_ui.cc index 63b1b153..2fadd47 100644 --- a/chrome/browser/dom_ui/downloads_ui.cc +++ b/chrome/browser/dom_ui/downloads_ui.cc @@ -14,6 +14,7 @@ #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" @@ -134,11 +135,7 @@ DownloadsUI::DownloadsUI(TabContents* contents) : DOMUI(contents) { DownloadsUIHTMLSource* html_source = new DownloadsUIHTMLSource(); // Set up the chrome://downloads/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index 08dceb3..81dddb2 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -422,13 +422,9 @@ 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); } @@ -1139,12 +1135,7 @@ FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) { FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource(); // Set up the chrome://filebrowse/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/flags_ui.cc b/chrome/browser/dom_ui/flags_ui.cc index d57dc3b..b301673 100644 --- a/chrome/browser/dom_ui/flags_ui.cc +++ b/chrome/browser/dom_ui/flags_ui.cc @@ -14,6 +14,8 @@ #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" @@ -180,11 +182,7 @@ FlagsUI::FlagsUI(TabContents* contents) : DOMUI(contents) { FlagsUIHTMLSource* html_source = new FlagsUIHTMLSource(); // Set up the about:flags source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/gpu_internals_ui.cc b/chrome/browser/dom_ui/gpu_internals_ui.cc index c37a071..9948264 100644 --- a/chrome/browser/dom_ui/gpu_internals_ui.cc +++ b/chrome/browser/dom_ui/gpu_internals_ui.cc @@ -29,6 +29,8 @@ #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" @@ -307,9 +309,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", ""); @@ -365,11 +367,6 @@ GpuInternalsUI::GpuInternalsUI(TabContents* contents) : DOMUI(contents) { GpuHTMLSource* html_source = new GpuHTMLSource(); // Set up the chrome://gpu/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/history2_ui.cc b/chrome/browser/dom_ui/history2_ui.cc index bdfe536..aaf7fdc 100644 --- a/chrome/browser/dom_ui/history2_ui.cc +++ b/chrome/browser/dom_ui/history2_ui.cc @@ -129,12 +129,9 @@ BrowsingHistoryHandler2::~BrowsingHistoryHandler2() { WebUIMessageHandler* BrowsingHistoryHandler2::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* profile = dom_ui->GetProfile(); + profile->GetChromeURLDataManager()->AddDataSource( + new WebUIFavIconSource(profile)); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, @@ -400,12 +397,7 @@ HistoryUI2::HistoryUI2(TabContents* contents) : DOMUI(contents) { HistoryUIHTMLSource2* html_source = new HistoryUIHTMLSource2(); // Set up the chrome://history2/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/history_ui.cc b/chrome/browser/dom_ui/history_ui.cc index 2013256..80be7d3 100644 --- a/chrome/browser/dom_ui/history_ui.cc +++ b/chrome/browser/dom_ui/history_ui.cc @@ -129,16 +129,13 @@ BrowsingHistoryHandler::~BrowsingHistoryHandler() { WebUIMessageHandler* BrowsingHistoryHandler::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* profile = dom_ui->GetProfile(); + profile->GetChromeURLDataManager()->AddDataSource( + new WebUIFavIconSource(profile)); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(dom_ui->GetProfile()->GetOriginalProfile())); + Source<Profile>(profile->GetOriginalProfile())); return WebUIMessageHandler::Attach(dom_ui); } @@ -388,12 +385,7 @@ HistoryUI::HistoryUI(TabContents* contents) : DOMUI(contents) { HistoryUIHTMLSource* html_source = new HistoryUIHTMLSource(); // Set up the chrome://history/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/dom_ui/keyboard_ui.cc b/chrome/browser/dom_ui/keyboard_ui.cc index 413cb0d..375acd1 100644 --- a/chrome/browser/dom_ui/keyboard_ui.cc +++ b/chrome/browser/dom_ui/keyboard_ui.cc @@ -9,6 +9,7 @@ #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" @@ -19,12 +20,7 @@ KeyboardUI::KeyboardUI(TabContents* contents) : DOMUI(contents) { KeyboardHTMLSource* html_source = new KeyboardHTMLSource(); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } KeyboardUI::~KeyboardUI() { diff --git a/chrome/browser/dom_ui/mediaplayer_ui.cc b/chrome/browser/dom_ui/mediaplayer_ui.cc index 8b2b300..858d6d8 100644 --- a/chrome/browser/dom_ui/mediaplayer_ui.cc +++ b/chrome/browser/dom_ui/mediaplayer_ui.cc @@ -209,12 +209,9 @@ MediaplayerHandler::~MediaplayerHandler() { WebUIMessageHandler* MediaplayerHandler::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* profile = dom_ui->GetProfile(); + profile->GetChromeURLDataManager()->AddDataSource( + new WebUIFavIconSource(profile)); return WebUIMessageHandler::Attach(dom_ui); } @@ -612,10 +609,5 @@ MediaplayerUI::MediaplayerUI(TabContents* contents) : DOMUI(contents) { new MediaplayerUIHTMLSource(is_playlist); // Set up the chrome://mediaplayer/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/most_visited_handler.cc b/chrome/browser/dom_ui/most_visited_handler.cc index 9bf80c2..7e9e61e 100644 --- a/chrome/browser/dom_ui/most_visited_handler.cc +++ b/chrome/browser/dom_ui/most_visited_handler.cc @@ -64,30 +64,21 @@ MostVisitedHandler::~MostVisitedHandler() { } WebUIMessageHandler* MostVisitedHandler::Attach(DOMUI* dom_ui) { - url_blacklist_ = dom_ui->GetProfile()->GetPrefs()-> - GetMutableDictionary(prefs::kNTPMostVisitedURLsBlacklist); - pinned_urls_ = dom_ui->GetProfile()->GetPrefs()-> - GetMutableDictionary(prefs::kNTPMostVisitedPinnedURLs); + Profile* profile = dom_ui->GetProfile(); + url_blacklist_ = profile->GetPrefs()->GetMutableDictionary( + prefs::kNTPMostVisitedURLsBlacklist); + pinned_urls_ = profile->GetPrefs()->GetMutableDictionary( + prefs::kNTPMostVisitedPinnedURLs); // Set up our sources for thumbnail and favicon data. - 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))); + WebUIThumbnailSource* thumbnail_src = new WebUIThumbnailSource(profile); + profile->GetChromeURLDataManager()->AddDataSource(thumbnail_src); + + WebUIFavIconSource* favicon_src = new WebUIFavIconSource(profile); + profile->GetChromeURLDataManager()->AddDataSource(favicon_src); // Get notifications when history is cleared. registrar_.Add(this, NotificationType::HISTORY_URLS_DELETED, - Source<Profile>(dom_ui->GetProfile())); + Source<Profile>(profile)); 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 8296623..00e4ce3 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,10 +1162,5 @@ NetInternalsUI::NetInternalsUI(TabContents* contents) : DOMUI(contents) { NetInternalsHTMLSource* html_source = new NetInternalsHTMLSource(); // Set up the chrome://net-internals/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index ad95bca..d4f6174 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -332,12 +332,7 @@ NewTabUI::NewTabUI(TabContents* contents) InitializeCSSCaches(); NewTabHTMLSource* html_source = new NewTabHTMLSource(GetProfile()->GetOriginalProfile()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); // Listen for theme installation. registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, @@ -422,13 +417,9 @@ void NewTabUI::Observe(NotificationType type, } void NewTabUI::InitializeCSSCaches() { - WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(theme))); + Profile* profile = GetProfile(); + WebUIThemeSource* theme = new WebUIThemeSource(profile); + profile->GetChromeURLDataManager()->AddDataSource(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 83d5223..b8b1cb5 100644 --- a/chrome/browser/dom_ui/options/browser_options_handler.cc +++ b/chrome/browser/dom_ui/options/browser_options_handler.cc @@ -126,12 +126,8 @@ void BrowserOptionsHandler::Initialize() { Profile* profile = dom_ui_->GetProfile(); // Create our favicon data source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new WebUIFavIconSource(profile)))); + profile->GetChromeURLDataManager()->AddDataSource( + 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 2ae3772..24e83d9 100644 --- a/chrome/browser/dom_ui/options/options_ui.cc +++ b/chrome/browser/dom_ui/options/options_ui.cc @@ -193,25 +193,15 @@ OptionsUI::OptionsUI(TabContents* contents) new OptionsUIHTMLSource(localized_strings); // Set up the chrome://settings/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); // Set up the chrome://theme/ source. - WebUIThemeSource* theme = new WebUIThemeSource(GetProfile()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(theme))); + WebUIThemeSource* theme = new WebUIThemeSource(contents->profile()); + contents->profile()->GetChromeURLDataManager()->AddDataSource(theme); // Initialize the chrome://about/ source in case the user clicks the credits // link. - InitializeAboutDataSource(); + InitializeAboutDataSource(contents->profile()); } OptionsUI::~OptionsUI() { diff --git a/chrome/browser/dom_ui/plugins_ui.cc b/chrome/browser/dom_ui/plugins_ui.cc index 74980cb..b67397b 100644 --- a/chrome/browser/dom_ui/plugins_ui.cc +++ b/chrome/browser/dom_ui/plugins_ui.cc @@ -349,11 +349,7 @@ PluginsUI::PluginsUI(TabContents* contents) : DOMUI(contents) { PluginsUIHTMLSource* html_source = new PluginsUIHTMLSource(); // Set up the chrome://plugins/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/print_preview_ui.cc b/chrome/browser/dom_ui/print_preview_ui.cc index fd3476c..a52d173 100644 --- a/chrome/browser/dom_ui/print_preview_ui.cc +++ b/chrome/browser/dom_ui/print_preview_ui.cc @@ -8,6 +8,8 @@ #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), @@ -17,12 +19,7 @@ PrintPreviewUI::PrintPreviewUI(TabContents* contents) AddMessageHandler(handler->Attach(this)); // Set up the chrome://print/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - html_source_)); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source_); } PrintPreviewUI::~PrintPreviewUI() { diff --git a/chrome/browser/dom_ui/remoting_ui.cc b/chrome/browser/dom_ui/remoting_ui.cc index f3e0899..648b857 100644 --- a/chrome/browser/dom_ui/remoting_ui.cc +++ b/chrome/browser/dom_ui/remoting_ui.cc @@ -7,6 +7,8 @@ #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" @@ -64,11 +66,7 @@ RemotingUI::RemotingUI(TabContents* contents) : DOMUI(contents) { RemotingUIHTMLSource* html_source = new RemotingUIHTMLSource(); // Set up the chrome://remoting source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(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 4922f1e..167a67a 100644 --- a/chrome/browser/dom_ui/shared_resources_data_source.cc +++ b/chrome/browser/dom_ui/shared_resources_data_source.cc @@ -53,17 +53,6 @@ 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 a162b43..1aec881 100644 --- a/chrome/browser/dom_ui/shared_resources_data_source.h +++ b/chrome/browser/dom_ui/shared_resources_data_source.h @@ -18,8 +18,7 @@ class GURL; // A DataSource for chrome://resources/ URLs. class SharedResourcesDataSource : public ChromeURLDataManager::DataSource { public: - // Registers an instance of this data source with the ChromeUrlDataManager. - static void Register(); + SharedResourcesDataSource(); // Overridden from ChromeURLDataManager::DataSource: virtual void StartDataRequest(const std::string& path, @@ -28,7 +27,6 @@ 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 78a3965..105fd79 100644 --- a/chrome/browser/dom_ui/slideshow_ui.cc +++ b/chrome/browser/dom_ui/slideshow_ui.cc @@ -148,14 +148,10 @@ SlideshowHandler::~SlideshowHandler() { } WebUIMessageHandler* SlideshowHandler::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(); + // Create our favicon data source. + profile_->GetChromeURLDataManager()->AddDataSource( + new WebUIFavIconSource(profile_)); return WebUIMessageHandler::Attach(dom_ui); } @@ -284,10 +280,5 @@ SlideshowUI::SlideshowUI(TabContents* contents) : DOMUI(contents) { SlideshowUIHTMLSource* html_source = new SlideshowUIHTMLSource(); // Set up the chrome://slideshow/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/dom_ui/sync_internals_ui.cc b/chrome/browser/dom_ui/sync_internals_ui.cc index 0af9f0c..bf36c5f 100644 --- a/chrome/browser/dom_ui/sync_internals_ui.cc +++ b/chrome/browser/dom_ui/sync_internals_ui.cc @@ -30,12 +30,8 @@ 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. - (void)BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new SyncInternalsHTMLSource()))); + contents->profile()->GetChromeURLDataManager()->AddDataSource( + new SyncInternalsHTMLSource()); } SyncInternalsUI::~SyncInternalsUI() { diff --git a/chrome/browser/dom_ui/textfields_ui.cc b/chrome/browser/dom_ui/textfields_ui.cc index 7d75aaa..cca22c9 100644 --- a/chrome/browser/dom_ui/textfields_ui.cc +++ b/chrome/browser/dom_ui/textfields_ui.cc @@ -11,6 +11,8 @@ #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" @@ -68,9 +70,5 @@ TextfieldsUI::TextfieldsUI(TabContents* contents) : DOMUI(contents) { TextfieldsUIHTMLSource* html_source = new TextfieldsUIHTMLSource(); // Set up the chrome://textfields/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 839b341..3d6f4d4 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -391,11 +391,7 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher( // ChromeURLDataManager. if (extension->HasHostPermission(GURL(chrome::kChromeUIFavIconURL))) { WebUIFavIconSource* favicon_source = new WebUIFavIconSource(profile_); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(favicon_source))); + profile_->GetChromeURLDataManager()->AddDataSource(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 087102c..c0406dd 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -959,12 +959,7 @@ ExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) { ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource(); // Set up the chrome://extensions/ source. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod( - ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(html_source))); + contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); } // static diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index e42ae2d..573ffdc 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -11,6 +11,7 @@ #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" @@ -732,6 +733,13 @@ 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 5d57b46..943b0fd 100644 --- a/chrome/browser/net/chrome_url_request_context.h +++ b/chrome/browser/net/chrome_url_request_context.h @@ -40,6 +40,7 @@ class DnsCertProvenanceChecker; class NetworkDelegate; } +class ChromeURLDataManagerBackend; class ChromeURLRequestContext; class ChromeURLRequestContextFactory; @@ -102,6 +103,8 @@ class ChromeURLRequestContext : public net::URLRequestContext { return prerender_manager_.get(); } + ChromeURLDataManagerBackend* GetChromeURLDataManagerBackend(); + protected: virtual ~ChromeURLRequestContext(); @@ -191,6 +194,7 @@ 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 52e4739..0e2f79d 100644 --- a/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc +++ b/chrome/browser/printing/cloud_print/cloud_print_setup_flow.cc @@ -88,11 +88,8 @@ CloudPrintSetupFlow::CloudPrintSetupFlow(const std::string& args, delegate_(delegate) { // TODO(hclam): The data source should be added once. profile_ = profile; - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new CloudPrintSetupSource()))); + profile->GetChromeURLDataManager()->AddDataSource( + new CloudPrintSetupSource()); } CloudPrintSetupFlow::~CloudPrintSetupFlow() { diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 85c71ad..0c59310 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -17,6 +17,7 @@ #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" @@ -630,6 +631,12 @@ 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; } @@ -719,6 +726,8 @@ 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 976eacd..2f09b1c 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 ChromeURLRequestContextGetter; +class ChromeURLDataManager; class CloudPrintProxyService; class DesktopNotificationService; class DownloadManager; @@ -497,6 +497,9 @@ 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 aa8fabf..d3c633d 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -26,6 +26,7 @@ #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" @@ -1372,6 +1373,12 @@ 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 acc0d5b..d65e7b6 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -131,6 +131,7 @@ 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); @@ -306,6 +307,8 @@ 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 2d5811d..918855a 100644 --- a/chrome/browser/remoting/setup_flow.cc +++ b/chrome/browser/remoting/setup_flow.cc @@ -115,18 +115,16 @@ 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. - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(new RemotingResourcesSource()))); + profile->GetChromeURLDataManager()->AddDataSource( + 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 f843159..99e9ede 100644 --- a/chrome/browser/sync/profile_sync_service_mock.cc +++ b/chrome/browser/sync/profile_sync_service_mock.cc @@ -9,6 +9,4 @@ 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 2cb6b7e..632d60d 100644 --- a/chrome/browser/sync/sync_setup_wizard.cc +++ b/chrome/browser/sync/sync_setup_wizard.cc @@ -260,19 +260,14 @@ 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. Avoid + // If we're in a unit test, we may not have an IO thread or profile. Avoid // creating a SyncResourcesSource since we may leak it (since it's // DeleteOnUIThread). - if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { + if (BrowserThread::IsMessageLoopValid(BrowserThread::IO) && + service_->profile()) { // Add our network layer data source for 'cloudy' URLs. SyncResourcesSource* sync_source = new SyncResourcesSource(); - bool posted = - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - NewRunnableMethod(ChromeURLDataManager::GetInstance(), - &ChromeURLDataManager::AddDataSource, - make_scoped_refptr(sync_source))); - DCHECK(posted); + service_->profile()->GetChromeURLDataManager()->AddDataSource(sync_source); } } diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc index 7122170..96dd2c909 100644 --- a/chrome/browser/sync/sync_ui_util_unittest.cc +++ b/chrome/browser/sync/sync_ui_util_unittest.cc @@ -3,6 +3,7 @@ // 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" @@ -12,6 +13,8 @@ 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 a2df005..2113459 100644 --- a/chrome/browser/tab_contents/render_view_host_manager_unittest.cc +++ b/chrome/browser/tab_contents/render_view_host_manager_unittest.cc @@ -275,6 +275,7 @@ 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 fac8d4f..ea4e102 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -855,6 +855,8 @@ '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 e7102df..6cfec31 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -16,6 +16,7 @@ #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" @@ -49,6 +50,7 @@ #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 @@ -759,6 +761,12 @@ 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 ee16eb6..c32b44e 100644 --- a/chrome/test/testing_profile.h +++ b/chrome/test/testing_profile.h @@ -273,6 +273,7 @@ class TestingProfile : public Profile { virtual ExtensionInfoMap* GetExtensionInfoMap(); virtual PromoCounter* GetInstantPromoCounter(); virtual policy::ProfilePolicyContext* GetPolicyContext(); + virtual ChromeURLDataManager* GetChromeURLDataManager(); virtual PrerenderManager* GetPrerenderManager(); virtual PrefService* GetOffTheRecordPrefs(); @@ -381,6 +382,8 @@ 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 |