blob: 8238a6c003c2063122dc752b7aacdc63909cc1e4 [file] [log] [blame]
tmartinoe3f9c38e2016-09-13 14:05:321// Copyright 2016 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
Scott Chen532ec2c2018-09-26 21:50:055#include "chrome/browser/ui/webui/welcome/welcome_ui.h"
tmartinoe3f9c38e2016-09-13 14:05:326
Dan Beama896f662019-03-19 18:26:397#include <map>
Dan Beame3e79472019-03-15 01:23:338
9#include "base/bind.h"
Scott Chenf68c9b22018-10-12 02:15:2510#include "base/metrics/histogram_macros.h"
Dan Beame3e79472019-03-15 01:23:3311#include "base/stl_util.h"
Hector Carmonac98557a992018-06-27 17:51:4312#include "build/build_config.h"
David Rogerf53a0752018-06-18 14:46:4813#include "chrome/browser/signin/account_consistency_mode_manager.h"
Dan Beam18cd5972019-02-07 03:54:2914#include "chrome/browser/ui/webui/dark_mode_handler.h"
Lei Zhang0a1c1c72018-12-13 20:41:3315#include "chrome/browser/ui/webui/localized_string.h"
Hector Carmona207744f2018-10-25 23:49:5416#include "chrome/browser/ui/webui/welcome/nux/bookmark_handler.h"
Scott Chenf68c9b22018-10-12 02:15:2517#include "chrome/browser/ui/webui/welcome/nux/constants.h"
Scott Chenf68c9b22018-10-12 02:15:2518#include "chrome/browser/ui/webui/welcome/nux/google_apps_handler.h"
John Leeeba59092019-02-05 23:44:5819#include "chrome/browser/ui/webui/welcome/nux/ntp_background_handler.h"
Scott Chenf68c9b22018-10-12 02:15:2520#include "chrome/browser/ui/webui/welcome/nux/set_as_default_handler.h"
Scott Chenc74ed762018-09-21 00:23:1621#include "chrome/browser/ui/webui/welcome/nux_helper.h"
Scott Chen532ec2c2018-09-26 21:50:0522#include "chrome/browser/ui/webui/welcome/welcome_handler.h"
tmartino6254f472016-11-21 01:22:5623#include "chrome/common/pref_names.h"
tmartinoe3f9c38e2016-09-13 14:05:3224#include "chrome/grit/browser_resources.h"
25#include "chrome/grit/chrome_unscaled_resources.h"
26#include "chrome/grit/chromium_strings.h"
27#include "chrome/grit/generated_resources.h"
dpapadb1f8e9a2018-10-18 21:36:0828#include "chrome/grit/onboarding_welcome_resources.h"
29#include "chrome/grit/onboarding_welcome_resources_map.h"
tmartino6254f472016-11-21 01:22:5630#include "components/prefs/pref_service.h"
Hector Carmona7f52fab2019-04-18 23:31:2231#include "components/signin/core/browser/signin_pref_names.h"
Scott Chen395516b2018-10-23 00:05:4832#include "components/strings/grit/components_strings.h"
Scott Chenf68c9b22018-10-12 02:15:2533#include "content/public/browser/web_contents.h"
tmartino7f0818b2016-09-27 23:39:0734#include "net/base/url_util.h"
tmartinoe3f9c38e2016-09-13 14:05:3235#include "ui/base/l10n/l10n_util.h"
tmartinoe3f9c38e2016-09-13 14:05:3236
Scott Chene8414882018-10-30 03:14:3537#if defined(OS_WIN)
38#include "base/win/windows_version.h"
39#endif
40
Scott Chenc6706672017-11-17 17:40:2741namespace {
Dan Beama896f662019-03-19 18:26:3942
Scott Chen532ec2c2018-09-26 21:50:0543const bool kIsBranded =
Scott Chenc6706672017-11-17 17:40:2744#if defined(GOOGLE_CHROME_BUILD)
Scott Chen532ec2c2018-09-26 21:50:0545 true;
Scott Chenc6706672017-11-17 17:40:2746#else
Scott Chen532ec2c2018-09-26 21:50:0547 false;
Scott Chenc6706672017-11-17 17:40:2748#endif
Dan Beama896f662019-03-19 18:26:3949
50const char kPreviewBackgroundPath[] = "preview-background.jpg";
Scott Chenc6706672017-11-17 17:40:2751
dpapad28dccc442019-04-09 22:06:4052bool ShouldHandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,
53 const std::string& path) {
Dan Beama896f662019-03-19 18:26:3954 if (!base::StartsWith(path, kPreviewBackgroundPath,
John Lee6eb43ae2019-02-28 21:25:2655 base::CompareCase::SENSITIVE)) {
56 return false;
57 }
58
59 std::string index_param = path.substr(path.find_first_of("?") + 1);
60 int background_index = -1;
61 if (!base::StringToInt(index_param, &background_index) ||
62 background_index < 0) {
63 return false;
64 }
65
dpapad28dccc442019-04-09 22:06:4066 return !weak_ptr ? false : true;
67}
John Lee6eb43ae2019-02-28 21:25:2668
dpapad28dccc442019-04-09 22:06:4069void HandleRequestCallback(
70 base::WeakPtr<WelcomeUI> weak_ptr,
71 const std::string& path,
72 const content::WebUIDataSource::GotDataCallback& callback) {
73 DCHECK(ShouldHandleRequestCallback(weak_ptr, path));
74
75 std::string index_param = path.substr(path.find_first_of("?") + 1);
76 int background_index = -1;
77 CHECK(base::StringToInt(index_param, &background_index) ||
78 background_index < 0);
79
80 DCHECK(weak_ptr);
81 weak_ptr->CreateBackgroundFetcher(background_index, callback);
John Lee6eb43ae2019-02-28 21:25:2682}
83
Scott Chen395516b2018-10-23 00:05:4884void AddOnboardingStrings(content::WebUIDataSource* html_source) {
85 static constexpr LocalizedString kLocalizedStrings[] = {
86 // Shared strings.
Scott Chen395516b2018-10-23 00:05:4887 {"acceptText", IDS_WELCOME_ACCEPT_BUTTON},
Scott Chen395516b2018-10-23 00:05:4888 {"bookmarkAdded", IDS_ONBOARDING_WELCOME_BOOKMARK_ADDED},
Hector Carmona6d779282018-10-30 23:48:4089 {"bookmarksAdded", IDS_ONBOARDING_WELCOME_BOOKMARKS_ADDED},
Scott Chen395516b2018-10-23 00:05:4890 {"bookmarkRemoved", IDS_ONBOARDING_WELCOME_BOOKMARK_REMOVED},
Hector Carmona6d779282018-10-30 23:48:4091 {"bookmarksRemoved", IDS_ONBOARDING_WELCOME_BOOKMARKS_REMOVED},
Scott Chen395516b2018-10-23 00:05:4892 {"bookmarkReplaced", IDS_ONBOARDING_WELCOME_BOOKMARK_REPLACED},
Scott Chen5524784e2019-04-02 02:54:5893 {"defaultBrowserChanged", IDS_ONBOARDING_DEFAULT_BROWSER_CHANGED},
Scott Chenebfdce732018-10-26 02:34:2694 {"getStarted", IDS_ONBOARDING_WELCOME_GET_STARTED},
95 {"headerText", IDS_WELCOME_HEADER},
96 {"next", IDS_ONBOARDING_WELCOME_NEXT},
97 {"noThanks", IDS_NO_THANKS},
98 {"skip", IDS_ONBOARDING_WELCOME_SKIP},
Scott Chen395516b2018-10-23 00:05:4899
100 // Sign-in view strings.
101 {"signInHeader", IDS_ONBOARDING_WELCOME_SIGNIN_VIEW_HEADER},
102 {"signInSubHeader", IDS_ONBOARDING_WELCOME_SIGNIN_VIEW_SUB_HEADER},
103 {"signIn", IDS_ONBOARDING_WELCOME_SIGNIN_VIEW_SIGNIN},
104
Scott Chen395516b2018-10-23 00:05:48105 // Google apps module strings.
106 {"googleAppsDescription",
107 IDS_ONBOARDING_WELCOME_NUX_GOOGLE_APPS_DESCRIPTION},
108
John Lee0c3ede532019-01-30 02:58:50109 // New Tab Page background module strings.
110 {"ntpBackgroundDescription",
111 IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_DESCRIPTION},
John Leecea68d42019-02-12 20:02:57112 {"ntpBackgroundDefault",
113 IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_DEFAULT_TITLE},
John Lee10f19872019-03-11 21:28:50114 {"ntpBackgroundPreviewUpdated",
115 IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED},
John Leeb5d871e2019-03-12 03:30:18116 {"ntpBackgroundReset", IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_RESET},
John Lee0c3ede532019-01-30 02:58:50117
Scott Chen395516b2018-10-23 00:05:48118 // Set as default module strings.
119 {"setDefaultHeader", IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_HEADER},
120 {"setDefaultSubHeader",
121 IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_SUB_HEADER},
122 {"setDefaultSkip", IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_SKIP},
123 {"setDefaultConfirm",
124 IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_SET_AS_DEFAULT},
Scott Chen618035d2018-10-24 00:48:15125
126 // Landing view strings.
127 {"landingTitle", IDS_ONBOARDING_WELCOME_LANDING_TITLE},
128 {"landingDescription", IDS_ONBOARDING_WELCOME_LANDING_DESCRIPTION},
129 {"landingNewUser", IDS_ONBOARDING_WELCOME_LANDING_NEW_USER},
130 {"landingExistingUser", IDS_ONBOARDING_WELCOME_LANDING_EXISTING_USER},
Scott Chen395516b2018-10-23 00:05:48131 };
Lei Zhang0a1c1c72018-12-13 20:41:33132 AddLocalizedStringsBulk(html_source, kLocalizedStrings,
133 base::size(kLocalizedStrings));
Scott Chen395516b2018-10-23 00:05:48134}
135
Dan Beama896f662019-03-19 18:26:39136const std::map<std::string, bool>& GetGzipMap() {
137 static std::map<std::string, bool>* gzip_map = nullptr;
138 if (!gzip_map) {
139 gzip_map = new std::map<std::string, bool>();
140 for (size_t i = 0; i < kOnboardingWelcomeResourcesSize; ++i) {
141 (*gzip_map)[kOnboardingWelcomeResources[i].name] =
142 kOnboardingWelcomeResources[i].gzipped;
143 }
144 (*gzip_map)[kPreviewBackgroundPath] = false;
145 }
146 return *gzip_map;
147}
148
149} // namespace
150
tmartinoe3f9c38e2016-09-13 14:05:32151WelcomeUI::WelcomeUI(content::WebUI* web_ui, const GURL& url)
John Lee6eb43ae2019-02-28 21:25:26152 : content::WebUIController(web_ui), weak_ptr_factory_(this) {
tmartino7f0818b2016-09-27 23:39:07153 Profile* profile = Profile::FromWebUI(web_ui);
154
155 // This page is not shown to incognito or guest profiles. If one should end up
156 // here, we return, causing a 404-like page.
157 if (!profile ||
158 profile->GetProfileType() != Profile::ProfileType::REGULAR_PROFILE) {
159 return;
160 }
161
Scott Chenf68c9b22018-10-12 02:15:25162 StorePageSeen(profile);
tmartino6254f472016-11-21 01:22:56163
Jinho Bang7ab7a4e2018-01-15 14:36:07164 web_ui->AddMessageHandler(std::make_unique<WelcomeHandler>(web_ui));
tmartinoe3f9c38e2016-09-13 14:05:32165
166 content::WebUIDataSource* html_source =
167 content::WebUIDataSource::Create(url.host());
168
Dan Beam18cd5972019-02-07 03:54:29169 DarkModeHandler::Initialize(web_ui, html_source);
170
Scott Chenc6706672017-11-17 17:40:27171 // There are multiple possible configurations that affects the layout, but
172 // first add resources that are shared across all layouts.
tmartinoe3f9c38e2016-09-13 14:05:32173 html_source->AddResourcePath("logo.png", IDR_PRODUCT_LOGO_128);
174 html_source->AddResourcePath("logo2x.png", IDR_PRODUCT_LOGO_256);
Scott Chena1264452017-11-14 13:32:08175
Dan Beama896f662019-03-19 18:26:39176 if (nux::IsNuxOnboardingEnabled(profile)) {
Scott Chenc74ed762018-09-21 00:23:16177 // Add Onboarding welcome strings.
Scott Chen395516b2018-10-23 00:05:48178 AddOnboardingStrings(html_source);
Scott Chenc74ed762018-09-21 00:23:16179
dpapadb1f8e9a2018-10-18 21:36:08180 // Add all Onboarding resources.
181 for (size_t i = 0; i < kOnboardingWelcomeResourcesSize; ++i) {
182 html_source->AddResourcePath(kOnboardingWelcomeResources[i].name,
183 kOnboardingWelcomeResources[i].value);
184 }
Scott Chenaac2e182018-10-23 01:49:44185
186 // chrome://welcome
Scott Chenc74ed762018-09-21 00:23:16187 html_source->SetDefaultResource(
188 IDR_WELCOME_ONBOARDING_WELCOME_WELCOME_HTML);
Scott Chenf68c9b22018-10-12 02:15:25189
Scott Chene8414882018-10-30 03:14:35190#if defined(OS_WIN)
191 html_source->AddBoolean(
192 "is_win10", base::win::GetVersion() >= base::win::VERSION_WIN10);
193#endif
194
Hector Carmona207744f2018-10-25 23:49:54195 // Add the shared bookmark handler for onboarding modules.
196 web_ui->AddMessageHandler(
197 std::make_unique<nux::BookmarkHandler>(profile->GetPrefs()));
Hector Carmona207744f2018-10-25 23:49:54198
Scott Chenf68c9b22018-10-12 02:15:25199 // Add google apps bookmarking onboarding module.
Scott Chen3bb4c578362018-10-31 00:23:31200 web_ui->AddMessageHandler(std::make_unique<nux::GoogleAppsHandler>());
Scott Chenf68c9b22018-10-12 02:15:25201
John Leeeba59092019-02-05 23:44:58202 // Add NTP custom background onboarding module.
203 web_ui->AddMessageHandler(std::make_unique<nux::NtpBackgroundHandler>());
204
Scott Chenf68c9b22018-10-12 02:15:25205 // Add set-as-default onboarding module.
206 web_ui->AddMessageHandler(std::make_unique<nux::SetAsDefaultHandler>());
Scott Chen00858242018-11-01 23:40:47207
208 html_source->AddString(
Scott Chen7243c1a2018-11-06 01:33:41209 "newUserModules",
Scott Chen00858242018-11-01 23:40:47210 nux::GetNuxOnboardingModules(profile).FindKey("new-user")->GetString());
Scott Chen7243c1a2018-11-06 01:33:41211 html_source->AddString("returningUserModules",
Scott Chen00858242018-11-01 23:40:47212 nux::GetNuxOnboardingModules(profile)
213 .FindKey("returning-user")
214 ->GetString());
Hector Carmona7f52fab2019-04-18 23:31:22215 html_source->AddBoolean("signinAllowed", profile->GetPrefs()->GetBoolean(
216 prefs::kSigninAllowed));
dpapad28dccc442019-04-09 22:06:40217 html_source->SetRequestFilter(
218 base::BindRepeating(&ShouldHandleRequestCallback,
219 weak_ptr_factory_.GetWeakPtr()),
220 base::BindRepeating(&HandleRequestCallback,
221 weak_ptr_factory_.GetWeakPtr()));
Dan Beama896f662019-03-19 18:26:39222 html_source->UseGzip(base::BindRepeating(&WelcomeUI::IsGzipped));
Hector Carmonae3b2605c2019-04-11 22:28:35223 html_source->SetJsonPath("strings.js");
Dan Beama896f662019-03-19 18:26:39224 } else if (kIsBranded &&
225 AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)) {
Scott Chenc74ed762018-09-21 00:23:16226 // Use special layout if the application is branded and DICE is enabled.
Scott Chenc6706672017-11-17 17:40:27227 html_source->AddLocalizedString("headerText", IDS_WELCOME_HEADER);
Thomas Tangl441b06782018-09-27 19:37:07228 html_source->AddLocalizedString("acceptText",
229 IDS_PROFILES_DICE_SIGNIN_BUTTON);
Scott Chenc6706672017-11-17 17:40:27230 html_source->AddLocalizedString("secondHeaderText",
231 IDS_DICE_WELCOME_SECOND_HEADER);
232 html_source->AddLocalizedString("descriptionText",
233 IDS_DICE_WELCOME_DESCRIPTION);
234 html_source->AddLocalizedString("declineText",
235 IDS_DICE_WELCOME_DECLINE_BUTTON);
Mihai Sardarescu631f3b472018-05-04 15:08:15236 html_source->AddResourcePath("welcome_browser_proxy.html",
237 IDR_DICE_WELCOME_BROWSER_PROXY_HTML);
238 html_source->AddResourcePath("welcome_browser_proxy.js",
239 IDR_DICE_WELCOME_BROWSER_PROXY_JS);
Scott Chenc6706672017-11-17 17:40:27240 html_source->AddResourcePath("welcome_app.html", IDR_DICE_WELCOME_APP_HTML);
241 html_source->AddResourcePath("welcome_app.js", IDR_DICE_WELCOME_APP_JS);
Scott Chena1264452017-11-14 13:32:08242 html_source->AddResourcePath("welcome.css", IDR_DICE_WELCOME_CSS);
243 html_source->SetDefaultResource(IDR_DICE_WELCOME_HTML);
244 } else {
Mihai Sardarescu631f3b472018-05-04 15:08:15245 // Use default layout for non-DICE or unbranded build.
246 std::string value;
247 bool is_everywhere_variant =
248 (net::GetValueForKeyInQuery(url, "variant", &value) &&
249 value == "everywhere");
250
Scott Chenc6706672017-11-17 17:40:27251 if (kIsBranded) {
252 base::string16 subheader =
253 is_everywhere_variant
254 ? base::string16()
255 : l10n_util::GetStringUTF16(IDS_WELCOME_SUBHEADER);
256 html_source->AddString("subheaderText", subheader);
257 }
258
259 int header_id = is_everywhere_variant ? IDS_WELCOME_HEADER_AFTER_FIRST_RUN
260 : IDS_WELCOME_HEADER;
261 html_source->AddString("headerText", l10n_util::GetStringUTF16(header_id));
Thomas Tangl441b06782018-09-27 19:37:07262 html_source->AddLocalizedString("acceptText", IDS_WELCOME_ACCEPT_BUTTON);
Scott Chenc6706672017-11-17 17:40:27263 html_source->AddLocalizedString("descriptionText", IDS_WELCOME_DESCRIPTION);
264 html_source->AddLocalizedString("declineText", IDS_WELCOME_DECLINE_BUTTON);
Scott Chena1264452017-11-14 13:32:08265 html_source->AddResourcePath("welcome.js", IDR_WELCOME_JS);
266 html_source->AddResourcePath("welcome.css", IDR_WELCOME_CSS);
267 html_source->SetDefaultResource(IDR_WELCOME_HTML);
268 }
tmartinoe3f9c38e2016-09-13 14:05:32269
tmartinoe3f9c38e2016-09-13 14:05:32270 content::WebUIDataSource::Add(profile, html_source);
271}
272
273WelcomeUI::~WelcomeUI() {}
Hector Carmona8f2c3cb2018-07-12 21:07:58274
John Lee6eb43ae2019-02-28 21:25:26275void WelcomeUI::CreateBackgroundFetcher(
276 size_t background_index,
277 const content::WebUIDataSource::GotDataCallback& callback) {
278 background_fetcher_ =
279 std::make_unique<nux::NtpBackgroundFetcher>(background_index, callback);
280}
281
Scott Chenf68c9b22018-10-12 02:15:25282void WelcomeUI::StorePageSeen(Profile* profile) {
Hector Carmona8f2c3cb2018-07-12 21:07:58283 // Store that this profile has been shown the Welcome page.
284 profile->GetPrefs()->SetBoolean(prefs::kHasSeenWelcomePage, true);
285}
Dan Beama896f662019-03-19 18:26:39286
287bool WelcomeUI::IsGzipped(const std::string& path) {
288 const std::map<std::string, bool>& gzip_map = GetGzipMap();
289 const auto it = gzip_map.find(path);
290 return it == gzip_map.end() || it->second;
291}