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
68using content::BrowserThread;
69
70namespace {
71
72// The URL for the the Learn More page shown on incognito new tab.
73const 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.
81const char kLearnMoreGuestSessionUrl[] =
82    "https://www.google.com/support/chromeos/bin/answer.py?answer=1057090";
83
84base::string16 GetUrlWithLang(const GURL& url) {
85  return ASCIIToUTF16(google_util::AppendGoogleLocaleParam(url).spec());
86}
87
88std::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.
101std::string SkColorToRGBComponents(SkColor color) {
102  return base::StringPrintf(
103      "%d,%d,%d",
104      SkColorGetR(color),
105      SkColorGetG(color),
106      SkColorGetB(color));
107}
108
109SkColor 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.
119std::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).
152std::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
161NTPResourceCache::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
198NTPResourceCache::~NTPResourceCache() {}
199
200bool 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
217NTPResourceCache::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
232base::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
252base::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
269void 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
284void 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
292void 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
349void 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
370void 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
557void 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
590void 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
623void 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