| 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 <shlobj.h>  // For SHChangeNotify(). | 7 #include <shlobj.h>  // For SHChangeNotify(). | 
| 8 | 8 | 
| 9 #include <string> | 9 #include <string> | 
| 10 #include <vector> | 10 #include <vector> | 
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 132   offscreen_canvas.drawBitmap(app_icon_bitmap, 0, 0); | 132   offscreen_canvas.drawBitmap(app_icon_bitmap, 0, 0); | 
| 133   offscreen_canvas.drawBitmap(sk_icon, | 133   offscreen_canvas.drawBitmap(sk_icon, | 
| 134                               app_icon_bitmap.width() - sk_icon.width(), | 134                               app_icon_bitmap.width() - sk_icon.width(), | 
| 135                               app_icon_bitmap.height() - sk_icon.height()); | 135                               app_icon_bitmap.height() - sk_icon.height()); | 
| 136   return badged_bitmap; | 136   return badged_bitmap; | 
| 137 } | 137 } | 
| 138 | 138 | 
| 139 // Updates the preferences with the current icon version on icon creation | 139 // Updates the preferences with the current icon version on icon creation | 
| 140 // success. | 140 // success. | 
| 141 void OnProfileIconCreateSuccess(base::FilePath profile_path) { | 141 void OnProfileIconCreateSuccess(base::FilePath profile_path) { | 
| 142   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 142   DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
| 143   if (!g_browser_process->profile_manager()) | 143   if (!g_browser_process->profile_manager()) | 
| 144     return; | 144     return; | 
| 145   Profile* profile = | 145   Profile* profile = | 
| 146       g_browser_process->profile_manager()->GetProfileByPath(profile_path); | 146       g_browser_process->profile_manager()->GetProfileByPath(profile_path); | 
| 147   if (profile) { | 147   if (profile) { | 
| 148     profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion, | 148     profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion, | 
| 149                                     kCurrentProfileIconVersion); | 149                                     kCurrentProfileIconVersion); | 
| 150   } | 150   } | 
| 151 } | 151 } | 
| 152 | 152 | 
| 153 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, | 153 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, | 
| 154 // badging the browser distribution icon with the profile avatar. | 154 // badging the browser distribution icon with the profile avatar. | 
| 155 // Returns a path to the shortcut icon file on disk, which is empty if this | 155 // Returns a path to the shortcut icon file on disk, which is empty if this | 
| 156 // fails. Use index 0 when assigning the resulting file as the icon. If both | 156 // fails. Use index 0 when assigning the resulting file as the icon. If both | 
| 157 // given bitmaps are empty, an unbadged icon is created. | 157 // given bitmaps are empty, an unbadged icon is created. | 
| 158 // Returns the path to the created icon on success and an empty base::FilePath | 158 // Returns the path to the created icon on success and an empty base::FilePath | 
| 159 // on failure. | 159 // on failure. | 
| 160 // TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's | 160 // TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's | 
| 161 // resources in the case of an unbadged icon. | 161 // resources in the case of an unbadged icon. | 
| 162 base::FilePath CreateOrUpdateShortcutIconForProfile( | 162 base::FilePath CreateOrUpdateShortcutIconForProfile( | 
| 163     const base::FilePath& profile_path, | 163     const base::FilePath& profile_path, | 
| 164     const SkBitmap& avatar_bitmap_1x, | 164     const SkBitmap& avatar_bitmap_1x, | 
| 165     const SkBitmap& avatar_bitmap_2x) { | 165     const SkBitmap& avatar_bitmap_2x) { | 
| 166   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 166   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 167 | 167 | 
| 168   if (!base::PathExists(profile_path)) { | 168   if (!base::PathExists(profile_path)) { | 
| 169     LOG(ERROR) << "Profile directory " << profile_path.value() | 169     LOG(ERROR) << "Profile directory " << profile_path.value() | 
| 170                << " did not exist when trying to create profile icon"; | 170                << " did not exist when trying to create profile icon"; | 
| 171     return base::FilePath(); | 171     return base::FilePath(); | 
| 172   } | 172   } | 
| 173 | 173 | 
| 174   scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize)); | 174   scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize)); | 
| 175   if (!app_icon_bitmap) | 175   if (!app_icon_bitmap) | 
| 176     return base::FilePath(); | 176     return base::FilePath(); | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 257       return base::FilePath(&long_path[0]); | 257       return base::FilePath(&long_path[0]); | 
| 258   } | 258   } | 
| 259   return path; | 259   return path; | 
| 260 } | 260 } | 
| 261 | 261 | 
| 262 // Returns true if the file at |path| is a Chrome shortcut and returns its | 262 // Returns true if the file at |path| is a Chrome shortcut and returns its | 
| 263 // command line in output parameter |command_line|. | 263 // command line in output parameter |command_line|. | 
| 264 bool IsChromeShortcut(const base::FilePath& path, | 264 bool IsChromeShortcut(const base::FilePath& path, | 
| 265                       const base::FilePath& chrome_exe, | 265                       const base::FilePath& chrome_exe, | 
| 266                       base::string16* command_line) { | 266                       base::string16* command_line) { | 
| 267   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 267   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 268 | 268 | 
| 269   if (path.Extension() != installer::kLnkExt) | 269   if (path.Extension() != installer::kLnkExt) | 
| 270     return false; | 270     return false; | 
| 271 | 271 | 
| 272   base::FilePath target_path; | 272   base::FilePath target_path; | 
| 273   if (!base::win::ResolveShortcut(path, &target_path, command_line)) | 273   if (!base::win::ResolveShortcut(path, &target_path, command_line)) | 
| 274     return false; | 274     return false; | 
| 275   // One of the paths may be in short (elided) form. Compare long paths to | 275   // One of the paths may be in short (elided) form. Compare long paths to | 
| 276   // ensure these are still properly matched. | 276   // ensure these are still properly matched. | 
| 277   return ConvertToLongPath(target_path) == ConvertToLongPath(chrome_exe); | 277   return ConvertToLongPath(target_path) == ConvertToLongPath(chrome_exe); | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 319                  old_shortcut_path.value().c_str(), | 319                  old_shortcut_path.value().c_str(), | 
| 320                  new_shortcut_path.value().c_str()); | 320                  new_shortcut_path.value().c_str()); | 
| 321   return true; | 321   return true; | 
| 322 } | 322 } | 
| 323 | 323 | 
| 324 // Renames an existing Chrome desktop profile shortcut. Must be called on the | 324 // Renames an existing Chrome desktop profile shortcut. Must be called on the | 
| 325 // FILE thread. | 325 // FILE thread. | 
| 326 void RenameChromeDesktopShortcutForProfile( | 326 void RenameChromeDesktopShortcutForProfile( | 
| 327     const base::string16& old_shortcut_filename, | 327     const base::string16& old_shortcut_filename, | 
| 328     const base::string16& new_shortcut_filename) { | 328     const base::string16& new_shortcut_filename) { | 
| 329   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 329   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 330 | 330 | 
| 331   base::FilePath user_shortcuts_directory; | 331   base::FilePath user_shortcuts_directory; | 
| 332   base::FilePath system_shortcuts_directory; | 332   base::FilePath system_shortcuts_directory; | 
| 333   if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, | 333   if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, | 
| 334                                       &system_shortcuts_directory)) { | 334                                       &system_shortcuts_directory)) { | 
| 335     return; | 335     return; | 
| 336   } | 336   } | 
| 337 | 337 | 
| 338   const base::FilePath old_shortcut_path = | 338   const base::FilePath old_shortcut_path = | 
| 339       user_shortcuts_directory.Append(old_shortcut_filename); | 339       user_shortcuts_directory.Append(old_shortcut_filename); | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 386   SkBitmap avatar_image_2x; | 386   SkBitmap avatar_image_2x; | 
| 387 }; | 387 }; | 
| 388 | 388 | 
| 389 // Updates all desktop shortcuts for the given profile to have the specified | 389 // Updates all desktop shortcuts for the given profile to have the specified | 
| 390 // parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut | 390 // parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut | 
| 391 // is created if no existing ones were found. Whether non-profile shortcuts | 391 // is created if no existing ones were found. Whether non-profile shortcuts | 
| 392 // should be updated is specified by |params.action|. Must be called on the FILE | 392 // should be updated is specified by |params.action|. Must be called on the FILE | 
| 393 // thread. | 393 // thread. | 
| 394 void CreateOrUpdateDesktopShortcutsAndIconForProfile( | 394 void CreateOrUpdateDesktopShortcutsAndIconForProfile( | 
| 395     const CreateOrUpdateShortcutsParams& params) { | 395     const CreateOrUpdateShortcutsParams& params) { | 
| 396   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 396   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 397 | 397 | 
| 398   const base::FilePath shortcut_icon = | 398   const base::FilePath shortcut_icon = | 
| 399       CreateOrUpdateShortcutIconForProfile(params.profile_path, | 399       CreateOrUpdateShortcutIconForProfile(params.profile_path, | 
| 400                                            params.avatar_image_1x, | 400                                            params.avatar_image_1x, | 
| 401                                            params.avatar_image_2x); | 401                                            params.avatar_image_2x); | 
| 402   if (shortcut_icon.empty() || | 402   if (shortcut_icon.empty() || | 
| 403       params.create_mode == | 403       params.create_mode == | 
| 404           ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) { | 404           ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) { | 
| 405     return; | 405     return; | 
| 406   } | 406   } | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 492 | 492 | 
| 493   return false; | 493   return false; | 
| 494 } | 494 } | 
| 495 | 495 | 
| 496 // Deletes all desktop shortcuts for the specified profile. If | 496 // Deletes all desktop shortcuts for the specified profile. If | 
| 497 // |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will | 497 // |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will | 
| 498 // be created if this function would otherwise delete the last Chrome desktop | 498 // be created if this function would otherwise delete the last Chrome desktop | 
| 499 // shortcut(s). Must be called on the FILE thread. | 499 // shortcut(s). Must be called on the FILE thread. | 
| 500 void DeleteDesktopShortcuts(const base::FilePath& profile_path, | 500 void DeleteDesktopShortcuts(const base::FilePath& profile_path, | 
| 501                             bool ensure_shortcuts_remain) { | 501                             bool ensure_shortcuts_remain) { | 
| 502   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 502   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 503 | 503 | 
| 504   base::FilePath chrome_exe; | 504   base::FilePath chrome_exe; | 
| 505   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 505   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
| 506     NOTREACHED(); | 506     NOTREACHED(); | 
| 507     return; | 507     return; | 
| 508   } | 508   } | 
| 509 | 509 | 
| 510   const base::string16 command_line = | 510   const base::string16 command_line = | 
| 511       profiles::internal::CreateProfileShortcutFlags(profile_path); | 511       profiles::internal::CreateProfileShortcutFlags(profile_path); | 
| 512   std::vector<base::FilePath> shortcuts; | 512   std::vector<base::FilePath> shortcuts; | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 543                                                           distribution)); | 543                                                           distribution)); | 
| 544     ShellUtil::CreateOrUpdateShortcut( | 544     ShellUtil::CreateOrUpdateShortcut( | 
| 545         ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties, | 545         ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties, | 
| 546         ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL); | 546         ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL); | 
| 547   } | 547   } | 
| 548 } | 548 } | 
| 549 | 549 | 
| 550 // Returns true if profile at |profile_path| has any shortcuts. Does not | 550 // Returns true if profile at |profile_path| has any shortcuts. Does not | 
| 551 // consider non-profile shortcuts. Must be called on the FILE thread. | 551 // consider non-profile shortcuts. Must be called on the FILE thread. | 
| 552 bool HasAnyProfileShortcuts(const base::FilePath& profile_path) { | 552 bool HasAnyProfileShortcuts(const base::FilePath& profile_path) { | 
| 553   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 553   DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 
| 554 | 554 | 
| 555   base::FilePath chrome_exe; | 555   base::FilePath chrome_exe; | 
| 556   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 556   if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { | 
| 557     NOTREACHED(); | 557     NOTREACHED(); | 
| 558     return false; | 558     return false; | 
| 559   } | 559   } | 
| 560 | 560 | 
| 561   const base::string16 command_line = | 561   const base::string16 command_line = | 
| 562       profiles::internal::CreateProfileShortcutFlags(profile_path); | 562       profiles::internal::CreateProfileShortcutFlags(profile_path); | 
| 563   std::vector<base::FilePath> shortcuts; | 563   std::vector<base::FilePath> shortcuts; | 
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 865         // Ensure the profile's icon file has been created. | 865         // Ensure the profile's icon file has been created. | 
| 866         CreateOrUpdateProfileIcon(profile->GetPath()); | 866         CreateOrUpdateProfileIcon(profile->GetPath()); | 
| 867       } | 867       } | 
| 868       break; | 868       break; | 
| 869     } | 869     } | 
| 870     default: | 870     default: | 
| 871       NOTREACHED(); | 871       NOTREACHED(); | 
| 872       break; | 872       break; | 
| 873   } | 873   } | 
| 874 } | 874 } | 
| OLD | NEW | 
|---|