Home | History | Annotate | Download | only in ntp
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/webui/ntp/ntp_resource_cache.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/command_line.h"
     11 #include "base/memory/ref_counted_memory.h"
     12 #include "base/prefs/pref_service.h"
     13 #include "base/strings/string16.h"
     14 #include "base/strings/string_number_conversions.h"
     15 #include "base/strings/stringprintf.h"
     16 #include "base/strings/utf_string_conversions.h"
     17 #include "base/values.h"
     18 #include "chrome/browser/browser_process.h"
     19 #include "chrome/browser/chrome_notification_types.h"
     20 #include "chrome/browser/first_run/first_run.h"
     21 #include "chrome/browser/profiles/profile.h"
     22 #include "chrome/browser/search/search.h"
     23 #include "chrome/browser/sync/profile_sync_service.h"
     24 #include "chrome/browser/sync/profile_sync_service_factory.h"
     25 #include "chrome/browser/themes/theme_properties.h"
     26 #include "chrome/browser/themes/theme_service.h"
     27 #include "chrome/browser/themes/theme_service_factory.h"
     28 #include "chrome/browser/ui/app_list/app_list_util.h"
     29 #include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h"
     30 #include "chrome/browser/ui/sync/sync_promo_ui.h"
     31 #include "chrome/browser/ui/webui/ntp/new_tab_page_handler.h"
     32 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
     33 #include "chrome/browser/ui/webui/ntp/ntp_login_handler.h"
     34 #include "chrome/browser/ui/webui/sync_setup_handler.h"
     35 #include "chrome/browser/web_resource/notification_promo.h"
     36 #include "chrome/common/chrome_switches.h"
     37 #include "chrome/common/extensions/extension_constants.h"
     38 #include "chrome/common/pref_names.h"
     39 #include "chrome/common/url_constants.h"
     40 #include "components/google/core/browser/google_util.h"
     41 #include "content/public/browser/browser_thread.h"
     42 #include "content/public/browser/notification_service.h"
     43 #include "content/public/browser/render_process_host.h"
     44 #include "extensions/common/extension.h"
     45 #include "grit/browser_resources.h"
     46 #include "grit/chromium_strings.h"
     47 #include "grit/generated_resources.h"
     48 #include "grit/locale_settings.h"
     49 #include "grit/theme_resources.h"
     50 #include "ui/base/l10n/l10n_util.h"
     51 #include "ui/base/resource/resource_bundle.h"
     52 #include "ui/base/theme_provider.h"
     53 #include "ui/base/webui/jstemplate_builder.h"
     54 #include "ui/base/webui/web_ui_util.h"
     55 #include "ui/gfx/animation/animation.h"
     56 #include "ui/gfx/color_utils.h"
     57 #include "ui/gfx/sys_color_change_listener.h"
     58 
     59 #if defined(OS_CHROMEOS)
     60 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     61 #include "chromeos/chromeos_switches.h"
     62 #endif
     63 
     64 #if defined(OS_MACOSX)
     65 #include "chrome/browser/platform_util.h"
     66 #endif
     67 
     68 using content::BrowserThread;
     69 
     70 namespace {
     71 
     72 // The URL for the the Learn More page shown on incognito new tab.
     73 const char kLearnMoreIncognitoUrl[] =
     74 #if defined(OS_CHROMEOS)
     75     "https://www.google.com/support/chromeos/bin/answer.py?answer=95464";
     76 #else
     77     "https://www.google.com/support/chrome/bin/answer.py?answer=95464";
     78 #endif
     79 
     80 // The URL for the Learn More page shown on guest session new tab.
     81 const char kLearnMoreGuestSessionUrl[] =
     82     "https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
     83 
     84 std::string SkColorToRGBAString(SkColor color) {
     85   // We convert the alpha using DoubleToString because StringPrintf will use
     86   // locale specific formatters (e.g., use , instead of . in German).
     87   return base::StringPrintf(
     88       "rgba(%d,%d,%d,%s)",
     89       SkColorGetR(color),
     90       SkColorGetG(color),
     91       SkColorGetB(color),
     92       base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
     93 }
     94 
     95 // Creates an rgb string for an SkColor, but leaves the alpha blank so that the
     96 // css can fill it in.
     97 std::string SkColorToRGBComponents(SkColor color) {
     98   return base::StringPrintf(
     99       "%d,%d,%d",
    100       SkColorGetR(color),
    101       SkColorGetG(color),
    102       SkColorGetB(color));
    103 }
    104 
    105 SkColor GetThemeColor(ui::ThemeProvider* tp, int id) {
    106   SkColor color = tp->GetColor(id);
    107   // If web contents are being inverted because the system is in high-contrast
    108   // mode, any system theme colors we use must be inverted too to cancel out.
    109   return gfx::IsInvertedColorScheme() ?
    110       color_utils::InvertColor(color) : color;
    111 }
    112 
    113 // Get the CSS string for the background position on the new tab page for the
    114 // states when the bar is attached or detached.
    115 std::string GetNewTabBackgroundCSS(const ui::ThemeProvider* theme_provider,
    116                                    bool bar_attached) {
    117   // TODO(glen): This is a quick workaround to hide the notused.png image when
    118   // no image is provided - we don't have time right now to figure out why
    119   // this is painting as white.
    120   // http://crbug.com/17593
    121   if (!theme_provider->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) {
    122     return "-64px";
    123   }
    124 
    125   int alignment = theme_provider->GetDisplayProperty(
    126       ThemeProperties::NTP_BACKGROUND_ALIGNMENT);
    127 
    128   if (bar_attached)
    129     return ThemeProperties::AlignmentToString(alignment);
    130 
    131   if (alignment & ThemeProperties::ALIGN_TOP) {
    132     // The bar is detached, so we must offset the background by the bar size
    133     // if it's a top-aligned bar.
    134     int offset = chrome::kNTPBookmarkBarHeight;
    135 
    136     if (alignment & ThemeProperties::ALIGN_LEFT)
    137       return "left " + base::IntToString(-offset) + "px";
    138     else if (alignment & ThemeProperties::ALIGN_RIGHT)
    139       return "right " + base::IntToString(-offset) + "px";
    140     return "center " + base::IntToString(-offset) + "px";
    141   }
    142 
    143   return ThemeProperties::AlignmentToString(alignment);
    144 }
    145 
    146 // How the background image on the new tab page should be tiled (see tiling
    147 // masks in theme_service.h).
    148 std::string GetNewTabBackgroundTilingCSS(
    149     const ui::ThemeProvider* theme_provider) {
    150   int repeat_mode = theme_provider->GetDisplayProperty(
    151       ThemeProperties::NTP_BACKGROUND_TILING);
    152   return ThemeProperties::TilingToString(repeat_mode);
    153 }
    154 
    155 }  // namespace
    156 
    157 NTPResourceCache::NTPResourceCache(Profile* profile)
    158     : profile_(profile), is_swipe_tracking_from_scroll_events_enabled_(false),
    159       should_show_apps_page_(NewTabUI::ShouldShowApps()),
    160       should_show_most_visited_page_(true),
    161       should_show_other_devices_menu_(true),
    162       should_show_recently_closed_menu_(true) {
    163   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
    164                  content::Source<ThemeService>(
    165                      ThemeServiceFactory::GetForProfile(profile)));
    166   registrar_.Add(this, chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED,
    167                  content::NotificationService::AllSources());
    168 
    169   base::Closure callback = base::Bind(&NTPResourceCache::OnPreferenceChanged,
    170                                       base::Unretained(this));
    171 
    172   // Watch for pref changes that cause us to need to invalidate the HTML cache.
    173   profile_pref_change_registrar_.Init(profile_->GetPrefs());
    174   profile_pref_change_registrar_.Add(prefs::kShowBookmarkBar, callback);
    175   profile_pref_change_registrar_.Add(prefs::kNtpShownPage, callback);
    176   profile_pref_change_registrar_.Add(prefs::kSignInPromoShowNTPBubble,
    177                                      callback);
    178   profile_pref_change_registrar_.Add(prefs::kHideWebStoreIcon, callback);
    179 
    180   // Some tests don't have a local state.
    181 #if defined(ENABLE_APP_LIST)
    182   if (g_browser_process->local_state()) {
    183     local_state_pref_change_registrar_.Init(g_browser_process->local_state());
    184     local_state_pref_change_registrar_.Add(prefs::kShowAppLauncherPromo,
    185                                            callback);
    186     local_state_pref_change_registrar_.Add(
    187         prefs::kAppLauncherHasBeenEnabled, callback);
    188   }
    189 #endif
    190 }
    191 
    192 NTPResourceCache::~NTPResourceCache() {}
    193 
    194 bool NTPResourceCache::NewTabCacheNeedsRefresh() {
    195 #if defined(OS_MACOSX)
    196   // Invalidate if the current value is different from the cached value.
    197   bool is_enabled = platform_util::IsSwipeTrackingFromScrollEventsEnabled();
    198   if (is_enabled != is_swipe_tracking_from_scroll_events_enabled_) {
    199     is_swipe_tracking_from_scroll_events_enabled_ = is_enabled;
    200     return true;
    201   }
    202 #endif
    203   bool should_show_apps_page = NewTabUI::ShouldShowApps();
    204   if (should_show_apps_page != should_show_apps_page_) {
    205     should_show_apps_page_ = should_show_apps_page;
    206     return true;
    207   }
    208   return false;
    209 }
    210 
    211 NTPResourceCache::WindowType NTPResourceCache::GetWindowType(
    212     Profile* profile, content::RenderProcessHost* render_host) {
    213   if (profile->IsGuestSession()) {
    214     return NTPResourceCache::GUEST;
    215   } else if (render_host) {
    216     // Sometimes the |profile| is the parent (non-incognito) version of the user
    217     // so we check the |render_host| if it is provided.
    218     if (render_host->GetBrowserContext()->IsOffTheRecord())
    219       return NTPResourceCache::INCOGNITO;
    220   } else if (profile->IsOffTheRecord()) {
    221     return NTPResourceCache::INCOGNITO;
    222   }
    223   return NTPResourceCache::NORMAL;
    224 }
    225 
    226 base::RefCountedMemory* NTPResourceCache::GetNewTabHTML(WindowType win_type) {
    227   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    228   if (win_type == GUEST) {
    229     if (!new_tab_guest_html_.get())
    230       CreateNewTabGuestHTML();
    231     return new_tab_guest_html_.get();
    232   } else if (win_type == INCOGNITO) {
    233     if (!new_tab_incognito_html_.get())
    234       CreateNewTabIncognitoHTML();
    235     return new_tab_incognito_html_.get();
    236   } else {
    237     // Refresh the cached HTML if necessary.
    238     // NOTE: NewTabCacheNeedsRefresh() must be called every time the new tab
    239     // HTML is fetched, because it needs to initialize cached values.
    240     if (NewTabCacheNeedsRefresh() || !new_tab_html_.get())
    241       CreateNewTabHTML();
    242     return new_tab_html_.get();
    243   }
    244 }
    245 
    246 base::RefCountedMemory* NTPResourceCache::GetNewTabCSS(WindowType win_type) {
    247   DCHECK_CURRENTLY_ON(BrowserThread::UI);
    248   if (win_type == GUEST) {
    249     if (!new_tab_guest_css_.get())
    250       CreateNewTabGuestCSS();
    251     return new_tab_guest_css_.get();
    252   } else if (win_type == INCOGNITO) {
    253     if (!new_tab_incognito_css_.get())
    254       CreateNewTabIncognitoCSS();
    255     return new_tab_incognito_css_.get();
    256   } else {
    257     if (!new_tab_css_.get())
    258       CreateNewTabCSS();
    259     return new_tab_css_.get();
    260   }
    261 }
    262 
    263 void NTPResourceCache::Observe(int type,
    264                                const content::NotificationSource& source,
    265                                const content::NotificationDetails& details) {
    266   // Invalidate the cache.
    267   if (chrome::NOTIFICATION_BROWSER_THEME_CHANGED == type ||
    268       chrome::NOTIFICATION_PROMO_RESOURCE_STATE_CHANGED == type) {
    269     new_tab_incognito_html_ = NULL;
    270     new_tab_html_ = NULL;
    271     new_tab_incognito_css_ = NULL;
    272     new_tab_css_ = NULL;
    273   } else {
    274     NOTREACHED();
    275   }
    276 }
    277 
    278 void NTPResourceCache::OnPreferenceChanged() {
    279   // A change occurred to one of the preferences we care about, so flush the
    280   // cache.
    281   new_tab_incognito_html_ = NULL;
    282   new_tab_html_ = NULL;
    283   new_tab_css_ = NULL;
    284 }
    285 
    286 void NTPResourceCache::CreateNewTabIncognitoHTML() {
    287   base::DictionaryValue localized_strings;
    288   localized_strings.SetString("title",
    289       l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
    290   int new_tab_description_ids = IDS_NEW_TAB_OTR_DESCRIPTION;
    291   int new_tab_heading_ids = IDS_NEW_TAB_OTR_HEADING;
    292   int new_tab_link_ids = IDS_NEW_TAB_OTR_LEARN_MORE_LINK;
    293   int new_tab_warning_ids = IDS_NEW_TAB_OTR_MESSAGE_WARNING;
    294   int new_tab_html_idr = IDR_INCOGNITO_TAB_HTML;
    295   const char* new_tab_link = kLearnMoreIncognitoUrl;
    296 
    297   if (profile_->IsGuestSession()) {
    298     localized_strings.SetString("guestTabDescription",
    299         l10n_util::GetStringUTF16(new_tab_description_ids));
    300     localized_strings.SetString("guestTabHeading",
    301         l10n_util::GetStringUTF16(new_tab_heading_ids));
    302   } else {
    303     localized_strings.SetString("incognitoTabDescription",
    304         l10n_util::GetStringUTF16(new_tab_description_ids));
    305     localized_strings.SetString("incognitoTabHeading",
    306         l10n_util::GetStringUTF16(new_tab_heading_ids));
    307     localized_strings.SetString("incognitoTabWarning",
    308         l10n_util::GetStringUTF16(new_tab_warning_ids));
    309   }
    310 
    311   localized_strings.SetString("learnMore",
    312       l10n_util::GetStringUTF16(new_tab_link_ids));
    313   localized_strings.SetString("learnMoreLink", new_tab_link);
    314 
    315   bool bookmark_bar_attached = profile_->GetPrefs()->GetBoolean(
    316       prefs::kShowBookmarkBar);
    317   localized_strings.SetBoolean("bookmarkbarattached", bookmark_bar_attached);
    318 
    319   webui::SetFontAndTextDirection(&localized_strings);
    320 
    321   static const base::StringPiece incognito_tab_html(
    322       ResourceBundle::GetSharedInstance().GetRawDataResource(
    323           new_tab_html_idr));
    324 
    325   std::string full_html = webui::GetI18nTemplateHtml(
    326       incognito_tab_html, &localized_strings);
    327 
    328   new_tab_incognito_html_ = base::RefCountedString::TakeString(&full_html);
    329 }
    330 
    331 void NTPResourceCache::CreateNewTabGuestHTML() {
    332   base::DictionaryValue localized_strings;
    333   localized_strings.SetString("title",
    334       l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
    335   const char* guest_tab_link = kLearnMoreGuestSessionUrl;
    336   int guest_tab_ids = IDR_GUEST_TAB_HTML;
    337   int guest_tab_description_ids = IDS_NEW_TAB_GUEST_SESSION_DESCRIPTION;
    338   int guest_tab_heading_ids = IDS_NEW_TAB_GUEST_SESSION_HEADING;
    339   int guest_tab_link_ids = IDS_NEW_TAB_GUEST_SESSION_LEARN_MORE_LINK;
    340 
    341 #if defined(OS_CHROMEOS)
    342   guest_tab_ids = IDR_GUEST_SESSION_TAB_HTML;
    343   guest_tab_link = kLearnMoreGuestSessionUrl;
    344 
    345   policy::BrowserPolicyConnectorChromeOS* connector =
    346       g_browser_process->platform_part()->browser_policy_connector_chromeos();
    347   std::string enterprise_domain = connector->GetEnterpriseDomain();
    348 
    349   if (!enterprise_domain.empty()) {
    350     // Device is enterprise enrolled.
    351     localized_strings.SetString("enterpriseInfoVisible", "true");
    352     base::string16 enterprise_info = l10n_util::GetStringFUTF16(
    353         IDS_DEVICE_OWNED_BY_NOTICE,
    354         base::UTF8ToUTF16(enterprise_domain));
    355     localized_strings.SetString("enterpriseInfoMessage", enterprise_info);
    356     localized_strings.SetString("enterpriseLearnMore",
    357         l10n_util::GetStringUTF16(IDS_LEARN_MORE));
    358     localized_strings.SetString("enterpriseInfoHintLink",
    359                                 chrome::kLearnMoreEnterpriseURL);
    360   } else {
    361     localized_strings.SetString("enterpriseInfoVisible", "false");
    362   }
    363 #endif
    364 
    365   localized_strings.SetString("guestTabDescription",
    366       l10n_util::GetStringUTF16(guest_tab_description_ids));
    367   localized_strings.SetString("guestTabHeading",
    368       l10n_util::GetStringUTF16(guest_tab_heading_ids));
    369   localized_strings.SetString("learnMore",
    370       l10n_util::GetStringUTF16(guest_tab_link_ids));
    371   localized_strings.SetString("learnMoreLink", guest_tab_link);
    372 
    373   webui::SetFontAndTextDirection(&localized_strings);
    374 
    375   static const base::StringPiece guest_tab_html(
    376       ResourceBundle::GetSharedInstance().GetRawDataResource(guest_tab_ids));
    377 
    378   std::string full_html = webui::GetI18nTemplateHtml(
    379       guest_tab_html, &localized_strings);
    380 
    381   new_tab_guest_html_ = base::RefCountedString::TakeString(&full_html);
    382 }
    383 
    384 void NTPResourceCache::CreateNewTabHTML() {
    385   // TODO(estade): these strings should be defined in their relevant handlers
    386   // (in GetLocalizedValues) and should have more legible names.
    387   // Show the profile name in the title and most visited labels if the current
    388   // profile is not the default.
    389   PrefService* prefs = profile_->GetPrefs();
    390   base::DictionaryValue load_time_data;
    391   load_time_data.SetBoolean("bookmarkbarattached",
    392       prefs->GetBoolean(prefs::kShowBookmarkBar));
    393   load_time_data.SetBoolean("hasattribution",
    394       ThemeServiceFactory::GetForProfile(profile_)->HasCustomImage(
    395           IDR_THEME_NTP_ATTRIBUTION));
    396   load_time_data.SetBoolean("showMostvisited", should_show_most_visited_page_);
    397   load_time_data.SetBoolean("showAppLauncherPromo",
    398       ShouldShowAppLauncherPromo());
    399   load_time_data.SetBoolean("showRecentlyClosed",
    400       should_show_recently_closed_menu_);
    401   load_time_data.SetString("title",
    402       l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE));
    403   load_time_data.SetString("mostvisited",
    404       l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED));
    405   load_time_data.SetString("suggestions",
    406       l10n_util::GetStringUTF16(IDS_NEW_TAB_SUGGESTIONS));
    407   load_time_data.SetString("restoreThumbnailsShort",
    408       l10n_util::GetStringUTF16(IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK));
    409   load_time_data.SetString("recentlyclosed",
    410       l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED));
    411   load_time_data.SetString("webStoreTitle",
    412       l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE));
    413   load_time_data.SetString("webStoreTitleShort",
    414       l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE_SHORT));
    415   load_time_data.SetString("closedwindowsingle",
    416       l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE));
    417   load_time_data.SetString("closedwindowmultiple",
    418       l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE));
    419   load_time_data.SetString("attributionintro",
    420       l10n_util::GetStringUTF16(IDS_NEW_TAB_ATTRIBUTION_INTRO));
    421   load_time_data.SetString("thumbnailremovednotification",
    422       l10n_util::GetStringUTF16(IDS_NEW_TAB_THUMBNAIL_REMOVED_NOTIFICATION));
    423   load_time_data.SetString("undothumbnailremove",
    424       l10n_util::GetStringUTF16(IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE));
    425   load_time_data.SetString("removethumbnailtooltip",
    426       l10n_util::GetStringUTF16(IDS_NEW_TAB_REMOVE_THUMBNAIL_TOOLTIP));
    427   load_time_data.SetString("appuninstall",
    428       l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL));
    429   load_time_data.SetString("appoptions",
    430       l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_OPTIONS));
    431   load_time_data.SetString("appdetails",
    432       l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_DETAILS));
    433   load_time_data.SetString("appcreateshortcut",
    434       l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_CREATE_SHORTCUT));
    435   load_time_data.SetString("appDefaultPageName",
    436       l10n_util::GetStringUTF16(IDS_APP_DEFAULT_PAGE_NAME));
    437   load_time_data.SetString("applaunchtypepinned",
    438       l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
    439   load_time_data.SetString("applaunchtyperegular",
    440       l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
    441   load_time_data.SetString("applaunchtypewindow",
    442       l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
    443   load_time_data.SetString("applaunchtypefullscreen",
    444       l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
    445   load_time_data.SetString("syncpromotext",
    446       l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL));
    447   load_time_data.SetString("syncLinkText",
    448       l10n_util::GetStringUTF16(IDS_SYNC_ADVANCED_OPTIONS));
    449   load_time_data.SetBoolean("shouldShowSyncLogin",
    450                             NTPLoginHandler::ShouldShow(profile_));
    451   load_time_data.SetString("otherSessions",
    452       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_LABEL));
    453   load_time_data.SetString("otherSessionsEmpty",
    454       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_EMPTY));
    455   load_time_data.SetString("otherSessionsLearnMoreUrl",
    456       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_LEARN_MORE_URL));
    457   load_time_data.SetString("learnMore",
    458       l10n_util::GetStringUTF16(IDS_LEARN_MORE));
    459   load_time_data.SetString("webStoreLink",
    460       google_util::AppendGoogleLocaleParam(
    461           GURL(extension_urls::GetWebstoreLaunchURL()),
    462           g_browser_process->GetApplicationLocale()).spec());
    463   load_time_data.SetString("appInstallHintText",
    464       l10n_util::GetStringUTF16(IDS_NEW_TAB_APP_INSTALL_HINT_LABEL));
    465   load_time_data.SetBoolean("isDiscoveryInNTPEnabled",
    466       NewTabUI::IsDiscoveryInNTPEnabled());
    467   load_time_data.SetString("collapseSessionMenuItemText",
    468       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_COLLAPSE_SESSION));
    469   load_time_data.SetString("expandSessionMenuItemText",
    470       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_EXPAND_SESSION));
    471   load_time_data.SetString("restoreSessionMenuItemText",
    472       l10n_util::GetStringUTF16(IDS_NEW_TAB_OTHER_SESSIONS_OPEN_ALL));
    473   load_time_data.SetString("learn_more",
    474       l10n_util::GetStringUTF16(IDS_LEARN_MORE));
    475   load_time_data.SetString("tile_grid_screenreader_accessible_description",
    476       l10n_util::GetStringUTF16(IDS_NEW_TAB_TILE_GRID_ACCESSIBLE_DESCRIPTION));
    477   load_time_data.SetString("page_switcher_change_title",
    478       l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_CHANGE_TITLE));
    479   load_time_data.SetString("page_switcher_same_title",
    480       l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_SWITCHER_SAME_TITLE));
    481   load_time_data.SetString("appsPromoTitle",
    482       l10n_util::GetStringUTF16(IDS_NEW_TAB_PAGE_APPS_PROMO_TITLE));
    483   // On Mac OS X 10.7+, horizontal scrolling can be treated as a back or
    484   // forward gesture. Pass through a flag that indicates whether or not that
    485   // feature is enabled.
    486   load_time_data.SetBoolean("isSwipeTrackingFromScrollEventsEnabled",
    487                             is_swipe_tracking_from_scroll_events_enabled_);
    488   // Supervised users can not have apps installed currently so there's no need
    489   // to show the app cards.
    490   if (profile_->IsSupervised())
    491     should_show_apps_page_ = false;
    492 
    493   load_time_data.SetBoolean("showApps", should_show_apps_page_);
    494   load_time_data.SetBoolean("showWebStoreIcon",
    495                             !prefs->GetBoolean(prefs::kHideWebStoreIcon));
    496 
    497   bool streamlined_hosted_apps = CommandLine::ForCurrentProcess()->HasSwitch(
    498       switches::kEnableStreamlinedHostedApps);
    499   load_time_data.SetBoolean("enableStreamlinedHostedApps",
    500                             streamlined_hosted_apps);
    501   // Use a different string for launching as a regular tab for streamlined
    502   // hosted apps.
    503   if (streamlined_hosted_apps) {
    504     load_time_data.SetString("applaunchtypetab",
    505         l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB));
    506   }
    507 
    508 #if defined(OS_CHROMEOS)
    509   load_time_data.SetString("expandMenu",
    510       l10n_util::GetStringUTF16(IDS_NEW_TAB_CLOSE_MENU_EXPAND));
    511 #endif
    512 
    513   NewTabPageHandler::GetLocalizedValues(profile_, &load_time_data);
    514   NTPLoginHandler::GetLocalizedValues(profile_, &load_time_data);
    515 
    516   webui::SetFontAndTextDirection(&load_time_data);
    517 
    518   // Control fade and resize animations.
    519   load_time_data.SetBoolean("anim",
    520                             gfx::Animation::ShouldRenderRichAnimation());
    521 
    522   ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
    523   int alignment = tp->GetDisplayProperty(
    524       ThemeProperties::NTP_BACKGROUND_ALIGNMENT);
    525   load_time_data.SetString("themegravity",
    526       (alignment & ThemeProperties::ALIGN_RIGHT) ? "right" : "");
    527 
    528   // Disable the promo if this is the first run, otherwise set the promo string
    529   // for display if there is a valid outstanding promo.
    530   if (first_run::IsChromeFirstRun()) {
    531     NotificationPromo::HandleClosed(NotificationPromo::NTP_NOTIFICATION_PROMO);
    532   } else {
    533     NotificationPromo notification_promo;
    534     notification_promo.InitFromPrefs(NotificationPromo::NTP_NOTIFICATION_PROMO);
    535     if (notification_promo.CanShow()) {
    536       load_time_data.SetString("notificationPromoText",
    537                                notification_promo.promo_text());
    538       DVLOG(1) << "Notification promo:" << notification_promo.promo_text();
    539     }
    540 
    541     NotificationPromo bubble_promo;
    542     bubble_promo.InitFromPrefs(NotificationPromo::NTP_BUBBLE_PROMO);
    543     if (bubble_promo.CanShow()) {
    544       load_time_data.SetString("bubblePromoText",
    545                                bubble_promo.promo_text());
    546       DVLOG(1) << "Bubble promo:" << bubble_promo.promo_text();
    547     }
    548   }
    549 
    550   // Determine whether to show the menu for accessing tabs on other devices.
    551   bool show_other_sessions_menu = should_show_other_devices_menu_ &&
    552       !CommandLine::ForCurrentProcess()->HasSwitch(
    553           switches::kDisableNTPOtherSessionsMenu);
    554   load_time_data.SetBoolean("showOtherSessionsMenu", show_other_sessions_menu);
    555   load_time_data.SetBoolean("isUserSignedIn",
    556       !prefs->GetString(prefs::kGoogleServicesUsername).empty());
    557 
    558   // Load the new tab page appropriate for this build.
    559   base::StringPiece new_tab_html(ResourceBundle::GetSharedInstance().
    560       GetRawDataResource(IDR_NEW_TAB_4_HTML));
    561   webui::UseVersion2 version2;
    562   std::string full_html =
    563       webui::GetI18nTemplateHtml(new_tab_html, &load_time_data);
    564   new_tab_html_ = base::RefCountedString::TakeString(&full_html);
    565 }
    566 
    567 void NTPResourceCache::CreateNewTabIncognitoCSS() {
    568   ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
    569   DCHECK(tp);
    570 
    571   // Get our theme colors
    572   SkColor color_background =
    573       GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
    574 
    575   // Generate the replacements.
    576   std::vector<std::string> subst;
    577 
    578   // Cache-buster for background.
    579   subst.push_back(
    580       profile_->GetPrefs()->GetString(prefs::kCurrentThemeID));  // $1
    581 
    582   // Colors.
    583   subst.push_back(SkColorToRGBAString(color_background));  // $2
    584   subst.push_back(GetNewTabBackgroundCSS(tp, false));  // $3
    585   subst.push_back(GetNewTabBackgroundCSS(tp, true));  // $4
    586   subst.push_back(GetNewTabBackgroundTilingCSS(tp));  // $5
    587 
    588   // Get our template.
    589   static const base::StringPiece new_tab_theme_css(
    590       ResourceBundle::GetSharedInstance().GetRawDataResource(
    591           IDR_NEW_INCOGNITO_TAB_THEME_CSS));
    592 
    593   // Create the string from our template and the replacements.
    594   std::string full_css = ReplaceStringPlaceholders(
    595       new_tab_theme_css, subst, NULL);
    596 
    597   new_tab_incognito_css_ = base::RefCountedString::TakeString(&full_css);
    598 }
    599 
    600 void NTPResourceCache::CreateNewTabGuestCSS() {
    601   ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
    602   DCHECK(tp);
    603 
    604   // Get our theme colors
    605   SkColor color_background =
    606       GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
    607 
    608   // Generate the replacements.
    609   std::vector<std::string> subst;
    610 
    611   // Cache-buster for background.
    612   subst.push_back(
    613       profile_->GetPrefs()->GetString(prefs::kCurrentThemeID));  // $1
    614 
    615   // Colors.
    616   subst.push_back(SkColorToRGBAString(color_background));  // $2
    617   subst.push_back(GetNewTabBackgroundCSS(tp, false));  // $3
    618   subst.push_back(GetNewTabBackgroundCSS(tp, true));  // $4
    619   subst.push_back(GetNewTabBackgroundTilingCSS(tp));  // $5
    620 
    621   // Get our template.
    622   static const base::StringPiece new_tab_theme_css(
    623       ResourceBundle::GetSharedInstance().GetRawDataResource(
    624           IDR_NEW_GUEST_TAB_THEME_CSS));
    625 
    626   // Create the string from our template and the replacements.
    627   std::string full_css = ReplaceStringPlaceholders(
    628       new_tab_theme_css, subst, NULL);
    629 
    630   new_tab_guest_css_ = base::RefCountedString::TakeString(&full_css);
    631 }
    632 
    633 void NTPResourceCache::CreateNewTabCSS() {
    634   ui::ThemeProvider* tp = ThemeServiceFactory::GetForProfile(profile_);
    635   DCHECK(tp);
    636 
    637   // Get our theme colors
    638   SkColor color_background =
    639       GetThemeColor(tp, ThemeProperties::COLOR_NTP_BACKGROUND);
    640   SkColor color_text = GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT);
    641   SkColor color_link = GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK);
    642   SkColor color_link_underline =
    643       GetThemeColor(tp, ThemeProperties::COLOR_NTP_LINK_UNDERLINE);
    644 
    645   SkColor color_section =
    646       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION);
    647   SkColor color_section_text =
    648       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_TEXT);
    649   SkColor color_section_link =
    650       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_LINK);
    651   SkColor color_section_link_underline =
    652       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_LINK_UNDERLINE);
    653   SkColor color_section_header_text =
    654       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT);
    655   SkColor color_section_header_text_hover =
    656       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_TEXT_HOVER);
    657   SkColor color_section_header_rule =
    658       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE);
    659   SkColor color_section_header_rule_light =
    660       GetThemeColor(tp, ThemeProperties::COLOR_NTP_SECTION_HEADER_RULE_LIGHT);
    661   SkColor color_text_light =
    662       GetThemeColor(tp, ThemeProperties::COLOR_NTP_TEXT_LIGHT);
    663 
    664   SkColor color_header =
    665       GetThemeColor(tp, ThemeProperties::COLOR_NTP_HEADER);
    666   // Generate a lighter color for the header gradients.
    667   color_utils::HSL header_lighter;
    668   color_utils::SkColorToHSL(color_header, &header_lighter);
    669   header_lighter.l += (1 - header_lighter.l) * 0.33;
    670   SkColor color_header_gradient_light =
    671       color_utils::HSLToSkColor(header_lighter, SkColorGetA(color_header));
    672 
    673   // Generate section border color from the header color. See
    674   // BookmarkBarView::Paint for how we do this for the bookmark bar
    675   // borders.
    676   SkColor color_section_border =
    677       SkColorSetARGB(80,
    678                      SkColorGetR(color_header),
    679                      SkColorGetG(color_header),
    680                      SkColorGetB(color_header));
    681 
    682   // Generate the replacements.
    683   std::vector<std::string> subst;
    684 
    685   // Cache-buster for background.
    686   subst.push_back(
    687       profile_->GetPrefs()->GetString(prefs::kCurrentThemeID));  // $1
    688 
    689   // Colors.
    690   subst.push_back(SkColorToRGBAString(color_background));  // $2
    691   subst.push_back(GetNewTabBackgroundCSS(tp, false));  // $3
    692   subst.push_back(GetNewTabBackgroundCSS(tp, true));  // $4
    693   subst.push_back(GetNewTabBackgroundTilingCSS(tp));  // $5
    694   subst.push_back(SkColorToRGBAString(color_header));  // $6
    695   subst.push_back(SkColorToRGBAString(color_header_gradient_light));  // $7
    696   subst.push_back(SkColorToRGBAString(color_text));  // $8
    697   subst.push_back(SkColorToRGBAString(color_link));  // $9
    698   subst.push_back(SkColorToRGBAString(color_section));  // $10
    699   subst.push_back(SkColorToRGBAString(color_section_border));  // $11
    700   subst.push_back(SkColorToRGBAString(color_section_text));  // $12
    701   subst.push_back(SkColorToRGBAString(color_section_link));  // $13
    702   subst.push_back(SkColorToRGBAString(color_link_underline));  // $14
    703   subst.push_back(SkColorToRGBAString(color_section_link_underline));  // $15
    704   subst.push_back(SkColorToRGBAString(color_section_header_text));  // $16
    705   subst.push_back(SkColorToRGBAString(
    706       color_section_header_text_hover));  // $17
    707   subst.push_back(SkColorToRGBAString(color_section_header_rule));  // $18
    708   subst.push_back(SkColorToRGBAString(
    709       color_section_header_rule_light));  // $19
    710   subst.push_back(SkColorToRGBAString(
    711       SkColorSetA(color_section_header_rule, 0)));  // $20
    712   subst.push_back(SkColorToRGBAString(color_text_light));  // $21
    713   subst.push_back(SkColorToRGBComponents(color_section_border));  // $22
    714   subst.push_back(SkColorToRGBComponents(color_text));  // $23
    715 
    716   // Get our template.
    717   static const base::StringPiece new_tab_theme_css(
    718       ResourceBundle::GetSharedInstance().GetRawDataResource(
    719           IDR_NEW_TAB_4_THEME_CSS));
    720 
    721   // Create the string from our template and the replacements.
    722   std::string css_string;
    723   css_string = ReplaceStringPlaceholders(new_tab_theme_css, subst, NULL);
    724   new_tab_css_ = base::RefCountedString::TakeString(&css_string);
    725 }
    726