| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" |    5 #include "chrome/browser/profiles/profile_shortcut_manager_win.h" | 
|    6  |    6  | 
|    7 #include <string> |    7 #include <string> | 
|    8 #include <vector> |    8 #include <vector> | 
|    9  |    9  | 
|   10 #include "base/bind.h" |   10 #include "base/bind.h" | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
|   27 #include "skia/ext/image_operations.h" |   27 #include "skia/ext/image_operations.h" | 
|   28 #include "skia/ext/platform_canvas.h" |   28 #include "skia/ext/platform_canvas.h" | 
|   29 #include "ui/base/resource/resource_bundle.h" |   29 #include "ui/base/resource/resource_bundle.h" | 
|   30 #include "ui/gfx/icon_util.h" |   30 #include "ui/gfx/icon_util.h" | 
|   31 #include "ui/gfx/image/image.h" |   31 #include "ui/gfx/image/image.h" | 
|   32  |   32  | 
|   33 using content::BrowserThread; |   33 using content::BrowserThread; | 
|   34  |   34  | 
|   35 namespace { |   35 namespace { | 
|   36  |   36  | 
|   37 const char kProfileIconFileName[] = "Google Profile.ico"; |  | 
|   38 const int kProfileAvatarShortcutBadgeWidth = 28; |   37 const int kProfileAvatarShortcutBadgeWidth = 28; | 
|   39 const int kProfileAvatarShortcutBadgeHeight = 28; |   38 const int kProfileAvatarShortcutBadgeHeight = 28; | 
|   40 const int kShortcutIconSize = 48; |   39 const int kShortcutIconSize = 48; | 
|   41  |   40  | 
|   42 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, |   41 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, | 
|   43 // badging the browser distribution icon with the profile avatar. |   42 // badging the browser distribution icon with the profile avatar. | 
|   44 // Returns a path to the shortcut icon file on disk, which is empty if this |   43 // Returns a path to the shortcut icon file on disk, which is empty if this | 
|   45 // fails. Use index 0 when assigning the resulting file as the icon. |   44 // fails. Use index 0 when assigning the resulting file as the icon. | 
|   46 FilePath CreateChromeDesktopShortcutIconForProfile( |   45 FilePath CreateChromeDesktopShortcutIconForProfile( | 
|   47     const FilePath& profile_path, |   46     const FilePath& profile_path, | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   84   DCHECK(offscreen_canvas.get()); |   83   DCHECK(offscreen_canvas.get()); | 
|   85   offscreen_canvas->drawBitmap(*app_icon_bitmap, 0, 0); |   84   offscreen_canvas->drawBitmap(*app_icon_bitmap, 0, 0); | 
|   86   offscreen_canvas->drawBitmap( |   85   offscreen_canvas->drawBitmap( | 
|   87       sk_icon, |   86       sk_icon, | 
|   88       app_icon_bitmap->width() - kProfileAvatarShortcutBadgeWidth, |   87       app_icon_bitmap->width() - kProfileAvatarShortcutBadgeWidth, | 
|   89       app_icon_bitmap->height() - kProfileAvatarShortcutBadgeHeight); |   88       app_icon_bitmap->height() - kProfileAvatarShortcutBadgeHeight); | 
|   90   const SkBitmap& final_bitmap = |   89   const SkBitmap& final_bitmap = | 
|   91       offscreen_canvas->getDevice()->accessBitmap(false); |   90       offscreen_canvas->getDevice()->accessBitmap(false); | 
|   92  |   91  | 
|   93   // Finally, write the .ico file containing this new bitmap. |   92   // Finally, write the .ico file containing this new bitmap. | 
|   94   FilePath icon_path = profile_path.AppendASCII(kProfileIconFileName); |   93   const FilePath icon_path = | 
 |   94       profile_path.AppendASCII(profiles::internal::kProfileIconFileName); | 
|   95   if (!IconUtil::CreateIconFileFromSkBitmap(final_bitmap, icon_path)) |   95   if (!IconUtil::CreateIconFileFromSkBitmap(final_bitmap, icon_path)) | 
|   96     return FilePath(); |   96     return FilePath(); | 
|   97  |   97  | 
|   98   return icon_path; |   98   return icon_path; | 
|   99 } |   99 } | 
|  100  |  100  | 
|  101 // Returns the command-line flags to launch Chrome with the given profile. |  | 
|  102 string16 CreateProfileShortcutFlags(const FilePath& profile_path) { |  | 
|  103   return base::StringPrintf(L"--%ls=\"%ls\"", |  | 
|  104                             ASCIIToUTF16(switches::kProfileDirectory).c_str(), |  | 
|  105                             profile_path.BaseName().value().c_str()); |  | 
|  106 } |  | 
|  107  |  | 
|  108 // Gets the directory where to create desktop shortcuts. |  101 // Gets the directory where to create desktop shortcuts. | 
|  109 bool GetDesktopShortcutsDirectory(FilePath* directory) { |  102 bool GetDesktopShortcutsDirectory(FilePath* directory) { | 
|  110   const bool result = |  103   const bool result = | 
|  111       ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, |  104       ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, | 
|  112                                  BrowserDistribution::GetDistribution(), |  105                                  BrowserDistribution::GetDistribution(), | 
|  113                                  ShellUtil::CURRENT_USER, directory); |  106                                  ShellUtil::CURRENT_USER, directory); | 
|  114   DCHECK(result); |  107   DCHECK(result); | 
|  115   return result; |  108   return result; | 
|  116 } |  109 } | 
|  117  |  110  | 
|  118 // Returns true if the file at |path| is a Chrome shortcut with the given |  111 // Returns true if the file at |path| is a Chrome shortcut and returns its | 
|  119 // |command_line|. |  112 // command line in output parameter |command_line|. | 
|  120 bool IsChromeShortcutWithCommandLine(const FilePath& path, |  113 bool IsChromeShortcut(const FilePath& path, | 
|  121                                      const FilePath& chrome_exe, |  114                       const FilePath& chrome_exe, | 
|  122                                      const string16& command_line) { |  115                       string16* command_line) { | 
|  123   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  116   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
|  124  |  117  | 
|  125   if (path.Extension() != installer::kLnkExt) |  118   if (path.Extension() != installer::kLnkExt) | 
|  126     return false; |  119     return false; | 
|  127  |  120  | 
|  128   FilePath target_path; |  121   FilePath target_path; | 
|  129   string16 command_line_args; |  122   if (!base::win::ResolveShortcut(path, &target_path, command_line)) | 
|  130   if (!base::win::ResolveShortcut(path, &target_path, &command_line_args)) |  | 
|  131     return false; |  123     return false; | 
|  132  |  124   return target_path == chrome_exe; | 
|  133   // TODO(asvitkine): Change this to build a CommandLine object and ensure all |  | 
|  134   // args from |command_line| are present in the shortcut's CommandLine. This |  | 
|  135   // will be more robust when |command_line| contains multiple args. |  | 
|  136   return target_path == chrome_exe && |  | 
|  137          command_line_args.find(command_line) != string16::npos; |  | 
|  138 } |  125 } | 
|  139  |  126  | 
|  140 // Populates |paths| with the file paths of Chrome desktop shortcuts that have |  127 // Populates |paths| with the file paths of Chrome desktop shortcuts that have | 
|  141 // the specified |command_line|. |  128 // the specified |command_line|. If |include_empty_command_lines| is true, | 
 |  129 // Chrome desktop shortcuts with empty command lines will also be included. | 
