summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-06 18:11:15 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-06 18:11:15 +0000
commit12f520c53db26ec0dc45f263904d8995e809e800 (patch)
treedefcb2b679cc43a1d0ebb85adcda4f606549883d
parenta1ca40db95ac3c0dc8c12c42fe736c800d46c00b (diff)
downloadchromium_src-12f520c53db26ec0dc45f263904d8995e809e800.zip
chromium_src-12f520c53db26ec0dc45f263904d8995e809e800.tar.gz
chromium_src-12f520c53db26ec0dc45f263904d8995e809e800.tar.bz2
Append profile info to win7 app id per issue 30414
Add profile info to app id for non-default profile so that win7 could group chrome icons based on profile. - Add a new chrome/common/win_util.h/cc to hold app id functions that would include profile info for non-default profiles; - Add unit test to the new GetChromiumAppId function; - Browser and JumpList to use the GetChromiumAppId for BrowserWindow and JumpList; - UserDataManager to use it for shortcuts it creates; - Make app id for web apps include profile info as well; - Change web_app::UpdateShortcuts to just update shortcuts description, icon and app id; BUG=30414 TEST=Verify fix for issue 30414. Review URL: http://codereview.chromium.org/506079 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35634 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.cc10
-rw-r--r--chrome/browser/jumplist.cc22
-rw-r--r--chrome/browser/jumplist.h3
-rw-r--r--chrome/browser/shell_integration.h12
-rw-r--r--chrome/browser/shell_integration_unittest.cc26
-rw-r--r--chrome/browser/shell_integration_win.cc59
-rw-r--r--chrome/browser/user_data_manager.cc18
-rw-r--r--chrome/browser/views/create_application_shortcut_view.cc2
-rw-r--r--chrome/browser/web_applications/web_app.cc59
-rw-r--r--chrome/browser/web_applications/web_app.h8
10 files changed, 176 insertions, 43 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 671f73f..bc72c9a 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -89,6 +89,7 @@
#include "chrome/browser/cert_store.h"
#include "chrome/browser/download/save_package.h"
#include "chrome/browser/ssl/ssl_error_info.h"
+#include "chrome/browser/shell_integration.h"
#include "chrome/browser/task_manager.h"
#include "chrome/browser/user_data_manager.h"
#include "chrome/browser/view_ids.h"
@@ -258,9 +259,12 @@ void Browser::CreateBrowserWindow() {
#if defined(OS_WIN)
// Set the app user model id for this application to that of the application
// name. See http://crbug.com/7028.
- win_util::SetAppIdForWindow(type_ & TYPE_APP ? app_name_ :
- std::wstring(chrome::kBrowserAppID),
- window()->GetNativeHandle());
+ win_util::SetAppIdForWindow(
+ type_ & TYPE_APP ?
+ ShellIntegration::GetAppId(app_name_.c_str(),
+ profile_->GetPath()) :
+ ShellIntegration::GetChromiumAppId(profile_->GetPath()),
+ window()->GetNativeHandle());
#endif
NotificationService::current()->Notify(
diff --git a/chrome/browser/jumplist.cc b/chrome/browser/jumplist.cc
index 327d929..7456e35 100644
--- a/chrome/browser/jumplist.cc
+++ b/chrome/browser/jumplist.cc
@@ -29,6 +29,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/sessions/session_types.h"
#include "chrome/browser/sessions/tab_restore_service.h"
+#include "chrome/browser/shell_integration.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
@@ -381,7 +382,8 @@ HRESULT UpdateTaskCategory(ScopedComPtr<ICustomDestinationList> list,
// * Creating an ICustomDestinationList instance;
// * Updating the categories of the ICustomDestinationList instance, and;
// * Sending it to Taskbar of Windows 7.
-bool UpdateJumpList(const ShellLinkItemList& most_visited_pages,
+bool UpdateJumpList(const wchar_t* app_id,
+ const ShellLinkItemList& most_visited_pages,
const ShellLinkItemList& recently_closed_pages) {
// JumpList is implemented only on Windows 7 or later.
// So, we should return now when this function is called on earlier versions
@@ -397,7 +399,7 @@ bool UpdateJumpList(const ShellLinkItemList& most_visited_pages,
return false;
// Set the App ID for this JumpList.
- destination_list->SetAppID(l10n_util::GetString(IDS_PRODUCT_NAME).c_str());
+ destination_list->SetAppID(app_id);
// Start a transaction that updates the JumpList of this application.
// This implementation just replaces the all items in this JumpList, so
@@ -480,10 +482,12 @@ bool UpdateJumpList(const ShellLinkItemList& most_visited_pages,
// 3. Post this task to the file thread.
class JumpListUpdateTask : public Task {
public:
- JumpListUpdateTask(const FilePath& icon_dir,
+ JumpListUpdateTask(const wchar_t* app_id,
+ const FilePath& icon_dir,
const ShellLinkItemList& most_visited_pages,
const ShellLinkItemList& recently_closed_pages)
- : icon_dir_(icon_dir),
+ : app_id_(app_id),
+ icon_dir_(icon_dir),
most_visited_pages_(most_visited_pages),
recently_closed_pages_(recently_closed_pages) {
}
@@ -493,6 +497,9 @@ class JumpListUpdateTask : public Task {
// When we post this task to a file thread, the thread calls this function.
void Run();
+ // App id to associate with the jump list.
+ std::wstring app_id_;
+
// The directory which contains JumpList icons.
FilePath icon_dir_;
@@ -545,7 +552,7 @@ void JumpListUpdateTask::Run() {
// We finished collecting all resources needed for updating an appliation
// JumpList. So, create a new JumpList and replace the current JumpList
// with it.
- UpdateJumpList(most_visited_pages_, recently_closed_pages_);
+ UpdateJumpList(app_id_.c_str(), most_visited_pages_, recently_closed_pages_);
// Delete all items in these lists now since we don't need the ShellLinkItem
// objects in these lists.
@@ -582,6 +589,7 @@ bool JumpList::AddObserver(Profile* profile) {
if (!tab_restore_service)
return false;
+ app_id_ = ShellIntegration::GetChromiumAppId(profile->GetPath());
icon_dir_ = profile->GetPath().Append(chrome::kJumpListIconDirname);
profile_ = profile;
tab_restore_service->AddObserver(this);
@@ -756,8 +764,8 @@ void JumpList::OnFavIconDataAvailable(
// the file thread.
ChromeThread::PostTask(
ChromeThread::FILE, FROM_HERE,
- new JumpListUpdateTask(
- icon_dir_, most_visited_pages_, recently_closed_pages_));
+ new JumpListUpdateTask(app_id_.c_str(), icon_dir_, most_visited_pages_,
+ recently_closed_pages_));
// Delete all items in these lists since we don't need these lists any longer.
most_visited_pages_.clear();
diff --git a/chrome/browser/jumplist.h b/chrome/browser/jumplist.h
index 9f56cca..5ba7e04 100644
--- a/chrome/browser/jumplist.h
+++ b/chrome/browser/jumplist.h
@@ -171,6 +171,9 @@ class JumpList : public TabRestoreService::Observer {
// The Profile object used for listening its events.
Profile* profile_;
+ // App id to associate with the jump list.
+ std::wstring app_id_;
+
// The directory which contains JumpList icons.
FilePath icon_dir_;
diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h
index 9e7b8bb..5acea09 100644
--- a/chrome/browser/shell_integration.h
+++ b/chrome/browser/shell_integration.h
@@ -74,6 +74,18 @@ class ShellIntegration {
static void CreateDesktopShortcut(const ShortcutInfo& shortcut_info);
#endif // defined(OS_LINUX)
+#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 std::wstring GetAppId(const wchar_t* app_name,
+ const FilePath& profile_path);
+
+ // Generates Win7 app id for Chromium by calling GetAppId with
+ // chrome::kBrowserAppID as app_name.
+ static std::wstring GetChromiumAppId(const FilePath& profile_path);
+#endif // defined(OS_WIN)
+
// The current default browser UI state
enum DefaultBrowserUIState {
STATE_PROCESSING,
diff --git a/chrome/browser/shell_integration_unittest.cc b/chrome/browser/shell_integration_unittest.cc
index 7133031..e409013 100644
--- a/chrome/browser/shell_integration_unittest.cc
+++ b/chrome/browser/shell_integration_unittest.cc
@@ -7,6 +7,7 @@
#include "base/file_path.h"
#include "base/string_util.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths_internal.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -170,4 +171,27 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) {
test_cases[i].icon_name));
}
}
-#endif // defined(OS_LINUX)
+#elif defined(OS_WIN)
+TEST(ShellIntegrationTest, GetChromiumAppIdTest) {
+ // Empty profile path should get chrome::kBrowserAppID
+ FilePath empty_path;
+ EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
+ ShellIntegration::GetChromiumAppId(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.Append(chrome::kNotSignedInProfile);
+ EXPECT_EQ(std::wstring(chrome::kBrowserAppID),
+ ShellIntegration::GetChromiumAppId(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(std::wstring(chrome::kBrowserAppID) + L".udd.UserDataTest",
+ ShellIntegration::GetChromiumAppId(profile_path));
+}
+#endif
diff --git a/chrome/browser/shell_integration_win.cc b/chrome/browser/shell_integration_win.cc
index 1042cd4..b35ac18 100644
--- a/chrome/browser/shell_integration_win.cc
+++ b/chrome/browser/shell_integration_win.cc
@@ -18,6 +18,8 @@
#include "base/task.h"
#include "base/win_util.h"
#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_paths_internal.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/create_reg_key_work_item.h"
#include "chrome/installer/util/set_reg_value_work_item.h"
@@ -26,6 +28,44 @@
#include "chrome/installer/util/work_item.h"
#include "chrome/installer/util/work_item_list.h"
+namespace {
+
+// Helper function for ShellIntegration::GetAppId to generates profile id
+// from profile path. "profile_id" is composed of sanitized basenames of
+// user data dir and profile dir joined by a ".".
+std::wstring GetProfileIdFromPath(const FilePath& profile_path) {
+ // Return empty string if profile_path is empty
+ if (profile_path.empty())
+ return EmptyWString();
+
+ FilePath default_user_data_dir;
+ // Return empty string if profile_path is in default user data
+ // dir and is the default profile.
+ if (chrome::GetDefaultUserDataDirectory(&default_user_data_dir) &&
+ profile_path.DirName() == default_user_data_dir &&
+ profile_path.BaseName().value() == chrome::kNotSignedInProfile)
+ return EmptyWString();
+
+ // Get joined basenames of user data dir and profile.
+ std::wstring basenames = profile_path.DirName().BaseName().value() +
+ L"." + profile_path.BaseName().value();
+
+ std::wstring profile_id;
+ profile_id.reserve(basenames.size());
+
+ // Generate profile_id from sanitized basenames.
+ for (size_t i = 0; i < basenames.length(); ++i) {
+ if (IsAsciiAlpha(basenames[i]) ||
+ IsAsciiDigit(basenames[i]) ||
+ basenames[i] == L'.')
+ profile_id += basenames[i];
+ }
+
+ return profile_id;
+}
+
+};
+
bool ShellIntegration::SetAsDefaultBrowser() {
std::wstring chrome_exe;
if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
@@ -148,3 +188,22 @@ bool ShellIntegration::IsFirefoxDefaultBrowser() {
}
return ff_default;
}
+
+std::wstring ShellIntegration::GetAppId(const wchar_t* app_name,
+ const FilePath& profile_path) {
+ std::wstring app_id(app_name);
+
+ std::wstring 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;
+}
+
+std::wstring ShellIntegration::GetChromiumAppId(const FilePath& profile_path) {
+ return GetAppId(chrome::kBrowserAppID, profile_path);
+}
diff --git a/chrome/browser/user_data_manager.cc b/chrome/browser/user_data_manager.cc
index e7d71c2..01057be 100644
--- a/chrome/browser/user_data_manager.cc
+++ b/chrome/browser/user_data_manager.cc
@@ -25,6 +25,7 @@
#if defined(OS_WIN)
#include <windows.h>
+#include "chrome/browser/shell_integration.h"
#include "chrome/installer/util/shell_util.h"
#endif
@@ -291,14 +292,15 @@ bool UserDataManager::CreateDesktopShortcutForProfile(
shortcut_name.append(L".lnk");
file_util::AppendToPath(&shortcut_path, shortcut_name);
- return file_util::CreateShortcutLink(cmd.c_str(),
- shortcut_path.c_str(),
- exe_folder.c_str(),
- args.c_str(),
- NULL,
- exe_path.c_str(),
- 0,
- chrome::kBrowserAppID);
+ return file_util::CreateShortcutLink(
+ cmd.c_str(),
+ shortcut_path.c_str(),
+ exe_folder.c_str(),
+ args.c_str(),
+ NULL,
+ exe_path.c_str(),
+ 0,
+ ShellIntegration::GetChromiumAppId(FilePath(user_data_dir)).c_str());
#else
// TODO(port): should probably use freedesktop.org standard for desktop files.
NOTIMPLEMENTED();
diff --git a/chrome/browser/views/create_application_shortcut_view.cc b/chrome/browser/views/create_application_shortcut_view.cc
index 6551d15..37d4b81 100644
--- a/chrome/browser/views/create_application_shortcut_view.cc
+++ b/chrome/browser/views/create_application_shortcut_view.cc
@@ -381,7 +381,7 @@ bool CreateApplicationShortcutView::Accept() {
shortcut_info_.create_in_quick_launch_bar = false;
#endif
- web_app::CreateShortcut(web_app::GetDataDir(tab_contents_->profile()),
+ web_app::CreateShortcut(tab_contents_->profile()->GetPath(),
shortcut_info_,
NULL);
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index 4184501..d09db36 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -181,7 +181,7 @@ bool CheckAndSaveIcon(const FilePath& icon_file, const SkBitmap& image) {
// when finished (either success or failure).
class CreateShortcutTask : public Task {
public:
- CreateShortcutTask(const FilePath& root_dir,
+ CreateShortcutTask(const FilePath& profile_path,
const ShellIntegration::ShortcutInfo& shortcut_info,
web_app::CreateShortcutCallback* callback);
@@ -213,6 +213,9 @@ class CreateShortcutTask : public Task {
// Path to store persisted data for web app.
FilePath web_app_path_;
+ // Out copy of profile path.
+ FilePath profile_path_;
+
// Our copy of short cut data.
ShellIntegration::ShortcutInfo shortcut_info_;
@@ -224,10 +227,12 @@ class CreateShortcutTask : public Task {
};
CreateShortcutTask::CreateShortcutTask(
- const FilePath& root_dir,
+ const FilePath& profile_path,
const ShellIntegration::ShortcutInfo& shortcut_info,
web_app::CreateShortcutCallback* callback)
- : web_app_path_(GetWebAppDataDirectory(root_dir, shortcut_info.url)),
+ : web_app_path_(GetWebAppDataDirectory(web_app::GetDataDir(profile_path),
+ shortcut_info.url)),
+ profile_path_(profile_path),
shortcut_info_(shortcut_info),
callback_(callback),
message_loop_(MessageLoop::current()) {
@@ -349,6 +354,11 @@ bool CreateShortcutTask::CreateShortcut() {
}
std::wstring wide_switchs(UTF8ToWide(switches));
+ // Generates app id from web app url and profile path.
+ std::wstring app_id = ShellIntegration::GetAppId(
+ web_app::GenerateApplicationNameFromURL(shortcut_info_.url).c_str(),
+ profile_path_);
+
bool success = true;
for (size_t i = 0; i < shortcut_paths.size(); ++i) {
FilePath shortcut_file = shortcut_paths[i].Append(file_name).
@@ -360,7 +370,7 @@ bool CreateShortcutTask::CreateShortcut() {
shortcut_info_.description.c_str(),
icon_file.value().c_str(),
0,
- web_app::GenerateApplicationNameFromURL(shortcut_info_.url).c_str());
+ app_id.c_str());
}
if (success && pin_to_taskbar) {
@@ -426,8 +436,8 @@ class UpdateShortcutWorker : public NotificationObserver {
// Cached shortcut data from the tab_contents_.
ShellIntegration::ShortcutInfo shortcut_info_;
- // Root dir of web app data.
- FilePath root_dir_;
+ // Our copy of profile path.
+ FilePath profile_path_;
// File name of shortcut/ico file based on app title.
FilePath file_name_;
@@ -440,7 +450,7 @@ class UpdateShortcutWorker : public NotificationObserver {
UpdateShortcutWorker::UpdateShortcutWorker(TabContents* tab_contents)
: tab_contents_(tab_contents),
- root_dir_(web_app::GetDataDir(tab_contents->profile())) {
+ profile_path_(tab_contents->profile()->GetPath()) {
web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_);
web_app::GetIconsInfo(tab_contents_->web_app_info(), &unprocessed_icons_);
file_name_ = GetSanitizedFileName(shortcut_info_.title);
@@ -564,21 +574,33 @@ void UpdateShortcutWorker::UpdateShortcuts() {
void UpdateShortcutWorker::UpdateShortcutsOnFileThread() {
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
- FilePath web_app_path = GetWebAppDataDirectory(root_dir_, shortcut_info_.url);
+ FilePath web_app_path = GetWebAppDataDirectory(
+ web_app::GetDataDir(profile_path_), shortcut_info_.url);
FilePath icon_file = web_app_path.Append(file_name_).ReplaceExtension(
FILE_PATH_LITERAL(".ico"));
CheckAndSaveIcon(icon_file, shortcut_info_.favicon);
+ // Update existing shortcuts' description, icon and app id.
CheckExistingShortcuts();
- if (shortcut_files_.empty()) {
- // No shortcuts to update.
- OnShortcutsUpdated(true);
- } else {
- // Re-create shortcuts to make sure application url, name and description
- // are up to date
- web_app::CreateShortcut(root_dir_, shortcut_info_,
- NewCallback(this, &UpdateShortcutWorker::OnShortcutsUpdated));
+ if (!shortcut_files_.empty()) {
+ // Generates app id from web app url and profile path.
+ std::wstring app_id = ShellIntegration::GetAppId(
+ web_app::GenerateApplicationNameFromURL(shortcut_info_.url).c_str(),
+ profile_path_);
+
+ for (size_t i = 0; i < shortcut_files_.size(); ++i) {
+ file_util::UpdateShortcutLink(NULL,
+ shortcut_files_[i].value().c_str(),
+ NULL,
+ NULL,
+ shortcut_info_.description.c_str(),
+ icon_file.value().c_str(),
+ 0,
+ app_id.c_str());
+ }
}
+
+ OnShortcutsUpdated(true);
}
void UpdateShortcutWorker::OnShortcutsUpdated(bool) {
@@ -646,9 +668,8 @@ bool IsValidUrl(const GURL& url) {
return false;
}
-FilePath GetDataDir(Profile* profile) {
- DCHECK(profile);
- return profile->GetPath().Append(chrome::kWebAppDirname);
+FilePath GetDataDir(const FilePath& profile_path) {
+ return profile_path.Append(chrome::kWebAppDirname);
}
void GetIconsInfo(const webkit_glue::WebApplicationInfo& app_info,
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h
index 28b1e9c..56f26b6 100644
--- a/chrome/browser/web_applications/web_app.h
+++ b/chrome/browser/web_applications/web_app.h
@@ -25,20 +25,20 @@ std::wstring GenerateApplicationNameFromURL(const GURL& url);
typedef Callback1<bool>::Type CreateShortcutCallback;
// Creates a shortcut for web application based on given shortcut data.
-// |root_dir| is used as root directory for persisted data such as icon.
+// |profile_path| is used as root directory for persisted data such as icon.
// Directory layout is similar to what Gears has, i.e. an web application's
// file is stored under "#/host_name/scheme_port", where '#' is the
// |root_dir|.
void CreateShortcut(
- const FilePath& data_dir,
+ const FilePath& profile_path,
const ShellIntegration::ShortcutInfo& shortcut_info,
CreateShortcutCallback* callback);
// Returns true if given url is a valid web app url.
bool IsValidUrl(const GURL& url);
-// Returns data dir for web apps for given profile.
-FilePath GetDataDir(Profile* profile);
+// Returns data dir for web apps for given profile path.
+FilePath GetDataDir(const FilePath& profile_path);
// Extracts icons info from web app data. Take only square shaped icons and
// sort them from smallest to largest.