diff options
author | huangs@chromium.org <huangs@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-01 03:18:35 +0000 |
---|---|---|
committer | huangs@chromium.org <huangs@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-01 03:18:35 +0000 |
commit | 60c8c0bbbdb7b9a9a222c3a2532e4a5f8c511bb9 (patch) | |
tree | 83a643ba8debfaa66c881285c5ffa05a60df4419 /chrome | |
parent | f5864911d8c71c4bd6585e6c6a42858a9c2155d0 (diff) | |
download | chromium_src-60c8c0bbbdb7b9a9a222c3a2532e4a5f8c511bb9.zip chromium_src-60c8c0bbbdb7b9a9a222c3a2532e4a5f8c511bb9.tar.gz chromium_src-60c8c0bbbdb7b9a9a222c3a2532e4a5f8c511bb9.tar.bz2 |
Implementing app command to query EULA acceptance state for Chrome.
There are 2 parts to this change:
1. Implement setup.exe switch --query-eula-acceptance, and return the result via exit code.
- Main use case is system-level, which requires the "--system-level" switch.
- Return code: 0 if "not accepted", 1 if "accepted", and -1 if failed.
2. Add the app command query-eula-acceptance to Chrome binary during installation to execute:
setup.exe --query-eula-acceptance [--system-level]
BUG=151303
TBR=ben
Review URL: https://chromiumcodereview.appspot.com/12035043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180052 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/chrome_installer_util.gypi | 2 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.cc | 36 | ||||
-rw-r--r-- | chrome/installer/setup/install_worker.h | 10 | ||||
-rw-r--r-- | chrome/installer/setup/setup_main.cc | 3 | ||||
-rw-r--r-- | chrome/installer/util/eula_util.cc | 110 | ||||
-rw-r--r-- | chrome/installer/util/eula_util.h | 25 | ||||
-rw-r--r-- | chrome/installer/util/installation_validator.cc | 35 | ||||
-rw-r--r-- | chrome/installer/util/installation_validator.h | 9 | ||||
-rw-r--r-- | chrome/installer/util/installation_validator_unittest.cc | 40 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.cc | 5 | ||||
-rw-r--r-- | chrome/installer/util/util_constants.h | 2 |
11 files changed, 266 insertions, 11 deletions
diff --git a/chrome/chrome_installer_util.gypi b/chrome/chrome_installer_util.gypi index 5fdc8724..2db8b70 100644 --- a/chrome/chrome_installer_util.gypi +++ b/chrome/chrome_installer_util.gypi @@ -134,6 +134,8 @@ 'installer/util/compat_checks.h', 'installer/util/delete_after_reboot_helper.cc', 'installer/util/delete_after_reboot_helper.h', + 'installer/util/eula_util.cc', + 'installer/util/eula_util.h', 'installer/util/google_chrome_distribution.cc', 'installer/util/google_chrome_distribution.h', 'installer/util/html_dialog.h', diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc index 81173a0..ef4fa36 100644 --- a/chrome/installer/setup/install_worker.cc +++ b/chrome/installer/setup/install_worker.cc @@ -211,7 +211,6 @@ void AddInstallerCopyTasks(const InstallerState& installer_state, void AddInstallAppCommandWorkItems(const InstallerState& installer_state, const InstallationState& machine_state, - const FilePath& setup_path, const Version& new_version, const Product& product, WorkItemList* work_item_list) { @@ -252,12 +251,16 @@ void AddProductSpecificWorkItems(const InstallationState& original_state, } if (p.is_chrome_app_host()) { AddInstallAppCommandWorkItems(installer_state, original_state, - setup_path, new_version, p, list); + new_version, p, list); } if (p.is_chrome()) { AddOsUpgradeWorkItems(installer_state, setup_path, new_version, p, list); } + if (p.is_chrome_binaries()) { + AddQueryEULAAcceptanceWorkItems(installer_state, setup_path, new_version, + p, list); + } } } @@ -1636,4 +1639,33 @@ void AddOsUpgradeWorkItems(const InstallerState& installer_state, } } +void AddQueryEULAAcceptanceWorkItems(const InstallerState& installer_state, + const FilePath& setup_path, + const Version& new_version, + const Product& product, + WorkItemList* work_item_list) { + const HKEY root_key = installer_state.root_key(); + string16 cmd_key(product.distribution()->GetVersionKey()); + cmd_key.append(1, FilePath::kSeparators[0]) + .append(google_update::kRegCommandsKey) + .append(1, FilePath::kSeparators[0]) + .append(kCmdQueryEULAAcceptance); + if (installer_state.operation() == InstallerState::UNINSTALL) { + work_item_list->AddDeleteRegKeyWorkItem(root_key, cmd_key)-> + set_log_message("Removing query EULA acceptance command"); + } else { + CommandLine cmd_line(installer_state + .GetInstallerDirectory(new_version) + .Append(setup_path.BaseName())); + cmd_line.AppendSwitch(switches::kQueryEULAAcceptance); + if (installer_state.system_install()) + cmd_line.AppendSwitch(installer::switches::kSystemLevel); + if (installer_state.verbose_logging()) + cmd_line.AppendSwitch(installer::switches::kVerboseLogging); + AppCommand cmd(cmd_line.GetCommandLineString()); + cmd.set_is_web_accessible(true); + cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); + } +} + } // namespace installer diff --git a/chrome/installer/setup/install_worker.h b/chrome/installer/setup/install_worker.h index a303b28..a9d59b3 100644 --- a/chrome/installer/setup/install_worker.h +++ b/chrome/installer/setup/install_worker.h @@ -215,6 +215,16 @@ void AddOsUpgradeWorkItems(const InstallerState& installer_state, const Product& product, WorkItemList* install_list); +// Adds work items to add or remove the "query-eula-acceptance" command to +// |product|'s version key on the basis of the current operation (represented +// in |installer_state|). |new_version| is the version of the product(s) +// currently being installed -- can be empty on uninstall. +void AddQueryEULAAcceptanceWorkItems(const InstallerState& installer_state, + const FilePath& setup_path, + const Version& new_version, + const Product& product, + WorkItemList* work_item_list); + } // namespace installer #endif // CHROME_INSTALLER_SETUP_INSTALL_WORKER_H_ diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc index 9582423..0d9e800 100644 --- a/chrome/installer/setup/setup_main.cc +++ b/chrome/installer/setup/setup_main.cc @@ -43,6 +43,7 @@ #include "chrome/installer/util/channel_info.h" #include "chrome/installer/util/delete_after_reboot_helper.h" #include "chrome/installer/util/delete_tree_work_item.h" +#include "chrome/installer/util/eula_util.h" #include "chrome/installer/util/google_update_constants.h" #include "chrome/installer/util/google_update_settings.h" #include "chrome/installer/util/google_update_util.h" @@ -1406,6 +1407,8 @@ bool HandleNonInstallCmdLineOptions(const InstallationState& original_state, LOG(DFATAL) << "Chrome product not found."; } *exit_code = InstallUtil::GetInstallReturnCode(status); + } else if (cmd_line.HasSwitch(installer::switches::kQueryEULAAcceptance)) { + *exit_code = installer::IsEULAAccepted(installer_state->system_install()); } else if (cmd_line.HasSwitch(installer::switches::kInactiveUserToast)) { // Launch the inactive user toast experiment. int flavor = -1; diff --git a/chrome/installer/util/eula_util.cc b/chrome/installer/util/eula_util.cc new file mode 100644 index 0000000..98c23c7 --- /dev/null +++ b/chrome/installer/util/eula_util.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/installer/util/eula_util.h" + +#include "base/file_util.h" +#include "base/memory/scoped_ptr.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/installer/util/browser_distribution.h" +#include "chrome/installer/util/install_util.h" +#include "chrome/installer/util/installation_state.h" +#include "chrome/installer/util/master_preferences.h" +#include "chrome/installer/util/master_preferences_constants.h" +#include "chrome/installer/util/util_constants.h" + +namespace installer { + +namespace { + +bool IsChromeFirstRunPending(BrowserDistribution* dist) { + // Chrome creates the first run sentinel after the user has gone through the + // first-run flow. Assume Chrome has been run if the path to the sentinel + // cannot be determined. + FilePath first_run_sentinel; + return InstallUtil::GetSentinelFilePath(chrome::kFirstRunSentinel, + dist, + &first_run_sentinel) + && !file_util::PathExists(first_run_sentinel); +} + +bool IsEULAAcceptanceFlagged(BrowserDistribution* dist) { + // Chrome creates the EULA sentinel after the EULA has been accepted when + // doing so is required by master_preferences. Assume the EULA has not been + // accepted if the path to the sentinel cannot be determined. + FilePath eula_sentinel; + return InstallUtil::GetSentinelFilePath(kEULASentinelFile, + dist, + &eula_sentinel) + && file_util::PathExists(eula_sentinel); +} + +scoped_ptr<MasterPreferences> GetMasterPrefs(const ProductState& prod_state) { + // The standard location of the master prefs is next to the chrome binary. + FilePath master_prefs_path( + prod_state.GetSetupPath().DirName().DirName().DirName()); + scoped_ptr<MasterPreferences> install_prefs(new MasterPreferences( + master_prefs_path.AppendASCII(kDefaultMasterPrefs))); + if (install_prefs && install_prefs->read_from_file()) + return install_prefs.Pass(); + + return scoped_ptr<MasterPreferences>(); +} + +// Attempts to initialize |state| with any Chrome-related product. +// Returns true if any of these product are installed, otherwise false. +bool GetAnyChromeProductState(bool system_level, ProductState* state) { + return state->Initialize(system_level, BrowserDistribution::CHROME_BROWSER) + || state->Initialize(system_level, BrowserDistribution::CHROME_FRAME) + || state->Initialize(system_level, BrowserDistribution::CHROME_APP_HOST); +} + +} // namespace + +EULAAcceptanceResponse IsEULAAccepted(bool system_level) { + ProductState prod_state; + + if (!system_level) { // User-level case has seprate flow. + // Do not simply check Chrome binaries. Instead, check whether or not + // any Chrome-related products is installed, because the presence of any of + // these products at user-level implies that the EULA has been accepted. + return GetAnyChromeProductState(false, &prod_state) + ? QUERY_EULA_ACCEPTED : QUERY_EULA_NOT_ACCEPTED; + } + + // System-level. Try to use Chrome binaries product state. + if (!prod_state.Initialize(true, BrowserDistribution::CHROME_BINARIES)) { + // Fall back to Chrome Browser product state only. + if (!prod_state.Initialize(true, BrowserDistribution::CHROME_BROWSER)) + return QUERY_EULA_FAIL; + + LOG_IF(DFATAL, prod_state.is_multi_install()) + << "Binaries are not installed, but Chrome is multi-install."; + } + BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution( + BrowserDistribution::CHROME_BROWSER); + + // Is Google Update waiting for Chrome's EULA to be accepted? + DWORD eula_accepted = 0; + if (prod_state.GetEulaAccepted(&eula_accepted) && !eula_accepted) + return QUERY_EULA_NOT_ACCEPTED; + + if (!IsChromeFirstRunPending(dist) || IsEULAAcceptanceFlagged(dist)) + return QUERY_EULA_ACCEPTED; + + // EULA acceptance not flagged. Now see if it is required. + scoped_ptr<MasterPreferences> install_prefs(GetMasterPrefs(prod_state)); + // If we fail to get master preferences, assume that EULA is not required. + if (!install_prefs) + return QUERY_EULA_ACCEPTED; + + bool eula_required = false; + // If kRequireEula value is absent, assume EULA is not required. + if (!install_prefs->GetBool(master_preferences::kRequireEula, &eula_required)) + return QUERY_EULA_ACCEPTED; + + return eula_required ? QUERY_EULA_NOT_ACCEPTED : QUERY_EULA_ACCEPTED; +} + +} // namespace installer diff --git a/chrome/installer/util/eula_util.h b/chrome/installer/util/eula_util.h new file mode 100644 index 0000000..7888c09 --- /dev/null +++ b/chrome/installer/util/eula_util.h @@ -0,0 +1,25 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains helper functions to read the Chrome EULA. + +#ifndef CHROME_INSTALLER_UTIL_EULA_UTIL_H_ +#define CHROME_INSTALLER_UTIL_EULA_UTIL_H_ + +namespace installer { + +enum EULAAcceptanceResponse{ + QUERY_EULA_FAIL = -1, + QUERY_EULA_NOT_ACCEPTED = 0, + QUERY_EULA_ACCEPTED = 1, +}; + +// Performs a comprehensive test on EULA acceptance in Chrome. +// This is mostly intended for system-level Chrome, although it also supports +// user-level Chrome (should return QUERY_EULA_ACCEPTED). +EULAAcceptanceResponse IsEULAAccepted(bool system_level); + +} // namespace installer + +#endif // CHROME_INSTALLER_UTIL_EULA_UTIL_H_ diff --git a/chrome/installer/util/installation_validator.cc b/chrome/installer/util/installation_validator.cc index 435c777..3790061 100644 --- a/chrome/installer/util/installation_validator.cc +++ b/chrome/installer/util/installation_validator.cc @@ -270,6 +270,39 @@ void InstallationValidator::ValidateOnOsUpgradeCommand( } } +// Validates the "query-eula-acceptance" Google Update product command. +void InstallationValidator::ValidateQueryEULAAcceptanceCommand( + const ProductContext& ctx, + const AppCommand& command, + bool* is_valid) { + DCHECK(is_valid); + + CommandLine the_command(CommandLine::FromString(command.command_line())); + + ValidateSetupPath(ctx, the_command.GetProgram(), "query EULA acceptance", + is_valid); + + SwitchExpectations expected; + expected.push_back(std::make_pair(std::string(switches::kQueryEULAAcceptance), + true)); + expected.push_back(std::make_pair(std::string(switches::kSystemLevel), + ctx.system_install)); + + ValidateCommandExpectations(ctx, the_command, expected, + "query EULA acceptance", is_valid); + + if (command.sends_pings()) { + *is_valid = false; + LOG(ERROR) << "Query-EULA-acceptance command " + "should not be able to send pings."; + } + + if (!command.is_web_accessible()) { + *is_valid = false; + LOG(ERROR) << "Query-EULA-acceptance command is not web accessible."; + } +} + // Validates the "quick-enable-cf" Google Update product command. void InstallationValidator::ValidateQuickEnableCfCommand( const ProductContext& ctx, @@ -410,6 +443,8 @@ void InstallationValidator::ValidateBinariesCommands( expectations[kCmdQuickEnableApplicationHost] = &ValidateQuickEnableApplicationHostCommand; + + expectations[kCmdQueryEULAAcceptance] = &ValidateQueryEULAAcceptanceCommand; } ValidateAppCommandExpectations(ctx, expectations, is_valid); diff --git a/chrome/installer/util/installation_validator.h b/chrome/installer/util/installation_validator.h index 5ab6031..6315a74 100644 --- a/chrome/installer/util/installation_validator.h +++ b/chrome/installer/util/installation_validator.h @@ -186,12 +186,15 @@ class InstallationValidator { const ProductRules& rules; }; - static void ValidateOnOsUpgradeCommand(const ProductContext& ctx, - const AppCommand& command, - bool* is_valid); static void ValidateInstallAppCommand(const ProductContext& ctx, const AppCommand& command, bool* is_valid); + static void ValidateOnOsUpgradeCommand(const ProductContext& ctx, + const AppCommand& command, + bool* is_valid); + static void ValidateQueryEULAAcceptanceCommand(const ProductContext& ctx, + const AppCommand& command, + bool* is_valid); static void ValidateQuickEnableCfCommand(const ProductContext& ctx, const AppCommand& command, bool* is_valid); diff --git a/chrome/installer/util/installation_validator_unittest.cc b/chrome/installer/util/installation_validator_unittest.cc index 5b2b4eb..9f988da 100644 --- a/chrome/installer/util/installation_validator_unittest.cc +++ b/chrome/installer/util/installation_validator_unittest.cc @@ -90,6 +90,10 @@ class FakeProductState : public ProductState { Level install_level, const char* version, int channel_modifiers); + void AddQueryEULAAcceptanceCommand(BrowserDistribution::Type dist_type, + Level install_level, + const char* version, + int channel_modifiers); void set_multi_install(bool is_multi_install) { multi_install_ = is_multi_install; } @@ -266,6 +270,25 @@ void FakeProductState::AddOsUpgradeCommand(BrowserDistribution::Type dist_type, commands_.Set(installer::kCmdOnOsUpgrade, app_cmd); } +// Adds the "query-eula-acceptance" Google Update product command. +void FakeProductState::AddQueryEULAAcceptanceCommand( + BrowserDistribution::Type dist_type, + Level install_level, + const char* version, + int channel_modifiers) { + DCHECK_EQ(dist_type, BrowserDistribution::CHROME_BINARIES); + + CommandLine cmd_line(GetSetupExePath(dist_type, install_level, version, + channel_modifiers)); + cmd_line.AppendSwitch(installer::switches::kQueryEULAAcceptance); + if (install_level == SYSTEM_LEVEL) + cmd_line.AppendSwitch(installer::switches::kSystemLevel); + cmd_line.AppendSwitch(installer::switches::kVerboseLogging); + AppCommand app_cmd(cmd_line.GetCommandLineString()); + app_cmd.set_is_web_accessible(true); + commands_.Set(installer::kCmdQueryEULAAcceptance, app_cmd); +} + } // namespace // Fixture for testing the InstallationValidator. Errors logged by the @@ -450,12 +473,17 @@ void InstallationValidatorTest::MakeProductState( state->SetUninstallCommand(prod_type, install_level, chrome::kChromeVersion, channel_modifiers, vehicle); state->set_multi_install(is_multi_install); - if (prod_type == BrowserDistribution::CHROME_BINARIES && - (inst_type == InstallationValidator::CHROME_MULTI || - inst_type == - InstallationValidator::CHROME_FRAME_READY_MODE_CHROME_MULTI)) { - state->AddQuickEnableCfCommand(prod_type, install_level, - chrome::kChromeVersion, channel_modifiers); + if (prod_type == BrowserDistribution::CHROME_BINARIES) { + if (inst_type == InstallationValidator::CHROME_MULTI || + inst_type == + InstallationValidator::CHROME_FRAME_READY_MODE_CHROME_MULTI) { + state->AddQuickEnableCfCommand(prod_type, install_level, + chrome::kChromeVersion, channel_modifiers); + } + state->AddQueryEULAAcceptanceCommand(prod_type, + install_level, + chrome::kChromeVersion, + channel_modifiers); } if (prod_type == BrowserDistribution::CHROME_BINARIES) { state->AddQuickEnableApplicationHostCommand(prod_type, diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc index ef2b076..b41fada 100644 --- a/chrome/installer/util/util_constants.cc +++ b/chrome/installer/util/util_constants.cc @@ -122,6 +122,10 @@ const char kNewSetupExe[] = "new-setup-exe"; // Notify the installer that the OS has been upgraded. const char kOnOsUpgrade[] = "on-os-upgrade"; +// Determines whether or not EULA has been accepted at some point. Returns via +// exit code: 0 if EULA not accepted, 1 if EULA accepted, and E_FAIL on error. +const char kQueryEULAAcceptance[] = "query-eula-acceptance"; + // Register Chrome as a valid browser on the current sytem. This option // requires that setup.exe is running as admin. If this option is specified, // options kInstallArchive and kUninstall are ignored. @@ -215,6 +219,7 @@ const wchar_t kChromeNewExe[] = L"new_chrome.exe"; const wchar_t kChromeOldExe[] = L"old_chrome.exe"; const wchar_t kCmdInstallApp[] = L"install-application"; const wchar_t kCmdOnOsUpgrade[] = L"on-os-upgrade"; +const wchar_t kCmdQueryEULAAcceptance[] = L"query-eula-acceptance"; const wchar_t kCmdQuickEnableApplicationHost[] = L"quick-enable-application-host"; const wchar_t kCmdQuickEnableCf[] = L"quick-enable-cf"; diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h index da07084..3892cc2a 100644 --- a/chrome/installer/util/util_constants.h +++ b/chrome/installer/util/util_constants.h @@ -158,6 +158,7 @@ extern const char kMsi[]; extern const char kMultiInstall[]; extern const char kNewSetupExe[]; extern const char kOnOsUpgrade[]; +extern const char kQueryEULAAcceptance[]; extern const char kRegisterChromeBrowser[]; extern const char kRegisterChromeBrowserSuffix[]; extern const char kRegisterDevChrome[]; @@ -191,6 +192,7 @@ extern const wchar_t kChromeOldExe[]; extern const wchar_t kChromeNewExe[]; extern const wchar_t kCmdInstallApp[]; extern const wchar_t kCmdOnOsUpgrade[]; +extern const wchar_t kCmdQueryEULAAcceptance[]; extern const wchar_t kCmdQuickEnableApplicationHost[]; extern const wchar_t kCmdQuickEnableCf[]; extern const wchar_t kDelegateExecuteExe[]; |