|  142 void ListDesktopShortcutsWithCommandLine(const FilePath& chrome_exe, |  130 void ListDesktopShortcutsWithCommandLine(const FilePath& chrome_exe, | 
|  143                                          const string16& command_line, |  131                                          const string16& command_line, | 
 |  132                                          bool include_empty_command_lines, | 
|  144                                          std::vector<FilePath>* paths) { |  133                                          std::vector<FilePath>* paths) { | 
|  145   FilePath shortcuts_directory; |  134   FilePath shortcuts_directory; | 
|  146   if (!GetDesktopShortcutsDirectory(&shortcuts_directory)) |  135   if (!GetDesktopShortcutsDirectory(&shortcuts_directory)) | 
|  147     return; |  136     return; | 
|  148  |  137  | 
|  149   file_util::FileEnumerator enumerator(shortcuts_directory, false, |  138   file_util::FileEnumerator enumerator(shortcuts_directory, false, | 
|  150       file_util::FileEnumerator::FILES); |  139       file_util::FileEnumerator::FILES); | 
|  151   for (FilePath path = enumerator.Next(); !path.empty(); |  140   for (FilePath path = enumerator.Next(); !path.empty(); | 
|  152        path = enumerator.Next()) { |  141        path = enumerator.Next()) { | 
|  153     if (IsChromeShortcutWithCommandLine(path, chrome_exe, command_line)) |  142     string16 shortcut_command_line; | 
 |  143     if (!IsChromeShortcut(path, chrome_exe, &shortcut_command_line)) | 
 |  144       continue; | 
 |  145  | 
 |  146     // TODO(asvitkine): Change this to build a CommandLine object and ensure all | 
 |  147     // args from |command_line| are present in the shortcut's CommandLine. This | 
 |  148     // will be more robust when |command_line| contains multiple args. | 
 |  149     if ((shortcut_command_line.empty() && include_empty_command_lines) || | 
 |  150         (shortcut_command_line.find(command_line) != string16::npos)) { | 
|  154       paths->push_back(path); |  151       paths->push_back(path); | 
 |  152     } | 
|  155   } |  153   } | 
|  156 } |  154 } | 
|  157  |  155  | 
|  158 // Renames an existing Chrome desktop profile shortcut. Must be called on the |  156 // Renames an existing Chrome desktop profile shortcut. Must be called on the | 
|  159 // FILE thread. |  157 // FILE thread. | 
|  160 void RenameChromeDesktopShortcutForProfile( |  158 void RenameChromeDesktopShortcutForProfile( | 
|  161     const string16& old_shortcut_file, |  159     const string16& old_shortcut_file, | 
|  162     const string16& new_shortcut_file) { |  160     const string16& new_shortcut_file) { | 
|  163   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  161   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
|  164  |  162  | 
|  165   FilePath shortcuts_directory; |  163   FilePath shortcuts_directory; | 
|  166   if (!GetDesktopShortcutsDirectory(&shortcuts_directory)) |  164   if (!GetDesktopShortcutsDirectory(&shortcuts_directory)) | 
|  167     return; |  165     return; | 
|  168  |  166  | 
|  169   FilePath old_shortcut_path = shortcuts_directory.Append(old_shortcut_file); |  167   FilePath old_shortcut_path = shortcuts_directory.Append(old_shortcut_file); | 
|  170   // If the shortcut does not exist, it may have been renamed by the user. In |  168   // If the shortcut does not exist, it may have been renamed by the user. In | 
|  171   // that case, its name should not be changed. |  169   // that case, its name should not be changed. | 
|  172   if (!file_util::PathExists(old_shortcut_path)) |  170   if (!file_util::PathExists(old_shortcut_path)) | 
|  173     return; |  171     return; | 
|  174  |  172  | 
|  175   FilePath new_shortcut_path = shortcuts_directory.Append(new_shortcut_file); |  173   FilePath new_shortcut_path = shortcuts_directory.Append(new_shortcut_file); | 
|  176   if (!file_util::Move(old_shortcut_path, new_shortcut_path)) |  174   if (!file_util::Move(old_shortcut_path, new_shortcut_path)) | 
|  177     LOG(ERROR) << "Could not rename Windows profile desktop shortcut."; |  175     LOG(ERROR) << "Could not rename Windows profile desktop shortcut."; | 
|  178 } |  176 } | 
|  179  |  177  | 
|  180 // Updates all desktop shortcuts for the given profile to have the specified |  178 // Updates all desktop shortcuts for the given profile to have the specified | 
|  181 // parameters. If |create| is true, a new desktop shortcut is created if no |  179 // parameters. If |create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut is | 
|  182 // existing ones were found. Must be called on the FILE thread. |  180 // created if no existing ones were found. Whether non-profile shortcuts should | 
|  183 void CreateOrUpdateDesktopShortcutsForProfile(const FilePath& profile_path, |  181 // be updated is specified by |action|. Must be called on the FILE thread. | 
|  184                                               const string16& profile_name, |  182 void CreateOrUpdateDesktopShortcutsForProfile( | 
|  185                                               const SkBitmap& avatar_image, |  183     const FilePath& profile_path, | 
|  186                                               bool create) { |  184     const string16& profile_name, | 
 |  185     const SkBitmap& avatar_image, | 
 |  186     ProfileShortcutManagerWin::CreateOrUpdateMode create_mode, | 
 |  187     ProfileShortcutManagerWin::NonProfileShortcutAction action) { | 
|  187   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  188   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
|  188  |  189  | 
|  189   FilePath chrome_exe; |  190   FilePath chrome_exe; | 
|  190   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |  191   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
|  191     NOTREACHED(); |  192     NOTREACHED(); | 
|  192     return; |  193     return; | 
|  193   } |  194   } | 
|  194  |  195  | 
|  195   BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); |  196   BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); | 
|  196   installer::Product product(distribution); |  197   installer::Product product(distribution); | 
|  197  |  198  | 
|  198   ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); |  199   ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); | 
|  199   product.AddDefaultShortcutProperties(chrome_exe, &properties); |  200   product.AddDefaultShortcutProperties(chrome_exe, &properties); | 
|  200   const FilePath shortcut_icon = |  201   const FilePath shortcut_icon = | 
|  201       CreateChromeDesktopShortcutIconForProfile(profile_path, avatar_image); |  202       CreateChromeDesktopShortcutIconForProfile(profile_path, avatar_image); | 
|  202   if (!shortcut_icon.empty()) |  203   if (!shortcut_icon.empty()) | 
|  203     properties.set_icon(shortcut_icon, 0); |  204     properties.set_icon(shortcut_icon, 0); | 
|  204  |  205  | 
|  205   const string16 command_line = CreateProfileShortcutFlags(profile_path); |  206   const string16 command_line = | 
 |  207       profiles::internal::CreateProfileShortcutFlags(profile_path); | 
