diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 18:11:15 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 18:11:15 +0000 |
commit | 12f520c53db26ec0dc45f263904d8995e809e800 (patch) | |
tree | defcb2b679cc43a1d0ebb85adcda4f606549883d | |
parent | a1ca40db95ac3c0dc8c12c42fe736c800d46c00b (diff) | |
download | chromium_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.cc | 10 | ||||
-rw-r--r-- | chrome/browser/jumplist.cc | 22 | ||||
-rw-r--r-- | chrome/browser/jumplist.h | 3 | ||||
-rw-r--r-- | chrome/browser/shell_integration.h | 12 | ||||
-rw-r--r-- | chrome/browser/shell_integration_unittest.cc | 26 | ||||
-rw-r--r-- | chrome/browser/shell_integration_win.cc | 59 | ||||
-rw-r--r-- | chrome/browser/user_data_manager.cc | 18 | ||||
-rw-r--r-- | chrome/browser/views/create_application_shortcut_view.cc | 2 | ||||
-rw-r--r-- | chrome/browser/web_applications/web_app.cc | 59 | ||||
-rw-r--r-- | chrome/browser/web_applications/web_app.h | 8 |
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. |