Index: chrome/browser/profiles/profile_shortcut_manager_win.cc |
=================================================================== |
--- chrome/browser/profiles/profile_shortcut_manager_win.cc (revision 152316) |
+++ chrome/browser/profiles/profile_shortcut_manager_win.cc (working copy) |
@@ -15,7 +15,7 @@ |
#include "chrome/browser/app_icon_win.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/prefs/pref_service.h" |
-#include "chrome/browser/profiles/profile_info_cache.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/common/chrome_constants.h" |
@@ -48,9 +48,8 @@ |
// Use index 0 when assigning the resulting file as the icon. |
FilePath CreateChromeDesktopShortcutIconForProfile( |
const FilePath& profile_path, |
- const gfx::Image& avatar_image) { |
+ const SkBitmap& avatar_bitmap) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- const SkBitmap* avatar_bitmap = avatar_image.ToSkBitmap(); |
HICON app_icon_handle = GetAppIconForSize(kShortcutIconSize); |
scoped_ptr<SkBitmap> app_icon_bitmap( |
IconUtil::CreateSkBitmapFromHICON(app_icon_handle)); |
@@ -62,16 +61,16 @@ |
// avatar_menu_button::DrawTaskBarDecoration. |
const SkBitmap* source_bitmap = NULL; |
SkBitmap squarer_bitmap; |
- if ((avatar_bitmap->width() == profiles::kAvatarIconWidth) && |
- (avatar_bitmap->height() == profiles::kAvatarIconHeight)) { |
+ if ((avatar_bitmap.width() == profiles::kAvatarIconWidth) && |
+ (avatar_bitmap.height() == profiles::kAvatarIconHeight)) { |
// Shave a couple of columns so the bitmap is more square. So when |
// resized to a square aspect ratio it looks pretty. |
int x = 2; |
- avatar_bitmap->extractSubset(&squarer_bitmap, SkIRect::MakeXYWH(x, 0, |
+ avatar_bitmap.extractSubset(&squarer_bitmap, SkIRect::MakeXYWH(x, 0, |
profiles::kAvatarIconWidth - x * 2, profiles::kAvatarIconHeight)); |
source_bitmap = &squarer_bitmap; |
} else { |
- source_bitmap = avatar_bitmap; |
+ source_bitmap = &avatar_bitmap; |
} |
SkBitmap sk_icon = skia::ImageOperations::Resize( |
*source_bitmap, |
@@ -108,51 +107,86 @@ |
profile_path.BaseName().value().c_str()); |
} |
-// Wrap a ShellUtil function that returns a bool so it can be posted in a |
-// task to the FILE thread. |
-void CallShellUtilBoolFunction( |
+// Wrap a ShellUtil/FileUtil function that returns a bool so it can be posted |
+// in a task to the FILE thread. |
+void CallBoolFunction( |
const base::Callback<bool(void)>& bool_function) { |
bool_function.Run(); |
} |
+// Renames an existing Chrome desktop profile shortcut. Must be called on the |
+// FILE thread. |
+void RenameChromeDesktopShortcutForProfile( |
+ const string16& old_shortcut_file, |
+ const string16& new_shortcut_file) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ FilePath shortcut_path; |
+ if (ShellUtil::GetDesktopPath(false, // User's directory instead of system. |
+ &shortcut_path)) { |
+ FilePath old_shortcut_path = shortcut_path.Append(old_shortcut_file); |
+ FilePath new_shortcut_path = shortcut_path.Append(new_shortcut_file); |
+ if (!file_util::Move(old_shortcut_path, new_shortcut_path)) |
+ LOG(ERROR) << "Could not rename Windows profile desktop shortcut."; |
+ } |
+} |
+ |
+// Create or update a profile desktop shortcut. Must be called on the FILE |
+// thread. |
+void CreateOrUpdateProfileDesktopShortcut( |
+ const FilePath& profile_path, |
+ const string16& profile_name, |
+ const SkBitmap& avatar_image, |
+ bool create) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ FilePath shortcut_icon = CreateChromeDesktopShortcutIconForProfile( |
+ profile_path, avatar_image); |
+ |
+ FilePath chrome_exe; |
+ if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
+ return; |
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
+ if (!dist) |
+ return; |
+ string16 description(dist->GetAppDescription()); |
+ |
+ uint32 options = create ? ShellUtil::SHORTCUT_CREATE_ALWAYS : |
+ ShellUtil::SHORTCUT_NO_OPTIONS; |
+ ShellUtil::CreateChromeDesktopShortcut( |
+ dist, |
+ chrome_exe.value(), |
+ description, |
+ profile_name, |
+ CreateProfileShortcutFlags(profile_path), |
+ shortcut_icon.empty() ? chrome_exe.value() : shortcut_icon.value(), |
+ shortcut_icon.empty() ? dist->GetIconIndex() : 0, |
+ ShellUtil::CURRENT_USER, |
+ options); |
+} |
+ |
} // namespace |
-class ProfileShortcutManagerWin : public ProfileShortcutManager { |
+class ProfileShortcutManagerWin : public ProfileShortcutManager, |
+ public ProfileInfoCacheObserver { |
public: |
- ProfileShortcutManagerWin(); |
+ explicit ProfileShortcutManagerWin(ProfileInfoCache& cache); |
virtual ~ProfileShortcutManagerWin(); |
- virtual void CreateChromeDesktopShortcut( |
+ virtual void StartProfileDesktopShortcutCreation( |
const FilePath& profile_path, const string16& profile_name, |
const gfx::Image& avatar_image) OVERRIDE; |
- virtual void DeleteChromeDesktopShortcut(const FilePath& profile_path) |
- OVERRIDE; |
+ virtual void DeleteProfileDesktopShortcut(const FilePath& profile_path, |
+ const string16& profile_name) OVERRIDE; |
+ virtual void OnProfileAdded(const FilePath& profile_path) OVERRIDE; |
+ virtual void OnProfileWillBeRemoved(const FilePath& profile_path) OVERRIDE; |
+ virtual void OnProfileWasRemoved(const FilePath& profile_path, |
+ const string16& profile_name) OVERRIDE; |
+ virtual void OnProfileNameChanged(const FilePath& profile_path, |
+ const string16& old_profile_name) OVERRIDE; |
+ virtual void OnProfileAvatarChanged(const FilePath& profile_path) OVERRIDE; |
+ |
private: |
- struct ProfileShortcutInfo { |
- string16 flags; |
- string16 profile_name; |
- gfx::Image avatar_image; |
- |
- ProfileShortcutInfo() |
- : flags(string16()), |
- profile_name(string16()), |
- avatar_image(gfx::Image()) { |
- } |
- |
- ProfileShortcutInfo( |
- string16 p_flags, |
- string16 p_profile_name, |
- gfx::Image p_avatar_image) |
- : flags(p_flags), |
- profile_name(p_profile_name), |
- avatar_image(p_avatar_image) { |
- } |
- }; |
- |
- // TODO(hallielaine): Repopulate this map on chrome session startup |
- typedef std::map<FilePath, ProfileShortcutInfo> ProfileShortcutsMap; |
- ProfileShortcutsMap profile_shortcuts_; |
+ ProfileInfoCache& profile_info_cache_; |
}; |
// static |
@@ -165,65 +199,129 @@ |
} |
// static |
-ProfileShortcutManager* ProfileShortcutManager::Create() { |
- return new ProfileShortcutManagerWin(); |
+ProfileShortcutManager* ProfileShortcutManager::Create( |
+ ProfileInfoCache& cache) { |
+ return new ProfileShortcutManagerWin(cache); |
} |
-ProfileShortcutManagerWin::ProfileShortcutManagerWin() { |
+ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileInfoCache& cache) |
+ : profile_info_cache_(cache) { |
+ cache.AddObserver(this); |
} |
ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |
+ profile_info_cache_.RemoveObserver(this); |
} |
-void ProfileShortcutManagerWin::CreateChromeDesktopShortcut( |
+void ProfileShortcutManagerWin::StartProfileDesktopShortcutCreation( |
const FilePath& profile_path, const string16& profile_name, |
const gfx::Image& avatar_image) { |
- FilePath shortcut_icon = CreateChromeDesktopShortcutIconForProfile( |
- profile_path, avatar_image); |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
- FilePath chrome_exe; |
- if (!PathService::Get(base::FILE_EXE, &chrome_exe)) |
- return; |
- BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
- string16 description; |
- if (!dist) |
- return; |
- description = WideToUTF16(dist->GetAppDescription()); |
+ DCHECK(!avatar_image.IsEmpty()); |
+ const SkBitmap* avatar_bitmap = avatar_image.ToSkBitmap(); |
- // Add the profile to the map if it doesn't exist already |
- if (!profile_shortcuts_.count(profile_path)) { |
- string16 flags = CreateProfileShortcutFlags(profile_path); |
- profile_shortcuts_.insert(std::make_pair(profile_path, |
- ProfileShortcutInfo(flags, profile_name, |
- avatar_image))); |
- } |
- |
- ShellUtil::CreateChromeDesktopShortcut( |
- dist, |
- chrome_exe.value(), |
- description, |
- profile_shortcuts_[profile_path].profile_name, |
- profile_shortcuts_[profile_path].flags, |
- shortcut_icon.empty() ? chrome_exe.value() : shortcut_icon.value(), |
- shortcut_icon.empty() ? dist->GetIconIndex() : 0, |
- ShellUtil::CURRENT_USER, |
- ShellUtil::SHORTCUT_CREATE_ALWAYS); |
+ // Make a copy of the SkBitmap to ensure that we can safely use the image |
+ // data on the FILE thread. |
+ SkBitmap avatar_bitmap_copy; |
+ DCHECK(avatar_bitmap->deepCopyTo(&avatar_bitmap_copy, |
+ avatar_bitmap->getConfig())); |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&CreateOrUpdateProfileDesktopShortcut, |
+ profile_path, profile_name, avatar_bitmap_copy, true)); |
} |
-void ProfileShortcutManagerWin::DeleteChromeDesktopShortcut( |
- const FilePath& profile_path) { |
+void ProfileShortcutManagerWin::DeleteProfileDesktopShortcut( |
+ const FilePath& profile_path, const string16& profile_name) { |
BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
string16 shortcut; |
// If we can find the shortcut, delete it |
if (ShellUtil::GetChromeShortcutName(dist, false, |
- profile_shortcuts_[profile_path].profile_name, &shortcut)) { |
+ profile_name, &shortcut)) { |
std::vector<string16> appended_names(1, shortcut); |
BrowserThread::PostTask( |
BrowserThread::FILE, FROM_HERE, |
- base::Bind(&CallShellUtilBoolFunction, base::Bind( |
+ base::Bind(&CallBoolFunction, base::Bind( |
&ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames, |
appended_names))); |
- profile_shortcuts_.erase(profile_path); |
} |
+ FilePath icon_path = profile_path.AppendASCII(kProfileIconFileName); |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&CallBoolFunction, base::Bind( |
+ &file_util::Delete, icon_path, false))); |
} |
+void ProfileShortcutManagerWin::OnProfileAdded(const FilePath& profile_path) { |
+} |
+ |
+void ProfileShortcutManagerWin::OnProfileWillBeRemoved( |
+ const FilePath& profile_path) { |
+} |
+ |
+void ProfileShortcutManagerWin::OnProfileWasRemoved( |
+ const FilePath& profile_path, |
+ const string16& profile_name) { |
+} |
+ |
+void ProfileShortcutManagerWin::OnProfileNameChanged( |
+ const FilePath& profile_path, |
+ const string16& old_profile_name) { |
+ size_t profile_index = profile_info_cache_.GetIndexOfProfileWithPath( |
+ profile_path); |
+ if (profile_index == std::string::npos) |
+ return; |
+ |
+ string16 new_profile_name = |
+ profile_info_cache_.GetNameOfProfileAtIndex(profile_index); |
+ |
+ string16 old_shortcut_file; |
+ string16 new_shortcut_file; |
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
+ if (ShellUtil::GetChromeShortcutName( |
+ dist, false, old_profile_name, &old_shortcut_file) && |
+ ShellUtil::GetChromeShortcutName( |
+ dist, false, new_profile_name, &new_shortcut_file)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&RenameChromeDesktopShortcutForProfile, |
+ old_shortcut_file, |
+ new_shortcut_file)); |
+ } |
+} |
+ |
+void ProfileShortcutManagerWin::OnProfileAvatarChanged( |
+ const FilePath& profile_path) { |
+ size_t profile_index = profile_info_cache_.GetIndexOfProfileWithPath( |
+ profile_path); |
+ if (profile_index == std::string::npos) |
+ return; |
+ |
+ string16 profile_name = |
+ profile_info_cache_.GetNameOfProfileAtIndex(profile_index); |
+ string16 shortcut; |
+ |
+ BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
+ if (ShellUtil::GetChromeShortcutName( |
+ dist, false, profile_name, &shortcut)) { |
+ size_t new_icon_index = profile_info_cache_. |
+ GetAvatarIconIndexOfProfileAtIndex(profile_index); |
+ gfx::Image avatar_image = |
+ ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
+ profile_info_cache_.GetDefaultAvatarIconResourceIDAtIndex( |
+ new_icon_index)); |
+ |
+ DCHECK(!avatar_image.IsEmpty()); |
+ const SkBitmap* avatar_bitmap = avatar_image.ToSkBitmap(); |
+ |
+ // Make a copy of the SkBitmap to ensure that we can safely use the image |
+ // data on the FILE thread. |
+ SkBitmap avatar_bitmap_copy; |
+ DCHECK(avatar_bitmap->deepCopyTo(&avatar_bitmap_copy, |
+ avatar_bitmap->getConfig())); |
+ BrowserThread::PostTask( |
+ BrowserThread::FILE, FROM_HERE, |
+ base::Bind(&CreateOrUpdateProfileDesktopShortcut, |
+ profile_path, profile_name, avatar_bitmap_copy, false)); |
+ } |
+} |
+ |