|  206   properties.set_arguments(command_line); |  208   properties.set_arguments(command_line); | 
|  207  |  209  | 
|  208   ShellUtil::ShortcutOperation operation = |  210   ShellUtil::ShortcutOperation operation = | 
|  209       ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; |  211       ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; | 
|  210  |  212  | 
|  211   std::vector<FilePath> shortcuts; |  213   std::vector<FilePath> shortcuts; | 
|  212   ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, &shortcuts); |  214   ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, | 
|  213   if (create && shortcuts.empty()) { |  215       action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS, | 
 |  216       &shortcuts); | 
 |  217   if (create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND && | 
 |  218       shortcuts.empty()) { | 
|  214     const string16 shortcut_name = |  219     const string16 shortcut_name = | 
|  215         profiles::internal::GetShortcutFilenameForProfile(profile_name, |  220         profiles::internal::GetShortcutFilenameForProfile(profile_name, | 
|  216                                                           distribution); |  221                                                           distribution); | 
|  217     shortcuts.push_back(FilePath(shortcut_name)); |  222     shortcuts.push_back(FilePath(shortcut_name)); | 
|  218     operation = ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS; |  223     operation = ShellUtil::SHELL_SHORTCUT_CREATE_ALWAYS; | 
|  219   } |  224   } | 
|  220  |  225  | 
|  221   for (size_t i = 0; i < shortcuts.size(); ++i) { |  226   for (size_t i = 0; i < shortcuts.size(); ++i) { | 
|  222     const FilePath shortcut_name = shortcuts[i].BaseName().RemoveExtension(); |  227     const FilePath shortcut_name = shortcuts[i].BaseName().RemoveExtension(); | 
|  223     properties.set_shortcut_name(shortcut_name.value()); |  228     properties.set_shortcut_name(shortcut_name.value()); | 
|  224     ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, |  229     ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, | 
|  225         distribution, properties, operation); |  230         distribution, properties, operation); | 
|  226   } |  231   } | 
|  227 } |  232 } | 
|  228  |  233  | 
|  229 // Deletes all desktop shortcuts for the specified profile and also removes the |  234 // Deletes all desktop shortcuts for the specified profile and also removes the | 
|  230 // corresponding icon file. Must be called on the FILE thread. |  235 // corresponding icon file. Must be called on the FILE thread. | 
|  231 void DeleteDesktopShortcutsAndIconFile(const FilePath& profile_path, |  236 void DeleteDesktopShortcutsAndIconFile(const FilePath& profile_path, | 
|  232                                        const FilePath& icon_path) { |  237                                        const FilePath& icon_path) { | 
|  233   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |  238   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 
|  234  |  239  | 
|  235   FilePath chrome_exe; |  240   FilePath chrome_exe; | 
|  236   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { |  241   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
|  237     NOTREACHED(); |  242     NOTREACHED(); | 
|  238     return; |  243     return; | 
|  239   } |  244   } | 
|  240  |  245  | 
|  241   const string16 command_line = CreateProfileShortcutFlags(profile_path); |  246   const string16 command_line = | 
 |  247       profiles::internal::CreateProfileShortcutFlags(profile_path); | 
|  242   std::vector<FilePath> shortcuts; |  248   std::vector<FilePath> shortcuts; | 
|  243   ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, &shortcuts); |  249   ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, false, | 
 |  250                                       &shortcuts); | 
