1 // 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 
5 #include "chrome/browser/ui/webui/welcome/welcome_ui.h"
6 
7 #include "base/bind.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/string_util.h"
10 #include "build/branding_buildflags.h"
11 #include "chrome/browser/signin/account_consistency_mode_manager.h"
12 #include "chrome/browser/ui/webui/webui_util.h"
13 #include "chrome/browser/ui/webui/welcome/bookmark_handler.h"
14 #include "chrome/browser/ui/webui/welcome/google_apps_handler.h"
15 #include "chrome/browser/ui/webui/welcome/helpers.h"
16 #include "chrome/browser/ui/webui/welcome/ntp_background_handler.h"
17 #include "chrome/browser/ui/webui/welcome/set_as_default_handler.h"
18 #include "chrome/browser/ui/webui/welcome/welcome_handler.h"
19 #include "chrome/common/pref_names.h"
20 #include "chrome/grit/chrome_unscaled_resources.h"
21 #include "chrome/grit/chromium_strings.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "chrome/grit/welcome_resources.h"
24 #include "chrome/grit/welcome_resources_map.h"
25 #include "components/prefs/pref_service.h"
26 #include "components/signin/public/base/signin_pref_names.h"
27 #include "components/strings/grit/components_strings.h"
28 #include "net/base/url_util.h"
29 #include "ui/base/webui/web_ui_util.h"
30 
31 #if defined(OS_WIN)
32 #include "base/win/windows_version.h"
33 #endif
34 
35 namespace {
36 
37 const char kPreviewBackgroundPath[] = "preview-background.jpg";
38 
ShouldHandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,const std::string & path)39 bool ShouldHandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,
40                                  const std::string& path) {
41   if (!base::StartsWith(path, kPreviewBackgroundPath,
42                         base::CompareCase::SENSITIVE)) {
43     return false;
44   }
45 
46   std::string index_param = path.substr(path.find_first_of("?") + 1);
47   int background_index = -1;
48   if (!base::StringToInt(index_param, &background_index) ||
49       background_index < 0) {
50     return false;
51   }
52 
53   return !!weak_ptr;
54 }
55 
HandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,const std::string & path,content::WebUIDataSource::GotDataCallback callback)56 void HandleRequestCallback(base::WeakPtr<WelcomeUI> weak_ptr,
57                            const std::string& path,
58                            content::WebUIDataSource::GotDataCallback callback) {
59   DCHECK(ShouldHandleRequestCallback(weak_ptr, path));
60 
61   std::string index_param = path.substr(path.find_first_of("?") + 1);
62   int background_index = -1;
63   CHECK(base::StringToInt(index_param, &background_index) ||
64         background_index < 0);
65 
66   DCHECK(weak_ptr);
67   weak_ptr->CreateBackgroundFetcher(background_index, std::move(callback));
68 }
69 
AddStrings(content::WebUIDataSource * html_source)70 void AddStrings(content::WebUIDataSource* html_source) {
71   static constexpr webui::LocalizedString kLocalizedStrings[] = {
72       // Shared strings.
73       {"bookmarkAdded", IDS_WELCOME_BOOKMARK_ADDED},
74       {"bookmarksAdded", IDS_WELCOME_BOOKMARKS_ADDED},
75       {"bookmarkRemoved", IDS_WELCOME_BOOKMARK_REMOVED},
76       {"bookmarksRemoved", IDS_WELCOME_BOOKMARKS_REMOVED},
77       {"defaultBrowserChanged", IDS_DEFAULT_BROWSER_CHANGED},
78       {"headerText", IDS_WELCOME_HEADER},
79       {"next", IDS_WELCOME_NEXT},
80       {"noThanks", IDS_NO_THANKS},
81       {"skip", IDS_WELCOME_SKIP},
82       {"stepsLabel", IDS_WELCOME_STEPS},
83 
84       // Sign-in view strings.
85       {"signInHeader", IDS_WELCOME_SIGNIN_VIEW_HEADER},
86       {"signInSubHeader", IDS_WELCOME_SIGNIN_VIEW_SUB_HEADER},
87       {"signIn", IDS_WELCOME_SIGNIN_VIEW_SIGNIN},
88 
89       // Google apps module strings.
90       {"googleAppsDescription", IDS_WELCOME_GOOGLE_APPS_DESCRIPTION},
91 
92       // New Tab Page background module strings.
93       {"ntpBackgroundDescription", IDS_WELCOME_NTP_BACKGROUND_DESCRIPTION},
94       {"ntpBackgroundDefault", IDS_WELCOME_NTP_BACKGROUND_DEFAULT_TITLE},
95       {"ntpBackgroundPreviewUpdated",
96        IDS_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED},
97       {"ntpBackgroundReset", IDS_WELCOME_NTP_BACKGROUND_RESET},
98 
99       // Set as default module strings.
100       {"setDefaultHeader", IDS_WELCOME_SET_AS_DEFAULT_HEADER},
101       {"setDefaultSubHeader", IDS_WELCOME_SET_AS_DEFAULT_SUB_HEADER},
102       {"setDefaultConfirm", IDS_WELCOME_SET_AS_DEFAULT_SET_AS_DEFAULT},
103 
104       // Landing view strings.
105       {"landingTitle", IDS_WELCOME_LANDING_TITLE},
106       {"landingDescription", IDS_WELCOME_LANDING_DESCRIPTION},
107       {"landingNewUser", IDS_WELCOME_LANDING_NEW_USER},
108       {"landingExistingUser", IDS_WELCOME_LANDING_EXISTING_USER},
109   };
110   AddLocalizedStringsBulk(html_source, kLocalizedStrings);
111 }
112 
113 }  // namespace
114 
WelcomeUI(content::WebUI * web_ui,const GURL & url)115 WelcomeUI::WelcomeUI(content::WebUI* web_ui, const GURL& url)
116     : content::WebUIController(web_ui) {
117   Profile* profile = Profile::FromWebUI(web_ui);
118 
119   // This page is not shown to incognito or guest profiles. If one should end up
120   // here, we return, causing a 404-like page.
121   if (!profile || !profile->IsRegularProfile()) {
122     return;
123   }
124 
125   StorePageSeen(profile);
126 
127   web_ui->AddMessageHandler(std::make_unique<WelcomeHandler>(web_ui));
128 
129   content::WebUIDataSource* html_source =
130       content::WebUIDataSource::Create(url.host());
131   webui::SetupWebUIDataSource(
132       html_source, base::make_span(kWelcomeResources, kWelcomeResourcesSize),
133       "", IDR_WELCOME_WELCOME_HTML);
134 
135   // Add welcome strings.
136   AddStrings(html_source);
137 
138 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
139   // Load unscaled images.
140   static constexpr webui::ResourcePath kPaths[] = {
141       {"images/module_icons/google_dark.svg",
142        IDR_WELCOME_MODULE_ICONS_GOOGLE_DARK},
143       {"images/module_icons/google_light.svg",
144        IDR_WELCOME_MODULE_ICONS_GOOGLE_LIGHT},
145       {"images/module_icons/set_default_dark.svg",
146        IDR_WELCOME_MODULE_ICONS_SET_DEFAULT_DARK},
147       {"images/module_icons/set_default_light.svg",
148        IDR_WELCOME_MODULE_ICONS_SET_DEFAULT_LIGHT},
149       {"images/module_icons/wallpaper_dark.svg",
150        IDR_WELCOME_MODULE_ICONS_WALLPAPER_DARK},
151       {"images/module_icons/wallpaper_light.svg",
152        IDR_WELCOME_MODULE_ICONS_WALLPAPER_LIGHT},
153       {"images/ntp_thumbnails/art.jpg", IDR_WELCOME_NTP_THUMBNAILS_ART},
154       {"images/ntp_thumbnails/cityscape.jpg",
155        IDR_WELCOME_NTP_THUMBNAILS_CITYSCAPE},
156       {"images/ntp_thumbnails/earth.jpg", IDR_WELCOME_NTP_THUMBNAILS_EARTH},
157       {"images/ntp_thumbnails/geometric_shapes.jpg",
158        IDR_WELCOME_NTP_THUMBNAILS_GEOMETRIC_SHAPES},
159       {"images/ntp_thumbnails/landscape.jpg",
160        IDR_WELCOME_NTP_THUMBNAILS_LANDSCAPE},
161       {"images/set_default_dark.svg", IDR_WELCOME_SET_DEFAULT_DARK},
162       {"images/set_default_light.svg", IDR_WELCOME_SET_DEFAULT_LIGHT},
163   };
164   webui::AddResourcePathsBulk(html_source, kPaths);
165 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
166 
167 #if defined(OS_WIN)
168   html_source->AddBoolean("is_win10",
169                           base::win::GetVersion() >= base::win::Version::WIN10);
170 #endif
171 
172   // Add the shared bookmark handler for welcome modules.
173   web_ui->AddMessageHandler(
174       std::make_unique<welcome::BookmarkHandler>(profile->GetPrefs()));
175 
176   // Add google apps bookmarking module.
177   web_ui->AddMessageHandler(std::make_unique<welcome::GoogleAppsHandler>());
178 
179   // Add NTP custom background module.
180   web_ui->AddMessageHandler(std::make_unique<welcome::NtpBackgroundHandler>());
181 
182   // Add set-as-default module.
183   web_ui->AddMessageHandler(std::make_unique<welcome::SetAsDefaultHandler>());
184 
185   html_source->AddString(
186       "newUserModules",
187       welcome::GetModules(profile).FindKey("new-user")->GetString());
188   html_source->AddString(
189       "returningUserModules",
190       welcome::GetModules(profile).FindKey("returning-user")->GetString());
191   html_source->AddBoolean(
192       "signinAllowed", profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed));
193   html_source->SetRequestFilter(
194       base::BindRepeating(&ShouldHandleRequestCallback,
195                           weak_ptr_factory_.GetWeakPtr()),
196       base::BindRepeating(&HandleRequestCallback,
197                           weak_ptr_factory_.GetWeakPtr()));
198 
199   content::WebUIDataSource::Add(profile, html_source);
200 }
201 
~WelcomeUI()202 WelcomeUI::~WelcomeUI() {}
203 
CreateBackgroundFetcher(size_t background_index,content::WebUIDataSource::GotDataCallback callback)204 void WelcomeUI::CreateBackgroundFetcher(
205     size_t background_index,
206     content::WebUIDataSource::GotDataCallback callback) {
207   background_fetcher_ = std::make_unique<welcome::NtpBackgroundFetcher>(
208       background_index, std::move(callback));
209 }
210 
StorePageSeen(Profile * profile)211 void WelcomeUI::StorePageSeen(Profile* profile) {
212   // Store that this profile has been shown the Welcome page.
213   profile->GetPrefs()->SetBoolean(prefs::kHasSeenWelcomePage, true);
214 }
215