summaryrefslogtreecommitdiffstats
path: root/chrome/browser/dom_ui
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/dom_ui')
-rw-r--r--chrome/browser/dom_ui/chrome_url_data_manager.cc24
-rw-r--r--chrome/browser/dom_ui/chrome_url_data_manager.h13
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.cc52
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.h23
-rw-r--r--chrome/browser/dom_ui/new_tab_ui.cc122
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);
}
///////////////////////////////////////////////////////////////////////////////