|  244  |  251  | 
|  245   BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); |  252   BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); | 
|  246   for (size_t i = 0; i < shortcuts.size(); ++i) { |  253   for (size_t i = 0; i < shortcuts.size(); ++i) { | 
|  247     const string16 shortcut_name = |  254     const string16 shortcut_name = | 
|  248         shortcuts[i].BaseName().RemoveExtension().value(); |  255         shortcuts[i].BaseName().RemoveExtension().value(); | 
|  249     ShellUtil::RemoveShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, |  256     ShellUtil::RemoveShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, | 
|  250                               distribution, chrome_exe.value(), |  257                               distribution, chrome_exe.value(), | 
|  251                               ShellUtil::CURRENT_USER, |  258                               ShellUtil::CURRENT_USER, | 
|  252                               &shortcut_name); |  259                               &shortcut_name); | 
|  253   } |  260   } | 
|  254  |  261  | 
|  255   file_util::Delete(icon_path, false); |  262   file_util::Delete(icon_path, false); | 
|  256 } |  263 } | 
|  257  |  264  | 
|  258 }  // namespace |  265 }  // namespace | 
|  259  |  266  | 
|  260 namespace profiles { |  267 namespace profiles { | 
|  261 namespace internal { |  268 namespace internal { | 
|  262  |  269  | 
 |  270 const char kProfileIconFileName[] = "Google Profile.ico"; | 
 |  271  | 
|  263 string16 GetShortcutFilenameForProfile(const string16& profile_name, |  272 string16 GetShortcutFilenameForProfile(const string16& profile_name, | 
|  264                                        BrowserDistribution* distribution) { |  273                                        BrowserDistribution* distribution) { | 
|  265   string16 shortcut_name; |  274   string16 shortcut_name; | 
|  266   if (!profile_name.empty()) { |  275   if (!profile_name.empty()) { | 
|  267     shortcut_name.append(profile_name); |  276     shortcut_name.append(profile_name); | 
|  268     shortcut_name.append(L" - "); |  277     shortcut_name.append(L" - "); | 
|  269   } |  278   } | 
|  270   shortcut_name.append(distribution->GetAppShortCutName()); |  279   shortcut_name.append(distribution->GetAppShortCutName()); | 
|  271   return shortcut_name + installer::kLnkExt; |  280   return shortcut_name + installer::kLnkExt; | 
|  272 } |  281 } | 
|  273  |  282  | 
 |  283 string16 CreateProfileShortcutFlags(const FilePath& profile_path) { | 
 |  284   return base::StringPrintf(L"--%ls=\"%ls\"", | 
 |  285                             ASCIIToUTF16(switches::kProfileDirectory).c_str(), | 
 |  286                             profile_path.BaseName().value().c_str()); | 
 |  287 } | 
 |  288  | 
|  274 }  // namespace internal |  289 }  // namespace internal | 
|  275 }  // namespace profiles |  290 }  // namespace profiles | 
|  276  |  291  | 
|  277 // static |  292 // static | 
|  278 bool ProfileShortcutManager::IsFeatureEnabled() { |  293 bool ProfileShortcutManager::IsFeatureEnabled() { | 
|  279   return false; |  294   return false; | 
|  280 } |  295 } | 
|  281  |  296  | 
|  282 // static |  297 // static | 
|  283 ProfileShortcutManager* ProfileShortcutManager::Create( |  298 ProfileShortcutManager* ProfileShortcutManager::Create( | 
|  284     ProfileManager* manager) { |  299     ProfileManager* manager) { | 
|  285   return new ProfileShortcutManagerWin(manager); |  300   return new ProfileShortcutManagerWin(manager); | 
|  286 } |  301 } | 
|  287  |  302  | 
|  288 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) |  303 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) | 
|  289     : profile_manager_(manager) { |  304     : profile_manager_(manager) { | 
|  290   profile_manager_->GetProfileInfoCache().AddObserver(this); |  305   profile_manager_->GetProfileInfoCache().AddObserver(this); | 
|  291 } |  306 } | 
|  292  |  307  | 
|  293 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { |  308 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { | 
|  294   profile_manager_->GetProfileInfoCache().RemoveObserver(this); |  309   profile_manager_->GetProfileInfoCache().RemoveObserver(this); | 
|  295 } |  310 } | 
|  296  |  311  | 
|  297 void ProfileShortcutManagerWin::CreateProfileShortcut( |  312 void ProfileShortcutManagerWin::CreateProfileShortcut( | 
|  298     const FilePath& profile_path) { |  313     const FilePath& profile_path) { | 
|  299   UpdateShortcutsForProfileAtPath(profile_path, true); |  314   CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND, | 
 |  315                                           IGNORE_NON_PROFILE_SHORTCUTS); | 
|  300 } |  316 } | 
|  301  |  317  | 
|  302 void ProfileShortcutManagerWin::OnProfileAdded(const FilePath& profile_path) { |  318 void ProfileShortcutManagerWin::OnProfileAdded(const FilePath& profile_path) { | 
|  303   const size_t profile_count = |  319   const size_t profile_count = | 
|  304       profile_manager_->GetProfileInfoCache().GetNumberOfProfiles(); |  320       profile_manager_->GetProfileInfoCache().GetNumberOfProfiles(); | 
|  305   if (profile_count == 1) { |  321   if (profile_count == 1) { | 
|  306     UpdateShortcutsForProfileAtPath(profile_path, true); |  322     CreateOrUpdateShortcutsForProfileAtPath(profile_path, | 
 |  323                                             CREATE_WHEN_NONE_FOUND, | 
 |  324                                             UPDATE_NON_PROFILE_SHORTCUTS); | 
|  307   } else if (profile_count == 2) { |  325   } else if (profile_count == 2) { | 
|  308     UpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), false); |  326     CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), | 
 |  327                                             UPDATE_EXISTING_ONLY, | 
 |  328                                             UPDATE_NON_PROFILE_SHORTCUTS); | 
