summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/jumplist_win.cc2
-rw-r--r--chrome/browser/shell_integration.h22
-rw-r--r--chrome/browser/shell_integration_unittest.cc20
-rw-r--r--chrome/browser/shell_integration_win.cc49
-rw-r--r--chrome/browser/ui/browser.cc5
-rw-r--r--chrome/browser/ui/views/extensions/shell_window_views.cc4
-rw-r--r--chrome/browser/ui/web_applications/web_app_ui.cc3
-rw-r--r--chrome/browser/web_applications/web_app_win.cc2
-rw-r--r--chrome/installer/setup/uninstall.cc10
-rw-r--r--chrome/installer/util/browser_distribution.cc2
-rw-r--r--chrome/installer/util/browser_distribution.h6
-rw-r--r--chrome/installer/util/chromium_binaries_distribution.cc2
-rw-r--r--chrome/installer/util/chromium_binaries_distribution.h2
-rw-r--r--chrome/installer/util/google_chrome_distribution.cc2
-rw-r--r--chrome/installer/util/google_chrome_distribution.h2
-rw-r--r--chrome/installer/util/google_chrome_distribution_dummy.cc2
-rw-r--r--chrome/installer/util/google_chrome_sxs_distribution.cc2
-rw-r--r--chrome/installer/util/google_chrome_sxs_distribution.h2
-rw-r--r--chrome/installer/util/shell_util.cc73
-rw-r--r--chrome/installer/util/shell_util.h14
-rw-r--r--chrome/installer/util/shell_util_unittest.cc113
-rw-r--r--chrome/installer/util/util_constants.cc2
-rw-r--r--chrome/installer/util/util_constants.h2
23 files changed, 248 insertions, 95 deletions
diff --git a/chrome/browser/jumplist_win.cc b/chrome/browser/jumplist_win.cc
index dc510c1..ddf53be 100644
--- a/chrome/browser/jumplist_win.cc
+++ b/chrome/browser/jumplist_win.cc
@@ -513,7 +513,7 @@ bool JumpList::AddObserver(Profile* profile) {
if (!tab_restore_service)
return false;
- app_id_ = ShellIntegration::GetChromiumAppId(profile->GetPath());
+ app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile->GetPath());
icon_dir_ = profile->GetPath().Append(chrome::kJumpListIconDirname);
profile_ = profile;
history::TopSites* top_sites = profile_->GetTopSites();
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h
index eb7d716..a1ce234 100644
--- a/chrome/browser/shell_integration.h
+++ b/chrome/browser/shell_integration.h
@@ -123,15 +123,19 @@ class ShellIntegration {
bool is_platform_app);
#if defined(OS_WIN)
- // Generates Win7 app id for given app name and profile path. The returned app
- // id is in the format of "|app_name|[.<profile_id>]". "profile_id" is
- // appended when user override the default value.
- static string16 GetAppId(const string16& app_name,
- const FilePath& profile_path);
-
- // Generates Win7 app id for Chromium by calling GetAppId with
- // chrome::kBrowserAppID as app_name.
- static string16 GetChromiumAppId(const FilePath& profile_path);
+ // Generates an application user model ID (AppUserModelId) for a given app
+ // name and profile path. The returned app id is in the format of
+ // "|app_name|[.<profile_id>]". "profile_id" is appended when user override
+ // the default value.
+ // Note: If the app has an installation specific suffix (e.g. on user-level
+ // Chrome installs), |app_name| should already be suffixed, this method will
+ // then further suffix it with the profile id as described above.
+ static string16 GetAppModelIdForProfile(const string16& app_name,
+ const FilePath& profile_path);
+
+ // Generates an application user model ID (AppUserModelId) for Chromium by
+ // calling GetAppModelIdForProfile() with ShellUtil::GetAppId() as app_name.
+ static string16 GetChromiumModelIdForProfile(const FilePath& profile_path);
// Returns the path to the Chromium icon. This is used to specify the icon
// to use for the taskbar group on Win 7.
diff --git a/chrome/browser/shell_integration_unittest.cc b/chrome/browser/shell_integration_unittest.cc
index 714e295..b6168c7 100644
--- a/chrome/browser/shell_integration_unittest.cc
+++ b/chrome/browser/shell_integration_unittest.cc
@@ -365,27 +365,31 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
}
}
#elif defined(OS_WIN)
-TEST(ShellIntegrationTest, GetChromiumAppIdTest) {
+TEST(ShellIntegrationTest, GetAppModelIdForProfileTest) {
+ const string16 base_app_id(
+ BrowserDistribution::GetDistribution()->GetBaseAppId());
+
// Empty profile path should get chrome::kBrowserAppID
FilePath empty_path;
- EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId(),
- ShellIntegration::GetChromiumAppId(empty_path));
+ EXPECT_EQ(base_app_id,
+ ShellIntegration::GetAppModelIdForProfile(base_app_id, empty_path));
// Default profile path should get chrome::kBrowserAppID
FilePath default_user_data_dir;
chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
FilePath default_profile_path =
default_user_data_dir.AppendASCII(chrome::kInitialProfile);
- EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId(),
- ShellIntegration::GetChromiumAppId(default_profile_path));
+ EXPECT_EQ(base_app_id,
+ ShellIntegration::GetAppModelIdForProfile(base_app_id,
+ default_profile_path));
// Non-default profile path should get chrome::kBrowserAppID joined with
// profile info.
FilePath profile_path(FILE_PATH_LITERAL("root"));
profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
- EXPECT_EQ(BrowserDistribution::GetDistribution()->GetBrowserAppId() +
- L".udd.UserDataTest",
- ShellIntegration::GetChromiumAppId(profile_path));
+ EXPECT_EQ(base_app_id + L".udd.UserDataTest",
+ ShellIntegration::GetAppModelIdForProfile(base_app_id,
+ profile_path));
}
#endif
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index 68e0cca..ceb412c 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -293,10 +293,12 @@ bool GetExpectedAppId(const FilePath& chrome_exe,
app_name = UTF8ToUTF16(web_app::GenerateApplicationNameFromExtensionId(
command_line.GetSwitchValueASCII(switches::kAppId)));
} else {
- app_name = BrowserDistribution::GetDistribution()->GetBrowserAppId();
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ app_name = ShellUtil::GetBrowserModelId(dist, chrome_exe.value());
}
- expected_app_id->assign(ShellIntegration::GetAppId(app_name, profile_path));
+ expected_app_id->assign(
+ ShellIntegration::GetAppModelIdForProfile(app_name, profile_path));
return true;
}
@@ -550,24 +552,27 @@ bool ShellIntegration::IsFirefoxDefaultBrowser() {
return ff_default;
}
-string16 ShellIntegration::GetAppId(const string16& app_name,
- const FilePath& profile_path) {
- string16 app_id(app_name);
-
- string16 profile_id(GetProfileIdFromPath(profile_path));
- if (!profile_id.empty()) {
- app_id += L".";
- app_id += profile_id;
- }
-
- // App id should be less than 128 chars.
- DCHECK(app_id.length() < 128);
- return app_id;
+string16 ShellIntegration::GetAppModelIdForProfile(
+ const string16& app_name,
+ const FilePath& profile_path) {
+ std::vector<string16> components;
+ components.push_back(app_name);
+ const string16 profile_id(GetProfileIdFromPath(profile_path));
+ if (!profile_id.empty())
+ components.push_back(profile_id);
+ return ShellUtil::BuildAppModelId(components);
}
-string16 ShellIntegration::GetChromiumAppId(const FilePath& profile_path) {
- return GetAppId(BrowserDistribution::GetDistribution()->GetBrowserAppId(),
- profile_path);
+string16 ShellIntegration::GetChromiumModelIdForProfile(
+ const FilePath& profile_path) {
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution();
+ FilePath chrome_exe;
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
+ NOTREACHED();
+ return dist->GetBaseAppId();
+ }
+ return GetAppModelIdForProfile(
+ ShellUtil::GetBrowserModelId(dist, chrome_exe.value()), profile_path);
}
string16 ShellIntegration::GetChromiumIconPath() {
@@ -597,6 +602,12 @@ void ShellIntegration::MigrateChromiumShortcuts() {
bool ShellIntegration::ActivateMetroChrome() {
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- const string16 app_id(dist->GetBrowserAppId());
+ FilePath chrome_exe;
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
+ NOTREACHED();
+ return false;
+ }
+ const string16 app_id(
+ ShellUtil::GetBrowserModelId(dist, chrome_exe.value()));
return ActivateApplication(app_id);
}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 5aa2819..895b108 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -534,8 +534,9 @@ void Browser::InitBrowserWindow() {
// name. See http://crbug.com/7028.
ui::win::SetAppIdForWindow(
is_app() && !is_type_panel() ?
- ShellIntegration::GetAppId(UTF8ToWide(app_name_), profile_->GetPath()) :
- ShellIntegration::GetChromiumAppId(profile_->GetPath()),
+ ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(app_name_),
+ profile_->GetPath()) :
+ ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()),
window()->GetNativeWindow());
if (is_type_panel()) {
diff --git a/chrome/browser/ui/views/extensions/shell_window_views.cc b/chrome/browser/ui/views/extensions/shell_window_views.cc
index 0d32d0a..b0a8ce6 100644
--- a/chrome/browser/ui/views/extensions/shell_window_views.cc
+++ b/chrome/browser/ui/views/extensions/shell_window_views.cc
@@ -204,8 +204,8 @@ ShellWindowViews::ShellWindowViews(Profile* profile,
std::string app_name = web_app::GenerateApplicationNameFromExtensionId(
extension->id());
ui::win::SetAppIdForWindow(
- ShellIntegration::GetAppId(UTF8ToWide(app_name),
- profile->GetPath()),
+ ShellIntegration::GetAppModelIdForProfile(UTF8ToWide(app_name),
+ profile->GetPath()),
GetWidget()->GetTopLevelWidget()->GetNativeWindow());
#endif
OnViewWasResized();
diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc
index 6e36ba8..ed55194 100644
--- a/chrome/browser/ui/web_applications/web_app_ui.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui.cc
@@ -8,6 +8,7 @@
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/path_service.h"
+#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "chrome/browser/extensions/extension_tab_helper.h"
@@ -248,7 +249,7 @@ void UpdateShortcutWorker::UpdateShortcutsOnFileThread() {
CheckExistingShortcuts();
if (!shortcut_files_.empty()) {
// Generates app id from web app url and profile path.
- std::wstring app_id = ShellIntegration::GetAppId(
+ string16 app_id = ShellIntegration::GetAppModelIdForProfile(
UTF8ToWide(web_app::GenerateApplicationNameFromURL(shortcut_info_.url)),
profile_path_);
diff --git a/chrome/browser/web_applications/web_app_win.cc b/chrome/browser/web_applications/web_app_win.cc
index 73fed7d..7c86dde 100644
--- a/chrome/browser/web_applications/web_app_win.cc
+++ b/chrome/browser/web_applications/web_app_win.cc
@@ -206,7 +206,7 @@ bool CreatePlatformShortcut(
// Generates app id from web app url and profile path.
std::string app_name =
web_app::GenerateApplicationNameFromInfo(shortcut_info);
- string16 app_id = ShellIntegration::GetAppId(
+ string16 app_id = ShellIntegration::GetAppModelIdForProfile(
UTF8ToUTF16(app_name), profile_path);
FilePath shortcut_to_pin;
diff --git a/chrome/installer/setup/uninstall.cc b/chrome/installer/setup/uninstall.cc
index 428920d..e09be35 100644
--- a/chrome/installer/setup/uninstall.cc
+++ b/chrome/installer/setup/uninstall.cc
@@ -533,7 +533,15 @@ bool DeleteChromeRegistrationKeys(BrowserDistribution* dist, HKEY root,
// Delete Software\Classes\Chrome (Same comment as above applies for this too)
string16 chrome_app_id(ShellUtil::kRegClasses);
chrome_app_id.push_back(FilePath::kSeparators[0]);
- chrome_app_id.append(dist->GetBrowserAppId());
+ if (browser_entry_suffix.empty()) {
+ // An unsuffixed appid used to be registered on some user-level install
+ // (dev-channel 21.0.1171.0). Make sure it gets cleaned up here.
+ // Note: this couldn't be cleaned on update as a currently running old
+ // chrome might still be using the unsuffixed appid when the registration
+ // update steps run.
+ InstallUtil::DeleteRegistryKey(root, chrome_app_id + dist->GetBaseAppId());
+ }
+ chrome_app_id.append(ShellUtil::GetBrowserModelId(dist, chrome_exe.value()));
InstallUtil::DeleteRegistryKey(root, chrome_app_id);
// Delete all Start Menu Internet registrations that refer to this Chrome.
diff --git a/chrome/installer/util/browser_distribution.cc b/chrome/installer/util/browser_distribution.cc
index d3579b0..f958db8 100644
--- a/chrome/installer/util/browser_distribution.cc
+++ b/chrome/installer/util/browser_distribution.cc
@@ -161,7 +161,7 @@ string16 BrowserDistribution::GetAlternateApplicationName() {
return L"The Internet";
}
-string16 BrowserDistribution::GetBrowserAppId() {
+string16 BrowserDistribution::GetBaseAppId() {
return L"Chromium";
}
diff --git a/chrome/installer/util/browser_distribution.h b/chrome/installer/util/browser_distribution.h
index 7d02b63..7a78cc5 100644
--- a/chrome/installer/util/browser_distribution.h
+++ b/chrome/installer/util/browser_distribution.h
@@ -79,7 +79,11 @@ class BrowserDistribution {
virtual string16 GetAlternateApplicationName();
- virtual string16 GetBrowserAppId();
+ // Returns the unsuffixed appid of this program.
+ // The AppUserModelId is a property of Windows programs.
+ // IMPORTANT: This should only be called by ShellUtil::GetAppId as the appid
+ // should be suffixed in all scenarios.
+ virtual string16 GetBaseAppId();
virtual string16 GetInstallSubDir();
diff --git a/chrome/installer/util/chromium_binaries_distribution.cc b/chrome/installer/util/chromium_binaries_distribution.cc
index 179e891..e12f56b 100644
--- a/chrome/installer/util/chromium_binaries_distribution.cc
+++ b/chrome/installer/util/chromium_binaries_distribution.cc
@@ -38,7 +38,7 @@ string16 ChromiumBinariesDistribution::GetAlternateApplicationName() {
return string16();
}
-string16 ChromiumBinariesDistribution::GetBrowserAppId() {
+string16 ChromiumBinariesDistribution::GetBaseAppId() {
NOTREACHED();
return string16();
}
diff --git a/chrome/installer/util/chromium_binaries_distribution.h b/chrome/installer/util/chromium_binaries_distribution.h
index a40bf85..51c26e3 100644
--- a/chrome/installer/util/chromium_binaries_distribution.h
+++ b/chrome/installer/util/chromium_binaries_distribution.h
@@ -22,7 +22,7 @@ class ChromiumBinariesDistribution : public BrowserDistribution {
virtual string16 GetAlternateApplicationName() OVERRIDE;
- virtual string16 GetBrowserAppId() OVERRIDE;
+ virtual string16 GetBaseAppId() OVERRIDE;
virtual string16 GetInstallSubDir() OVERRIDE;
diff --git a/chrome/installer/util/google_chrome_distribution.cc b/chrome/installer/util/google_chrome_distribution.cc
index 4b41b44..98cc8ff 100644
--- a/chrome/installer/util/google_chrome_distribution.cc
+++ b/chrome/installer/util/google_chrome_distribution.cc
@@ -434,7 +434,7 @@ string16 GoogleChromeDistribution::GetAlternateApplicationName() {
return alt_product_name;
}
-string16 GoogleChromeDistribution::GetBrowserAppId() {
+string16 GoogleChromeDistribution::GetBaseAppId() {
return kBrowserAppId;
}
diff --git a/chrome/installer/util/google_chrome_distribution.h b/chrome/installer/util/google_chrome_distribution.h
index 6c4d87d..9642f97 100644
--- a/chrome/installer/util/google_chrome_distribution.h
+++ b/chrome/installer/util/google_chrome_distribution.h
@@ -44,7 +44,7 @@ class GoogleChromeDistribution : public BrowserDistribution {
virtual string16 GetAlternateApplicationName() OVERRIDE;
- virtual string16 GetBrowserAppId() OVERRIDE;
+ virtual string16 GetBaseAppId() OVERRIDE;
virtual string16 GetInstallSubDir() OVERRIDE;
diff --git a/chrome/installer/util/google_chrome_distribution_dummy.cc b/chrome/installer/util/google_chrome_distribution_dummy.cc
index ac7c9b5..ce2771f 100644
--- a/chrome/installer/util/google_chrome_distribution_dummy.cc
+++ b/chrome/installer/util/google_chrome_distribution_dummy.cc
@@ -46,7 +46,7 @@ string16 GoogleChromeDistribution::GetAlternateApplicationName() {
return string16();
}
-string16 GoogleChromeDistribution::GetBrowserAppId() {
+string16 GoogleChromeDistribution::GetBaseAppId() {
NOTREACHED();
return string16();
}
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.cc b/chrome/installer/util/google_chrome_sxs_distribution.cc
index 8798295..32d95f0 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.cc
+++ b/chrome/installer/util/google_chrome_sxs_distribution.cc
@@ -35,7 +35,7 @@ string16 GoogleChromeSxSDistribution::GetAppShortCutName() {
return shortcut_name;
}
-string16 GoogleChromeSxSDistribution::GetBrowserAppId() {
+string16 GoogleChromeSxSDistribution::GetBaseAppId() {
return kBrowserAppId;
}
diff --git a/chrome/installer/util/google_chrome_sxs_distribution.h b/chrome/installer/util/google_chrome_sxs_distribution.h
index 8e3e769..72b653b 100644
--- a/chrome/installer/util/google_chrome_sxs_distribution.h
+++ b/chrome/installer/util/google_chrome_sxs_distribution.h
@@ -22,7 +22,7 @@ class GoogleChromeSxSDistribution : public GoogleChromeDistribution {
public:
virtual string16 GetBaseAppName() OVERRIDE;
virtual string16 GetAppShortCutName() OVERRIDE;
- virtual string16 GetBrowserAppId() OVERRIDE;
+ virtual string16 GetBaseAppId() OVERRIDE;
virtual string16 GetInstallSubDir() OVERRIDE;
virtual string16 GetUninstallRegPath() OVERRIDE;
virtual bool CanSetAsDefault() OVERRIDE;
diff --git a/chrome/installer/util/shell_util.cc b/chrome/installer/util/shell_util.cc
index 582ef07..6a2fe83 100644
--- a/chrome/installer/util/shell_util.cc
+++ b/chrome/installer/util/shell_util.cc
@@ -136,7 +136,7 @@ class RegistryEntry {
string16 delegate_command(ShellUtil::GetChromeDelegateCommand(chrome_exe));
// For user-level installs: entries for the app id and DelegateExecute verb
// handler will be in HKCU; thus we do not need a suffix on those entries.
- string16 app_id(dist->GetBrowserAppId());
+ string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe));
string16 delegate_guid;
// TODO(grt): remove HasDelegateExecuteHandler when the exe is ever-present;
// see also install_worker.cc's AddDelegateExecuteWorkItems.
@@ -663,7 +663,7 @@ void RemoveBadWindows8RegistrationIfNeeded(
// suffix.
const string16 installation_suffix(
ShellUtil::GetCurrentInstallationSuffix(dist, chrome_exe));
- const string16 app_id(dist->GetBrowserAppId());
+ const string16 app_id(ShellUtil::GetBrowserModelId(dist, chrome_exe));
// <root hkey>\Software\Classes\<app_id>
string16 key(ShellUtil::kRegClasses);
@@ -1074,6 +1074,62 @@ string16 ShellUtil::GetApplicationName(BrowserDistribution* dist,
return app_name;
}
+string16 ShellUtil::GetBrowserModelId(BrowserDistribution* dist,
+ const string16& chrome_exe) {
+ string16 app_id(dist->GetBaseAppId());
+ string16 suffix;
+ if (InstallUtil::IsPerUserInstall(chrome_exe.c_str()) &&
+ !GetUserSpecificRegistrySuffix(&suffix)) {
+ NOTREACHED();
+ }
+ // There is only one component (i.e. the suffixed appid) in this case, but it
+ // is still necessary to go through the appid constructor to make sure the
+ // returned appid is truncated if necessary.
+ std::vector<string16> components(1, app_id.append(suffix));
+ return BuildAppModelId(components);
+}
+
+string16 ShellUtil::BuildAppModelId(
+ const std::vector<string16>& components) {
+ DCHECK_GT(components.size(), 0U);
+
+ // Find the maximum numbers of characters allowed in each component
+ // (accounting for the dots added between each component).
+ const size_t available_chars =
+ installer::kMaxAppModelIdLength - (components.size() - 1);
+ const size_t max_component_length = available_chars / components.size();
+
+ // |max_component_length| should be at least 2; otherwise the truncation logic
+ // below breaks.
+ if (max_component_length < 2U) {
+ NOTREACHED();
+ return (*components.begin()).substr(0, installer::kMaxAppModelIdLength);
+ }
+
+ string16 app_id;
+ app_id.reserve(installer::kMaxAppModelIdLength);
+ for (std::vector<string16>::const_iterator it = components.begin();
+ it != components.end(); ++it) {
+ if (it != components.begin())
+ app_id.push_back(L'.');
+
+ const string16& component = *it;
+ DCHECK(!component.empty());
+ if (component.length() > max_component_length) {
+ // Append a shortened version of this component. Cut in the middle to try
+ // to avoid losing the unique parts of this component (which are usually
+ // at the beginning or end for things like usernames and paths).
+ app_id.append(component.c_str(), 0, max_component_length / 2);
+ app_id.append(component.c_str(),
+ component.length() - ((max_component_length + 1) / 2),
+ string16::npos);
+ } else {
+ app_id.append(component);
+ }
+ }
+ return app_id;
+}
+
// static
bool ShellUtil::CanMakeChromeDefaultUnattended() {
return base::win::GetVersion() < base::win::VERSION_WIN8;
@@ -1437,24 +1493,25 @@ bool ShellUtil::UpdateChromeShortcut(BrowserDistribution* dist,
const string16& icon_path,
int icon_index,
uint32 options) {
- string16 chrome_path = FilePath(chrome_exe).DirName().value();
+ const FilePath chrome_path(FilePath(chrome_exe).DirName());
- FilePath prefs_path(chrome_path);
- prefs_path = prefs_path.AppendASCII(installer::kDefaultMasterPrefs);
- installer::MasterPreferences prefs(prefs_path);
+ installer::MasterPreferences prefs(
+ chrome_path.AppendASCII(installer::kDefaultMasterPrefs));
if (FilePath::CompareEqualIgnoreCase(icon_path, chrome_exe)) {
prefs.GetInt(installer::master_preferences::kChromeShortcutIconIndex,
&icon_index);
}
+ const string16 app_id(GetBrowserModelId(dist, chrome_exe));
+
return file_util::CreateOrUpdateShortcutLink(
chrome_exe.c_str(),
shortcut.c_str(),
- chrome_path.c_str(),
+ chrome_path.value().c_str(),
arguments.c_str(),
description.c_str(),
icon_path.c_str(),
icon_index,
- dist->GetBrowserAppId().c_str(),
+ app_id.c_str(),
ConvertShellUtilShortcutOptionsToFileUtil(options));
}
diff --git a/chrome/installer/util/shell_util.h b/chrome/installer/util/shell_util.h
index 4be4dbb..a29cadd 100644
--- a/chrome/installer/util/shell_util.h
+++ b/chrome/installer/util/shell_util.h
@@ -242,6 +242,20 @@ class ShellUtil {
static string16 GetApplicationName(BrowserDistribution* dist,
const string16& chrome_exe);
+ // Returns the AppUserModelId for |dist|. This identifier is unconditionally
+ // suffixed with the user id for user-level installs (in contrast to other
+ // registration entries which are suffix as described in
+ // GetCurrentInstallationSuffix() above).
+ static string16 GetBrowserModelId(BrowserDistribution* dist,
+ const string16& chrome_exe);
+
+ // Returns an AppUserModelId composed of each member of |components| separated
+ // by dots.
+ // The returned appid is guaranteed to be no longer than
+ // chrome::kMaxAppModelIdLength (some of the components might have been
+ // shortened to enforce this).
+ static string16 BuildAppModelId(const std::vector<string16>& components);
+
// Returns true if Chrome can make itself the default browser without relying
// on the Windows shell to prompt the user. This is the case for versions of
// Windows prior to Windows 8.
diff --git a/chrome/installer/util/shell_util_unittest.cc b/chrome/installer/util/shell_util_unittest.cc
index 2ad39ac..516155d 100644
--- a/chrome/installer/util/shell_util_unittest.cc
+++ b/chrome/installer/util/shell_util_unittest.cc
@@ -7,15 +7,18 @@
#include <shlobj.h>
#include <fstream>
+#include <vector>
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_temp_dir.h"
+#include "base/string16.h"
#include "base/win/scoped_comptr.h"
#include "base/win/windows_version.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/master_preferences.h"
#include "chrome/installer/util/shell_util.h"
+#include "chrome/installer/util/util_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -89,16 +92,18 @@ class ShellUtilTest : public testing::Test {
protected:
virtual void SetUp() {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ dist_ = BrowserDistribution::GetDistribution();
+ ASSERT_TRUE(dist_ != NULL);
}
+ BrowserDistribution* dist_;
+
ScopedTempDir temp_dir_;
};
};
// Test that we can open archives successfully.
TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- ASSERT_TRUE(dist != NULL);
// Create an executable in test path by copying ourself to it.
wchar_t exe_full_path_str[MAX_PATH];
EXPECT_FALSE(::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH) == 0);
@@ -110,13 +115,13 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
FilePath shortcut_path = temp_dir_.path().AppendASCII("shortcut.lnk");
const std::wstring description(L"dummy description");
EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(
- dist,
+ dist_,
exe_path.value(),
shortcut_path.value(),
L"",
description,
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
@@ -137,13 +142,13 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
file.close();
ASSERT_TRUE(file_util::Delete(shortcut_path, false));
EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(
- dist,
+ dist_,
exe_path.value(),
shortcut_path.value(),
L"",
description,
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
@@ -152,13 +157,13 @@ TEST_F(ShellUtilTest, UpdateChromeShortcutTest) {
// Now change only description to update shortcut and make sure icon index
// doesn't change.
const std::wstring description2(L"dummy description 2");
- EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist,
+ EXPECT_TRUE(ShellUtil::UpdateChromeShortcut(dist_,
exe_path.value(),
shortcut_path.value(),
L"",
description2,
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SHORTCUT_NO_OPTIONS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
shortcut_path.value(),
@@ -172,8 +177,6 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
return;
}
- BrowserDistribution* dist = BrowserDistribution::GetDistribution();
- ASSERT_TRUE(dist != NULL);
// Create an executable in test path by copying ourself to it.
wchar_t exe_full_path_str[MAX_PATH];
EXPECT_FALSE(::GetModuleFileName(NULL, exe_full_path_str, MAX_PATH) == 0);
@@ -190,18 +193,18 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::GetDesktopPath(true, &system_desktop_path));
std::wstring shortcut_name;
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false, L"",
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist_, false, L"",
&shortcut_name));
std::wstring default_profile_shortcut_name;
const std::wstring default_profile_user_name = L"Minsk";
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false,
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist_, false,
default_profile_user_name,
&default_profile_shortcut_name));
std::wstring second_profile_shortcut_name;
const std::wstring second_profile_user_name = L"Pinsk";
- EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist, false,
+ EXPECT_TRUE(ShellUtil::GetChromeShortcutName(dist_, false,
second_profile_user_name,
&second_profile_shortcut_name));
@@ -214,13 +217,13 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
// Test simple creation of a user-level shortcut.
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -228,19 +231,19 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
description,
0));
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
- dist,
+ dist_,
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_NO_OPTIONS));
// Test simple creation of a system-level shortcut.
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -248,30 +251,30 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
description,
0));
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
- dist,
+ dist_,
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_NO_OPTIONS));
// Test creation of a user-level shortcut when a system-level shortcut
// is already present (should fail).
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_FALSE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -280,30 +283,30 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
0));
EXPECT_FALSE(file_util::PathExists(user_shortcut_path));
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
- dist,
+ dist_,
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_NO_OPTIONS));
// Test creation of a system-level shortcut when a user-level shortcut
// is already present (should succeed).
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
L"",
L"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -315,24 +318,24 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
description,
0));
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
- dist,
+ dist_,
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_NO_OPTIONS));
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcut(
- dist,
+ dist_,
ShellUtil::SYSTEM_LEVEL,
ShellUtil::SHORTCUT_NO_OPTIONS));
// Test creation of two profile-specific shortcuts (these are always
// user-level).
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
default_profile_user_name,
L"--profile-directory=\"Default\"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -340,13 +343,13 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
description,
0));
EXPECT_TRUE(ShellUtil::CreateChromeDesktopShortcut(
- dist,
+ dist_,
exe_path.value(),
description,
second_profile_user_name,
L"--profile-directory=\"Profile 1\"",
exe_path.value(),
- dist->GetIconIndex(),
+ dist_->GetIconIndex(),
ShellUtil::CURRENT_USER,
ShellUtil::SHORTCUT_CREATE_ALWAYS));
EXPECT_TRUE(VerifyChromeShortcut(exe_path.value(),
@@ -359,3 +362,45 @@ TEST_F(ShellUtilTest, CreateChromeDesktopShortcutTest) {
EXPECT_TRUE(ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames(
profile_names));
}
+
+TEST_F(ShellUtilTest, BuildAppModelIdBasic) {
+ std::vector<string16> components;
+ const string16 base_app_id(dist_->GetBaseAppId());
+ components.push_back(base_app_id);
+ ASSERT_EQ(base_app_id, ShellUtil::BuildAppModelId(components));
+}
+
+TEST_F(ShellUtilTest, BuildAppModelIdManySmall) {
+ std::vector<string16> components;
+ const string16 suffixed_app_id(dist_->GetBaseAppId().append(L".gab"));
+ components.push_back(suffixed_app_id);
+ components.push_back(L"Default");
+ components.push_back(L"Test");
+ ASSERT_EQ(suffixed_app_id + L".Default.Test",
+ ShellUtil::BuildAppModelId(components));
+}
+
+TEST_F(ShellUtilTest, BuildAppModelIdLongUsernameNormalProfile) {
+ std::vector<string16> components;
+ const string16 long_appname(
+ L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_"
+ L"that_goes_over_64_characters");
+ components.push_back(long_appname);
+ components.push_back(L"Default");
+ ASSERT_EQ(L"Chrome.a_user_wer_64_characters.Default",
+ ShellUtil::BuildAppModelId(components));
+}
+
+TEST_F(ShellUtilTest, BuildAppModelIdLongEverything) {
+ std::vector<string16> components;
+ const string16 long_appname(
+ L"Chrome.a_user_who_has_a_crazy_long_name_with_some_weird@symbols_in_it_"
+ L"that_goes_over_64_characters");
+ components.push_back(long_appname);
+ components.push_back(
+ L"A_crazy_profile_name_not_even_sure_whether_that_is_possible");
+ const string16 constructed_app_id(ShellUtil::BuildAppModelId(components));
+ ASSERT_LE(constructed_app_id.length(), installer::kMaxAppModelIdLength);
+ ASSERT_EQ(L"Chrome.a_user_wer_64_characters.A_crazy_profilethat_is_possible",
+ constructed_app_id);
+}
diff --git a/chrome/installer/util/util_constants.cc b/chrome/installer/util/util_constants.cc
index d2af2a4..ec6d660 100644
--- a/chrome/installer/util/util_constants.cc
+++ b/chrome/installer/util/util_constants.cc
@@ -213,4 +213,6 @@ const wchar_t kChromeChannelDev[] = L"dev";
const wchar_t kChromeChannelBeta[] = L"beta";
const wchar_t kChromeChannelStable[] = L"";
+const size_t kMaxAppModelIdLength = 64U;
+
} // namespace installer
diff --git a/chrome/installer/util/util_constants.h b/chrome/installer/util/util_constants.h
index 402cfe3..0a0b027 100644
--- a/chrome/installer/util/util_constants.h
+++ b/chrome/installer/util/util_constants.h
@@ -218,6 +218,8 @@ extern const wchar_t kChromeChannelDev[];
extern const wchar_t kChromeChannelBeta[];
extern const wchar_t kChromeChannelStable[];
+extern const size_t kMaxAppModelIdLength;
+
} // namespace installer
#endif // CHROME_INSTALLER_UTIL_UTIL_CONSTANTS_H_