new_tab_ui.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/metrics_handler.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/favicon_webui_handler.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/foreign_session_handler.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/most_visited_handler.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
239ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "chrome/browser/ui/webui/ntp/ntp_user_data_logger.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/url_data_source.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/new_tab_page_sync_handler.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/ntp_login_handler.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/suggestions_page_handler.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/android/bookmarks_handler.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/android/context_menu_handler.h"
49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/browser/ui/webui/ntp/android/navigation_handler.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/android/new_tab_page_ready_handler.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/android/promo_handler.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_THEMES)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/theme_handler.h"
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_ASH)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIController;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The amount of time there must be no painting for us to consider painting
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// finished.  Observed times are in the ~1200ms range on Windows.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTimeoutMs = 2000;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Strings sent to the page via jstemplates used to set the direction of the
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTML document based on locale.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRTLHtmlTextDirection[] = "rtl";
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLTRHtmlTextDirection[] = "ltr";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static base::LazyInstance<std::set<const WebUIController*> > g_live_new_tabs;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char* GetHtmlTextDirection(const base::string16& text) {
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (base::i18n::IsRTL() && base::i18n::StringContainsStrongRTLChars(text))
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return kRTLHtmlTextDirection;
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return kLTRHtmlTextDirection;
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NewTabUI
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NewTabUI::NewTabUI(content::WebUI* web_ui)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : WebUIController(web_ui),
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WebContentsObserver(web_ui->GetWebContents()),
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      showing_sync_bubble_(false) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_live_new_tabs.Pointer()->insert(this);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->OverrideTitle(l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We count all link clicks as AUTO_BOOKMARK, so that site can be ranked more
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // highly. Note this means we're including clicks on not only most visited
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thumbnails, but also clicks on recently bookmarked.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->SetLinkTransitionType(content::PAGE_TRANSITION_AUTO_BOOKMARK);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetProfile()->IsOffTheRecord()) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new browser_sync::ForeignSessionHandler());
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    web_ui->AddMessageHandler(new MetricsHandler());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new MostVisitedHandler());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new RecentlyClosedTabsHandler());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
109a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    web_ui->AddMessageHandler(new FaviconWebUIHandler());
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new NewTabPageHandler());
111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    web_ui->AddMessageHandler(new CoreAppLauncherHandler());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (NewTabUI::IsDiscoveryInNTPEnabled())
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_ui->AddMessageHandler(new SuggestionsHandler());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Android doesn't have a sync promo/username on NTP.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_ui->AddMessageHandler(new NewTabPageSyncHandler());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (MightShowApps()) {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionService* service = GetProfile()->GetExtensionService();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // We might not have an ExtensionService (on ChromeOS when not logged in
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // for example).
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (service)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        web_ui->AddMessageHandler(new AppLauncherHandler(service));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These handlers are specific to the Android NTP page.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->AddMessageHandler(new BookmarksHandler());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->AddMessageHandler(new ContextMenuHandler());
131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  web_ui->AddMessageHandler(new FaviconWebUIHandler());
132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  web_ui->AddMessageHandler(new NavigationHandler());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui->AddMessageHandler(new NewTabPageReadyHandler());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetProfile()->IsOffTheRecord())
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new PromoHandler());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Android uses native UI for sync setup.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NTPLoginHandler::ShouldShow(GetProfile()))
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_ui->AddMessageHandler(new NTPLoginHandler());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_THEMES)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The theme handler can require some CPU, so do it after hooking up the most
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // visited handler. This allows the DB query for the new tab thumbs to happen
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // earlier.
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_ui->AddMessageHandler(new ThemeHandler());
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<NewTabHTMLSource> html_source(new NewTabHTMLSource(
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetProfile()->GetOriginalProfile()));
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These two resources should be loaded only if suggestions NTP is enabled.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  html_source->AddResource("suggestions_page.css", "text/css",
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NewTabUI::IsDiscoveryInNTPEnabled() ? IDR_SUGGESTIONS_PAGE_CSS : 0);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NewTabUI::IsDiscoveryInNTPEnabled()) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    html_source->AddResource("suggestions_page.js", "application/javascript",
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_SUGGESTIONS_PAGE_JS);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // content::URLDataSource assumes the ownership of the html_source.
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::URLDataSource::Add(GetProfile(), html_source.release());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pref_change_registrar_.Init(GetProfile()->GetPrefs());
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pref_change_registrar_.Add(prefs::kShowBookmarkBar,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             base::Bind(&NewTabUI::OnShowBookmarkBarChanged,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        base::Unretained(this)));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NewTabUI::~NewTabUI() {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_live_new_tabs.Pointer()->erase(this);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The timer callback.  If enough time has elapsed since the last paint
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message, we say we're done painting; otherwise, we keep waiting.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::PaintTimeout() {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The amount of time there must be no painting for us to consider painting
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // finished.  Observed times are in the ~1200ms range on Windows.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks now = base::TimeTicks::Now();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((now - last_paint_) >= base::TimeDelta::FromMilliseconds(kTimeoutMs)) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Painting has quieted down.  Log this as the full time to run.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta load_time = last_paint_ - start_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int load_time_ms = static_cast<int>(load_time.InMilliseconds());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NotificationService::current()->Notify(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_INITIAL_NEW_TAB_UI_LOAD,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<Profile>(GetProfile()),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Details<int>(&load_time_ms));
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_TIMES("NewTabUI load", load_time);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Not enough quiet time has elapsed.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Some more paints must've occurred since we set the timeout.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wait some more.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeoutMs), this,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 &NewTabUI::PaintTimeout);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::StartTimingPaint(RenderViewHost* render_view_host) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  start_ = base::TimeTicks::Now();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_paint_ = start_;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationSource source =
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<content::RenderWidgetHost>(render_view_host);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!registrar_.IsRegistered(this,
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          source)) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimeoutMs), this,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               &NewTabUI::PaintTimeout);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::RenderViewCreated(RenderViewHost* render_view_host) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartTimingPaint(render_view_host);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::RenderViewReused(RenderViewHost* render_view_host) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartTimingPaint(render_view_host);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void NewTabUI::WasHidden() {
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EmitNtpStatistics();
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::Observe(int type,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE: {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_paint_ = base::TimeTicks::Now();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(false) << "Unexpected notification: " << type;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NewTabUI::EmitNtpStatistics() {
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NTPUserDataLogger::GetOrCreateFromWebContents(
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      web_contents())->EmitNtpStatistics();
2439ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch}
2449ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NewTabUI::OnShowBookmarkBarChanged() {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringValue attached(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetProfile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) ?
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "true" : "false");
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->CallJavascriptFunction("ntp.setBookmarkBarAttached", attached);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NewTabUI::RegisterProfilePrefs(
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    user_prefs::PrefRegistrySyncable* registry) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CoreAppLauncherHandler::RegisterProfilePrefs(registry);
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  NewTabPageHandler::RegisterProfilePrefs(registry);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (NewTabUI::IsDiscoveryInNTPEnabled())
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    SuggestionsHandler::RegisterProfilePrefs(registry);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  MostVisitedHandler::RegisterProfilePrefs(registry);
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool NewTabUI::MightShowApps() {
26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Android does not have apps.
26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_ANDROID)
26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return false;
27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#else
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NewTabUI::ShouldShowApps() {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Ash shows apps in app list thus should not show apps page in NTP4.
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Android does not have apps.
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#elif defined(USE_ASH)
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return chrome::GetActiveDesktop() != chrome::HOST_DESKTOP_TYPE_ASH;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NewTabUI::IsDiscoveryInNTPEnabled() {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(beaudoin): The flag was removed during a clean-up pass. We leave that
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here to easily enable it back when we will explore this option again.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::SetUrlTitleAndDirection(DictionaryValue* dictionary,
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const base::string16& title,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const GURL& gurl) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary->SetString("url", gurl.spec());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool using_url_as_the_title = false;
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 title_to_set(title);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (title_to_set.empty()) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    using_url_as_the_title = true;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    title_to_set = UTF8ToUTF16(gurl.spec());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We set the "dir" attribute of the title, so that in RTL locales, a LTR
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // title is rendered left-to-right and truncated from the right. For example,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the title of http://msdn.microsoft.com/en-us/default.aspx is "MSDN:
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Microsoft developer network". In RTL locales, in the [New Tab] page, if
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the "dir" of this title is not specified, it takes Chrome UI's
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // directionality. So the title will be truncated as "soft developer
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // network". Setting the "dir" attribute as "ltr" renders the truncated title
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as "MSDN: Microsoft D...". As another example, the title of
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://yahoo.com is "Yahoo!". In RTL locales, in the [New Tab] page, the
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // title will be rendered as "!Yahoo" if its "dir" attribute is not set to
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "ltr".
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string direction;
320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (using_url_as_the_title)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    direction = kLTRHtmlTextDirection;
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  else
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    direction = GetHtmlTextDirection(title);
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary->SetString("title", title_to_set);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dictionary->SetString("direction", direction);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void NewTabUI::SetFullNameAndDirection(const base::string16& full_name,
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                       base::DictionaryValue* dictionary) {
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  dictionary->SetString("full_name", full_name);
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  dictionary->SetString("full_name_direction", GetHtmlTextDirection(full_name));
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// static
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NewTabUI* NewTabUI::FromWebUIController(WebUIController* ui) {
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_live_new_tabs.Pointer()->count(ui))
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<NewTabUI*>(ui);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Profile* NewTabUI::GetProfile() const {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Profile::FromWebUI(web_ui());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NewTabHTMLSource
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NewTabUI::NewTabHTMLSource::NewTabHTMLSource(Profile* profile)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile) {
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string NewTabUI::NewTabHTMLSource::GetSource() const {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return chrome::kChromeUINewTabHost;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NewTabUI::NewTabHTMLSource::StartDataRequest(
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& path,
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_process_id,
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int render_view_id,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::URLDataSource::GotDataCallback& callback) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, std::pair<std::string, int> >::iterator it =
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resource_map_.find(path);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != resource_map_.end()) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::RefCountedStaticMemory> resource_bytes(
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        it->second.second ?
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ResourceBundle::GetSharedInstance().LoadDataResourceBytes(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                it->second.second) :
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            new base::RefCountedStaticMemory);
373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback.Run(resource_bytes.get());
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!path.empty() && path[0] != '#') {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A path under new-tab was requested; it's likely a bad relative
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // URL from the new tab page, but in any case it's an error.
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(dtrainor): Can remove this #if check once we update the
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // accessibility script to no longer try to access urls like
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // '?2314124523523'.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See http://crbug.com/150252.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << path << " should not have been requested on the NTP";
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(NULL);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::RenderProcessHost* render_host =
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::RenderProcessHost::FromID(render_process_id);
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  NTPResourceCache::WindowType win_type = NTPResourceCache::GetWindowType(
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      profile_, render_host);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedMemory> html_bytes(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NTPResourceCacheFactory::GetForProfile(profile_)->
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetNewTabHTML(win_type));
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback.Run(html_bytes.get());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string& resource)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, std::pair<std::string, int> >::const_iterator it =
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resource_map_.find(resource);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it != resource_map_.end())
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return it->second.first;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "text/html";
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NewTabUI::NewTabHTMLSource::ShouldReplaceExistingSource() const {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool NewTabUI::NewTabHTMLSource::ShouldAddContentSecurityPolicy() const {
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NewTabUI::NewTabHTMLSource::AddResource(const char* resource,
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             const char* mime_type,
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int resource_id) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(resource);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(mime_type);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resource_map_[std::string(resource)] =
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::make_pair(std::string(mime_type), resource_id);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NewTabUI::NewTabHTMLSource::~NewTabHTMLSource() {}
430