|  309   } |  329   } | 
|  310 } |  330 } | 
|  311  |  331  | 
|  312 void ProfileShortcutManagerWin::OnProfileWillBeRemoved( |  332 void ProfileShortcutManagerWin::OnProfileWillBeRemoved( | 
|  313     const FilePath& profile_path) { |  333     const FilePath& profile_path) { | 
|  314 } |  334 } | 
|  315  |  335  | 
|  316 void ProfileShortcutManagerWin::OnProfileWasRemoved( |  336 void ProfileShortcutManagerWin::OnProfileWasRemoved( | 
|  317     const FilePath& profile_path, |  337     const FilePath& profile_path, | 
|  318     const string16& profile_name) { |  338     const string16& profile_name) { | 
|  319   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |  339   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 
|  320   // If there is only one profile remaining, remove the badging information |  340   // If there is only one profile remaining, remove the badging information | 
|  321   // from an existing shortcut. |  341   // from an existing shortcut. | 
|  322   if (cache.GetNumberOfProfiles() == 1) |  342   if (cache.GetNumberOfProfiles() == 1) { | 
|  323     UpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0), false); |  343     CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0), | 
 |  344                                             UPDATE_EXISTING_ONLY, | 
 |  345                                             IGNORE_NON_PROFILE_SHORTCUTS); | 
 |  346   } | 
