This source file includes following definitions.
- GetHtmlTextDirection
- showing_sync_bubble_
- PaintTimeout
- StartTimingPaint
- RenderViewCreated
- RenderViewReused
- WasHidden
- Observe
- EmitNtpStatistics
- OnShowBookmarkBarChanged
- RegisterProfilePrefs
- MightShowApps
- ShouldShowApps
- IsDiscoveryInNTPEnabled
- SetUrlTitleAndDirection
- SetFullNameAndDirection
- FromWebUIController
- GetProfile
- GetSource
- StartDataRequest
- GetMimeType
- ShouldReplaceExistingSource
- ShouldAddContentSecurityPolicy
- AddResource
#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
#include <set>
#include "base/i18n/rtl.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
#include "chrome/browser/ui/webui/ntp/favicon_webui_handler.h"
#include "chrome/browser/ui/webui/ntp/foreign_session_handler.h"
#include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
#include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h"
#include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
#include "chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/url_data_source.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "grit/browser_resources.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#if !defined(OS_ANDROID)
#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
#include "chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.h"
#include "chrome/browser/ui/webui/ntp/ntp_login_handler.h"
#include "chrome/browser/ui/webui/ntp/suggestions_page_handler.h"
#else
#include "chrome/browser/ui/webui/ntp/android/bookmarks_handler.h"
#include "chrome/browser/ui/webui/ntp/android/context_menu_handler.h"
#include "chrome/browser/ui/webui/ntp/android/navigation_handler.h"
#include "chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.h"
#include "chrome/browser/ui/webui/ntp/android/promo_handler.h"
#endif
#if defined(ENABLE_THEMES)
#include "chrome/browser/ui/webui/theme_handler.h"
#endif
#if defined(USE_ASH)
#include "chrome/browser/ui/host_desktop.h"
#endif
using content::BrowserThread;
using content::RenderViewHost;
using content::WebUIController;
namespace {
const int kTimeoutMs = 2000;
const char kRTLHtmlTextDirection[] = "rtl";
const char kLTRHtmlTextDirection[] = "ltr";
static base::LazyInstance<std::set<const WebUIController*> > g_live_new_tabs;
const char* GetHtmlTextDirection(const base::string16& text) {
if (base::i18n::IsRTL() && base::i18n::StringContainsStrongRTLChars(text))
return kRTLHtmlTextDirection;
else
return kLTRHtmlTextDirection;
}
}
NewTabUI::NewTabUI(content::WebUI* web_ui)
: WebUIController(web_ui),
WebContentsObserver(web_ui->GetWebContents()),
showing_sync_bubble_(false) {
g_live_new_tabs.Pointer()->insert(this);
web_ui->OverrideTitle(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
web_ui->SetLinkTransitionType(content::PAGE_TRANSITION_AUTO_BOOKMARK);
if (!GetProfile()->IsOffTheRecord()) {
web_ui->AddMessageHandler(new browser_sync::ForeignSessionHandler());
web_ui->AddMessageHandler(new MetricsHandler());
web_ui->AddMessageHandler(new MostVisitedHandler());
web_ui->AddMessageHandler(new RecentlyClosedTabsHandler());
#if !defined(OS_ANDROID)
web_ui->AddMessageHandler(new FaviconWebUIHandler());
web_ui->AddMessageHandler(new NewTabPageHandler());
web_ui->AddMessageHandler(new CoreAppLauncherHandler());
if (NewTabUI::IsDiscoveryInNTPEnabled())
web_ui->AddMessageHandler(new SuggestionsHandler());
web_ui->AddMessageHandler(new NewTabPageSyncHandler());
if (MightShowApps()) {
ExtensionService* service = GetProfile()->GetExtensionService();
if (service)
web_ui->AddMessageHandler(new AppLauncherHandler(service));
}
#endif
}
#if defined(OS_ANDROID)
web_ui->AddMessageHandler(new BookmarksHandler());
web_ui->AddMessageHandler(new ContextMenuHandler());
web_ui->AddMessageHandler(new FaviconWebUIHandler());
web_ui->AddMessageHandler(new NavigationHandler());
web_ui->AddMessageHandler(new NewTabPageReadyHandler());
if (!GetProfile()->IsOffTheRecord())
web_ui->AddMessageHandler(new PromoHandler());
#else
if (NTPLoginHandler::ShouldShow(GetProfile()))
web_ui->AddMessageHandler(new NTPLoginHandler());
#endif
#if defined(ENABLE_THEMES)
web_ui->AddMessageHandler(new ThemeHandler());
#endif
scoped_ptr<NewTabHTMLSource> html_source(new NewTabHTMLSource(
GetProfile()->GetOriginalProfile()));
html_source->AddResource("suggestions_page.css", "text/css",
NewTabUI::IsDiscoveryInNTPEnabled() ? IDR_SUGGESTIONS_PAGE_CSS : 0);
if (NewTabUI::IsDiscoveryInNTPEnabled()) {
html_source->AddResource("suggestions_page.js", "application/javascript",
IDR_SUGGESTIONS_PAGE_JS);
}
content::URLDataSource::Add(GetProfile(), html_source.release());
pref_change_registrar_.Init(GetProfile()->GetPrefs());
pref_change_registrar_.Add(prefs::kShowBookmarkBar,
base::Bind(&NewTabUI::OnShowBookmarkBarChanged,
base::Unretained(this)));
}
NewTabUI::~NewTabUI() {
g_live_new_tabs.Pointer()->erase(this);
}
void NewTabUI::PaintTimeout() {
base::TimeTicks now = base::TimeTicks::Now();
if ((now - last_paint_) >= base::TimeDelta::FromMilliseconds(kTimeoutMs)) {
base::TimeDelta load_time = last_paint_ - start_;
UMA_HISTOGRAM_TIMES("NewTabUI load", load_time);
} else {
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeoutMs), this,
&NewTabUI::PaintTimeout);
}
}
void NewTabUI::StartTimingPaint(RenderViewHost* render_view_host) {
start_ = base::TimeTicks::Now();
last_paint_ = start_;
content::NotificationSource source =
content::Source<content::RenderWidgetHost>(render_view_host);
if (!registrar_.IsRegistered(this,
content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
source)) {
registrar_.Add(
this,
content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
source);
}
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeoutMs), this,
&NewTabUI::PaintTimeout);
}
void NewTabUI::RenderViewCreated(RenderViewHost* render_view_host) {
StartTimingPaint(render_view_host);
}
void NewTabUI::RenderViewReused(RenderViewHost* render_view_host) {
StartTimingPaint(render_view_host);
}
void NewTabUI::WasHidden() {
EmitNtpStatistics();
}
void NewTabUI::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE: {
last_paint_ = base::TimeTicks::Now();
break;
}
default:
CHECK(false) << "Unexpected notification: " << type;
}
}
void NewTabUI::EmitNtpStatistics() {
NTPUserDataLogger::GetOrCreateFromWebContents(
web_contents())->EmitNtpStatistics();
}
void NewTabUI::OnShowBookmarkBarChanged() {
base::StringValue attached(
GetProfile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) ?
"true" : "false");
web_ui()->CallJavascriptFunction("ntp.setBookmarkBarAttached", attached);
}
void NewTabUI::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
#if !defined(OS_ANDROID)
CoreAppLauncherHandler::RegisterProfilePrefs(registry);
NewTabPageHandler::RegisterProfilePrefs(registry);
if (NewTabUI::IsDiscoveryInNTPEnabled())
SuggestionsHandler::RegisterProfilePrefs(registry);
#endif
MostVisitedHandler::RegisterProfilePrefs(registry);
browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry);
}
bool NewTabUI::MightShowApps() {
#if defined(OS_ANDROID)
return false;
#else
return true;
#endif
}
bool NewTabUI::ShouldShowApps() {
#if defined(OS_ANDROID)
return false;
#elif defined(USE_ASH)
return chrome::GetActiveDesktop() != chrome::HOST_DESKTOP_TYPE_ASH;
#else
return true;
#endif
}
bool NewTabUI::IsDiscoveryInNTPEnabled() {
return false;
}
void NewTabUI::SetUrlTitleAndDirection(base::DictionaryValue* dictionary,
const base::string16& title,
const GURL& gurl) {
dictionary->SetString("url", gurl.spec());
bool using_url_as_the_title = false;
base::string16 title_to_set(title);
if (title_to_set.empty()) {
using_url_as_the_title = true;
title_to_set = base::UTF8ToUTF16(gurl.spec());
}
std::string direction;
if (using_url_as_the_title)
direction = kLTRHtmlTextDirection;
else
direction = GetHtmlTextDirection(title);
dictionary->SetString("title", title_to_set);
dictionary->SetString("direction", direction);
}
void NewTabUI::SetFullNameAndDirection(const base::string16& full_name,
base::DictionaryValue* dictionary) {
dictionary->SetString("full_name", full_name);
dictionary->SetString("full_name_direction", GetHtmlTextDirection(full_name));
}
NewTabUI* NewTabUI::FromWebUIController(WebUIController* ui) {
if (!g_live_new_tabs.Pointer()->count(ui))
return NULL;
return static_cast<NewTabUI*>(ui);
}
Profile* NewTabUI::GetProfile() const {
return Profile::FromWebUI(web_ui());
}
NewTabUI::NewTabHTMLSource::NewTabHTMLSource(Profile* profile)
: profile_(profile) {
}
std::string NewTabUI::NewTabHTMLSource::GetSource() const {
return chrome::kChromeUINewTabHost;
}
void NewTabUI::NewTabHTMLSource::StartDataRequest(
const std::string& path,
int render_process_id,
int render_frame_id,
const content::URLDataSource::GotDataCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::map<std::string, std::pair<std::string, int> >::iterator it =
resource_map_.find(path);
if (it != resource_map_.end()) {
scoped_refptr<base::RefCountedStaticMemory> resource_bytes(
it->second.second ?
ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
it->second.second) :
new base::RefCountedStaticMemory);
callback.Run(resource_bytes.get());
return;
}
if (!path.empty() && path[0] != '#') {
#if !defined(OS_ANDROID)
NOTREACHED() << path << " should not have been requested on the NTP";
#endif
callback.Run(NULL);
return;
}
content::RenderProcessHost* render_host =
content::RenderProcessHost::FromID(render_process_id);
NTPResourceCache::WindowType win_type = NTPResourceCache::GetWindowType(
profile_, render_host);
scoped_refptr<base::RefCountedMemory> html_bytes(
NTPResourceCacheFactory::GetForProfile(profile_)->
GetNewTabHTML(win_type));
callback.Run(html_bytes.get());
}
std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string& resource)
const {
std::map<std::string, std::pair<std::string, int> >::const_iterator it =
resource_map_.find(resource);
if (it != resource_map_.end())
return it->second.first;
return "text/html";
}
bool NewTabUI::NewTabHTMLSource::ShouldReplaceExistingSource() const {
return false;
}
bool NewTabUI::NewTabHTMLSource::ShouldAddContentSecurityPolicy() const {
return false;
}
void NewTabUI::NewTabHTMLSource::AddResource(const char* resource,
const char* mime_type,
int resource_id) {
DCHECK(resource);
DCHECK(mime_type);
resource_map_[std::string(resource)] =
std::make_pair(std::string(mime_type), resource_id);
}
NewTabUI::NewTabHTMLSource::~NewTabHTMLSource() {}