diff options
Diffstat (limited to 'chrome/browser/dom_ui')
-rw-r--r-- | chrome/browser/dom_ui/chrome_url_data_manager.cc | 24 | ||||
-rw-r--r-- | chrome/browser/dom_ui/chrome_url_data_manager.h | 13 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_theme_source.cc | 52 | ||||
-rw-r--r-- | chrome/browser/dom_ui/dom_ui_theme_source.h | 23 | ||||
-rw-r--r-- | chrome/browser/dom_ui/new_tab_ui.cc | 122 |
5 files changed, 167 insertions, 67 deletions
diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.cc b/chrome/browser/dom_ui/chrome_url_data_manager.cc index d605fe3..4e3bd43 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.cc +++ b/chrome/browser/dom_ui/chrome_url_data_manager.cc @@ -12,6 +12,7 @@ #include "base/thread.h" #include "base/values.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_thread.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/ref_counted_util.h" #include "chrome/common/url_constants.h" @@ -225,9 +226,19 @@ bool ChromeURLDataManager::StartRequest(const GURL& url, job->SetMimeType(source->GetMimeType(path)); // Forward along the request to the data source. - source->message_loop()->PostTask(FROM_HERE, - NewRunnableMethod(source, &DataSource::StartDataRequest, - path, request_id)); + 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, 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, request_id)); + } return true; } @@ -261,12 +272,17 @@ void ChromeURLDataManager::DataAvailable( void ChromeURLDataManager::DataSource::SendResponse( RequestID request_id, RefCountedBytes* bytes) { - g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, + ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(FROM_HERE, NewRunnableMethod(&chrome_url_data_manager, &ChromeURLDataManager::DataAvailable, request_id, scoped_refptr<RefCountedBytes>(bytes))); } +MessageLoop* ChromeURLDataManager::DataSource::MessageLoopForRequestPath( + const std::string& path) const { + return message_loop_; +} + // static void ChromeURLDataManager::DataSource::SetFontAndTextDirection( DictionaryValue* localized_strings) { diff --git a/chrome/browser/dom_ui/chrome_url_data_manager.h b/chrome/browser/dom_ui/chrome_url_data_manager.h index 49e8fd1..81f220c 100644 --- a/chrome/browser/dom_ui/chrome_url_data_manager.h +++ b/chrome/browser/dom_ui/chrome_url_data_manager.h @@ -59,7 +59,18 @@ class ChromeURLDataManager { // the request is over. void SendResponse(int request_id, RefCountedBytes* bytes); - MessageLoop* message_loop() const { return message_loop_; } + // Returns the MessageLoop on which the DataSource wishes to have + // StartDataRequest called to handle the request for |path|. If the + // DataSource does not care which thread StartDataRequest is called on, + // this should return NULL. The default implementation always returns + // message_loop_, which generally results in processing on the UI thread. + // It may be beneficial to return NULL for requests that are safe to handle + // directly on the IO thread. This can improve performance by satisfying + // such requests more rapidly when there is a large amount of UI thread + // contention. + virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) + const; + const std::string& source_name() const { return source_name_; } static void SetFontAndTextDirection(DictionaryValue* localized_strings); diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.cc b/chrome/browser/dom_ui/dom_ui_theme_source.cc index 59f3485..f12dcba 100644 --- a/chrome/browser/dom_ui/dom_ui_theme_source.cc +++ b/chrome/browser/dom_ui/dom_ui_theme_source.cc @@ -50,6 +50,8 @@ static std::string StripQueryParams(const std::string& path) { DOMUIThemeSource::DOMUIThemeSource(Profile* profile) : DataSource(chrome::kChromeUIThemePath, MessageLoop::current()), profile_(profile) { + InitNewTabCSS(); + InitNewIncognitoTabCSS(); } void DOMUIThemeSource::StartDataRequest(const std::string& path, @@ -57,11 +59,11 @@ void DOMUIThemeSource::StartDataRequest(const std::string& path, // Our path may include cachebuster arguments, so trim them off. std::string uncached_path = StripQueryParams(path); - if (strcmp(uncached_path.c_str(), kNewTabCSSPath) == 0) { - SendNewTabCSS(request_id); + if (uncached_path == kNewTabCSSPath) { + SendNewTabCSS(request_id, new_tab_css_); return; - } else if (strcmp(uncached_path.c_str(), kNewIncognitoTabCSSPath) == 0) { - SendNewIncognitoTabCSS(request_id); + } else if (uncached_path == kNewIncognitoTabCSSPath) { + SendNewTabCSS(request_id, new_incognito_tab_css_); return; } else { int resource_id = ThemeResourcesUtil::GetId(uncached_path); @@ -77,9 +79,11 @@ void DOMUIThemeSource::StartDataRequest(const std::string& path, std::string DOMUIThemeSource::GetMimeType(const std::string& path) const { std::string uncached_path = StripQueryParams(path); - if (strcmp(uncached_path.c_str(), kNewTabCSSPath) == 0 || - strcmp(uncached_path.c_str(), kNewIncognitoTabCSSPath) == 0) + if (uncached_path == kNewTabCSSPath || + uncached_path == kNewIncognitoTabCSSPath) { return "text/css"; + } + return "image/png"; } @@ -87,10 +91,27 @@ void DOMUIThemeSource::SendResponse(int request_id, RefCountedBytes* data) { ChromeURLDataManager::DataSource::SendResponse(request_id, data); } +MessageLoop* DOMUIThemeSource::MessageLoopForRequestPath( + const std::string& path) const { + std::string uncached_path = StripQueryParams(path); + + if (uncached_path == kNewTabCSSPath || + uncached_path == kNewIncognitoTabCSSPath) { + // All of the operations that need to be on the UI thread for these + // requests are performed in InitNewTabCSS and InitNewIncognitoTabCSS, + // called by the constructor. It is safe to call StartDataRequest for + // these resources from any thread, so return NULL. + return NULL; + } + + // Superclass + return DataSource::MessageLoopForRequestPath(path); +} + //////////////////////////////////////////////////////////////////////////////// // DOMUIThemeSource, private: -void DOMUIThemeSource::SendNewTabCSS(int request_id) { +void DOMUIThemeSource::InitNewTabCSS() { ThemeProvider* tp = profile_->GetThemeProvider(); DCHECK(tp); @@ -161,19 +182,11 @@ void DOMUIThemeSource::SendNewTabCSS(int request_id) { string16 format_string = ASCIIToUTF16(new_tab_theme_css.as_string()); const std::string css_string = UTF16ToASCII(ReplaceStringPlaceholders( format_string, subst, NULL)); - const std::string css_string2 = UTF16ToASCII(ReplaceStringPlaceholders( + new_tab_css_ = UTF16ToASCII(ReplaceStringPlaceholders( ASCIIToUTF16(css_string), subst2, NULL)); - - // Convert to a format appropriate for sending. - scoped_refptr<RefCountedBytes> css_bytes(new RefCountedBytes); - css_bytes->data.resize(css_string2.size()); - std::copy(css_string2.begin(), css_string2.end(), css_bytes->data.begin()); - - // Send. - SendResponse(request_id, css_bytes); } -void DOMUIThemeSource::SendNewIncognitoTabCSS(int request_id) { +void DOMUIThemeSource::InitNewIncognitoTabCSS() { ThemeProvider* tp = profile_->GetThemeProvider(); DCHECK(tp); @@ -201,9 +214,12 @@ void DOMUIThemeSource::SendNewIncognitoTabCSS(int request_id) { // Create the string from our template and the replacements. string16 format_string = ASCIIToUTF16(new_tab_theme_css.as_string()); - const std::string css_string = UTF16ToASCII(ReplaceStringPlaceholders( + new_incognito_tab_css_ = UTF16ToASCII(ReplaceStringPlaceholders( format_string, subst, NULL)); +} +void DOMUIThemeSource::SendNewTabCSS(int request_id, + const std::string& css_string) { // Convert to a format appropriate for sending. scoped_refptr<RefCountedBytes> css_bytes(new RefCountedBytes); css_bytes->data.resize(css_string.size()); diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.h b/chrome/browser/dom_ui/dom_ui_theme_source.h index 47a59f8..fa90eba 100644 --- a/chrome/browser/dom_ui/dom_ui_theme_source.h +++ b/chrome/browser/dom_ui/dom_ui_theme_source.h @@ -24,12 +24,20 @@ class DOMUIThemeSource : public ChromeURLDataManager::DataSource { virtual void SendResponse(int request_id, RefCountedBytes* data); - private: - // Generate and send the CSS for the new tab. - void SendNewTabCSS(int request_id); + virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) const; - // Generate and send the CSS for the new incognito tab. - void SendNewIncognitoTabCSS(int request_id); + private: + // Populate new_tab_css_ and new_incognito_tab_css. These must be called + // from the UI thread because they involve profile and theme access. + // + // A new DOMUIThemeSource object is used for each new tab page instance + // and each reload of an existing new tab page, so there is no concern about + // cached data becoming stale. + void InitNewTabCSS(); + void InitNewIncognitoTabCSS(); + + // Send the CSS for the new tab or the new incognito tab. + void SendNewTabCSS(int request_id, const std::string& css_string); // Fetch and send the theme bitmap. void SendThemeBitmap(int request_id, int resource_id); @@ -42,6 +50,11 @@ class DOMUIThemeSource : public ChromeURLDataManager::DataSource { // masks in browser_theme_provider.h). std::string GetNewTabBackgroundTilingCSS(); + // The content to be served by SendNewTabCSS, stored by InitNewTabCSS and + // InitNewIncognitoTabCSS. + std::string new_tab_css_; + std::string new_incognito_tab_css_; + Profile* profile_; DISALLOW_COPY_AND_ASSIGN(DOMUIThemeSource); }; diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc index 95b976d..dfb97ba 100644 --- a/chrome/browser/dom_ui/new_tab_ui.cc +++ b/chrome/browser/dom_ui/new_tab_ui.cc @@ -200,6 +200,14 @@ class NewTabHTMLSource : public ChromeURLDataManager::DataSource { return "text/html"; } + virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) + const { + // NewTabHTMLSource does all of the operations that need to be on the + // UI thread from InitFullHTML, called by the constructor. It is safe + // to call StartDataRequest from any thread, so return NULL. + return NULL; + } + // Setters and getters for first_view. static void set_first_view(bool first_view) { first_view_ = first_view; } static bool first_view() { return first_view_; } @@ -214,6 +222,17 @@ class NewTabHTMLSource : public ChromeURLDataManager::DataSource { // string in case of failure. static std::string GetCustomNewTabPageFromCommandLine(); + // Populate full_html_. This must be called from the UI thread because it + // involves profile access. + // + // A new NewTabHTMLSource object is used for each new tab page instance + // and each reload of an existing new tab page, so there is no concern + // about cached data becoming stale. + void InitFullHTML(); + + // The content to be served by StartDataRequest, stored by InitFullHTML. + std::string full_html_; + // Whether this is the first viewing of the new tab page and // we think it is the user's startup page. static bool first_view_; @@ -234,6 +253,7 @@ bool NewTabHTMLSource::first_run_ = true; NewTabHTMLSource::NewTabHTMLSource(Profile* profile) : DataSource(chrome::kChromeUINewTabHost, MessageLoop::current()), profile_(profile) { + InitFullHTML(); } void NewTabHTMLSource::StartDataRequest(const std::string& path, @@ -245,6 +265,35 @@ void NewTabHTMLSource::StartDataRequest(const std::string& path, return; } + scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); + html_bytes->data.resize(full_html_.size()); + std::copy(full_html_.begin(), full_html_.end(), html_bytes->data.begin()); + + SendResponse(request_id, html_bytes); +} + +// static +std::string NewTabHTMLSource::GetCustomNewTabPageFromCommandLine() { + const CommandLine* command_line = CommandLine::ForCurrentProcess(); + const std::wstring file_path_wstring = command_line->GetSwitchValue( + switches::kNewTabPage); + +#if defined(OS_WIN) + const FilePath::StringType file_path = file_path_wstring; +#else + const FilePath::StringType file_path = WideToASCII(file_path_wstring); +#endif + + if (!file_path.empty()) { + std::string file_contents; + if (file_util::ReadFileToString(FilePath(file_path), &file_contents)) + return file_contents; + } + + return std::string(); +} + +void NewTabHTMLSource::InitFullHTML() { // Show the profile name in the title and most visited labels if the current // profile is not the default. std::wstring title; @@ -383,37 +432,10 @@ void NewTabHTMLSource::StartDataRequest(const std::string& path, IDR_NEW_NEW_TAB_HTML); } - std::string full_html(new_tab_html.data(), new_tab_html.size()); - jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html); - jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html); - jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html); - - scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); - html_bytes->data.resize(full_html.size()); - std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); - - SendResponse(request_id, html_bytes); -} - -// static -std::string NewTabHTMLSource::GetCustomNewTabPageFromCommandLine() { - const CommandLine* command_line = CommandLine::ForCurrentProcess(); - const std::wstring file_path_wstring = command_line->GetSwitchValue( - switches::kNewTabPage); - -#if defined(OS_WIN) - const FilePath::StringType file_path = file_path_wstring; -#else - const FilePath::StringType file_path = WideToASCII(file_path_wstring); -#endif - - if (!file_path.empty()) { - std::string file_contents; - if (file_util::ReadFileToString(FilePath(file_path), &file_contents)) - return file_contents; - } - - return std::string(); + full_html_.assign(new_tab_html.data(), new_tab_html.size()); + jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html_); + jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html_); + jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html_); } /////////////////////////////////////////////////////////////////////////////// @@ -432,7 +454,26 @@ class IncognitoTabHTMLSource : public ChromeURLDataManager::DataSource { return "text/html"; } + virtual MessageLoop* MessageLoopForRequestPath(const std::string& path) + const { + // IncognitoTabHTMLSource does all of the operations that need to be on + // the UI thread from InitFullHTML, called by the constructor. It is safe + // to call StartDataRequest from any thread, so return NULL. + return NULL; + } + private: + // Populate full_html_. This must be called from the UI thread because it + // involves profile access. + // + // A new IncognitoTabHTMLSource object is used for each incognito tab page + // instance and each reload of an existing incognito tab page, so there is + // no concern about cached data becoming stale. + void InitFullHTML(); + + // The content to be served by StartDataRequest, stored by InitFullHTML. + std::string full_html_; + bool bookmark_bar_attached_; DISALLOW_COPY_AND_ASSIGN(IncognitoTabHTMLSource); @@ -441,10 +482,19 @@ class IncognitoTabHTMLSource : public ChromeURLDataManager::DataSource { IncognitoTabHTMLSource::IncognitoTabHTMLSource(bool bookmark_bar_attached) : DataSource(chrome::kChromeUINewTabHost, MessageLoop::current()), bookmark_bar_attached_(bookmark_bar_attached) { + InitFullHTML(); } void IncognitoTabHTMLSource::StartDataRequest(const std::string& path, int request_id) { + scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); + html_bytes->data.resize(full_html_.size()); + std::copy(full_html_.begin(), full_html_.end(), html_bytes->data.begin()); + + SendResponse(request_id, html_bytes); +} + +void IncognitoTabHTMLSource::InitFullHTML() { DictionaryValue localized_strings; localized_strings.SetString(L"title", l10n_util::GetString(IDS_NEW_TAB_TITLE)); @@ -460,14 +510,8 @@ void IncognitoTabHTMLSource::StartDataRequest(const std::string& path, ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_INCOGNITO_TAB_HTML)); - const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( - incognito_tab_html, &localized_strings); - - scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); - html_bytes->data.resize(full_html.size()); - std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); - - SendResponse(request_id, html_bytes); + full_html_ = jstemplate_builder::GetI18nTemplateHtml(incognito_tab_html, + &localized_strings); } /////////////////////////////////////////////////////////////////////////////// |