Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: chrome/browser/profiles/profile_shortcut_manager_win.cc

Issue 14137032: Create profile .ico file on profile creation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move icon creation into profile_shortcut_manager Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/file_util.h" 14 #include "base/file_util.h"
15 #include "base/path_service.h" 15 #include "base/path_service.h"
16 #include "base/prefs/pref_service.h"
16 #include "base/string16.h" 17 #include "base/string16.h"
17 #include "base/string_util.h" 18 #include "base/string_util.h"
18 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
19 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
20 #include "base/win/shortcut.h" 21 #include "base/win/shortcut.h"
21 #include "chrome/browser/app_icon_win.h" 22 #include "chrome/browser/app_icon_win.h"
22 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/profiles/profile_info_cache_observer.h" 24 #include "chrome/browser/profiles/profile_info_cache_observer.h"
24 #include "chrome/browser/profiles/profile_info_util.h" 25 #include "chrome/browser/profiles/profile_info_util.h"
25 #include "chrome/browser/profiles/profile_manager.h" 26 #include "chrome/browser/profiles/profile_manager.h"
26 #include "chrome/browser/shell_integration.h" 27 #include "chrome/browser/shell_integration.h"
28 #include "chrome/common/chrome_notification_types.h"
27 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/chrome_switches.h"
30 #include "chrome/common/pref_names.h"
28 #include "chrome/installer/util/browser_distribution.h" 31 #include "chrome/installer/util/browser_distribution.h"
29 #include "chrome/installer/util/product.h" 32 #include "chrome/installer/util/product.h"
30 #include "chrome/installer/util/shell_util.h" 33 #include "chrome/installer/util/shell_util.h"
31 #include "content/public/browser/browser_thread.h" 34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/notification_service.h"
32 #include "grit/chrome_unscaled_resources.h" 36 #include "grit/chrome_unscaled_resources.h"
33 #include "grit/chromium_strings.h" 37 #include "grit/chromium_strings.h"
34 #include "skia/ext/image_operations.h" 38 #include "skia/ext/image_operations.h"
35 #include "skia/ext/platform_canvas.h" 39 #include "skia/ext/platform_canvas.h"
36 #include "ui/base/l10n/l10n_util.h" 40 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/resource/resource_bundle.h" 41 #include "ui/base/resource/resource_bundle.h"
38 #include "ui/gfx/icon_util.h" 42 #include "ui/gfx/icon_util.h"
39 #include "ui/gfx/image/image.h" 43 #include "ui/gfx/image/image.h"
40 #include "ui/gfx/image/image_family.h" 44 #include "ui/gfx/image/image_family.h"
41 #include "ui/gfx/rect.h" 45 #include "ui/gfx/rect.h"
42 #include "ui/gfx/skia_util.h" 46 #include "ui/gfx/skia_util.h"
43 47
44 using content::BrowserThread; 48 using content::BrowserThread;
45 49
46 namespace { 50 namespace {
47 51
52 // Name of the badged icon file generated for a given profile.
53 const char kProfileIconFileName[] = "Google Profile.ico";
54
48 // Characters that are not allowed in Windows filenames. Taken from 55 // Characters that are not allowed in Windows filenames. Taken from
49 // http://msdn.microsoft.com/en-us/library/aa365247.aspx 56 // http://msdn.microsoft.com/en-us/library/aa365247.aspx
50 const char16 kReservedCharacters[] = L"<>:\"/\\|?*\x01\x02\x03\x04\x05\x06\x07" 57 const char16 kReservedCharacters[] = L"<>:\"/\\|?*\x01\x02\x03\x04\x05\x06\x07"
51 L"\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19" 58 L"\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"
52 L"\x1A\x1B\x1C\x1D\x1E\x1F"; 59 L"\x1A\x1B\x1C\x1D\x1E\x1F";
53 60
54 // The maximum number of characters allowed in profile shortcuts' file names. 61 // The maximum number of characters allowed in profile shortcuts' file names.
55 // Warning: migration code will be needed if this is changed later, since 62 // Warning: migration code will be needed if this is changed later, since
56 // existing shortcuts might no longer be found if the name is generated 63 // existing shortcuts might no longer be found if the name is generated
57 // differently than it was when a shortcut was originally created. 64 // differently than it was when a shortcut was originally created.
58 const int kMaxProfileShortcutFileNameLength = 64; 65 const int kMaxProfileShortcutFileNameLength = 64;
59 66
60 const int kProfileAvatarBadgeSize = 28; 67 const int kProfileAvatarBadgeSize = 28;
61 const int kShortcutIconSize = 48; 68 const int kShortcutIconSize = 48;
62 69
70 const int kCurrentProfileIconVersion = 1;
71
63 // 2x sized profile avatar icons. Mirrors |kDefaultAvatarIconResources| in 72 // 2x sized profile avatar icons. Mirrors |kDefaultAvatarIconResources| in
64 // profile_info_cache.cc. 73 // profile_info_cache.cc.
65 const int kProfileAvatarIconResources2x[] = { 74 const int kProfileAvatarIconResources2x[] = {
66 IDR_PROFILE_AVATAR_2X_0, 75 IDR_PROFILE_AVATAR_2X_0,
67 IDR_PROFILE_AVATAR_2X_1, 76 IDR_PROFILE_AVATAR_2X_1,
68 IDR_PROFILE_AVATAR_2X_2, 77 IDR_PROFILE_AVATAR_2X_2,
69 IDR_PROFILE_AVATAR_2X_3, 78 IDR_PROFILE_AVATAR_2X_3,
70 IDR_PROFILE_AVATAR_2X_4, 79 IDR_PROFILE_AVATAR_2X_4,
71 IDR_PROFILE_AVATAR_2X_5, 80 IDR_PROFILE_AVATAR_2X_5,
72 IDR_PROFILE_AVATAR_2X_6, 81 IDR_PROFILE_AVATAR_2X_6,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 const SkBitmap& badged_bitmap = 142 const SkBitmap& badged_bitmap =
134 offscreen_canvas->getDevice()->accessBitmap(false); 143 offscreen_canvas->getDevice()->accessBitmap(false);
135 SkBitmap badged_bitmap_copy; 144 SkBitmap badged_bitmap_copy;
136 badged_bitmap.deepCopyTo(&badged_bitmap_copy, badged_bitmap.getConfig()); 145 badged_bitmap.deepCopyTo(&badged_bitmap_copy, badged_bitmap.getConfig());
137 return badged_bitmap_copy; 146 return badged_bitmap_copy;
138 } 147 }
139 148
140 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile, 149 // Creates a desktop shortcut icon file (.ico) on the disk for a given profile,
141 // badging the browser distribution icon with the profile avatar. 150 // badging the browser distribution icon with the profile avatar.
142 // Returns a path to the shortcut icon file on disk, which is empty if this 151 // Returns a path to the shortcut icon file on disk, which is empty if this
143 // fails. Use index 0 when assigning the resulting file as the icon. 152 // fails. Use index 0 when assigning the resulting file as the icon. If both
144 base::FilePath CreateChromeDesktopShortcutIconForProfile( 153 // given bitmaps are empty, an unbadged icon is created.
154 // |is_create| should be true if we are creating the icon at a time when it
gab 2013/06/18 15:36:58 There is no such |is_create| parameter..?
calamity 2013/06/27 08:10:11 Done.
155 // is not possibly already in use. If it is false, we will refresh the Windows
156 // icon cache.
157 // TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's
158 // resources in the case of an unbadged icon.
159 base::FilePath CreateOrUpdateShortcutIconForProfile(
145 const base::FilePath& profile_path, 160 const base::FilePath& profile_path,
146 const SkBitmap& avatar_bitmap_1x, 161 const SkBitmap& avatar_bitmap_1x,
147 const SkBitmap& avatar_bitmap_2x) { 162 const SkBitmap& avatar_bitmap_2x,
163 const base::Closure& callback) {
gab 2013/06/18 15:36:58 Explain what is |callback| in the method comment a
calamity 2013/06/27 08:10:11 Done.
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
149 scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize)); 165 scoped_ptr<SkBitmap> app_icon_bitmap(GetAppIconForSize(kShortcutIconSize));
150 if (!app_icon_bitmap) 166 if (!app_icon_bitmap)
151 return base::FilePath(); 167 return base::FilePath();
gab 2013/06/18 15:36:58 Also add to the method comment about what it retur
calamity 2013/06/27 08:10:11 Done.
152 168
153 gfx::ImageFamily badged_bitmaps; 169 gfx::ImageFamily badged_bitmaps;
154 badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap( 170 if (!avatar_bitmap_1x.empty()) {
155 BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
156
157 app_icon_bitmap = GetAppIconForSize(IconUtil::kLargeIconSize);
158 if (app_icon_bitmap) {
159 badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap( 171 badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
160 BadgeIcon(*app_icon_bitmap, avatar_bitmap_2x, 2))); 172 BadgeIcon(*app_icon_bitmap, avatar_bitmap_1x, 1)));
161 } 173 }
162 174
175 scoped_ptr<SkBitmap> large_app_icon_bitmap(
176 GetAppIconForSize(IconUtil::kLargeIconSize));
177 if (large_app_icon_bitmap && !avatar_bitmap_2x.empty()) {
178 badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
179 BadgeIcon(*large_app_icon_bitmap, avatar_bitmap_2x, 2)));
180 }
181
182 // If we have no badged bitmaps, we should just use the default chrome icon.
183 if (badged_bitmaps.empty()) {
184 badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(*app_icon_bitmap));
185 if (large_app_icon_bitmap) {
186 badged_bitmaps.Add(
187 gfx::Image::CreateFrom1xBitmap(*large_app_icon_bitmap));
188 }
189 }
163 // Finally, write the .ico file containing this new bitmap. 190 // Finally, write the .ico file containing this new bitmap.
164 const base::FilePath icon_path = 191 const base::FilePath icon_path =
165 profile_path.AppendASCII(profiles::internal::kProfileIconFileName); 192 profiles::internal::GetProfileIconPath(profile_path);
166 if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) 193 const bool had_icon = file_util::PathExists(icon_path);
194
195 if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) {
196 NOTREACHED();
167 return base::FilePath(); 197 return base::FilePath();
198 }
168 199
200 if (had_icon) {
201 // This invalidates the Windows icon cache and causes the icon changes to
202 // register with the taskbar and desktop. SHCNE_ASSOCCHANGED will cause a
203 // desktop flash and we would like to avoid that if possible.
204 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSHNOWAIT,
gab 2013/06/18 15:36:58 I don't think SHCNF_FLUSHNOWAIT is necessary here,
calamity 2013/06/27 08:10:11 Done.
205 NULL, NULL);
206 } else {
207 SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, icon_path.value().c_str(), NULL);
208 }
209 if (!callback.is_null())
210 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
169 return icon_path; 211 return icon_path;
170 } 212 }
171 213
214 void OnProfileIconCreateSuccess(Profile* profile) {
Alexei Svitkine (slow) 2013/06/18 15:27:19 Nit: Add a comment.
calamity 2013/06/27 08:10:11 Done.
215 profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion,
216 kCurrentProfileIconVersion);
gab 2013/06/18 15:36:58 In the current design, this will never be tried ag
217 }
218
172 // Gets the user and system directories for desktop shortcuts. Parameters may 219 // Gets the user and system directories for desktop shortcuts. Parameters may
173 // be NULL if a directory type is not needed. Returns true on success. 220 // be NULL if a directory type is not needed. Returns true on success.
174 bool GetDesktopShortcutsDirectories( 221 bool GetDesktopShortcutsDirectories(
175 base::FilePath* user_shortcuts_directory, 222 base::FilePath* user_shortcuts_directory,
176 base::FilePath* system_shortcuts_directory) { 223 base::FilePath* system_shortcuts_directory) {
177 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 224 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
178 if (user_shortcuts_directory && 225 if (user_shortcuts_directory &&
179 !ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP, 226 !ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
180 distribution, ShellUtil::CURRENT_USER, 227 distribution, ShellUtil::CURRENT_USER,
181 user_shortcuts_directory)) { 228 user_shortcuts_directory)) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 if (file_util::PathExists(possible_new_system_shortcut)) 340 if (file_util::PathExists(possible_new_system_shortcut))
294 file_util::Delete(old_shortcut_path, false); 341 file_util::Delete(old_shortcut_path, false);
295 else if (!RenameDesktopShortcut(old_shortcut_path, new_shortcut_path)) 342 else if (!RenameDesktopShortcut(old_shortcut_path, new_shortcut_path))
296 DLOG(ERROR) << "Could not rename Windows profile desktop shortcut."; 343 DLOG(ERROR) << "Could not rename Windows profile desktop shortcut.";
297 } else { 344 } else {
298 // If the shortcut does not exist, it may have been renamed by the user. In 345 // If the shortcut does not exist, it may have been renamed by the user. In
299 // that case, its name should not be changed. 346 // that case, its name should not be changed.
300 // It's also possible that a system-level shortcut exists instead - this 347 // It's also possible that a system-level shortcut exists instead - this
301 // should only be the case for the original Chrome shortcut from an 348 // should only be the case for the original Chrome shortcut from an
302 // installation. If that's the case, copy that one over - it will get its 349 // installation. If that's the case, copy that one over - it will get its
303 // properties updated by |CreateOrUpdateDesktopShortcutsForProfile()|. 350 // properties updated by
351 // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|.
304 const base::FilePath possible_old_system_shortcut = 352 const base::FilePath possible_old_system_shortcut =
305 system_shortcuts_directory.Append(old_shortcut_filename); 353 system_shortcuts_directory.Append(old_shortcut_filename);
306 if (file_util::PathExists(possible_old_system_shortcut)) 354 if (file_util::PathExists(possible_old_system_shortcut))
307 file_util::CopyFile(possible_old_system_shortcut, new_shortcut_path); 355 file_util::CopyFile(possible_old_system_shortcut, new_shortcut_path);
308 } 356 }
309 } 357 }
310 358
359 struct CreateOrUpdateShortcutsParams {
gab 2013/06/18 15:36:58 How about adding the callback to this list as well
calamity 2013/06/27 08:10:11 This doesn't avoid needing the parameter in Create
360 CreateOrUpdateShortcutsParams(
361 base::FilePath profile_path,
362 ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
363 ProfileShortcutManagerWin::NonProfileShortcutAction action)
364 : profile_path(profile_path), create_mode(create_mode), action(action) {}
365 ~CreateOrUpdateShortcutsParams() {}
366
367 ProfileShortcutManagerWin::CreateOrUpdateMode create_mode;
368 ProfileShortcutManagerWin::NonProfileShortcutAction action;
369
370 // The path for this profile.
371 base::FilePath profile_path;
372 // The profile name before this update. Empty on create.
373 string16 old_profile_name;
374 // The new profile name.
375 string16 profile_name;
376 // Avatar images for this profile.
377 SkBitmap avatar_image_1x;
378 SkBitmap avatar_image_2x;
379 };
380
311 // Updates all desktop shortcuts for the given profile to have the specified 381 // Updates all desktop shortcuts for the given profile to have the specified
312 // parameters. If |create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut is 382 // parameters. If |create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut is
313 // created if no existing ones were found. Whether non-profile shortcuts should 383 // created if no existing ones were found. Whether non-profile shortcuts should
314 // be updated is specified by |action|. Must be called on the FILE thread. 384 // be updated is specified by |action|. Must be called on the FILE thread.
gab 2013/06/18 15:36:58 This comment now refers to parameters that were mo
gab 2013/06/18 15:36:58 Add a param comment for |callback|.
calamity 2013/06/27 08:10:11 Done.
calamity 2013/06/27 08:10:11 Done.
315 void CreateOrUpdateDesktopShortcutsForProfile( 385 void CreateOrUpdateDesktopShortcutsAndIconForProfile(
316 const base::FilePath& profile_path, 386 const CreateOrUpdateShortcutsParams& params,
317 const string16& old_profile_name, 387 const base::Closure& callback) {
318 const string16& profile_name,
319 const SkBitmap& avatar_image_1x,
320 const SkBitmap& avatar_image_2x,
321 ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
322 ProfileShortcutManagerWin::NonProfileShortcutAction action) {
323 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
324 389
390 const base::FilePath shortcut_icon =
391 CreateOrUpdateShortcutIconForProfile(params.profile_path,
gab 2013/06/18 15:36:58 Shouldn't this only be called if the pref is < tha
calamity 2013/06/27 08:10:11 This is the codepath that CreateOrUpdateProfileIco
392 params.avatar_image_1x,
393 params.avatar_image_2x,
394 callback);
395 if (shortcut_icon.empty()) {
396 NOTREACHED();
397 return;
398 }
399 if (params.create_mode ==
400 ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) {
401 return;
402 }
403
325 base::FilePath chrome_exe; 404 base::FilePath chrome_exe;
326 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 405 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
327 NOTREACHED(); 406 NOTREACHED();
328 return; 407 return;
329 } 408 }
330 409
331 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 410 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
332 // Ensure that the distribution supports creating shortcuts. If it doesn't, 411 // Ensure that the distribution supports creating shortcuts. If it doesn't,
333 // the following code may result in NOTREACHED() being hit. 412 // the following code may result in NOTREACHED() being hit.
334 DCHECK(distribution->CanCreateDesktopShortcuts()); 413 DCHECK(distribution->CanCreateDesktopShortcuts());
335 414
336 if (old_profile_name != profile_name) { 415 if (params.old_profile_name != params.profile_name) {
337 const string16 old_shortcut_filename = 416 const string16 old_shortcut_filename =
338 profiles::internal::GetShortcutFilenameForProfile(old_profile_name, 417 profiles::internal::GetShortcutFilenameForProfile(
339 distribution); 418 params.old_profile_name,
419 distribution);
340 const string16 new_shortcut_filename = 420 const string16 new_shortcut_filename =
341 profiles::internal::GetShortcutFilenameForProfile(profile_name, 421 profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
342 distribution); 422 distribution);
343 RenameChromeDesktopShortcutForProfile(old_shortcut_filename, 423 RenameChromeDesktopShortcutForProfile(old_shortcut_filename,
344 new_shortcut_filename); 424 new_shortcut_filename);
345 } 425 }
346 426
347 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); 427 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
348 installer::Product product(distribution); 428 installer::Product product(distribution);
349 product.AddDefaultShortcutProperties(chrome_exe, &properties); 429 product.AddDefaultShortcutProperties(chrome_exe, &properties);
350 430
351 const string16 command_line = 431 const string16 command_line =
352 profiles::internal::CreateProfileShortcutFlags(profile_path); 432 profiles::internal::CreateProfileShortcutFlags(params.profile_path);
353 433
354 // Only set the profile-specific properties when |profile_name| is non empty. 434 // Only set the profile-specific properties when |profile_name| is non empty.
355 // If it is empty, it means the shortcut being created should be a regular, 435 // If it is empty, it means the shortcut being created should be a regular,
356 // non-profile Chrome shortcut. 436 // non-profile Chrome shortcut.
357 if (!profile_name.empty()) { 437 if (!params.profile_name.empty()) {
358 const base::FilePath shortcut_icon =
359 CreateChromeDesktopShortcutIconForProfile(profile_path,
360 avatar_image_1x,
361 avatar_image_2x);
362 if (!shortcut_icon.empty())
363 properties.set_icon(shortcut_icon, 0);
364 properties.set_arguments(command_line); 438 properties.set_arguments(command_line);
439 properties.set_icon(shortcut_icon, 0);
365 } else { 440 } else {
366 // Set the arguments explicitly to the empty string to ensure that 441 // Set the arguments explicitly to the empty string to ensure that
367 // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut. 442 // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut.
368 properties.set_arguments(string16()); 443 properties.set_arguments(string16());
369 } 444 }
370 445
371 properties.set_app_id( 446 properties.set_app_id(
372 ShellIntegration::GetChromiumModelIdForProfile(profile_path)); 447 ShellIntegration::GetChromiumModelIdForProfile(params.profile_path));
373 448
374 ShellUtil::ShortcutOperation operation = 449 ShellUtil::ShortcutOperation operation =
375 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; 450 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING;
376 451
377 std::vector<base::FilePath> shortcuts; 452 std::vector<base::FilePath> shortcuts;
378 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, 453 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line,
379 action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS, 454 params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
380 &shortcuts); 455 &shortcuts);
381 if (create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND && 456 if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
382 shortcuts.empty()) { 457 shortcuts.empty()) {
383 const string16 shortcut_name = 458 const string16 shortcut_name =
384 profiles::internal::GetShortcutFilenameForProfile(profile_name, 459 profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
385 distribution); 460 distribution);
386 shortcuts.push_back(base::FilePath(shortcut_name)); 461 shortcuts.push_back(base::FilePath(shortcut_name));
387 operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL; 462 operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL;
388 } 463 }
389 464
390 for (size_t i = 0; i < shortcuts.size(); ++i) { 465 for (size_t i = 0; i < shortcuts.size(); ++i) {
391 const base::FilePath shortcut_name = 466 const base::FilePath shortcut_name =
392 shortcuts[i].BaseName().RemoveExtension(); 467 shortcuts[i].BaseName().RemoveExtension();
393 properties.set_shortcut_name(shortcut_name.value()); 468 properties.set_shortcut_name(shortcut_name.value());
394 ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, 469 ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
(...skipping 12 matching lines...) Expand all
407 file_util::FileEnumerator::FILES); 482 file_util::FileEnumerator::FILES);
408 for (base::FilePath path = enumerator.Next(); !path.empty(); 483 for (base::FilePath path = enumerator.Next(); !path.empty();
409 path = enumerator.Next()) { 484 path = enumerator.Next()) {
410 if (IsChromeShortcut(path, chrome_exe, NULL)) 485 if (IsChromeShortcut(path, chrome_exe, NULL))
411 return true; 486 return true;
412 } 487 }
413 488
414 return false; 489 return false;
415 } 490 }
416 491
417 // Deletes all desktop shortcuts for the specified profile and also removes the 492 // Deletes all desktop shortcuts for the specified profile. If
418 // corresponding icon file. If |ensure_shortcuts_remain| is true, then a regular 493 // |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will
419 // non-profile shortcut will be created if this function would otherwise delete 494 // be created if this function would otherwise delete the last Chrome desktop
420 // the last Chrome desktop shortcut(s). Must be called on the FILE thread. 495 // shortcut(s). Must be called on the FILE thread.
421 void DeleteDesktopShortcutsAndIconFile(const base::FilePath& profile_path, 496 void DeleteDesktopShortcuts(const base::FilePath& profile_path,
422 bool ensure_shortcuts_remain) { 497 bool ensure_shortcuts_remain) {
423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
424 499
425 base::FilePath chrome_exe; 500 base::FilePath chrome_exe;
426 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 501 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
427 NOTREACHED(); 502 NOTREACHED();
428 return; 503 return;
429 } 504 }
430 505
431 const string16 command_line = 506 const string16 command_line =
432 profiles::internal::CreateProfileShortcutFlags(profile_path); 507 profiles::internal::CreateProfileShortcutFlags(profile_path);
433 std::vector<base::FilePath> shortcuts; 508 std::vector<base::FilePath> shortcuts;
434 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, false, 509 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, false,
435 &shortcuts); 510 &shortcuts);
436 511
437 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 512 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
438 for (size_t i = 0; i < shortcuts.size(); ++i) { 513 for (size_t i = 0; i < shortcuts.size(); ++i) {
439 // Use file_util::Delete() instead of ShellUtil::RemoveShortcut(), as the 514 // Use file_util::Delete() instead of ShellUtil::RemoveShortcut(), as the
440 // latter causes non-profile taskbar shortcuts to be unpinned. 515 // latter causes non-profile taskbar shortcuts to be unpinned.
441 file_util::Delete(shortcuts[i], false); 516 file_util::Delete(shortcuts[i], false);
442 // Notify the shell that the shortcut was deleted to ensure desktop refresh. 517 // Notify the shell that the shortcut was deleted to ensure desktop refresh.
443 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcuts[i].value().c_str(), 518 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcuts[i].value().c_str(),
444 NULL); 519 NULL);
445 } 520 }
446 521
447 const base::FilePath icon_path =
448 profile_path.AppendASCII(profiles::internal::kProfileIconFileName);
449 file_util::Delete(icon_path, false);
450
451 // If |ensure_shortcuts_remain| is true and deleting this profile caused the 522 // If |ensure_shortcuts_remain| is true and deleting this profile caused the
452 // last shortcuts to be removed, re-create a regular non-profile shortcut. 523 // last shortcuts to be removed, re-create a regular non-profile shortcut.
453 const bool had_shortcuts = !shortcuts.empty(); 524 const bool had_shortcuts = !shortcuts.empty();
454 if (ensure_shortcuts_remain && had_shortcuts && 525 if (ensure_shortcuts_remain && had_shortcuts &&
455 !ChromeDesktopShortcutsExist(chrome_exe)) { 526 !ChromeDesktopShortcutsExist(chrome_exe)) {
456 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 527 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
457 // Ensure that the distribution supports creating shortcuts. If it doesn't, 528 // Ensure that the distribution supports creating shortcuts. If it doesn't,
458 // the following code may result in NOTREACHED() being hit. 529 // the following code may result in NOTREACHED() being hit.
459 DCHECK(distribution->CanCreateDesktopShortcuts()); 530 DCHECK(distribution->CanCreateDesktopShortcuts());
460 installer::Product product(distribution); 531 installer::Product product(distribution);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 SkBitmap bitmap_copy; 593 SkBitmap bitmap_copy;
523 image_bitmap->deepCopyTo(&bitmap_copy, image_bitmap->getConfig()); 594 image_bitmap->deepCopyTo(&bitmap_copy, image_bitmap->getConfig());
524 return bitmap_copy; 595 return bitmap_copy;
525 } 596 }
526 597
527 } // namespace 598 } // namespace
528 599
529 namespace profiles { 600 namespace profiles {
530 namespace internal { 601 namespace internal {
531 602
532 const char kProfileIconFileName[] = "Google Profile.ico"; 603 base::FilePath GetProfileIconPath(const base::FilePath& profile_path) {
604 return profile_path.AppendASCII(kProfileIconFileName);
605 }
533 606
534 string16 GetShortcutFilenameForProfile(const string16& profile_name, 607 string16 GetShortcutFilenameForProfile(const string16& profile_name,
535 BrowserDistribution* distribution) { 608 BrowserDistribution* distribution) {
536 string16 shortcut_name; 609 string16 shortcut_name;
537 if (!profile_name.empty()) { 610 if (!profile_name.empty()) {
538 shortcut_name.append(SanitizeShortcutProfileNameString(profile_name)); 611 shortcut_name.append(SanitizeShortcutProfileNameString(profile_name));
539 shortcut_name.append(L" - "); 612 shortcut_name.append(L" - ");
540 shortcut_name.append(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 613 shortcut_name.append(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
541 } else { 614 } else {
542 shortcut_name.append(distribution->GetAppShortCutName()); 615 shortcut_name.append(distribution->GetAppShortCutName());
543 } 616 }
544 return shortcut_name + installer::kLnkExt; 617 return shortcut_name + installer::kLnkExt;
545 } 618 }
546 619
547 string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) { 620 string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) {
548 return base::StringPrintf(L"--%ls=\"%ls\"", 621 return base::StringPrintf(L"--%ls=\"%ls\"",
549 ASCIIToUTF16(switches::kProfileDirectory).c_str(), 622 ASCIIToUTF16(switches::kProfileDirectory).c_str(),
550 profile_path.BaseName().value().c_str()); 623 profile_path.BaseName().value().c_str());
551 } 624 }
552 625
553 } // namespace internal 626 } // namespace internal
554 } // namespace profiles 627 } // namespace profiles
555 628
556 // static 629 // static
557 bool ProfileShortcutManager::IsFeatureEnabled() { 630 bool ProfileShortcutManager::IsFeatureEnabled() {
558 return BrowserDistribution::GetDistribution()->CanCreateDesktopShortcuts() && 631 return BrowserDistribution::GetDistribution()->CanCreateDesktopShortcuts() &&
559 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir) && 632 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir);
gab 2013/06/18 15:36:58 I still don't like that this is disabled for --use
calamity 2013/06/27 08:10:11 This isn't a problem. Once relaunch details on bro
gab 2013/06/27 14:18:56 Ah, so the plan is to keep the runtime badging cod
Alexei Svitkine (slow) 2013/06/27 15:53:08 I think this discussion is outside the scope of th
gab 2013/06/27 17:55:44 Right, what I meant is that if the relaunch detail
560 !CommandLine::ForCurrentProcess()->HasSwitch(switches::kShowAppList);
gab 2013/06/18 15:36:58 Can this be done in a precursor CL? I feel this on
calamity 2013/06/27 08:10:11 Done.
561 } 633 }
562 634
563 // static 635 // static
564 ProfileShortcutManager* ProfileShortcutManager::Create( 636 ProfileShortcutManager* ProfileShortcutManager::Create(
565 ProfileManager* manager) { 637 ProfileManager* manager) {
566 return new ProfileShortcutManagerWin(manager); 638 return new ProfileShortcutManagerWin(manager);
567 } 639 }
568 640
569 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager) 641 ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager)
570 : profile_manager_(manager) { 642 : profile_manager_(manager) {
571 DCHECK_EQ( 643 DCHECK_EQ(
572 arraysize(kProfileAvatarIconResources2x), 644 arraysize(kProfileAvatarIconResources2x),
573 profile_manager_->GetProfileInfoCache().GetDefaultAvatarIconCount()); 645 profile_manager_->GetProfileInfoCache().GetDefaultAvatarIconCount());
574 646
647 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
Alexei Svitkine (slow) 2013/06/18 15:27:19 Add a comment to explain this is for profile icon
Alexei Svitkine (slow) 2013/06/18 15:44:32 Hmm, is this notified only when a profile gets _cr
calamity 2013/06/27 08:10:11 I'm fairly sure it's on load. It's in profile_impl
gab 2013/06/27 14:18:56 Ah ok I see, it seems to be when the Profile objec
gab 2013/07/05 13:47:24 Did you try this to confirm?
calamity 2013/07/08 07:45:49 Yeah, works as expected. Put a print and it comes
648 content::NotificationService::AllSources());
649
575 profile_manager_->GetProfileInfoCache().AddObserver(this); 650 profile_manager_->GetProfileInfoCache().AddObserver(this);
576 } 651 }
577 652
578 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() { 653 ProfileShortcutManagerWin::~ProfileShortcutManagerWin() {
579 profile_manager_->GetProfileInfoCache().RemoveObserver(this); 654 profile_manager_->GetProfileInfoCache().RemoveObserver(this);
580 } 655 }
581 656
657 void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon(
658 const base::FilePath& profile_path,
659 const base::Closure& callback) {
660 CreateOrUpdateShortcutsForProfileAtPath(profile_path,
661 CREATE_OR_UPDATE_ICON_ONLY,
gab 2013/06/27 14:18:56 Instead of introducing CREATE_OR_UPDATE_ICON_ONLY
Alexei Svitkine (slow) 2013/06/27 15:53:08 Seems like a reasonable suggestion to me, just add
calamity 2013/07/05 08:04:33 I'll still need to get the avatar resources...? I'
gab 2013/07/05 13:47:24 Ah, yes, my bad I hadn't noticed this called into
Alexei Svitkine (slow) 2013/07/05 15:14:24 Right, I remember now why I was okay with the curr
662 IGNORE_NON_PROFILE_SHORTCUTS,
663 callback);
664 }
665
582 void ProfileShortcutManagerWin::CreateProfileShortcut( 666 void ProfileShortcutManagerWin::CreateProfileShortcut(
583 const base::FilePath& profile_path) { 667 const base::FilePath& profile_path) {
584 CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND, 668 CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND,
585 IGNORE_NON_PROFILE_SHORTCUTS); 669 IGNORE_NON_PROFILE_SHORTCUTS,
670 base::Closure());
586 } 671 }
587 672
588 void ProfileShortcutManagerWin::RemoveProfileShortcuts( 673 void ProfileShortcutManagerWin::RemoveProfileShortcuts(
589 const base::FilePath& profile_path) { 674 const base::FilePath& profile_path) {
590 BrowserThread::PostTask( 675 BrowserThread::PostTask(
591 BrowserThread::FILE, FROM_HERE, 676 BrowserThread::FILE, FROM_HERE,
592 base::Bind(&DeleteDesktopShortcutsAndIconFile, profile_path, false)); 677 base::Bind(&DeleteDesktopShortcuts, profile_path, false));
593 } 678 }
594 679
595 void ProfileShortcutManagerWin::HasProfileShortcuts( 680 void ProfileShortcutManagerWin::HasProfileShortcuts(
596 const base::FilePath& profile_path, 681 const base::FilePath& profile_path,
597 const base::Callback<void(bool)>& callback) { 682 const base::Callback<void(bool)>& callback) {
598 BrowserThread::PostTaskAndReplyWithResult( 683 BrowserThread::PostTaskAndReplyWithResult(
599 BrowserThread::FILE, FROM_HERE, 684 BrowserThread::FILE, FROM_HERE,
600 base::Bind(&HasAnyProfileShortcuts, profile_path), callback); 685 base::Bind(&HasAnyProfileShortcuts, profile_path), callback);
601 } 686 }
602 687
603 void ProfileShortcutManagerWin::OnProfileAdded( 688 void ProfileShortcutManagerWin::OnProfileAdded(
604 const base::FilePath& profile_path) { 689 const base::FilePath& profile_path) {
690 CreateOrUpdateProfileIcon(profile_path, base::Closure());
605 if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) { 691 if (profile_manager_->GetProfileInfoCache().GetNumberOfProfiles() == 2) {
606 // When the second profile is added, make existing non-profile shortcuts 692 // When the second profile is added, make existing non-profile shortcuts
607 // point to the first profile and be badged/named appropriately. 693 // point to the first profile and be badged/named appropriately.
608 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path), 694 CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path),
609 UPDATE_EXISTING_ONLY, 695 UPDATE_EXISTING_ONLY,
610 UPDATE_NON_PROFILE_SHORTCUTS); 696 UPDATE_NON_PROFILE_SHORTCUTS,
697 base::Closure());
611 } 698 }
612 } 699 }
613 700
614 void ProfileShortcutManagerWin::OnProfileWillBeRemoved( 701 void ProfileShortcutManagerWin::OnProfileWillBeRemoved(
615 const base::FilePath& profile_path) { 702 const base::FilePath& profile_path) {
616 } 703 }
617 704
618 void ProfileShortcutManagerWin::OnProfileWasRemoved( 705 void ProfileShortcutManagerWin::OnProfileWasRemoved(
619 const base::FilePath& profile_path, 706 const base::FilePath& profile_path,
620 const string16& profile_name) { 707 const string16& profile_name) {
621 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); 708 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache();
622 // If there is only one profile remaining, remove the badging information 709 // If there is only one profile remaining, remove the badging information
623 // from an existing shortcut. 710 // from an existing shortcut.
624 const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1); 711 const bool deleting_down_to_last_profile = (cache.GetNumberOfProfiles() == 1);
625 if (deleting_down_to_last_profile) { 712 if (deleting_down_to_last_profile) {
713 // This is needed to unbadge the icon.
626 CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0), 714 CreateOrUpdateShortcutsForProfileAtPath(cache.GetPathOfProfileAtIndex(0),
627 UPDATE_EXISTING_ONLY, 715 UPDATE_EXISTING_ONLY,
628 IGNORE_NON_PROFILE_SHORTCUTS); 716 IGNORE_NON_PROFILE_SHORTCUTS,
717 base::Closure());
629 } 718 }
630 719
631 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 720 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
632 base::Bind(&DeleteDesktopShortcutsAndIconFile, 721 base::Bind(&DeleteDesktopShortcuts,
633 profile_path, 722 profile_path,
634 deleting_down_to_last_profile)); 723 deleting_down_to_last_profile));
635 } 724 }
636 725
637 void ProfileShortcutManagerWin::OnProfileNameChanged( 726 void ProfileShortcutManagerWin::OnProfileNameChanged(
638 const base::FilePath& profile_path, 727 const base::FilePath& profile_path,
639 const string16& old_profile_name) { 728 const string16& old_profile_name) {
640 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, 729 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
641 IGNORE_NON_PROFILE_SHORTCUTS); 730 IGNORE_NON_PROFILE_SHORTCUTS,
731 base::Closure());
642 } 732 }
643 733
644 void ProfileShortcutManagerWin::OnProfileAvatarChanged( 734 void ProfileShortcutManagerWin::OnProfileAvatarChanged(
645 const base::FilePath& profile_path) { 735 const base::FilePath& profile_path) {
646 CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY, 736 CreateOrUpdateProfileIcon(profile_path, base::Closure());
647 IGNORE_NON_PROFILE_SHORTCUTS);
648 } 737 }
649 738
650 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath( 739 base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath(
651 const base::FilePath& profile_path) { 740 const base::FilePath& profile_path) {
652 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache(); 741 const ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache();
653 DCHECK_EQ(2U, cache.GetNumberOfProfiles()); 742 DCHECK_EQ(2U, cache.GetNumberOfProfiles());
654 // Get the index of the current profile, in order to find the index of the 743 // Get the index of the current profile, in order to find the index of the
655 // other profile. 744 // other profile.
656 size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path); 745 size_t current_profile_index = cache.GetIndexOfProfileWithPath(profile_path);
657 size_t other_profile_index = (current_profile_index == 0) ? 1 : 0; 746 size_t other_profile_index = (current_profile_index == 0) ? 1 : 0;
658 return cache.GetPathOfProfileAtIndex(other_profile_index); 747 return cache.GetPathOfProfileAtIndex(other_profile_index);
659 } 748 }
660 749
661 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath( 750 void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
662 const base::FilePath& profile_path, 751 const base::FilePath& profile_path,
663 CreateOrUpdateMode create_mode, 752 CreateOrUpdateMode create_mode,
664 NonProfileShortcutAction action) { 753 NonProfileShortcutAction action,
754 const base::Closure& callback) {
755 CreateOrUpdateShortcutsParams params(profile_path, create_mode, action);
756
665 ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache(); 757 ProfileInfoCache* cache = &profile_manager_->GetProfileInfoCache();
666 size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path); 758 size_t profile_index = cache->GetIndexOfProfileWithPath(profile_path);
667 if (profile_index == std::string::npos) 759 if (profile_index == std::string::npos)
668 return; 760 return;
669 bool remove_badging = cache->GetNumberOfProfiles() == 1; 761 bool remove_badging = cache->GetNumberOfProfiles() == 1;
670 762
671 string16 old_shortcut_appended_name = 763 params.old_profile_name =
672 cache->GetShortcutNameOfProfileAtIndex(profile_index); 764 cache->GetShortcutNameOfProfileAtIndex(profile_index);
673 765
674 // Exit early if the mode is to update existing profile shortcuts only and 766 // Exit early if the mode is to update existing profile shortcuts only and
675 // none were ever created for this profile, per the shortcut name not being 767 // none were ever created for this profile, per the shortcut name not being
676 // set in the profile info cache. 768 // set in the profile info cache.
677 if (old_shortcut_appended_name.empty() && 769 if (params.old_profile_name.empty() &&
678 create_mode == UPDATE_EXISTING_ONLY && 770 create_mode == UPDATE_EXISTING_ONLY &&
679 action == IGNORE_NON_PROFILE_SHORTCUTS) { 771 action == IGNORE_NON_PROFILE_SHORTCUTS) {
680 return; 772 return;
681 } 773 }
682 774
683 string16 new_shortcut_appended_name; 775 if (!remove_badging) {
684 if (!remove_badging) 776 params.profile_name = cache->GetNameOfProfileAtIndex(profile_index);
685 new_shortcut_appended_name = cache->GetNameOfProfileAtIndex(profile_index);
686 777
687 SkBitmap avatar_bitmap_copy_1x;
688 SkBitmap avatar_bitmap_copy_2x;
689 if (!remove_badging) {
690 const size_t icon_index = 778 const size_t icon_index =
691 cache->GetAvatarIconIndexOfProfileAtIndex(profile_index); 779 cache->GetAvatarIconIndexOfProfileAtIndex(profile_index);
692 const int resource_id_1x = 780 const int resource_id_1x =
693 cache->GetDefaultAvatarIconResourceIDAtIndex(icon_index); 781 cache->GetDefaultAvatarIconResourceIDAtIndex(icon_index);
694 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index]; 782 const int resource_id_2x = kProfileAvatarIconResources2x[icon_index];
695 // Make a copy of the SkBitmaps to ensure that we can safely use the image 783 // Make a copy of the SkBitmaps to ensure that we can safely use the image
696 // data on the FILE thread. 784 // data on the FILE thread.
697 avatar_bitmap_copy_1x = GetImageResourceSkBitmapCopy(resource_id_1x); 785 params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
698 avatar_bitmap_copy_2x = GetImageResourceSkBitmapCopy(resource_id_2x); 786 params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
699 } 787 }
700 BrowserThread::PostTask( 788 BrowserThread::PostTask(
701 BrowserThread::FILE, FROM_HERE, 789 BrowserThread::FILE, FROM_HERE,
702 base::Bind(&CreateOrUpdateDesktopShortcutsForProfile, profile_path, 790 base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params,
703 old_shortcut_appended_name, new_shortcut_appended_name, 791 callback));
704 avatar_bitmap_copy_1x, avatar_bitmap_copy_2x, create_mode,
705 action));
706 792
707 cache->SetShortcutNameOfProfileAtIndex(profile_index, 793 cache->SetShortcutNameOfProfileAtIndex(profile_index,
708 new_shortcut_appended_name); 794 params.profile_name);
709 } 795 }
796
797 void ProfileShortcutManagerWin::Observe(
798 int type,
799 const content::NotificationSource& source,
800 const content::NotificationDetails& details) {
801 switch (type) {
Alexei Svitkine (slow) 2013/06/18 15:27:19 How about: if (type != chrome::NOTIFICATION_PROFI
calamity 2013/06/27 08:10:11 Other files such as: -chrome/browser/android/chrom
gab 2013/06/27 14:18:56 Yea, I like the switch personally and have seen th
Alexei Svitkine (slow) 2013/06/27 15:53:08 Fair enough, keep the switch then. :)
802 case chrome::NOTIFICATION_PROFILE_CREATED: {
gab 2013/06/27 14:18:56 Add a comment above this stipulating your findings
gab 2013/07/05 13:47:24 Ping on this -- mostly for my sanity as I don't li
calamity 2013/07/08 07:45:49 Done.
803 Profile* profile =
804 content::Source<Profile>(source).ptr()->GetOriginalProfile();
805 if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) <
Alexei Svitkine (slow) 2013/06/18 15:27:19 I suggest moving this to another anonymous functio
calamity 2013/06/27 08:10:11 Done.
806 kCurrentProfileIconVersion) {
gab 2013/06/18 15:36:58 I think this condition needs to be check every tim
calamity 2013/06/27 08:10:11 NOTIFICATION_PROFILE_CREATED was recommended by sa
807 // Ensure the profile's icon file has been created.
808 CreateOrUpdateProfileIcon(
809 profile->GetPath(),
810 base::Bind(&OnProfileIconCreateSuccess, profile));
811 }
812 break;
813 }
814 default:
815 NOTREACHED();
sail 2013/06/18 05:10:21 break;?
calamity 2013/06/27 08:10:11 Done.
816 }
817 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698