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