summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 22:11:23 +0000
committermpearson@chromium.org <mpearson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-25 22:11:23 +0000
commitefde268d313a402ff730906cc30719d71a7e07b0 (patch)
tree5998ac359a448c7d0541ff6d1d09a73272f938e3
parent3aa54ea723c1f673d9ba184465f42f3555719970 (diff)
downloadchromium_src-efde268d313a402ff730906cc30719d71a7e07b0.zip
chromium_src-efde268d313a402ff730906cc30719d71a7e07b0.tar.gz
chromium_src-efde268d313a402ff730906cc30719d71a7e07b0.tar.bz2
Revert 285661 "Remove some dead app host code."
Causes compile failures on official builders: e.g., http://build.chromium.org/p/chromium.chrome/builders/Google%20Chrome%20Win/ FAILED: ninja -t msvc -e environment.x64 -- c:\b\build\goma/gomacc "c:\b\depot_tools\win_toolchain\vs2013_files\VC\bin\amd64\cl.exe" /nologo /showIncludes /FC @obj\chrome\installer\util\installer_util_nacl_win64.chrome_app_host_distribution.obj.rsp /c ..\..\chrome\installer\util\chrome_app_host_distribution.cc /Foobj\chrome\installer\util\installer_util_nacl_win64.chrome_app_host_distribution.obj /Fdobj\chrome\installer_util_nacl_win64.cc.pdb c:\b\build\slave\google-chrome-rel-win\build\src\chrome\installer\util\chrome_app_host_distribution.cc(126) :error C2065: 'kChromeAppHostGuid' : undeclared identifier ninja: build stopped: subcommand failed. > Remove some dead app host code. > > app_host.exe was removed in r220555. This change removes some dead code > that was left behind. Specifically: > - chrome_launcher_support no longer exposes any methods related to the > AppHost. > - Chrome's uninstall prompt no longer has a special case to handle > suppressing the "delete your profile" checkbox. > - Chrome and its installer no longer have a dependency on > launcher_support. > - The installer no longer supports installing items from the webstore. > - GetUntrustedDataValue no longer has consumers and is gone. > > BUG=297647 > R=benwells@chromium.org,huangs@chromium.org,gab@chromium.org > > Review URL: https://codereview.chromium.org/422453004 TBR=grt@chromium.org Review URL: https://codereview.chromium.org/422593002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285706 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/BUILD.gn1
-rw-r--r--chrome/browser/chrome_browser_main_win.cc5
-rw-r--r--chrome/browser/extensions/BUILD.gn1
-rw-r--r--chrome/browser/ui/BUILD.gn1
-rw-r--r--chrome/browser/ui/uninstall_browser_prompt.h2
-rw-r--r--chrome/browser/ui/views/app_list/win/app_list_service_win.cc4
-rw-r--r--chrome/browser/ui/views/uninstall_view.cc31
-rw-r--r--chrome/browser/ui/views/uninstall_view.h4
-rw-r--r--chrome/chrome_browser.gypi1
-rw-r--r--chrome/chrome_browser_extensions.gypi1
-rw-r--r--chrome/chrome_browser_ui.gypi1
-rw-r--r--chrome/chrome_installer.gypi2
-rw-r--r--chrome/installer/launcher_support/chrome_launcher_support.cc146
-rw-r--r--chrome/installer/launcher_support/chrome_launcher_support.h54
-rw-r--r--chrome/installer/setup/install.cc14
-rw-r--r--chrome/installer/setup/install.h5
-rw-r--r--chrome/installer/setup/setup_constants.cc4
-rw-r--r--chrome/installer/setup/setup_constants.h2
-rw-r--r--chrome/installer/setup/setup_main.cc10
-rw-r--r--chrome/installer/setup/uninstall.cc29
-rw-r--r--chrome/installer/util/chrome_app_host_distribution.cc8
-rw-r--r--chrome/installer/util/google_update_util.cc100
-rw-r--r--chrome/installer/util/google_update_util.h14
-rw-r--r--chrome/installer/util/util_constants.cc1
-rw-r--r--chrome/installer/util/util_constants.h1
25 files changed, 394 insertions, 48 deletions
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index ae62e2d..2395bec 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -505,6 +505,7 @@ static_library("browser") {
"//third_party/wtl",
#"chrome_process_finder", TODO(GYP)
#"installer_util_strings", TODO(GYP)
+ #"launcher_support", TODO(GYP)
#"../chrome/chrome.gyp:chrome_version_header", TODO(GYP)
#"../chrome_elf/chrome_elf.gyp:chrome_elf", TODO(GYP)
#"../chrome_elf/chrome_elf.gyp:chrome_elf_constants", TODO(GYP)
diff --git a/chrome/browser/chrome_browser_main_win.cc b/chrome/browser/chrome_browser_main_win.cc
index 0912b3f..c03597d 100644
--- a/chrome/browser/chrome_browser_main_win.cc
+++ b/chrome/browser/chrome_browser_main_win.cc
@@ -38,6 +38,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/env_vars.h"
+#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/install_util.h"
@@ -118,7 +119,9 @@ int DoUninstallTasks(bool chrome_still_running) {
ShowCloseBrowserFirstMessageBox();
return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
}
- int result = chrome::ShowUninstallBrowserPrompt();
+ int result = chrome::ShowUninstallBrowserPrompt(
+ !chrome_launcher_support::IsAppLauncherPresent());
+ // Don't offer to delete the profile if the App Launcher is also installed.
if (browser_util::IsBrowserAlreadyRunning()) {
ShowCloseBrowserFirstMessageBox();
return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE;
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index a8a0cab..ec27dc8 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -196,6 +196,7 @@ static_library("extensions") {
deps += [
"//third_party/iaccessible2",
"//third_party/isimpledom",
+ #'launcher_support', TODO(GYP)
]
} else if (!is_chromeos) {
sources += [ "api/system_display/display_info_provider_aura.cc" ]
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 0960e3b..5789a58 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -340,6 +340,7 @@ static_library("ui") {
"//ui/views",
"//ui/views/controls/webview",
#'installer_util_strings', TODO(GYP)
+ #'launcher_support', TODO(GYP)
#'metro_utils', TODO(GYP)
#'../google_update/google_update.gyp:google_update', TODO(GYP)
]
diff --git a/chrome/browser/ui/uninstall_browser_prompt.h b/chrome/browser/ui/uninstall_browser_prompt.h
index 15ce952..eb3c5bc 100644
--- a/chrome/browser/ui/uninstall_browser_prompt.h
+++ b/chrome/browser/ui/uninstall_browser_prompt.h
@@ -11,7 +11,7 @@ namespace chrome {
// content::RESULT_CODE_NORMAL_EXIT,
// chrome::RESULT_CODE_UNINSTALL_DELETE_PROFILE or
// chrome::RESULT_CODE_UNINSTALL_USER_CANCEL.
-int ShowUninstallBrowserPrompt();
+int ShowUninstallBrowserPrompt(bool show_delete_profile);
} // namespace chrome
diff --git a/chrome/browser/ui/views/app_list/win/app_list_service_win.cc b/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
index fffb424..90cc609 100644
--- a/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
+++ b/chrome/browser/ui/views/app_list/win/app_list_service_win.cc
@@ -41,10 +41,10 @@
#include "ui/base/win/shell.h"
#if defined(GOOGLE_CHROME_BUILD)
+#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/util/google_update_settings.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/updating_app_registration_data.h"
-#include "chrome/installer/util/util_constants.h"
#endif // GOOGLE_CHROME_BUILD
// static
@@ -147,7 +147,7 @@ void SetDidRunForNDayActiveStats() {
if (chrome_binaries_dist &&
InstallUtil::IsMultiInstall(chrome_binaries_dist, system_install)) {
UpdatingAppRegistrationData app_launcher_reg_data(
- installer::kAppLauncherGuid);
+ chrome_launcher_support::kAppLauncherGuid);
GoogleUpdateSettings::UpdateDidRunStateForApp(
app_launcher_reg_data, true /* did_run */);
}
diff --git a/chrome/browser/ui/views/uninstall_view.cc b/chrome/browser/ui/views/uninstall_view.cc
index 4c04281..bbd856d 100644
--- a/chrome/browser/ui/views/uninstall_view.cc
+++ b/chrome/browser/ui/views/uninstall_view.cc
@@ -23,8 +23,10 @@
#include "ui/views/widget/widget.h"
UninstallView::UninstallView(int* user_selection,
- const base::Closure& quit_closure)
+ const base::Closure& quit_closure,
+ bool show_delete_profile)
: confirm_label_(NULL),
+ show_delete_profile_(show_delete_profile),
delete_profile_(NULL),
change_default_browser_(NULL),
browsers_combo_(NULL),
@@ -62,15 +64,17 @@ void UninstallView::SetupControls() {
layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
// The "delete profile" check box.
- ++column_set_id;
- column_set = layout->AddColumnSet(column_set_id);
- column_set->AddPaddingColumn(0, views::kPanelHorizIndentation);
- column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0);
- layout->StartRow(0, column_set_id);
- delete_profile_ = new views::Checkbox(
- l10n_util::GetStringUTF16(IDS_UNINSTALL_DELETE_PROFILE));
- layout->AddView(delete_profile_);
+ if (show_delete_profile_) {
+ ++column_set_id;
+ column_set = layout->AddColumnSet(column_set_id);
+ column_set->AddPaddingColumn(0, views::kPanelHorizIndentation);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0);
+ layout->StartRow(0, column_set_id);
+ delete_profile_ = new views::Checkbox(
+ l10n_util::GetStringUTF16(IDS_UNINSTALL_DELETE_PROFILE));
+ layout->AddView(delete_profile_);
+ }
// Set default browser combo box. If the default should not or cannot be
// changed, widgets are not shown. We assume here that if Chrome cannot
@@ -111,7 +115,7 @@ void UninstallView::SetupControls() {
bool UninstallView::Accept() {
user_selection_ = content::RESULT_CODE_NORMAL_EXIT;
- if (delete_profile_->checked())
+ if (show_delete_profile_ && delete_profile_->checked())
user_selection_ = chrome::RESULT_CODE_UNINSTALL_DELETE_PROFILE;
if (change_default_browser_ && change_default_browser_->checked()) {
BrowsersMap::const_iterator i = browsers_->begin();
@@ -163,7 +167,7 @@ base::string16 UninstallView::GetItemAt(int index) {
namespace chrome {
-int ShowUninstallBrowserPrompt() {
+int ShowUninstallBrowserPrompt(bool show_delete_profile) {
DCHECK(base::MessageLoopForUI::IsCurrent());
int result = content::RESULT_CODE_NORMAL_EXIT;
@@ -178,7 +182,8 @@ int ShowUninstallBrowserPrompt() {
base::RunLoop run_loop;
UninstallView* view = new UninstallView(&result,
- run_loop.QuitClosure());
+ run_loop.QuitClosure(),
+ show_delete_profile);
views::DialogDelegate::CreateDialogWidget(view, NULL, NULL)->Show();
run_loop.Run();
return result;
diff --git a/chrome/browser/ui/views/uninstall_view.h b/chrome/browser/ui/views/uninstall_view.h
index c50a3cd..8fc784d 100644
--- a/chrome/browser/ui/views/uninstall_view.h
+++ b/chrome/browser/ui/views/uninstall_view.h
@@ -29,7 +29,8 @@ class UninstallView : public views::ButtonListener,
public ui::ComboboxModel {
public:
explicit UninstallView(int* user_selection,
- const base::Closure& quit_closure);
+ const base::Closure& quit_closure,
+ bool show_delete_profile);
virtual ~UninstallView();
// Overridden form views::ButtonListener.
@@ -56,6 +57,7 @@ class UninstallView : public views::ButtonListener,
void SetupControls();
views::Label* confirm_label_;
+ bool show_delete_profile_;
views::Checkbox* delete_profile_;
views::Checkbox* change_default_browser_;
views::Combobox* browsers_combo_;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index b5f3886..5093cf4 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3332,6 +3332,7 @@
'dependencies': [
'chrome_process_finder',
'installer_util_strings',
+ 'launcher_support',
'../chrome/chrome.gyp:chrome_version_header',
'../chrome_elf/chrome_elf.gyp:chrome_elf',
'../chrome_elf/chrome_elf.gyp:chrome_elf_constants',
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index ee0c223..d84973a 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -1134,6 +1134,7 @@
}],
['OS=="win"', {
'dependencies': [
+ 'launcher_support',
'../third_party/iaccessible2/iaccessible2.gyp:iaccessible2',
'../third_party/isimpledom/isimpledom.gyp:isimpledom',
],
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index b467883..ad12cf1 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -2846,6 +2846,7 @@
],
'dependencies': [
'installer_util_strings',
+ 'launcher_support',
'metro_utils',
'../google_update/google_update.gyp:google_update',
'../third_party/iaccessible2/iaccessible2.gyp:iaccessible2',
diff --git a/chrome/chrome_installer.gypi b/chrome/chrome_installer.gypi
index 8281e21..ee3754b 100644
--- a/chrome/chrome_installer.gypi
+++ b/chrome/chrome_installer.gypi
@@ -216,6 +216,7 @@
'dependencies': [
'installer_util',
'installer_util_strings',
+ 'launcher_support',
'../base/base.gyp:base',
'../breakpad/breakpad.gyp:breakpad_handler',
'../chrome/common_constants.gyp:common_constants',
@@ -330,6 +331,7 @@
'dependencies': [
'installer_util',
'installer_util_strings',
+ 'launcher_support',
'../base/base.gyp:base',
'../base/base.gyp:base_i18n',
'../base/base.gyp:test_support_base',
diff --git a/chrome/installer/launcher_support/chrome_launcher_support.cc b/chrome/installer/launcher_support/chrome_launcher_support.cc
index 9e9ba92..8e5b6a5 100644
--- a/chrome/installer/launcher_support/chrome_launcher_support.cc
+++ b/chrome/installer/launcher_support/chrome_launcher_support.cc
@@ -5,12 +5,20 @@
#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include <windows.h>
+#include <tchar.h>
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/process/launch.h"
#include "base/strings/string16.h"
#include "base/win/registry.h"
+#ifndef OFFICIAL_BUILD
+#include "base/path_service.h"
+#endif
+
namespace chrome_launcher_support {
namespace {
@@ -18,6 +26,8 @@ namespace {
// TODO(huangs) Refactor the constants: http://crbug.com/148538
const wchar_t kGoogleRegClientStateKey[] =
L"Software\\Google\\Update\\ClientState";
+const wchar_t kGoogleRegClientsKey[] = L"Software\\Google\\Update\\Clients";
+const wchar_t kRegVersionField[] = L"pv";
// Copied from chrome_appid.cc.
const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
@@ -25,8 +35,14 @@ const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}";
// Copied from google_chrome_distribution.cc.
const wchar_t kBrowserAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}";
+// Copied frome google_chrome_sxs_distribution.cc.
+const wchar_t kSxSBrowserAppGuid[] = L"{4ea16ac7-fd5a-47c3-875b-dbf4a2008c20}";
+
// Copied from util_constants.cc.
+const wchar_t kChromeAppHostExe[] = L"app_host.exe";
+const char kChromeAppLauncher[] = "app-launcher";
const wchar_t kChromeExe[] = L"chrome.exe";
+const wchar_t kUninstallArgumentsField[] = L"UninstallArguments";
const wchar_t kUninstallStringField[] = L"UninstallString";
// Reads a string value from the specified product's "ClientState" registry key.
@@ -50,6 +66,33 @@ bool GetClientStateValue(InstallationLevel level,
return false;
}
+// Determines whether the specified product has a key in "Clients". This
+// indicates whether the product is installed at the given level.
+bool IsProductInstalled(InstallationLevel level, const wchar_t* app_guid) {
+ HKEY root_key = (level == USER_LEVEL_INSTALLATION) ?
+ HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
+ base::string16 subkey(kGoogleRegClientsKey);
+ subkey.append(1, L'\\').append(app_guid);
+ base::win::RegKey reg_key;
+ // Google Update always uses 32bit hive.
+ return reg_key.Open(root_key, subkey.c_str(),
+ KEY_QUERY_VALUE | KEY_WOW64_32KEY) == ERROR_SUCCESS &&
+ reg_key.HasValue(kRegVersionField);
+}
+
+bool IsAppLauncherEnabledAtLevel(InstallationLevel level) {
+ base::string16 uninstall_arguments;
+ if (GetClientStateValue(level,
+ kAppLauncherGuid,
+ kUninstallArgumentsField,
+ &uninstall_arguments)) {
+ return CommandLine::FromString(L"dummy.exe " + uninstall_arguments)
+ .HasSwitch(kChromeAppLauncher) &&
+ !GetAppHostPathForInstallationLevel(level).empty();
+ }
+ return false;
+}
+
// Reads the path to setup.exe from the value "UninstallString" within the
// specified product's "ClientState" registry key. Returns an empty FilePath if
// an error occurs or the product is not installed at the specified level.
@@ -64,22 +107,9 @@ base::FilePath GetSetupExeFromRegistry(InstallationLevel level,
return base::FilePath();
}
-// Returns the path to an existing setup.exe at the specified level, if it can
-// be found via Omaha client state.
-base::FilePath GetSetupExeForInstallationLevel(InstallationLevel level) {
- // Look in the registry for Chrome Binaries first.
- base::FilePath setup_exe_path(
- GetSetupExeFromRegistry(level, kBinariesAppGuid));
- // If the above fails, look in the registry for Chrome next.
- if (setup_exe_path.empty())
- setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid);
- // If we fail again, then setup_exe_path would be empty.
- return setup_exe_path;
-}
-
-// Returns the path to an installed |exe_file| (e.g. chrome.exe) at the
-// specified level, given |setup_exe_path| from Omaha client state. Returns
-// empty base::FilePath if none found, or if |setup_exe_path| is empty.
+// Returns the path to an installed |exe_file| (e.g. chrome.exe, app_host.exe)
+// at the specified level, given |setup_exe_path| from Omaha client state.
+// Returns empty base::FilePath if none found, or if |setup_exe_path| is empty.
base::FilePath FindExeRelativeToSetupExe(const base::FilePath setup_exe_path,
const wchar_t* exe_file) {
if (!setup_exe_path.empty()) {
@@ -101,11 +131,52 @@ base::FilePath FindExeRelativeToSetupExe(const base::FilePath setup_exe_path,
} // namespace
+const wchar_t kAppLauncherGuid[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
+
+void UninstallLegacyAppLauncher(InstallationLevel level) {
+ base::FilePath setup_exe(GetSetupExeFromRegistry(level, kAppLauncherGuid));
+ if (setup_exe.empty())
+ return;
+ base::string16 uninstall_arguments;
+ if (GetClientStateValue(level,
+ kAppLauncherGuid,
+ kUninstallArgumentsField,
+ &uninstall_arguments)) {
+ CommandLine uninstall_cmd = CommandLine::FromString(
+ L"\"" + setup_exe.value() + L"\" " + uninstall_arguments);
+
+ VLOG(1) << "Uninstalling legacy app launcher with command line: "
+ << uninstall_cmd.GetCommandLineString();
+ base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL);
+ }
+}
+
+base::FilePath GetSetupExeForInstallationLevel(InstallationLevel level) {
+ // Look in the registry for Chrome Binaries first.
+ base::FilePath setup_exe_path(
+ GetSetupExeFromRegistry(level, kBinariesAppGuid));
+ // If the above fails, look in the registry for Chrome next.
+ if (setup_exe_path.empty())
+ setup_exe_path = GetSetupExeFromRegistry(level, kBrowserAppGuid);
+ // If we fail again, then setup_exe_path would be empty.
+ return setup_exe_path;
+}
+
base::FilePath GetChromePathForInstallationLevel(InstallationLevel level) {
return FindExeRelativeToSetupExe(
GetSetupExeForInstallationLevel(level), kChromeExe);
}
+base::FilePath GetAppHostPathForInstallationLevel(InstallationLevel level) {
+ return FindExeRelativeToSetupExe(
+ GetSetupExeFromRegistry(level, kAppLauncherGuid), kChromeAppHostExe);
+}
+
+base::FilePath GetChromeSxSPathForInstallationLevel(InstallationLevel level) {
+ return FindExeRelativeToSetupExe(
+ GetSetupExeFromRegistry(level, kSxSBrowserAppGuid), kChromeExe);
+}
+
base::FilePath GetAnyChromePath() {
base::FilePath chrome_path;
if (chrome_path.empty())
@@ -115,4 +186,47 @@ base::FilePath GetAnyChromePath() {
return chrome_path;
}
+base::FilePath GetAnyAppHostPath() {
+ base::FilePath app_host_path;
+ if (app_host_path.empty()) {
+ app_host_path = GetAppHostPathForInstallationLevel(
+ SYSTEM_LEVEL_INSTALLATION);
+ }
+ if (app_host_path.empty())
+ app_host_path = GetAppHostPathForInstallationLevel(USER_LEVEL_INSTALLATION);
+ return app_host_path;
+}
+
+base::FilePath GetAnyChromeSxSPath() {
+ base::FilePath path =
+ GetChromeSxSPathForInstallationLevel(USER_LEVEL_INSTALLATION);
+ if (path.empty())
+ path = GetChromeSxSPathForInstallationLevel(SYSTEM_LEVEL_INSTALLATION);
+ return path;
+}
+
+bool IsAppHostPresent() {
+ base::FilePath app_host_exe = GetAnyAppHostPath();
+ return !app_host_exe.empty();
+}
+
+InstallationState GetAppLauncherInstallationState() {
+ if (IsAppLauncherEnabledAtLevel(SYSTEM_LEVEL_INSTALLATION))
+ return INSTALLED_AT_SYSTEM_LEVEL;
+
+ if (IsAppLauncherEnabledAtLevel(USER_LEVEL_INSTALLATION))
+ return INSTALLED_AT_USER_LEVEL;
+
+ return NOT_INSTALLED;
+}
+
+bool IsAppLauncherPresent() {
+ return GetAppLauncherInstallationState() != NOT_INSTALLED;
+}
+
+bool IsChromeBrowserPresent() {
+ return IsProductInstalled(USER_LEVEL_INSTALLATION, kBrowserAppGuid) ||
+ IsProductInstalled(SYSTEM_LEVEL_INSTALLATION, kBrowserAppGuid);
+}
+
} // namespace chrome_launcher_support
diff --git a/chrome/installer/launcher_support/chrome_launcher_support.h b/chrome/installer/launcher_support/chrome_launcher_support.h
index 9cf1479..f50ff28 100644
--- a/chrome/installer/launcher_support/chrome_launcher_support.h
+++ b/chrome/installer/launcher_support/chrome_launcher_support.h
@@ -16,18 +16,72 @@ enum InstallationLevel {
SYSTEM_LEVEL_INSTALLATION,
};
+enum InstallationState {
+ NOT_INSTALLED,
+ INSTALLED_AT_USER_LEVEL,
+ INSTALLED_AT_SYSTEM_LEVEL,
+};
+
+// The app GUID for Chrome App Launcher.
+extern const wchar_t kAppLauncherGuid[];
+
+// Returns the path to an existing setup.exe at the specified level, if it can
+// be found via Omaha client state.
+base::FilePath GetSetupExeForInstallationLevel(InstallationLevel level);
+
// Returns the path to an installed chrome.exe at the specified level, if it can
// be found via Omaha client state. Prefers the installer from a multi-install,
// but may also return that of a single-install of Chrome if no multi-install
// exists.
base::FilePath GetChromePathForInstallationLevel(InstallationLevel level);
+// Returns the path to an installed app_host.exe at the specified level, if
+// it can be found via Omaha client state.
+base::FilePath GetAppHostPathForInstallationLevel(InstallationLevel level);
+
+// Returns the path to an installed SxS chrome.exe at the specified level, if
+// it can be found via Omaha client state.
+base::FilePath GetChromeSxSPathForInstallationLevel(InstallationLevel level);
+
// Returns the path to an installed chrome.exe, or an empty path. Prefers a
// system-level installation to a user-level installation. Uses Omaha client
// state to identify a Chrome installation location.
// The file path returned (if any) is guaranteed to exist.
base::FilePath GetAnyChromePath();
+// Returns the path to an installed app_host.exe, or an empty path. Prefers a
+// system-level installation to a user-level installation. Uses Omaha client
+// state to identify a App Host installation location.
+// The file path returned (if any) is guaranteed to exist.
+base::FilePath GetAnyAppHostPath();
+
+// Returns the path to an installed SxS chrome.exe, or an empty path. Prefers a
+// user-level installation to a system-level installation. Uses Omaha client
+// state to identify a Chrome Canary installation location.
+// The file path returned (if any) is guaranteed to exist.
+base::FilePath GetAnyChromeSxSPath();
+
+// Uninstalls the legacy app launcher by launching setup.exe with the uninstall
+// arguments from the App Launcher ClientState registry key. The uninstall will
+// run asynchronously.
+void UninstallLegacyAppLauncher(InstallationLevel level);
+
+// Returns true if App Host is installed (system-level or user-level),
+// or in the same directory as the current executable.
+bool IsAppHostPresent();
+
+// Returns the app launcher installation state. If the launcher is installed
+// at both system level and user level, system level is returned.
+InstallationState GetAppLauncherInstallationState();
+
+// Returns true if App Launcher is installed (system-level or user-level).
+bool IsAppLauncherPresent();
+
+// Returns true if the Chrome browser is installed (system-level or user-level).
+// If this is running in an official build, it will check if a non-canary build
+// if installed. If it is not an official build, it will always return true.
+bool IsChromeBrowserPresent();
+
} // namespace chrome_launcher_support
#endif // CHROME_INSTALLER_LAUNCHER_SUPPORT_CHROME_LAUNCHER_SUPPORT_H_
diff --git a/chrome/installer/setup/install.cc b/chrome/installer/setup/install.cc
index 5ba2608..05e5b9b 100644
--- a/chrome/installer/setup/install.cc
+++ b/chrome/installer/setup/install.cc
@@ -10,12 +10,14 @@
#include <string>
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/numerics/safe_conversions.h"
#include "base/path_service.h"
+#include "base/process/launch.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@@ -23,6 +25,7 @@
#include "base/win/windows_version.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/setup/install_worker.h"
#include "chrome/installer/setup/setup_constants.h"
#include "chrome/installer/util/auto_launch_util.h"
@@ -688,4 +691,15 @@ void HandleActiveSetupForBrowser(const base::FilePath& installation_root,
chrome_exe, chrome, prefs, CURRENT_USER, install_operation);
}
+bool InstallFromWebstore(const std::string& app_code) {
+ base::FilePath app_host_path(chrome_launcher_support::GetAnyAppHostPath());
+ if (app_host_path.empty())
+ return false;
+
+ CommandLine cmd(app_host_path);
+ cmd.AppendSwitchASCII(::switches::kInstallFromWebstore, app_code);
+ VLOG(1) << "App install command: " << cmd.GetCommandLineString();
+ return base::LaunchProcess(cmd, base::LaunchOptions(), NULL);
+}
+
} // namespace installer
diff --git a/chrome/installer/setup/install.h b/chrome/installer/setup/install.h
index 22f3c3d..a700b3c 100644
--- a/chrome/installer/setup/install.h
+++ b/chrome/installer/setup/install.h
@@ -132,6 +132,11 @@ void HandleActiveSetupForBrowser(const base::FilePath& installation_root,
const Product& chrome,
bool force);
+// Launches app_host.exe to install content from web store (non-blocking).
+// Returns true on successful execution (although successful installation
+// is not guaranteed).
+bool InstallFromWebstore(const std::string& app_code);
+
} // namespace installer
#endif // CHROME_INSTALLER_SETUP_INSTALL_H_
diff --git a/chrome/installer/setup/setup_constants.cc b/chrome/installer/setup/setup_constants.cc
index 77c03a6..10b8479 100644
--- a/chrome/installer/setup/setup_constants.cc
+++ b/chrome/installer/setup/setup_constants.cc
@@ -20,4 +20,8 @@ const wchar_t kInstallSourceChromeDir[] = L"Chrome-bin";
const wchar_t kMediaPlayerRegPath[] =
L"Software\\Microsoft\\MediaPlayer\\ShimInclusionList";
+// Key names for values passed via the GoogleUpdateUntrustedData environment
+// variable.
+const char kInstallFromWebstore[] = "install-from-webstore";
+
} // namespace installer
diff --git a/chrome/installer/setup/setup_constants.h b/chrome/installer/setup/setup_constants.h
index 9e146b8..376350a 100644
--- a/chrome/installer/setup/setup_constants.h
+++ b/chrome/installer/setup/setup_constants.h
@@ -20,6 +20,8 @@ extern const wchar_t kInstallSourceChromeDir[];
extern const wchar_t kMediaPlayerRegPath[];
+extern const char kInstallFromWebstore[];
+
} // namespace installer
#endif // CHROME_INSTALLER_SETUP_SETUP_CONSTANTS_H__
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index eda79e5..c5b8c0ff 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -1639,6 +1639,16 @@ InstallStatus InstallProductsHelper(
RemoveChromeLegacyRegistryKeys(chrome->distribution(), chrome_exe);
}
}
+
+ if (prefs.install_chrome_app_launcher() &&
+ InstallUtil::GetInstallReturnCode(install_status) == 0) {
+ std::string webstore_item(google_update::GetUntrustedDataValue(
+ kInstallFromWebstore));
+ if (!webstore_item.empty()) {
+ bool success = InstallFromWebstore(webstore_item);
+ VLOG_IF(1, !success) << "Failed to launch app installation.";
+ }
+ }
}
}
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index ce02a20..146359f 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -26,6 +26,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_result_codes.h"
+#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/setup/install.h"
#include "chrome/installer/setup/install_worker.h"
#include "chrome/installer/setup/setup_constants.h"
@@ -1280,18 +1281,24 @@ InstallStatus UninstallProduct(const InstallationState& original_state,
// TODO(huangs): Implement actual migration code and remove the hack below.
// Remove the "shadow" App Launcher registry keys.
- // TODO(hunags): Management of this key should not be conditional on
- // multi-install since the app list feature is available regardless of how
- // chrome is installed.
if (installer_state.is_multi_install()) {
- // Delete the "shadow" keys.
- BrowserDistribution* shadow_app_launcher_dist =
- BrowserDistribution::GetSpecificDistribution(
- BrowserDistribution::CHROME_APP_HOST);
- InstallUtil::DeleteRegistryKey(
- reg_root,
- shadow_app_launcher_dist->GetVersionKey(),
- KEY_WOW64_32KEY);
+ // If we're not uninstalling the legacy App Launcher, and if it was
+ // not installed in the first place, then delete the "shadow" keys.
+ chrome_launcher_support::InstallationState level_to_check =
+ installer_state.system_install() ?
+ chrome_launcher_support::INSTALLED_AT_SYSTEM_LEVEL :
+ chrome_launcher_support::INSTALLED_AT_USER_LEVEL;
+ bool has_legacy_app_launcher = level_to_check ==
+ chrome_launcher_support::GetAppLauncherInstallationState();
+ if (!has_legacy_app_launcher) {
+ BrowserDistribution* shadow_app_launcher_dist =
+ BrowserDistribution::GetSpecificDistribution(
+ BrowserDistribution::CHROME_APP_HOST);
+ InstallUtil::DeleteRegistryKey(
+ reg_root,
+ shadow_app_launcher_dist->GetVersionKey(),
+ KEY_WOW64_32KEY);
+ }
}
}
diff --git a/chrome/installer/util/chrome_app_host_distribution.cc b/chrome/installer/util/chrome_app_host_distribution.cc
index 6e831e5..85e50d5 100644
--- a/chrome/installer/util/chrome_app_host_distribution.cc
+++ b/chrome/installer/util/chrome_app_host_distribution.cc
@@ -21,11 +21,17 @@
#include "installer_util_strings.h" // NOLINT
+namespace {
+
+const wchar_t kChromeAppHostGuid[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
+
+} // namespace
+
ChromeAppHostDistribution::ChromeAppHostDistribution()
: BrowserDistribution(
CHROME_APP_HOST,
scoped_ptr<AppRegistrationData>(
- new UpdatingAppRegistrationData(installer::kAppLauncherGuid))) {
+ new UpdatingAppRegistrationData(kChromeAppHostGuid))) {
}
base::string16 ChromeAppHostDistribution::GetBaseAppName() {
diff --git a/chrome/installer/util/google_update_util.cc b/chrome/installer/util/google_update_util.cc
index d3013ba..c7de7a5 100644
--- a/chrome/installer/util/google_update_util.cc
+++ b/chrome/installer/util/google_update_util.cc
@@ -4,19 +4,28 @@
#include "chrome/installer/util/google_update_util.h"
+#include <algorithm>
+#include <map>
+#include <utility>
+#include <vector>
+
#include "base/command_line.h"
+#include "base/environment.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/process/kill.h"
#include "base/process/launch.h"
#include "base/strings/string16.h"
+#include "base/strings/string_split.h"
#include "base/time/time.h"
#include "base/win/registry.h"
#include "base/win/scoped_handle.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
+#include "chrome/installer/launcher_support/chrome_launcher_support.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/google_update_constants.h"
#include "chrome/installer/util/google_update_settings.h"
@@ -32,6 +41,9 @@ namespace {
const int kGoogleUpdateTimeoutMs = 20 * 1000;
+const char kEnvVariableUntrustedData[] = "GoogleUpdateUntrustedData";
+const int kUntrustedDataMaxLength = 4096;
+
// Returns true if Google Update is present at the given level.
bool IsGoogleUpdatePresent(bool system_install) {
// Using the existence of version key in the registry to decide.
@@ -108,6 +120,73 @@ bool LaunchProcessAndWaitWithTimeout(const base::string16& cmd_string,
return success;
}
+bool IsNotPrintable(unsigned char c) {
+ return c < 32 || c >= 127;
+}
+
+// Returns whether or not |s| consists of printable characters.
+bool IsStringPrintable(const std::string& s) {
+ return std::find_if(s.begin(), s.end(), IsNotPrintable) == s.end();
+}
+
+bool IsIllegalUntrustedDataKeyChar(unsigned char c) {
+ return !(c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' ||
+ c >= '0' && c <= '9' || c == '-' || c == '_' || c == '$');
+}
+
+// Returns true if |key| from untrusted data is valid.
+bool IsUntrustedDataKeyValid(const std::string& key) {
+ return std::find_if(key.begin(), key.end(), IsIllegalUntrustedDataKeyChar)
+ == key.end();
+}
+
+// Parses |data_string| as key-value pairs and overwrites |untrusted_data| with
+// the result. Returns true if the data could be parsed.
+bool ParseUntrustedData(
+ const std::string& data_string,
+ std::map<std::string, std::string>* untrusted_data) {
+ DCHECK(untrusted_data);
+ if (data_string.length() > kUntrustedDataMaxLength ||
+ !IsStringPrintable(data_string)) {
+ LOG(ERROR) << "Invalid value in untrusted data string.";
+ return false;
+ }
+
+ VLOG(1) << "Untrusted data string: " << data_string;
+
+ std::vector<std::pair<std::string, std::string> > kv_pairs;
+ if (!base::SplitStringIntoKeyValuePairs(data_string, '=', '&', &kv_pairs)) {
+ LOG(ERROR) << "Failed to parse untrusted data: " << data_string;
+ return false;
+ }
+
+ untrusted_data->clear();
+ std::vector<std::pair<std::string, std::string> >::const_iterator it;
+ for (it = kv_pairs.begin(); it != kv_pairs.end(); ++it) {
+ const std::string& key(it->first);
+ // TODO(huangs): URL unescape |value|.
+ const std::string& value(it->second);
+ if (IsUntrustedDataKeyValid(key) && IsStringPrintable(value))
+ (*untrusted_data)[key] = value;
+ else
+ LOG(ERROR) << "Illegal character found in untrusted data.";
+ }
+ return true;
+}
+
+// Reads and parses untrusted data passed from Google Update as key-value
+// pairs, then overwrites |untrusted_data_map| with the result.
+// Returns true if data are successfully read.
+bool GetGoogleUpdateUntrustedData(
+ std::map<std::string, std::string>* untrusted_data) {
+ scoped_ptr<base::Environment> env(base::Environment::Create());
+ std::string data_string;
+ if (!env || !env->GetVar(kEnvVariableUntrustedData, &data_string))
+ return false;
+
+ return ParseUntrustedData(data_string, untrusted_data);
+}
+
} // namespace
bool EnsureUserLevelGoogleUpdatePresent() {
@@ -187,4 +266,25 @@ void ElevateIfNeededToReenableUpdates() {
}
}
+std::string GetUntrustedDataValue(const std::string& key) {
+ std::map<std::string, std::string> untrusted_data;
+ if (GetGoogleUpdateUntrustedData(&untrusted_data)) {
+ std::map<std::string, std::string>::const_iterator data_it(
+ untrusted_data.find(key));
+ if (data_it != untrusted_data.end())
+ return data_it->second;
+ }
+
+ return std::string();
+}
+
+std::string GetUntrustedDataValueFromTag(const std::string& tag,
+ const std::string& key) {
+ std::map<std::string, std::string> untrusted_data;
+ if (ParseUntrustedData(tag, &untrusted_data))
+ return untrusted_data[key];
+
+ return std::string();
+}
+
} // namespace google_update
diff --git a/chrome/installer/util/google_update_util.h b/chrome/installer/util/google_update_util.h
index 97edfad..4f240af 100644
--- a/chrome/installer/util/google_update_util.h
+++ b/chrome/installer/util/google_update_util.h
@@ -5,6 +5,8 @@
#ifndef CHROME_INSTALLER_UTIL_GOOGLE_UPDATE_UTIL_H_
#define CHROME_INSTALLER_UTIL_GOOGLE_UPDATE_UTIL_H_
+#include <string>
+
namespace google_update {
// If user-level Google Update is absent, calls the system-level
@@ -25,6 +27,18 @@ bool UninstallGoogleUpdate(bool system_install);
// GoogleUpdateSettings::ReenableAutoupdatesForApp() to do the work.
void ElevateIfNeededToReenableUpdates();
+// Returns the value corresponding to |key| in untrusted data passed from
+// Google Update. Returns an empty string if |key| is absent or if its value
+// contains non-printable characters.
+std::string GetUntrustedDataValue(const std::string& key);
+
+// Returns the value corresponding to |key| in untrusted data passed from
+// |tag|. |tag| should be a printable list of key-value pairs, e.g.
+// "key1=value1&key2=value2". Returns an empty string if |key| is absent or if
+// its value contains non-printable characters.
+std::string GetUntrustedDataValueFromTag(const std::string& tag,
+ const std::string& key);
+
} // namespace google_update
#endif // CHROME_INSTALLER_UTIL_GOOGLE_UPDATE_UTIL_H_
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index 67df18e..8800c5c 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -212,7 +212,6 @@ const char kOutputFile[] = "output-file";
// TODO(gab): Rename setup.exe itself altogether and use the same binary for
// Active Setup.
const wchar_t kActiveSetupExe[] = L"chrmstp.exe";
-const wchar_t kAppLauncherGuid[] = L"{FDA71E6F-AC4C-4a00-8B70-9958A68906BF}";
const wchar_t kChromeAppHostExe[] = L"app_host.exe";
const wchar_t kChromeDll[] = L"chrome.dll";
const wchar_t kChromeChildDll[] = L"chrome_child.dll";
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index da54a38..d2f648a 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -201,7 +201,6 @@ extern const char kOutputFile[];
} // namespace switches
extern const wchar_t kActiveSetupExe[];
-extern const wchar_t kAppLauncherGuid[];
extern const wchar_t kChromeAppHostExe[];
extern const wchar_t kChromeDll[];
extern const wchar_t kChromeChildDll[];