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