| Index: chrome/browser/profiles/profile_shortcut_manager_win.cc
|
| diff --git a/chrome/browser/profiles/profile_shortcut_manager_win.cc b/chrome/browser/profiles/profile_shortcut_manager_win.cc
|
| index cc8c250122bc43304e1f1b870161ecffa793dc44..7ce8ca2ace7dc180747a5f1819de6ef4fc907956 100644
|
| --- a/chrome/browser/profiles/profile_shortcut_manager_win.cc
|
| +++ b/chrome/browser/profiles/profile_shortcut_manager_win.cc
|
| @@ -14,6 +14,7 @@
|
| #include "base/file_util.h"
|
| #include "base/files/file_enumerator.h"
|
| #include "base/path_service.h"
|
| +#include "base/prefs/pref_service.h"
|
| #include "base/strings/string16.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| @@ -21,15 +22,18 @@
|
| #include "base/win/shortcut.h"
|
| #include "chrome/browser/app_icon_win.h"
|
| #include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/chrome_notification_types.h"
|
| #include "chrome/browser/profiles/profile_info_cache_observer.h"
|
| #include "chrome/browser/profiles/profile_info_util.h"
|
| #include "chrome/browser/profiles/profile_manager.h"
|
| #include "chrome/browser/shell_integration.h"
|
| #include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/pref_names.h"
|
| #include "chrome/installer/util/browser_distribution.h"
|
| #include "chrome/installer/util/product.h"
|
| #include "chrome/installer/util/shell_util.h"
|
| #include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/notification_service.h"
|
| #include "grit/chrome_unscaled_resources.h"
|
| #include "grit/chromium_strings.h"
|
| #include "skia/ext/image_operations.h"
|
| @@ -46,6 +50,9 @@ using content::BrowserThread;
|
|
|
| namespace {
|
|
|
| +// Name of the badged icon file generated for a given profile.
|
| +const char kProfileIconFileName[] = "Google Profile.ico";
|
| +
|
| // Characters that are not allowed in Windows filenames. Taken from
|
| // http://msdn.microsoft.com/en-us/library/aa365247.aspx
|
| const char16 kReservedCharacters[] = L"<>:\"/\\|?*\x01\x02\x03\x04\x05\x06\x07"
|
| @@ -61,6 +68,8 @@ const int kMaxProfileShortcutFileNameLength = 64;
|
| const int kProfileAvatarBadgeSize = 28;
|
| const int kShortcutIconSize = 48;
|
|
|
| +const int kCurrentProfileIconVersion = 1;
|
| +
|
| // 2x sized profile avatar icons. Mirrors |kDefaultAvatarIconResources| in
|
| // profile_info_cache.cc.
|
| const int kProfileAvatarIconResources2x[] = {
|
| @@ -141,35 +150,92 @@ SkBitmap BadgeIcon(const SkBitmap& app_icon_bitmap,
|
| // Creates a desktop shortcut icon file (.ico) on the disk for a given profile,
|
| // badging the browser distribution icon with the profile avatar.
|
| // Returns a path to the shortcut icon file on disk, which is empty if this
|
| -// fails. Use index 0 when assigning the resulting file as the icon.
|
| -base::FilePath CreateChromeDesktopShortcutIconForProfile(
|
| +// fails. Use index 0 when assigning the resulting file as the icon. If both
|
| +// given bitmaps are empty, an unbadged icon is created.
|
| +// |callback| will be run on successful icon creation.
|
| +// Returns the path to the created icon on success and an empty base::FilePath
|
| +// on failure.
|
| +// TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's
|
| +// resources in the case of an unbadged icon.
|
| +base::FilePath CreateOrUpdateShortcutIconForProfile(
|
| const base::FilePath& profile_path,
|
| const SkBitmap& avatar_bitmap_1x,
|
| - const SkBitmap& avatar_bitmap_2x) {
|
| + const SkBitmap& avatar_bitmap_2x,
|
| + const base::Closure& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
| +
|
| + if (!base::PathExists(profile_path)) {
|
| + LOG(ERROR) << "Profile directory " << profile_path.value()
|
| + << " did not exist when trying to create profile icon";
|
| + return base::FilePath();
|
| + }
|
| +
|
| scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize));
|
| if (!app_icon_bitmap)
|
| return base::FilePath();
|
|
|
| gfx::ImageFamily badged_bitmaps;
|
| - badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
|
| - BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
|
| + if (!avatar_bitmap_1x.empty()) {
|
| + badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
|
| + BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
|
| + }
|
|
|
| - app_icon_bitmap = GetAppIconForSize(IconUtil::kLargeIconSize);
|
| - if (app_icon_bitmap) {
|
| + scoped_ptr<SkBitmap> large_app_icon_bitmap(
|
| + GetAppIconForSize(IconUtil::kLargeIconSize));
|
| + if (large_app_icon_bitmap && !avatar_bitmap_2x.empty()) {
|
| badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
|
| - BadgeIcon(*app_icon_bitmap, avatar_bitmap_2x, 2)));
|
| + BadgeIcon(*large_app_icon_bitmap, avatar_bitmap_2x, 2)));
|
| }
|
|
|
| + // If we have no badged bitmaps, we should just use the default chrome icon.
|
| + if (badged_bitmaps.empty()) {
|
| + badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(*app_icon_bitmap));
|
| + if (large_app_icon_bitmap) {
|
| + badged_bitmaps.Add(
|
| + gfx::Image::CreateFrom1xBitmap(*large_app_icon_bitmap));
|
| + }
|
| + }
|
| // Finally, write the .ico file containing this new bitmap.
|
| const base::FilePath icon_path =
|
| - profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
|
| - if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path))
|
| + profiles::internal::GetProfileIconPath(profile_path);
|
| + const bool had_icon = base::PathExists(icon_path);
|
| +
|
| + if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) {
|
| + // This can happen in theory if the profile directory is deleted between the
|
| + // beginning of this function and here; however this is extremely unlikely
|
| + // and this check will help catch any regression where this call would start
|
| + // failing constantly.
|
| + NOTREACHED();
|
| return base::FilePath();
|
| + }
|
|
|
| + if (had_icon) {
|
| + // This invalidates the Windows icon cache and causes the icon changes to
|
| + // register with the taskbar and desktop. SHCNE_ASSOCCHANGED will cause a
|
| + // desktop flash and we would like to avoid that if possible.
|
| + SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
|
| + } else {
|
| + SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, icon_path.value().c_str(), NULL);
|
| + }
|
| + if (!callback.is_null())
|
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
|
| return icon_path;
|
| }
|
|
|
| +// Updates the preferences with the current icon version on icon creation
|
| +// success.
|
| +void OnProfileIconCreateSuccess(base::FilePath profile_path) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + if (!g_browser_process->profile_manager())
|
| + return;
|
| + Profile* profile =
|
| + g_browser_process->profile_manager()->GetProfileByPath(profile_path);
|
| + if (profile) {
|
| + profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion,
|
| + kCurrentProfileIconVersion);
|
| + }
|
| +}
|
| +
|
| // Gets the user and system directories for desktop shortcuts. Parameters may
|
| // be NULL if a directory type is not needed. Returns true on success.
|
| bool GetDesktopShortcutsDirectories(
|
| @@ -301,7 +367,8 @@ void RenameChromeDesktopShortcutForProfile(
|
| // It's also possible that a system-level shortcut exists instead - this
|
| // should only be the case for the original Chrome shortcut from an
|
| // installation. If that's the case, copy that one over - it will get its
|
| - // properties updated by |CreateOrUpdateDesktopShortcutsForProfile()|.
|
| + // properties updated by
|
| + // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|.
|
| const base::FilePath possible_old_system_shortcut =
|
| system_shortcuts_directory.Append(old_shortcut_filename);
|
| if (base::PathExists(possible_old_system_shortcut))
|
| @@ -309,20 +376,49 @@ void RenameChromeDesktopShortcutForProfile(
|
| }
|
| }
|
|
|
| +struct CreateOrUpdateShortcutsParams {
|
| + CreateOrUpdateShortcutsParams(
|
| + base::FilePath profile_path,
|
| + ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
|
| + ProfileShortcutManagerWin::NonProfileShortcutAction action)
|
| + : profile_path(profile_path), create_mode(create_mode), action(action) {}
|
| + ~CreateOrUpdateShortcutsParams() {}
|
| +
|
| + ProfileShortcutManagerWin::CreateOrUpdateMode create_mode;
|
| + ProfileShortcutManagerWin::NonProfileShortcutAction action;
|
| +
|
| + // The path for this profile.
|
| + base::FilePath profile_path;
|
| + // The profile name before this update. Empty on create.
|
| + string16 old_profile_name;
|
| + // The new profile name.
|
| + string16 profile_name;
|
| + // Avatar images for this profile.
|
| + SkBitmap avatar_image_1x;
|
| + SkBitmap avatar_image_2x;
|
| +};
|
| +
|
| // Updates all desktop shortcuts for the given profile to have the specified
|
| -// parameters. If |create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut is
|
| -// created if no existing ones were found. Whether non-profile shortcuts should
|
| -// be updated is specified by |action|. Must be called on the FILE thread.
|
| -void CreateOrUpdateDesktopShortcutsForProfile(
|
| - const base::FilePath& profile_path,
|
| - const string16& old_profile_name,
|
| - const string16& profile_name,
|
| - const SkBitmap& avatar_image_1x,
|
| - const SkBitmap& avatar_image_2x,
|
| - ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
|
| - ProfileShortcutManagerWin::NonProfileShortcutAction action) {
|
| +// parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut
|
| +// is created if no existing ones were found. Whether non-profile shortcuts
|
| +// should be updated is specified by |params.action|. Must be called on the FILE
|
| +// thread. |callback| is called on successful icon creation.
|
| +void CreateOrUpdateDesktopShortcutsAndIconForProfile(
|
| + const CreateOrUpdateShortcutsParams& params,
|
| + const base::Closure& callback) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
|
|
| + const base::FilePath shortcut_icon =
|
| + CreateOrUpdateShortcutIconForProfile(params.profile_path,
|
| + params.avatar_image_1x,
|
| + params.avatar_image_2x,
|
| + callback);
|
| + if (shortcut_icon.empty() ||
|
| + params.create_mode ==
|
| + ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) {
|
| + return;
|
| + }
|
| +
|
| base::FilePath chrome_exe;
|
| if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
|
| NOTREACHED();
|
| @@ -334,12 +430,13 @@ void CreateOrUpdateDesktopShortcutsForProfile(
|
| // the following code may result in NOTREACHED() being hit.
|
| DCHECK(distribution->CanCreateDesktopShortcuts());
|
|
|
| - if (old_profile_name != profile_name) {
|
| + if (params.old_profile_name != params.profile_name) {
|
| const string16 old_shortcut_filename =
|
| - profiles::internal::GetShortcutFilenameForProfile(old_profile_name,
|
| - distribution);
|
| + profiles::internal::GetShortcutFilenameForProfile(
|
| + params.old_profile_name,
|
| + distribution);
|
| const string16 new_shortcut_filename =
|
| - profiles::internal::GetShortcutFilenameForProfile(profile_name,
|
| + profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
|
| distribution);
|
| RenameChromeDesktopShortcutForProfile(old_shortcut_filename,
|
| new_shortcut_filename);
|
| @@ -350,19 +447,14 @@ void CreateOrUpdateDesktopShortcutsForProfile(
|
| product.AddDefaultShortcutProperties(chrome_exe, &properties);
|
|
|
| const string16 command_line =
|
| - profiles::internal::CreateProfileShortcutFlags(profile_path);
|
| + profiles::internal::CreateProfileShortcutFlags(params.profile_path);
|
|
|
| // Only set the profile-specific properties when |profile_name| is non empty.
|
| // If it is empty, it means the shortcut being created should be a regular,
|
| // non-profile Chrome shortcut.
|
| - if (!profile_name.empty()) {
|
| - const base::FilePath shortcut_icon =
|
| - CreateChromeDesktopShortcutIconForProfile(profile_path,
|
| - avatar_image_1x,
|
| - avatar_image_2x);
|
| - if (!shortcut_icon.empty())
|
| - properties.set_icon(shortcut_icon, 0);
|
| + if (!params.profile_name.empty()) {
|
| properties.set_arguments(command_line);
|
| + properties.set_icon(shortcut_icon, 0);
|
| } else {
|
| // Set the arguments explicitly to the empty string to ensure that
|
| // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut.
|
| @@ -370,19 +462,19 @@ void CreateOrUpdateDesktopShortcutsForProfile(
|
| }
|
|
|
| properties.set_app_id(
|
| - ShellIntegration::GetChromiumModelIdForProfile(profile_path));
|
| + ShellIntegration::GetChromiumModelIdForProfile(params.profile_path));
|
|
|
| ShellUtil::ShortcutOperation operation =
|
| ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING;
|
|
|
| std::vector<base::FilePath> shortcuts;
|
| ListDesktopShortcutsWithCommandLine(chrome_exe, command_line,
|
| - action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
|
| + params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
|
| &shortcuts);
|
| - if (create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
|
| + if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
|
| shortcuts.empty()) {
|
| const string16 shortcut_name =
|
| - profiles::internal::GetShortcutFilenameForProfile(profile_name,
|
| + profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
|
| distribution);
|
| shortcuts.push_back(base::FilePath(shortcut_name));
|
| operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL;
|
| @@ -415,12 +507,12 @@ bool ChromeDesktopShortcutsExist(const base::FilePath& chrome_exe) {
|
| return false;
|
| }
|
|
|
| -// Deletes all desktop shortcuts for the specified profile and also removes the
|
| -// corresponding icon file. If |ensure_shortcuts_remain| is true, then a regular
|
| -// non-profile shortcut will be created if this function would otherwise delete
|
| -// the last Chrome desktop shortcut(s). Must be called on the FILE thread.
|
| -void DeleteDesktopShortcutsAndIconFile(const base::FilePath& profile_path,
|
| - bool ensure_shortcuts_remain) {
|
| +// Deletes all desktop shortcuts for the specified profile. If
|
| +// |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will
|
| +// be created if this function would otherwise delete the last Chrome desktop
|
| +// shortcut(s). Must be called on the FILE thread.
|
| +void DeleteDesktopShortcuts(const base::FilePath& profile_path,
|
| + bool ensure_shortcuts_remain) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
|
|
|
| base::FilePath chrome_exe;
|
| @@ -445,10 +537,6 @@ void DeleteDesktopShortcutsAndIconFile(const base::FilePath& profile_path,
|
| NULL);
|
| }
|
|
|
| - const base::FilePath icon_path =
|
| - profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
|
| - base::DeleteFile(icon_path, false);
|
| -
|
| // If |ensure_shortcuts_remain| is true and deleting this profile caused the
|
| // last shortcuts to be removed, re-create a regular non-profile shortcut.
|
| const bool had_shortcuts = !shortcuts.empty();
|
| @@ -530,7 +618,9 @@ SkBitmap GetImageResourceSkBitmapCopy(int resource_id) {
|
| namespace profiles {
|
| namespace internal {
|
|
|
| -const char kProfileIconFileName[] = "Google Profile.ico";
|
| +base::FilePath GetProfileIconPath(const base::FilePath& profile_path) {
|
| + return profile_path.AppendASCII(kProfileIconFileName);
|
| +}
|
|
|
| string16 GetShortcutFilenameForProfile(const string16& profile_name,
|
| BrowserDistribution* distribution) {
|
| @@ -572,6 +662,9 @@ ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager)
|
| arraysize(kProfileAvatarIconResources2x),
|
| profile_manager_->GetProfileInfoCache().GetDefaultAvatarIconCount());
|
|
|
| + registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
|
| + content::NotificationService::AllSources());
|
| +
|
| profile_manager_->GetProfileInfoCache().AddObserver(this);
|
| }
|
|
|
| @@ -579,17 +672,27 @@ ProfileShortcutManagerWin::~ProfileShortcutManagerWin() {
|
| profile_manager_->GetProfileInfoCache().RemoveObserver(this);
|
| }
|
|
|
| +void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon(
|
| + const base::FilePath& profile_path,
|
| + const base::Closure& callback) {
|
| + CreateOrUpdateShortcutsForProfileAtPath(profile_path,
|
| + CREATE_OR_UPDATE_ICON_ONLY,
|
| + IGNORE_NON_PROFILE_SHORTCUTS,
|
| + callback);
|
| +}
|
| +
|
| void ProfileShortcutManagerWin::CreateProfileShortcut(
|
| const base::FilePath& profile_path) {
|
| CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND,
|
| - IGNORE_NON_PROFILE_SHORTCUTS);
|
| + IGNORE_NON_PROFILE_SHORTCUTS,
|
| + base::Closure());
|
| }
|
|
|
| void ProfileShortcutManagerWin::RemoveProfileShortcuts(
|
| const base::FilePath& profile_path) {
|
| BrowserThread::PostTask(
|
| BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&DeleteDesktopShortcutsAndIconFile, profile_path, false));
|
| + base::Bind(&DeleteDesktopShortcuts, profile_path, false));
|
| }
|
|
|
| void ProfileShortcutManagerWin::HasProfileShortcuts(
|
| @@ -602,12 +705,14 @@ void ProfileShortcutManagerWin::HasProfileShortcuts(
|
|
|
| void ProfileShortcutManagerWin::OnProfileAdded(
|
| const base::FilePath& profile_path) {
|
| + CreateOrUpdateProfileIcon(profile_path, base::Closure());
|
| if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) {
|
| // When the second profile is added, make existing non-profile shortcuts
|
| // point to the first profile and be badged/named appropriately.
|
| CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path),
|
| UPDATE_EXISTING_ONLY,
|
| - UPDATE_NON_PROFILE_SHORTCUTS);
|
| + UPDATE_NON_PROFILE_SHORTCUTS,
|
| + base::Closure());
|
| }
|
| }
|
|
|
| @@ -619,13 +724,15 @@ void ProfileShortcutManagerWin::OnProfileWasRemoved(
|
| // from an existing shortcut.
|
| const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1);
|
| if (deleting_down_to_last_profile) {
|
| + // This is needed to unbadge the icon.
|
| CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0),
|
| UPDATE_EXISTING_ONLY,
|
| - IGNORE_NON_PROFILE_SHORTCUTS);
|
| + IGNORE_NON_PROFILE_SHORTCUTS,
|
| + base::Closure());
|
| }
|
|
|
| BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&DeleteDesktopShortcutsAndIconFile,
|
| + base::Bind(&DeleteDesktopShortcuts,
|
| profile_path,
|
| deleting_down_to_last_profile));
|
| }
|
| @@ -634,13 +741,13 @@ void ProfileShortcutManagerWin::OnProfileNameChanged(
|
| const base::FilePath& profile_path,
|
| const string16& old_profile_name) {
|
| CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
|
| - IGNORE_NON_PROFILE_SHORTCUTS);
|
| + IGNORE_NON_PROFILE_SHORTCUTS,
|
| + base::Closure());
|
| }
|
|
|
| void ProfileShortcutManagerWin::OnProfileAvatarChanged(
|
| const base::FilePath& profile_path) {
|
| - CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
|
| - IGNORE_NON_PROFILE_SHORTCUTS);
|
| + CreateOrUpdateProfileIcon(profile_path, base::Closure());
|
| }
|
|
|
| base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath(
|
| @@ -657,32 +764,33 @@ base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath(
|
| void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
|
| const base::FilePath& profile_path,
|
| CreateOrUpdateMode create_mode,
|
| - NonProfileShortcutAction action) {
|
| + NonProfileShortcutAction action,
|
| + const base::Closure& callback) {
|
| + DCHECK(!BrowserThread::IsWellKnownThread(BrowserThread::UI) ||
|
| + BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| + CreateOrUpdateShortcutsParams params(profile_path, create_mode, action);
|
| +
|
| ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache();
|
| size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path);
|
| if (profile_index == std::string::npos)
|
| return;
|
| bool remove_badging = cache->GetNumberOfProfiles() == 1;
|
|
|
| - string16 old_shortcut_appended_name =
|
| + params.old_profile_name =
|
| cache->GetShortcutNameOfProfileAtIndex(profile_index);
|
|
|
| // Exit early if the mode is to update existing profile shortcuts only and
|
| // none were ever created for this profile, per the shortcut name not being
|
| // set in the profile info cache.
|
| - if (old_shortcut_appended_name.empty() &&
|
| + if (params.old_profile_name.empty() &&
|
| create_mode == UPDATE_EXISTING_ONLY &&
|
| action == IGNORE_NON_PROFILE_SHORTCUTS) {
|
| return;
|
| }
|
|
|
| - string16 new_shortcut_appended_name;
|
| - if (!remove_badging)
|
| - new_shortcut_appended_name = cache->GetNameOfProfileAtIndex(profile_index);
|
| -
|
| - SkBitmap avatar_bitmap_copy_1x;
|
| - SkBitmap avatar_bitmap_copy_2x;
|
| if (!remove_badging) {
|
| + params.profile_name = cache->GetNameOfProfileAtIndex(profile_index);
|
| +
|
| const size_t icon_index =
|
| cache->GetAvatarIconIndexOfProfileAtIndex(profile_index);
|
| const int resource_id_1x =
|
| @@ -690,16 +798,38 @@ void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
|
| const int resource_id_2x = kProfileAvatarIconResources2x[icon_index];
|
| // Make a copy of the SkBitmaps to ensure that we can safely use the image
|
| // data on the FILE thread.
|
| - avatar_bitmap_copy_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
|
| - avatar_bitmap_copy_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
|
| + params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
|
| + params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
|
| }
|
| BrowserThread::PostTask(
|
| BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(&CreateOrUpdateDesktopShortcutsForProfile, profile_path,
|
| - old_shortcut_appended_name, new_shortcut_appended_name,
|
| - avatar_bitmap_copy_1x, avatar_bitmap_copy_2x, create_mode,
|
| - action));
|
| + base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params,
|
| + callback));
|
|
|
| cache->SetShortcutNameOfProfileAtIndex(profile_index,
|
| - new_shortcut_appended_name);
|
| + params.profile_name);
|
| +}
|
| +
|
| +void ProfileShortcutManagerWin::Observe(
|
| + int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + switch (type) {
|
| + // This notification is triggered when a profile is loaded.
|
| + case chrome::NOTIFICATION_PROFILE_CREATED: {
|
| + Profile* profile =
|
| + content::Source<Profile>(source).ptr()->GetOriginalProfile();
|
| + if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) <
|
| + kCurrentProfileIconVersion) {
|
| + // Ensure the profile's icon file has been created.
|
| + CreateOrUpdateProfileIcon(
|
| + profile->GetPath(),
|
| + base::Bind(&OnProfileIconCreateSuccess, profile->GetPath()));
|
| + }
|
| + break;
|
| + }
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| }
|
|
|