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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/first_run/first_run_win.cc
diff --git a/chrome/browser/first_run/first_run_win.cc b/chrome/browser/first_run/first_run_win.cc
index 077a1cfaacd0cc76cb4d4208bcfd41fc8c744d10..fbd92bc10deb3388779a0d1f4a4d685a8d06236d 100644
--- a/chrome/browser/first_run/first_run_win.cc
+++ b/chrome/browser/first_run/first_run_win.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/first_run/first_run.h"
+#include <shellapi.h>
#include <shlobj.h>
#include <windows.h>
@@ -15,6 +16,7 @@
#include "base/string_split.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
+#include "base/win/metro.h"
#include "base/win/object_watcher.h"
#include "base/win/windows_version.h"
#include "chrome/browser/browser_process.h"
@@ -52,11 +54,10 @@
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/layout.h"
#include "ui/base/ui_base_switches.h"
+#include "ui/base/win/shell.h"
namespace {
-const char kEULASentinelFile[] = "EULA Accepted";
-
// Helper class that performs delayed first-run tasks that need more of the
// chrome infrastructure to be up and running before they can be attempted.
class FirstRunDelayedTasks : public content::NotificationObserver {
@@ -144,53 +145,61 @@ void PlatformSetup(Profile* profile) {
CreateChromeQuickLaunchShortcut();
}
-// Launches the setup exe with the given parameter/value on the command-line,
-// waits for its termination, returns its exit code in |*ret_code|, and
-// returns true if the exit code is valid.
-bool LaunchSetupWithParam(const std::string& param,
- const FilePath::StringType& value,
- int* ret_code) {
- FilePath exe_path;
- if (!PathService::Get(base::DIR_MODULE, &exe_path))
+// Launches the setup exe with the given parameter/value on the command-line.
+// For non-metro Windows, it waits for its termination, returns its exit code
+// in |*ret_code|, and returns true if the exit code is valid.
+// For metro Windows, it launches setup via ShellExecuteEx and returns in order
+// to bounce the user back to the desktop, then returns immediately.
+bool LaunchSetupForEula(const FilePath::StringType& value, int* ret_code) {
+ FilePath exe_dir;
+ if (!PathService::Get(base::DIR_MODULE, &exe_dir))
return false;
- exe_path = exe_path.Append(installer::kInstallerDir);
- exe_path = exe_path.Append(installer::kSetupExe);
+ exe_dir = exe_dir.Append(installer::kInstallerDir);
+ FilePath exe_path = exe_dir.Append(installer::kSetupExe);
base::ProcessHandle ph;
- CommandLine cl(exe_path);
- cl.AppendSwitchNative(param, value);
+
+ CommandLine cl(CommandLine::NO_PROGRAM);
+ cl.AppendSwitchNative(installer::switches::kShowEula, value);
CommandLine* browser_command_line = CommandLine::ForCurrentProcess();
if (browser_command_line->HasSwitch(switches::kChromeFrame)) {
cl.AppendSwitch(switches::kChromeFrame);
}
- // TODO(evan): should this use options.wait = true?
- if (!base::LaunchProcess(cl, base::LaunchOptions(), &ph))
- return false;
- DWORD wr = ::WaitForSingleObject(ph, INFINITE);
- if (wr != WAIT_OBJECT_0)
- return false;
- return (TRUE == ::GetExitCodeProcess(ph, reinterpret_cast<DWORD*>(ret_code)));
-}
-
-// Populates |path| with the path to |file| in the sentinel directory. This is
-// the application directory for user-level installs, and the default user data
-// dir for system-level installs. Returns false on error.
-bool GetSentinelFilePath(const char* file, FilePath* path) {
- FilePath exe_path;
- if (!PathService::Get(base::DIR_EXE, &exe_path))
- return false;
- if (InstallUtil::IsPerUserInstall(exe_path.value().c_str()))
- *path = exe_path;
- else if (!PathService::Get(chrome::DIR_USER_DATA, path))
+ if (base::win::IsMetroProcess()) {
+ cl.AppendSwitch(installer::switches::kShowEulaForMetro);
+
+ // This obscure use of the 'log usage' mask for windows 8 is documented here
+ // http://go.microsoft.com/fwlink/?LinkID=243079. It causes the desktop
+ // process to receive focus. Pass SEE_MASK_FLAG_NO_UI to avoid hangs if an
+ // error occurs since the UI can't be shown from a metro process.
+ ui::win::OpenAnyViaShell(exe_path.value(),
+ exe_dir.value(),
+ cl.GetCommandLineString(),
+ SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_FLAG_NO_UI);
return false;
+ } else {
+ base::LaunchOptions launch_options;
+ launch_options.wait = true;
+ CommandLine setup_path(exe_path);
+ setup_path.AppendArguments(cl, false);
+
+ DWORD exit_code = 0;
+ if (!base::LaunchProcess(setup_path, launch_options, &ph) ||
+ !::GetExitCodeProcess(ph, &exit_code)) {
+ return false;
+ }
- *path = path->AppendASCII(file);
- return true;
+ *ret_code = exit_code;
+ return true;
+ }
}
bool GetEULASentinelFilePath(FilePath* path) {
- return GetSentinelFilePath(kEULASentinelFile, path);
+ return InstallUtil::GetSentinelFilePath(
+ installer::kEULASentinelFile,
+ BrowserDistribution::GetDistribution(),
+ path);
}
// Returns true if the EULA is required but has not been accepted by this user.
@@ -234,7 +243,10 @@ bool CreateEULASentinel() {
return file_util::WriteFile(eula_sentinel, "", 0) != -1;
}
-void ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
+// Shows the EULA dialog if required. Returns true if the EULA is accepted,
+// returns false if the EULA has not been accepted, in which case the browser
+// should exit.
+bool ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
if (IsEULANotAccepted(install_prefs)) {
// Show the post-installation EULA. This is done by setup.exe and the
// result determines if we continue or not. We wait here until the user
@@ -245,14 +257,14 @@ void ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
FilePath inner_html;
if (WriteEULAtoTempFile(&inner_html)) {
int retcode = 0;
- if (!LaunchSetupWithParam(installer::switches::kShowEula,
- inner_html.value(), &retcode) ||
+ if (!LaunchSetupForEula(inner_html.value(), &retcode) ||
(retcode != installer::EULA_ACCEPTED &&
retcode != installer::EULA_ACCEPTED_OPT_IN)) {
- LOG(WARNING) << "EULA rejected. Fast exit.";
- ::ExitProcess(1);
+ LOG(WARNING) << "EULA flow requires fast exit.";
+ return false;
}
CreateEULASentinel();
+
if (retcode == installer::EULA_ACCEPTED) {
VLOG(1) << "EULA : no collection";
GoogleUpdateSettings::SetCollectStatsConsent(false);
@@ -262,6 +274,7 @@ void ShowPostInstallEULAIfNeeded(installer::MasterPreferences* install_prefs) {
}
}
}
+ return true;
}
// Installs a task to do an extensions update check once the extensions system
@@ -498,7 +511,10 @@ bool ImportSettings(Profile* profile,
}
bool GetFirstRunSentinelFilePath(FilePath* path) {
- return GetSentinelFilePath(kSentinelFile, path);
+ return InstallUtil::GetSentinelFilePath(
+ kSentinelFile,
+ BrowserDistribution::GetDistribution(),
+ path);
}
void SetImportPreferencesAndLaunchImport(
@@ -590,23 +606,26 @@ FilePath MasterPrefsPath() {
return master_prefs.AppendASCII(installer::kDefaultMasterPrefs);
}
-bool ProcessMasterPreferences(const FilePath& user_data_dir,
- MasterPrefs* out_prefs) {
+ProcessMasterPreferencesResult ProcessMasterPreferences(
+ const FilePath& user_data_dir,
+ MasterPrefs* out_prefs) {
DCHECK(!user_data_dir.empty());
FilePath master_prefs_path;
scoped_ptr<installer::MasterPreferences>
install_prefs(internal::LoadMasterPrefs(&master_prefs_path));
if (!install_prefs.get())
- return true;
+ return SHOW_FIRST_RUN;
out_prefs->new_tabs = install_prefs->GetFirstRunTabs();
internal::SetRLZPref(out_prefs, install_prefs.get());
- ShowPostInstallEULAIfNeeded(install_prefs.get());
+
+ if (!ShowPostInstallEULAIfNeeded(install_prefs.get()))
+ return EULA_EXIT_NOW;
if (!internal::CopyPrefFile(user_data_dir, master_prefs_path))
- return true;
+ return SHOW_FIRST_RUN;
DoDelayedInstallExtensionsIfNeeded(install_prefs.get());
@@ -618,19 +637,19 @@ bool ProcessMasterPreferences(const FilePath& user_data_dir,
// Note we are skipping all other master preferences if skip-first-run-ui
// is *not* specified. (That is, we continue only if skipping first run ui.)
if (!internal::SkipFirstRunUI(install_prefs.get()))
- return true;
+ return SHOW_FIRST_RUN;
// We need to be able to create the first run sentinel or else we cannot
// proceed because ImportSettings will launch the importer process which
// would end up here if the sentinel is not present.
if (!CreateSentinel())
- return false;
+ return SKIP_FIRST_RUN;
internal::SetShowWelcomePagePrefIfNeeded(install_prefs.get());
internal::SetImportPreferencesAndLaunchImport(out_prefs, install_prefs.get());
internal::SetDefaultBrowser(install_prefs.get());
- return false;
+ return SKIP_FIRST_RUN;
}
} // namespace first_run
« 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