|  324  |  347  | 
|  325   const FilePath icon_path = profile_path.AppendASCII(kProfileIconFileName); |  348   const FilePath icon_path = | 
 |  349       profile_path.AppendASCII(profiles::internal::kProfileIconFileName); | 
|  326   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |  350   BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 
|  327                           base::Bind(&DeleteDesktopShortcutsAndIconFile, |  351                           base::Bind(&DeleteDesktopShortcutsAndIconFile, | 
|  328                                      profile_path, icon_path)); |  352                                      profile_path, icon_path)); | 
|  329 } |  353 } | 
|  330  |  354  | 
|  331 void ProfileShortcutManagerWin::OnProfileNameChanged( |  355 void ProfileShortcutManagerWin::OnProfileNameChanged( | 
|  332     const FilePath& profile_path, |  356     const FilePath& profile_path, | 
|  333     const string16& old_profile_name) { |  357     const string16& old_profile_name) { | 
|  334   UpdateShortcutsForProfileAtPath(profile_path, false); |  358   CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, | 
 |  359                                           IGNORE_NON_PROFILE_SHORTCUTS); | 
|  335 } |  360 } | 
|  336  |  361  | 
|  337 void ProfileShortcutManagerWin::OnProfileAvatarChanged( |  362 void ProfileShortcutManagerWin::OnProfileAvatarChanged( | 
|  338     const FilePath& profile_path) { |  363     const FilePath& profile_path) { | 
|  339   UpdateShortcutsForProfileAtPath(profile_path, false); |  364   CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, | 
 |  365                                           IGNORE_NON_PROFILE_SHORTCUTS); | 
|  340 } |  366 } | 
|  341  |  367  | 
|  342 void ProfileShortcutManagerWin::StartProfileShortcutNameChange( |  368 void ProfileShortcutManagerWin::StartProfileShortcutNameChange( | 
|  343     const FilePath& profile_path, |  369     const FilePath& profile_path, | 
|  344     const string16& old_profile_name) { |  370     const string16& old_profile_name) { | 
|  345   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |  371   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 
|  346   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_path); |  372   size_t profile_index = cache.GetIndexOfProfileWithPath(profile_path); | 
|  347   if (profile_index == std::string::npos) |  373   if (profile_index == std::string::npos) | 
|  348     return; |  374     return; | 
|  349   // If the shortcut will have an appended name, get the profile name. |  375   // If the shortcut will have an appended name, get the profile name. | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  370   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); |  396   const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); | 
|  371   DCHECK_EQ(2U, cache.GetNumberOfProfiles()); |  397   DCHECK_EQ(2U, cache.GetNumberOfProfiles()); | 
|  372   // Get the index of the current profile, in order to find the index of the |  398   // Get the index of the current profile, in order to find the index of the | 
|  373   // other profile. |  399   // other profile. | 
|  374   size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path); |  400   size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path); | 
|  375   size_t other_profile_index = (current_profile_index == 0) ? 1 : 0; |  401   size_t other_profile_index = (current_profile_index == 0) ? 1 : 0; | 
|  376   return profile_manager_->GetProfileInfoCache(). |  402   return profile_manager_->GetProfileInfoCache(). | 
|  377       GetPathOfProfileAtIndex(other_profile_index); |  403       GetPathOfProfileAtIndex(other_profile_index); | 
|  378 } |  404 } | 
|  379  |  405  | 
|  380 void ProfileShortcutManagerWin::UpdateShortcutsForProfileAtPath( |  406 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( | 
|  381     const FilePath& profile_path, |  407     const FilePath& profile_path, | 
|  382     bool create_always) { |  408     CreateOrUpdateMode create_mode, | 
 |  409     NonProfileShortcutAction action) { | 
|  383   ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache(); |  410   ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache(); | 
|  384   size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path); |  411   size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path); | 
|  385   if (profile_index == std::string::npos) |  412   if (profile_index == std::string::npos) | 
|  386     return; |  413     return; | 
|  387   bool remove_badging = cache->GetNumberOfProfiles() == 1; |  414   bool remove_badging = cache->GetNumberOfProfiles() == 1; | 
|  388  |  415  | 
|  389   string16 old_shortcut_appended_name = |  416   string16 old_shortcut_appended_name = | 
|  390       cache->GetShortcutNameOfProfileAtIndex(profile_index); |  417       cache->GetShortcutNameOfProfileAtIndex(profile_index); | 
|  391  |  418  | 
|  392   string16 new_shortcut_appended_name; |  419   string16 new_shortcut_appended_name; | 
|  393   if (!remove_badging) |  420   if (!remove_badging) | 
|  394     new_shortcut_appended_name = cache->GetNameOfProfileAtIndex(profile_index); |  421     new_shortcut_appended_name = cache->GetNameOfProfileAtIndex(profile_index); | 
|  395  |  422  | 
|  396   if (!create_always && |  423   if (create_mode == UPDATE_EXISTING_ONLY && | 
|  397       new_shortcut_appended_name != old_shortcut_appended_name) { |  424       new_shortcut_appended_name != old_shortcut_appended_name) { | 
|  398     // TODO(asvitkine): Fold this into |UpdateDesktopShortcutsForProfile()|. |  425     // TODO(asvitkine): Fold this into |UpdateDesktopShortcutsForProfile()|. | 
|  399     StartProfileShortcutNameChange(profile_path, old_shortcut_appended_name); |  426     StartProfileShortcutNameChange(profile_path, old_shortcut_appended_name); | 
|  400   } |  427   } | 
|  401  |  428  | 
|  402   SkBitmap profile_avatar_bitmap_copy; |  429   SkBitmap profile_avatar_bitmap_copy; | 
|  403   if (!remove_badging) { |  430   if (!remove_badging) { | 
|  404     size_t profile_icon_index = |  431     size_t profile_icon_index = | 
|  405         cache->GetAvatarIconIndexOfProfileAtIndex(profile_index); |  432         cache->GetAvatarIconIndexOfProfileAtIndex(profile_index); | 
|  406     gfx::Image profile_avatar_image = ResourceBundle::GetSharedInstance(). |  433     gfx::Image profile_avatar_image = ResourceBundle::GetSharedInstance(). | 
|  407         GetNativeImageNamed( |  434         GetNativeImageNamed( | 
|  408             cache->GetDefaultAvatarIconResourceIDAtIndex(profile_icon_index)); |  435             cache->GetDefaultAvatarIconResourceIDAtIndex(profile_icon_index)); | 
|  409  |  436  | 
|  410     DCHECK(!profile_avatar_image.IsEmpty()); |  437     DCHECK(!profile_avatar_image.IsEmpty()); | 
|  411     const SkBitmap* profile_avatar_bitmap = profile_avatar_image.ToSkBitmap(); |  438     const SkBitmap* profile_avatar_bitmap = profile_avatar_image.ToSkBitmap(); | 
|  412     // Make a copy of the SkBitmap to ensure that we can safely use the image |  439     // Make a copy of the SkBitmap to ensure that we can safely use the image | 
|  413     // data on the FILE thread. |  440     // data on the FILE thread. | 
|  414     profile_avatar_bitmap->deepCopyTo(&profile_avatar_bitmap_copy, |  441     profile_avatar_bitmap->deepCopyTo(&profile_avatar_bitmap_copy, | 
|  415                                       profile_avatar_bitmap->getConfig()); |  442                                       profile_avatar_bitmap->getConfig()); | 
|  416   } |  443   } | 
|  417   BrowserThread::PostTask( |  444   BrowserThread::PostTask( | 
|  418       BrowserThread::FILE, FROM_HERE, |  445       BrowserThread::FILE, FROM_HERE, | 
|  419       base::Bind(&CreateOrUpdateDesktopShortcutsForProfile, |  446       base::Bind(&CreateOrUpdateDesktopShortcutsForProfile, | 
|  420                  profile_path, new_shortcut_appended_name, |  447                  profile_path, new_shortcut_appended_name, | 
|  421                  profile_avatar_bitmap_copy, create_always)); |  448                  profile_avatar_bitmap_copy, create_mode, action)); | 
|  422  |  449  | 
|  423   cache->SetShortcutNameOfProfileAtIndex(profile_index, |  450   cache->SetShortcutNameOfProfileAtIndex(profile_index, | 
|  424                                          new_shortcut_appended_name); |  451                                          new_shortcut_appended_name); | 
|  425 } |  452 } | 
| OLD | NEW |