Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: chrome/browser/first_run/first_run_win.cc

Issue 10837222: Enable EULA dialog to be shown from metro Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Dear Greg, the third. Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/first_run/first_run_posix.cc ('k') | chrome/browser/process_singleton_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/first_run/first_run.h" 5 #include "chrome/browser/first_run/first_run.h"
6 6
7 #include <shellapi.h>
7 #include <shlobj.h> 8 #include <shlobj.h>
8 #include <windows.h> 9 #include <windows.h>
9 10
10 #include "base/environment.h" 11 #include "base/environment.h"
11 #include "base/file_util.h" 12 #include "base/file_util.h"
12 #include "base/path_service.h" 13 #include "base/path_service.h"
13 #include "base/process_util.h" 14 #include "base/process_util.h"
14 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
15 #include "base/string_split.h" 16 #include "base/string_split.h"
16 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
17 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "base/win/metro.h"
18 #include "base/win/object_watcher.h" 20 #include "base/win/object_watcher.h"
19 #include "base/win/windows_version.h" 21 #include "base/win/windows_version.h"
20 #include "chrome/browser/browser_process.h" 22 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/extensions/extension_service.h" 23 #include "chrome/browser/extensions/extension_service.h"
22 #include "chrome/browser/extensions/updater/extension_updater.h" 24 #include "chrome/browser/extensions/updater/extension_updater.h"
23 #include "chrome/browser/first_run/first_run_import_observer.h" 25 #include "chrome/browser/first_run/first_run_import_observer.h"
24 #include "chrome/browser/first_run/first_run_internal.h" 26 #include "chrome/browser/first_run/first_run_internal.h"
25 #include "chrome/browser/importer/importer_host.h" 27 #include "chrome/browser/importer/importer_host.h"
26 #include "chrome/browser/importer/importer_list.h" 28 #include "chrome/browser/importer/importer_list.h"
27 #include "chrome/browser/importer/importer_progress_dialog.h" 29 #include "chrome/browser/importer/importer_progress_dialog.h"
(...skipping 17 matching lines...) Expand all
45 #include "content/public/browser/notification_service.h" 47 #include "content/public/browser/notification_service.h"
46 #include "content/public/browser/user_metrics.h" 48 #include "content/public/browser/user_metrics.h"
47 #include "google_update/google_update_idl.h" 49 #include "google_update/google_update_idl.h"
48 #include "grit/chromium_strings.h" 50 #include "grit/chromium_strings.h"
49 #include "grit/generated_resources.h" 51 #include "grit/generated_resources.h"
50 #include "grit/locale_settings.h" 52 #include "grit/locale_settings.h"
51 #include "grit/theme_resources.h" 53 #include "grit/theme_resources.h"
52 #include "ui/base/l10n/l10n_util.h" 54 #include "ui/base/l10n/l10n_util.h"
53 #include "ui/base/layout.h" 55 #include "ui/base/layout.h"
54 #include "ui/base/ui_base_switches.h" 56 #include "ui/base/ui_base_switches.h"
57 #include "ui/base/win/shell.h"
55 58
56 namespace { 59 namespace {
57 60
58 const char kEULASentinelFile[] = "EULA Accepted";
59
60 // Helper class that performs delayed first-run tasks that need more of the 61 // Helper class that performs delayed first-run tasks that need more of the
61 // chrome infrastructure to be up and running before they can be attempted. 62 // chrome infrastructure to be up and running before they can be attempted.
62 class FirstRunDelayedTasks : public content::NotificationObserver { 63 class FirstRunDelayedTasks : public content::NotificationObserver {
63 public: 64 public:
64 enum Tasks { 65 enum Tasks {
65 NO_TASK, 66 NO_TASK,
66 INSTALL_EXTENSIONS 67 INSTALL_EXTENSIONS
67 }; 68 };
68 69
69 explicit FirstRunDelayedTasks(Tasks task) { 70 explicit FirstRunDelayedTasks(Tasks task) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 138 }
138 139
139 void PlatformSetup(Profile* profile) { 140 void PlatformSetup(Profile* profile) {
140 CreateChromeDesktopShortcut(); 141 CreateChromeDesktopShortcut();
141 142
142 // Windows 7 has deprecated the quick launch bar. 143 // Windows 7 has deprecated the quick launch bar.
143 if (base::win::GetVersion() < base::win::VERSION_WIN7) 144 if (base::win::GetVersion() < base::win::VERSION_WIN7)
144 CreateChromeQuickLaunchShortcut(); 145 CreateChromeQuickLaunchShortcut();
145 } 146 }
146 147
147 // Launches the setup exe with the given parameter/value on the command-line, 148 // Launches the setup exe with the given parameter/value on the command-line.
148 // waits for its termination, returns its exit code in |*ret_code|, and 149 // For non-metro Windows, it waits for its termination, returns its exit code
149 // returns true if the exit code is valid. 150 // in |*ret_code|, and returns true if the exit code is valid.
150 bool LaunchSetupWithParam(const std::string& param, 151 // For metro Windows, it launches setup via ShellExecuteEx and returns in order
151 const FilePath::StringType& value, 152 // to bounce the user back to the desktop, then returns immediately.
152 int* ret_code) { 153 bool LaunchSetupForEula(const FilePath::StringType& value, int* ret_code) {
153 FilePath exe_path; 154 FilePath exe_dir;
154 if (!PathService::Get(base::DIR_MODULE, &exe_path)) 155 if (!PathService::Get(base::DIR_MODULE, &exe_dir))
155 return false; 156 return false;
156 exe_path = exe_path.Append(installer::kInstallerDir); 157 exe_dir = exe_dir.Append(installer::kInstallerDir);
157 exe_path = exe_path.Append(installer::kSetupExe); 158 FilePath exe_path = exe_dir.Append(installer::kSetupExe);
158 base::ProcessHandle ph; 159 base::ProcessHandle ph;
159 CommandLine cl(exe_path); 160
160 cl.AppendSwitchNative(param, value); 161 CommandLine cl(CommandLine::NO_PROGRAM);
162 cl.AppendSwitchNative(installer::switches::kShowEula, value);
161 163
162 CommandLine* browser_command_line = CommandLine::ForCurrentProcess(); 164 CommandLine* browser_command_line = CommandLine::ForCurrentProcess();
163 if (browser_command_line->HasSwitch(switches::kChromeFrame)) { 165 if (browser_command_line->HasSwitch(switches::kChromeFrame)) {
164 cl.AppendSwitch(switches::kChromeFrame); 166 cl.AppendSwitch(switches::kChromeFrame);
165 } 167 }
166 168
167 // TODO(evan): should this use options.wait = true? 169 if (base::win::IsMetroProcess()) {
168 if (!base::LaunchProcess(cl, base::LaunchOptions(), &ph)) 170 cl.AppendSwitch(installer::switches::kShowEulaForMetro);
171
172 // This obscure use of the 'log usage' mask for windows 8 is documented here
173 // http://go.microsoft.com/fwlink/?LinkID=243079. It causes the desktop
174 // process to receive focus. Pass SEE_MASK_FLAG_NO_UI to avoid hangs if an
175 // error occurs since the UI can't be shown from a metro process.
176 ui::win::OpenAnyViaShell(exe_path.value(),
177 exe_dir.value(),
178 cl.GetCommandLineString(),
179 SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_FLAG_NO_UI);
169 return false; 180 return false;
170 DWORD wr = ::WaitForSingleObject(ph, INFINITE); 181 } else {
171 if (wr != WAIT_OBJECT_0) 182 base::LaunchOptions launch_options;
172 return false; 183 launch_options.wait = true;
173 return (TRUE == ::GetExitCodeProcess(ph, reinterpret_cast<DWORD*>(ret_code))); 184 CommandLine setup_path(exe_path);
174 } 185 setup_path.AppendArguments(cl, false);
175 186
176 // Populates |path| with the path to |file| in the sentinel directory. This is 187 DWORD exit_code = 0;
177 // the application directory for user-level installs, and the default user data 188 if (!base::LaunchProcess(setup_path, launch_options, &ph) ||
178 // dir for system-level installs. Returns false on error. 189 !::GetExitCodeProcess(ph, &exit_code)) {
179 bool GetSentinelFilePath(const char* file, FilePath* path) { 190 return false;
180 FilePath exe_path; 191 }
181 if (!PathService::Get(base::DIR_EXE, &exe_path))
182 return false;
183 if (InstallUtil::IsPerUserInstall(exe_path.value().c_str()))
184 *path = exe_path;
185 else if (!PathService::Get(chrome::DIR_USER_DATA, path))
186 return false;
187 192
188 *path = path->AppendASCII(file); 193 *ret_code = exit_code;
189 return true; 194 return true;
195 }
190 } 196 }
191 197
192 bool GetEULASentinelFilePath(FilePath* path) { 198 bool GetEULASentinelFilePath(FilePath* path) {
193 return GetSentinelFilePath(kEULASentinelFile, path); 199 return InstallUtil::GetSentinelFilePath(
200 installer::kEULASentinelFile,
201 BrowserDistribution::GetDistribution(),
202 path);
194 } 203 }
195 204
196 // Returns true if the EULA is required but has not been accepted by this user. 205 // Returns true if the EULA is required but has not been accepted by this user.
197 // The EULA is considered having been accepted if the user has gotten past 206 // The EULA is considered having been accepted if the user has gotten past
198 // first run in the "other" environment (desktop or metro). 207 // first run in the "other" environment (desktop or metro).
199 bool IsEULANotAccepted(installer::MasterPreferences* install_prefs) { 208 bool IsEULANotAccepted(installer::MasterPreferences* install_prefs) {
200 bool value = false; 209 bool value = false;
201 if (install_prefs->GetBool(installer::master_preferences::kRequireEula, 210 if (install_prefs->GetBool(installer::master_preferences::kRequireEula,
202 &value) && value) { 211 &value) && value) {
203 FilePath eula_sentinel; 212 FilePath eula_sentinel;
(...skipping 23 matching lines...) Expand all
227 236
228 // Creates the sentinel indicating that the EULA was required and has been 237 // Creates the sentinel indicating that the EULA was required and has been
229 // accepted. 238 // accepted.
230 bool CreateEULASentinel() { 239 bool CreateEULASentinel() {
231 FilePath eula_sentinel; 240 FilePath eula_sentinel;
232 if (!GetEULASentinelFilePath(&eula_sentinel)) 241 if (!GetEULASentinelFilePath(&eula_sentinel))
233 return false; 242 return false;
234 return file_util::WriteFile(eula_sentinel, "", 0) != -1; 243 return file_util::WriteFile(eula_sentinel, "", 0) != -1;
235 } 244 }
236 245
237 void ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) { 246 // Shows the EULA dialog if required. Returns true if the EULA is accepted,
247 // returns false if the EULA has not been accepted, in which case the browser
248 // should exit.
249 bool ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
238 if (IsEULANotAccepted(install_prefs)) { 250 if (IsEULANotAccepted(install_prefs)) {
239 // Show the post-installation EULA. This is done by setup.exe and the 251 // Show the post-installation EULA. This is done by setup.exe and the
240 // result determines if we continue or not. We wait here until the user 252 // result determines if we continue or not. We wait here until the user
241 // dismisses the dialog. 253 // dismisses the dialog.
242 254
243 // The actual eula text is in a resource in chrome. We extract it to 255 // The actual eula text is in a resource in chrome. We extract it to
244 // a text file so setup.exe can use it as an inner frame. 256 // a text file so setup.exe can use it as an inner frame.
245 FilePath inner_html; 257 FilePath inner_html;
246 if (WriteEULAtoTempFile(&inner_html)) { 258 if (WriteEULAtoTempFile(&inner_html)) {
247 int retcode = 0; 259 int retcode = 0;
248 if (!LaunchSetupWithParam(installer::switches::kShowEula, 260 if (!LaunchSetupForEula(inner_html.value(), &retcode) ||
249 inner_html.value(), &retcode) ||
250 (retcode != installer::EULA_ACCEPTED && 261 (retcode != installer::EULA_ACCEPTED &&
251 retcode != installer::EULA_ACCEPTED_OPT_IN)) { 262 retcode != installer::EULA_ACCEPTED_OPT_IN)) {
252 LOG(WARNING) << "EULA rejected. Fast exit."; 263 LOG(WARNING) << "EULA flow requires fast exit.";
253 ::ExitProcess(1); 264 return false;
254 } 265 }
255 CreateEULASentinel(); 266 CreateEULASentinel();
267
256 if (retcode == installer::EULA_ACCEPTED) { 268 if (retcode == installer::EULA_ACCEPTED) {
257 VLOG(1) << "EULA : no collection"; 269 VLOG(1) << "EULA : no collection";
258 GoogleUpdateSettings::SetCollectStatsConsent(false); 270 GoogleUpdateSettings::SetCollectStatsConsent(false);
259 } else if (retcode == installer::EULA_ACCEPTED_OPT_IN) { 271 } else if (retcode == installer::EULA_ACCEPTED_OPT_IN) {
260 VLOG(1) << "EULA : collection consent"; 272 VLOG(1) << "EULA : collection consent";
261 GoogleUpdateSettings::SetCollectStatsConsent(true); 273 GoogleUpdateSettings::SetCollectStatsConsent(true);
262 } 274 }
263 } 275 }
264 } 276 }
277 return true;
265 } 278 }
266 279
267 // Installs a task to do an extensions update check once the extensions system 280 // Installs a task to do an extensions update check once the extensions system
268 // is running. 281 // is running.
269 void DoDelayedInstallExtensions() { 282 void DoDelayedInstallExtensions() {
270 new FirstRunDelayedTasks(FirstRunDelayedTasks::INSTALL_EXTENSIONS); 283 new FirstRunDelayedTasks(FirstRunDelayedTasks::INSTALL_EXTENSIONS);
271 } 284 }
272 285
273 void DoDelayedInstallExtensionsIfNeeded( 286 void DoDelayedInstallExtensionsIfNeeded(
274 installer::MasterPreferences* install_prefs) { 287 installer::MasterPreferences* install_prefs) {
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 int items_to_import) { 504 int items_to_import) {
492 return ImportSettingsWin( 505 return ImportSettingsWin(
493 profile, 506 profile,
494 importer_list->GetSourceProfileAt(0).importer_type, 507 importer_list->GetSourceProfileAt(0).importer_type,
495 items_to_import, 508 items_to_import,
496 FilePath(), 509 FilePath(),
497 false); 510 false);
498 } 511 }
499 512
500 bool GetFirstRunSentinelFilePath(FilePath* path) { 513 bool GetFirstRunSentinelFilePath(FilePath* path) {
501 return GetSentinelFilePath(kSentinelFile, path); 514 return InstallUtil::GetSentinelFilePath(
515 kSentinelFile,
516 BrowserDistribution::GetDistribution(),
517 path);
502 } 518 }
503 519
504 void SetImportPreferencesAndLaunchImport( 520 void SetImportPreferencesAndLaunchImport(
505 MasterPrefs* out_prefs, 521 MasterPrefs* out_prefs,
506 installer::MasterPreferences* install_prefs) { 522 installer::MasterPreferences* install_prefs) {
507 std::string import_bookmarks_path; 523 std::string import_bookmarks_path;
508 install_prefs->GetString( 524 install_prefs->GetString(
509 installer::master_preferences::kDistroImportBookmarksFromFilePref, 525 installer::master_preferences::kDistroImportBookmarksFromFilePref,
510 &import_bookmarks_path); 526 &import_bookmarks_path);
511 527
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 } 599 }
584 600
585 FilePath MasterPrefsPath() { 601 FilePath MasterPrefsPath() {
586 // The standard location of the master prefs is next to the chrome binary. 602 // The standard location of the master prefs is next to the chrome binary.
587 FilePath master_prefs; 603 FilePath master_prefs;
588 if (!PathService::Get(base::DIR_EXE, &master_prefs)) 604 if (!PathService::Get(base::DIR_EXE, &master_prefs))
589 return FilePath(); 605 return FilePath();
590 return master_prefs.AppendASCII(installer::kDefaultMasterPrefs); 606 return master_prefs.AppendASCII(installer::kDefaultMasterPrefs);
591 } 607 }
592 608
593 bool ProcessMasterPreferences(const FilePath& user_data_dir, 609 ProcessMasterPreferencesResult ProcessMasterPreferences(
594 MasterPrefs* out_prefs) { 610 const FilePath& user_data_dir,
611 MasterPrefs* out_prefs) {
595 DCHECK(!user_data_dir.empty()); 612 DCHECK(!user_data_dir.empty());
596 613
597 FilePath master_prefs_path; 614 FilePath master_prefs_path;
598 scoped_ptr<installer::MasterPreferences> 615 scoped_ptr<installer::MasterPreferences>
599 install_prefs(internal::LoadMasterPrefs(&master_prefs_path)); 616 install_prefs(internal::LoadMasterPrefs(&master_prefs_path));
600 if (!install_prefs.get()) 617 if (!install_prefs.get())
601 return true; 618 return SHOW_FIRST_RUN;
602 619
603 out_prefs->new_tabs = install_prefs->GetFirstRunTabs(); 620 out_prefs->new_tabs = install_prefs->GetFirstRunTabs();
604 621
605 internal::SetRLZPref(out_prefs, install_prefs.get()); 622 internal::SetRLZPref(out_prefs, install_prefs.get());
606 ShowPostInstallEULAIfNeeded(install_prefs.get()); 623
624 if (!ShowPostInstallEULAIfNeeded(install_prefs.get()))
625 return EULA_EXIT_NOW;
607 626
608 if (!internal::CopyPrefFile(user_data_dir, master_prefs_path)) 627 if (!internal::CopyPrefFile(user_data_dir, master_prefs_path))
609 return true; 628 return SHOW_FIRST_RUN;
610 629
611 DoDelayedInstallExtensionsIfNeeded(install_prefs.get()); 630 DoDelayedInstallExtensionsIfNeeded(install_prefs.get());
612 631
613 internal::SetupMasterPrefsFromInstallPrefs(out_prefs, 632 internal::SetupMasterPrefsFromInstallPrefs(out_prefs,
614 install_prefs.get()); 633 install_prefs.get());
615 634
616 // TODO(mirandac): Refactor skip-first-run-ui process into regular first run 635 // TODO(mirandac): Refactor skip-first-run-ui process into regular first run
617 // import process. http://crbug.com/49647 636 // import process. http://crbug.com/49647
618 // Note we are skipping all other master preferences if skip-first-run-ui 637 // Note we are skipping all other master preferences if skip-first-run-ui
619 // is *not* specified. (That is, we continue only if skipping first run ui.) 638 // is *not* specified. (That is, we continue only if skipping first run ui.)
620 if (!internal::SkipFirstRunUI(install_prefs.get())) 639 if (!internal::SkipFirstRunUI(install_prefs.get()))
621 return true; 640 return SHOW_FIRST_RUN;
622 641
623 // We need to be able to create the first run sentinel or else we cannot 642 // We need to be able to create the first run sentinel or else we cannot
624 // proceed because ImportSettings will launch the importer process which 643 // proceed because ImportSettings will launch the importer process which
625 // would end up here if the sentinel is not present. 644 // would end up here if the sentinel is not present.
626 if (!CreateSentinel()) 645 if (!CreateSentinel())
627 return false; 646 return SKIP_FIRST_RUN;
628 647
629 internal::SetShowWelcomePagePrefIfNeeded(install_prefs.get()); 648 internal::SetShowWelcomePagePrefIfNeeded(install_prefs.get());
630 internal::SetImportPreferencesAndLaunchImport(out_prefs, install_prefs.get()); 649 internal::SetImportPreferencesAndLaunchImport(out_prefs, install_prefs.get());
631 internal::SetDefaultBrowser(install_prefs.get()); 650 internal::SetDefaultBrowser(install_prefs.get());
632 651
633 return false; 652 return SKIP_FIRST_RUN;
634 } 653 }
635 654
636 } // namespace first_run 655 } // namespace first_run
OLDNEW
« no previous file with comments | « chrome/browser/first_run/first_run_posix.cc ('k') | chrome/browser/process_singleton_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698