summaryrefslogtreecommitdiffstats
path: root/chrome/browser/first_run/first_run_win.cc
diff options
context:
space:
mode:
authorrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-26 14:16:48 +0000
committerrobertshield@chromium.org <robertshield@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-26 14:16:48 +0000
commit7867996916cc0ca3d1d89d26c15bb7b39e994419 (patch)
tree89c2fb2fc2f5d41574d70d2fbf1ad93f7a858f1c /chrome/browser/first_run/first_run_win.cc
parentd83e5704eeb51d6e9fec081c00a618ad852abe35 (diff)
downloadchromium_src-7867996916cc0ca3d1d89d26c15bb7b39e994419.zip
chromium_src-7867996916cc0ca3d1d89d26c15bb7b39e994419.tar.gz
chromium_src-7867996916cc0ca3d1d89d26c15bb7b39e994419.tar.bz2
Enable EULA dialog to be shown from metro Chrome.
BUG=131033 TEST=Run Chrome in Metro mode while the EULA dialog still needs to be accepted. Get kicked back to the desktop to accept the dialog. On accept, get kicked back into metro mode. Review URL: https://chromiumcodereview.appspot.com/10837222 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158797 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/first_run/first_run_win.cc')
-rw-r--r--chrome/browser/first_run/first_run_win.cc119
1 files changed, 69 insertions, 50 deletions
diff --git a/chrome/browser/first_run/first_run_win.cc b/chrome/browser/first_run/first_run_win.cc
index 077a1cf..fbd92bc 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