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

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

Issue 1614943004: Revert of Uniquify profile shortcut name. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « chrome/browser/profiles/profile_shortcut_manager_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <algorithm>
10 #include <set>
11 #include <string> 9 #include <string>
12 #include <vector> 10 #include <vector>
13 11
14 #include "base/bind.h" 12 #include "base/bind.h"
15 #include "base/command_line.h" 13 #include "base/command_line.h"
16 #include "base/files/file_enumerator.h" 14 #include "base/files/file_enumerator.h"
17 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
18 #include "base/path_service.h" 16 #include "base/path_service.h"
19 #include "base/prefs/pref_service.h" 17 #include "base/prefs/pref_service.h"
20 #include "base/strings/string16.h" 18 #include "base/strings/string16.h"
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 return false; 282 return false;
285 283
286 base::FilePath target_path; 284 base::FilePath target_path;
287 if (!base::win::ResolveShortcut(path, &target_path, command_line)) 285 if (!base::win::ResolveShortcut(path, &target_path, command_line))
288 return false; 286 return false;
289 // One of the paths may be in short (elided) form. Compare long paths to 287 // One of the paths may be in short (elided) form. Compare long paths to
290 // ensure these are still properly matched. 288 // ensure these are still properly matched.
291 return ConvertToLongPath(target_path) == ConvertToLongPath(chrome_exe); 289 return ConvertToLongPath(target_path) == ConvertToLongPath(chrome_exe);
292 } 290 }
293 291
294 // A functor checks if |path| is the Chrome desktop shortcut (|chrome_exe|) 292 // Populates |paths| with the file paths of Chrome desktop shortcuts that have
295 // that have the specified |command_line|. If |include_empty_command_lines| is 293 // the specified |command_line|. If |include_empty_command_lines| is true,
296 // true Chrome desktop shortcuts with empty command lines will also be included. 294 // Chrome desktop shortcuts with empty command lines will also be included.
297 struct ChromeCommandLineFilter { 295 void ListDesktopShortcutsWithCommandLine(const base::FilePath& chrome_exe,
298 const base::FilePath& chrome_exe; 296 const base::string16& command_line,
299 const base::string16& command_line; 297 bool include_empty_command_lines,
300 bool include_empty_command_lines; 298 std::vector<base::FilePath>* paths) {
299 base::FilePath user_shortcuts_directory;
300 if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, NULL))
301 return;
301 302
302 ChromeCommandLineFilter(const base::FilePath& chrome_exe, 303 base::FileEnumerator enumerator(user_shortcuts_directory, false,
303 const base::string16& command_line, 304 base::FileEnumerator::FILES);
304 bool include_empty_command_lines) 305 for (base::FilePath path = enumerator.Next(); !path.empty();
305 : chrome_exe(chrome_exe), 306 path = enumerator.Next()) {
306 command_line(command_line),
307 include_empty_command_lines(include_empty_command_lines) {}
308
309 bool operator()(const base::FilePath& path) const {
310 base::string16 shortcut_command_line; 307 base::string16 shortcut_command_line;
311 if (!IsChromeShortcut(path, chrome_exe, &shortcut_command_line)) 308 if (!IsChromeShortcut(path, chrome_exe, &shortcut_command_line))
312 return false; 309 continue;
313 310
314 // TODO(asvitkine): Change this to build a CommandLine object and ensure all 311 // TODO(asvitkine): Change this to build a CommandLine object and ensure all
315 // args from |command_line| are present in the shortcut's CommandLine. This 312 // args from |command_line| are present in the shortcut's CommandLine. This
316 // will be more robust when |command_line| contains multiple args. 313 // will be more robust when |command_line| contains multiple args.
317 if ((shortcut_command_line.empty() && include_empty_command_lines) || 314 if ((shortcut_command_line.empty() && include_empty_command_lines) ||
318 (shortcut_command_line.find(command_line) != base::string16::npos)) { 315 (shortcut_command_line.find(command_line) != base::string16::npos)) {
319 return true; 316 paths->push_back(path);
320 } 317 }
321 return false;
322 } 318 }
323 };
324
325 // Get the file paths of desktop files and folders optionally filtered
326 // by |filter|.
327 std::set<base::FilePath> ListUserDesktopContents(
328 const ChromeCommandLineFilter* filter) {
329 std::set<base::FilePath> result;
330
331 base::FilePath user_shortcuts_directory;
332 if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, nullptr))
333 return result;
334
335 base::FileEnumerator enumerator(
336 user_shortcuts_directory, false,
337 base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
338 for (base::FilePath path = enumerator.Next(); !path.empty();
339 path = enumerator.Next()) {
340 if (!filter || (*filter)(path))
341 result.insert(path);
342 }
343 return result;
344 } 319 }
345 320
346 // Renames the given desktop shortcut and informs the shell of this change. 321 // Renames the given desktop shortcut and informs the shell of this change.
347 bool RenameDesktopShortcut(const base::FilePath& old_shortcut_path, 322 bool RenameDesktopShortcut(const base::FilePath& old_shortcut_path,
348 const base::FilePath& new_shortcut_path) { 323 const base::FilePath& new_shortcut_path) {
349 if (!base::Move(old_shortcut_path, new_shortcut_path)) 324 if (!base::Move(old_shortcut_path, new_shortcut_path))
350 return false; 325 return false;
351 326
352 // Notify the shell of the rename, which allows the icon to keep its position 327 // Notify the shell of the rename, which allows the icon to keep its position
353 // on the desktop when renamed. Note: This only works if either SHCNF_FLUSH or 328 // on the desktop when renamed. Note: This only works if either SHCNF_FLUSH or
354 // SHCNF_FLUSHNOWAIT is specified as a flag. 329 // SHCNF_FLUSHNOWAIT is specified as a flag.
355 SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT, 330 SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT,
356 old_shortcut_path.value().c_str(), 331 old_shortcut_path.value().c_str(),
357 new_shortcut_path.value().c_str()); 332 new_shortcut_path.value().c_str());
358 return true; 333 return true;
359 } 334 }
360 335
361 // Renames an existing Chrome desktop profile shortcut. Must be called on the 336 // Renames an existing Chrome desktop profile shortcut. Must be called on the
362 // FILE thread. 337 // FILE thread.
363 // |profile_shortcuts| are Chrome desktop shortcuts for the profile (there can
364 // be several).
365 // |desktop_contents| is the collection of all user desktop shortcuts
366 // (not only Chrome). It is used to make an unique shortcut for the
367 // |new_profile_name| among all shortcuts.
368 // This function updates |profile_shortcuts| and |desktop_contents| respectively
369 // when renaming occurs.
370 void RenameChromeDesktopShortcutForProfile( 338 void RenameChromeDesktopShortcutForProfile(
371 const base::string16& old_profile_name, 339 const base::string16& old_shortcut_filename,
372 const base::string16& new_profile_name, 340 const base::string16& new_shortcut_filename) {
373 std::set<base::FilePath>* profile_shortcuts,
374 std::set<base::FilePath>* desktop_contents) {
375 DCHECK(profile_shortcuts);
376 DCHECK(desktop_contents);
377 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 341 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
378 342
379 base::FilePath user_shortcuts_directory; 343 base::FilePath user_shortcuts_directory;
380 base::FilePath system_shortcuts_directory; 344 base::FilePath system_shortcuts_directory;
381 if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, 345 if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory,
382 &system_shortcuts_directory)) { 346 &system_shortcuts_directory)) {
383 return; 347 return;
384 } 348 }
385 349
386 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 350 const base::FilePath old_shortcut_path =
387 351 user_shortcuts_directory.Append(old_shortcut_filename);
388 // Get a new unique shortcut name.
389 const base::string16 new_shortcut_filename =
390 profiles::internal::GetUniqueShortcutFilenameForProfile(
391 new_profile_name, *desktop_contents, distribution);
392 const base::FilePath new_shortcut_path = 352 const base::FilePath new_shortcut_path =
393 user_shortcuts_directory.Append(new_shortcut_filename); 353 user_shortcuts_directory.Append(new_shortcut_filename);
394 354
395 if (!profile_shortcuts->empty()) { 355 if (base::PathExists(old_shortcut_path)) {
396 // From all profile_shortcuts choose the one with a known (canonical) name.
397 profiles::internal::ShortcutFilenameMatcher matcher(old_profile_name,
398 distribution);
399 auto it = std::find_if(profile_shortcuts->begin(), profile_shortcuts->end(),
400 [&matcher](const base::FilePath& p) {
401 return matcher.IsCanonical(p.BaseName().value());
402 });
403 // If all profile_shortcuts were renamed by user, respect it and do not
404 // rename.
405 if (it == profile_shortcuts->end())
406 return;
407 const base::FilePath old_shortcut_path = *it;
408
409 // Rename the old shortcut unless a system-level shortcut exists at the 356 // Rename the old shortcut unless a system-level shortcut exists at the
410 // destination, in which case the old shortcut is simply deleted. 357 // destination, in which case the old shortcut is simply deleted.
411 const base::FilePath possible_new_system_shortcut = 358 const base::FilePath possible_new_system_shortcut =
412 system_shortcuts_directory.Append(new_shortcut_filename); 359 system_shortcuts_directory.Append(new_shortcut_filename);
413 if (base::PathExists(possible_new_system_shortcut)) { 360 if (base::PathExists(possible_new_system_shortcut))
414 if (base::DeleteFile(old_shortcut_path, false)) { 361 base::DeleteFile(old_shortcut_path, false);
415 profile_shortcuts->erase(old_shortcut_path); 362 else if (!RenameDesktopShortcut(old_shortcut_path, new_shortcut_path))
416 desktop_contents->erase(old_shortcut_path); 363 DLOG(ERROR) << "Could not rename Windows profile desktop shortcut.";
417 } else {
418 DLOG(ERROR) << "Could not delete Windows profile desktop shortcut.";
419 }
420 } else {
421 if (RenameDesktopShortcut(old_shortcut_path, new_shortcut_path)) {
422 profile_shortcuts->erase(old_shortcut_path);
423 desktop_contents->erase(old_shortcut_path);
424 profile_shortcuts->insert(new_shortcut_path);
425 desktop_contents->insert(new_shortcut_path);
426 } else {
427 DLOG(ERROR) << "Could not rename Windows profile desktop shortcut.";
428 }
429 }
430 } else { 364 } else {
431 // If the shortcut does not exist, it may have been deleted by the user. 365 // If the shortcut does not exist, it may have been renamed by the user. In
366 // that case, its name should not be changed.
432 // It's also possible that a system-level shortcut exists instead - this 367 // It's also possible that a system-level shortcut exists instead - this
433 // should only be the case for the original Chrome shortcut from an 368 // should only be the case for the original Chrome shortcut from an
434 // installation. If that's the case, copy that one over - it will get its 369 // installation. If that's the case, copy that one over - it will get its
435 // properties updated by 370 // properties updated by
436 // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|. 371 // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|.
437 const auto old_shortcut_filename =
438 profiles::internal::GetShortcutFilenameForProfile(old_profile_name,
439 distribution);
440 const base::FilePath possible_old_system_shortcut = 372 const base::FilePath possible_old_system_shortcut =
441 system_shortcuts_directory.Append(old_shortcut_filename); 373 system_shortcuts_directory.Append(old_shortcut_filename);
442 if (base::PathExists(possible_old_system_shortcut)) { 374 if (base::PathExists(possible_old_system_shortcut))
443 if (base::CopyFile(possible_old_system_shortcut, new_shortcut_path)) { 375 base::CopyFile(possible_old_system_shortcut, new_shortcut_path);
444 profile_shortcuts->insert(new_shortcut_path);
445 desktop_contents->insert(new_shortcut_path);
446 } else {
447 DLOG(ERROR) << "Could not copy Windows profile desktop shortcut.";
448 }
449 }
450 } 376 }
451 } 377 }
452 378
453 struct CreateOrUpdateShortcutsParams { 379 struct CreateOrUpdateShortcutsParams {
454 CreateOrUpdateShortcutsParams( 380 CreateOrUpdateShortcutsParams(
455 base::FilePath profile_path, 381 base::FilePath profile_path,
456 ProfileShortcutManagerWin::CreateOrUpdateMode create_mode, 382 ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
457 ProfileShortcutManagerWin::NonProfileShortcutAction action) 383 ProfileShortcutManagerWin::NonProfileShortcutAction action)
458 : create_mode(create_mode), action(action), profile_path(profile_path) {} 384 : create_mode(create_mode), action(action), profile_path(profile_path) {}
459 ~CreateOrUpdateShortcutsParams() {} 385 ~CreateOrUpdateShortcutsParams() {}
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 421 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
496 NOTREACHED(); 422 NOTREACHED();
497 return; 423 return;
498 } 424 }
499 425
500 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 426 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
501 // Ensure that the distribution supports creating shortcuts. If it doesn't, 427 // Ensure that the distribution supports creating shortcuts. If it doesn't,
502 // the following code may result in NOTREACHED() being hit. 428 // the following code may result in NOTREACHED() being hit.
503 DCHECK(distribution->CanCreateDesktopShortcuts()); 429 DCHECK(distribution->CanCreateDesktopShortcuts());
504 430
505 std::set<base::FilePath> desktop_contents = ListUserDesktopContents(nullptr);
506
507 const base::string16 command_line =
508 profiles::internal::CreateProfileShortcutFlags(params.profile_path);
509 ChromeCommandLineFilter filter(
510 chrome_exe, command_line,
511 params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS);
512
513 std::set<base::FilePath> shortcuts;
514 // Do not call ListUserDesktopContents again (but with filter) to avoid
515 // excess work inside it. Just reuse non-filtered desktop_contents.
516 // We need both of them (desktop_contents and shortcuts) later.
517 std::copy_if(desktop_contents.begin(), desktop_contents.end(),
518 std::inserter(shortcuts, shortcuts.begin()), filter);
519
520 if (params.old_profile_name != params.profile_name) { 431 if (params.old_profile_name != params.profile_name) {
521 RenameChromeDesktopShortcutForProfile(params.old_profile_name, 432 const base::string16 old_shortcut_filename =
522 params.profile_name, &shortcuts, 433 profiles::internal::GetShortcutFilenameForProfile(
523 &desktop_contents); 434 params.old_profile_name,
435 distribution);
436 const base::string16 new_shortcut_filename =
437 profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
438 distribution);
439 RenameChromeDesktopShortcutForProfile(old_shortcut_filename,
440 new_shortcut_filename);
524 } 441 }
525 442
526 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER); 443 ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
527 installer::Product product(distribution); 444 installer::Product product(distribution);
528 product.AddDefaultShortcutProperties(chrome_exe, &properties); 445 product.AddDefaultShortcutProperties(chrome_exe, &properties);
529 446
447 const base::string16 command_line =
448 profiles::internal::CreateProfileShortcutFlags(params.profile_path);
530 449
531 // Only set the profile-specific properties when |profile_name| is non empty. 450 // Only set the profile-specific properties when |profile_name| is non empty.
532 // If it is empty, it means the shortcut being created should be a regular, 451 // If it is empty, it means the shortcut being created should be a regular,
533 // non-profile Chrome shortcut. 452 // non-profile Chrome shortcut.
534 if (!params.profile_name.empty()) { 453 if (!params.profile_name.empty()) {
535 properties.set_arguments(command_line); 454 properties.set_arguments(command_line);
536 properties.set_icon(shortcut_icon, 0); 455 properties.set_icon(shortcut_icon, 0);
537 } else { 456 } else {
538 // Set the arguments explicitly to the empty string to ensure that 457 // Set the arguments explicitly to the empty string to ensure that
539 // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut. 458 // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut.
540 properties.set_arguments(base::string16()); 459 properties.set_arguments(base::string16());
541 } 460 }
542 461
543 properties.set_app_id( 462 properties.set_app_id(
544 ShellIntegration::GetChromiumModelIdForProfile(params.profile_path)); 463 ShellIntegration::GetChromiumModelIdForProfile(params.profile_path));
545 464
546 ShellUtil::ShortcutOperation operation = 465 ShellUtil::ShortcutOperation operation =
547 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING; 466 ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING;
548 467
468 std::vector<base::FilePath> shortcuts;
469 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line,
470 params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS,
471 &shortcuts);
549 if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND && 472 if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
550 shortcuts.empty()) { 473 shortcuts.empty()) {
551 const base::string16 shortcut_name = 474 const base::string16 shortcut_name =
552 profiles::internal::GetUniqueShortcutFilenameForProfile( 475 profiles::internal::GetShortcutFilenameForProfile(params.profile_name,
553 params.profile_name, desktop_contents, distribution); 476 distribution);
554 shortcuts.insert(base::FilePath(shortcut_name)); 477 shortcuts.push_back(base::FilePath(shortcut_name));
555 operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL; 478 operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL;
556 } 479 }
557 480
558 for (const auto& shortcut : shortcuts) { 481 for (size_t i = 0; i < shortcuts.size(); ++i) {
559 const base::FilePath shortcut_name = shortcut.BaseName().RemoveExtension(); 482 const base::FilePath shortcut_name =
483 shortcuts[i].BaseName().RemoveExtension();
560 properties.set_shortcut_name(shortcut_name.value()); 484 properties.set_shortcut_name(shortcut_name.value());
561 ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP, 485 ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
562 distribution, properties, operation); 486 distribution, properties, operation);
563 } 487 }
564 } 488 }
565 489
566 // Returns true if any desktop shortcuts exist with target |chrome_exe|, 490 // Returns true if any desktop shortcuts exist with target |chrome_exe|,
567 // regardless of their command line arguments. 491 // regardless of their command line arguments.
568 bool ChromeDesktopShortcutsExist(const base::FilePath& chrome_exe) { 492 bool ChromeDesktopShortcutsExist(const base::FilePath& chrome_exe) {
569 base::FilePath user_shortcuts_directory; 493 base::FilePath user_shortcuts_directory;
(...skipping 20 matching lines...) Expand all
590 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 514 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
591 515
592 base::FilePath chrome_exe; 516 base::FilePath chrome_exe;
593 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 517 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
594 NOTREACHED(); 518 NOTREACHED();
595 return; 519 return;
596 } 520 }
597 521
598 const base::string16 command_line = 522 const base::string16 command_line =
599 profiles::internal::CreateProfileShortcutFlags(profile_path); 523 profiles::internal::CreateProfileShortcutFlags(profile_path);
600 ChromeCommandLineFilter filter(chrome_exe, command_line, false); 524 std::vector<base::FilePath> shortcuts;
601 const std::set<base::FilePath> shortcuts = ListUserDesktopContents(&filter); 525 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, false,
526 &shortcuts);
602 527
603 for (const auto& shortcut : shortcuts) { 528 for (size_t i = 0; i < shortcuts.size(); ++i) {
604 // Use base::DeleteFile() instead of ShellUtil::RemoveShortcuts(), as the 529 // Use base::DeleteFile() instead of ShellUtil::RemoveShortcuts(), as the
605 // latter causes non-profile taskbar shortcuts to be removed since it 530 // latter causes non-profile taskbar shortcuts to be removed since it
606 // doesn't consider the command-line of the shortcuts it deletes. 531 // doesn't consider the command-line of the shortcuts it deletes.
607 // TODO(huangs): Refactor with ShellUtil::RemoveShortcuts(). 532 // TODO(huangs): Refactor with ShellUtil::RemoveShortcuts().
608 base::win::UnpinShortcutFromTaskbar(shortcut); 533 base::win::UnpinShortcutFromTaskbar(shortcuts[i]);
609 base::DeleteFile(shortcut, false); 534 base::DeleteFile(shortcuts[i], false);
610 // Notify the shell that the shortcut was deleted to ensure desktop refresh. 535 // Notify the shell that the shortcut was deleted to ensure desktop refresh.
611 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcut.value().c_str(), nullptr); 536 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcuts[i].value().c_str(),
537 NULL);
612 } 538 }
613 539
614 // If |ensure_shortcuts_remain| is true and deleting this profile caused the 540 // If |ensure_shortcuts_remain| is true and deleting this profile caused the
615 // last shortcuts to be removed, re-create a regular non-profile shortcut. 541 // last shortcuts to be removed, re-create a regular non-profile shortcut.
616 const bool had_shortcuts = !shortcuts.empty(); 542 const bool had_shortcuts = !shortcuts.empty();
617 if (ensure_shortcuts_remain && had_shortcuts && 543 if (ensure_shortcuts_remain && had_shortcuts &&
618 !ChromeDesktopShortcutsExist(chrome_exe)) { 544 !ChromeDesktopShortcutsExist(chrome_exe)) {
619 BrowserDistribution* distribution = BrowserDistribution::GetDistribution(); 545 BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
620 // Ensure that the distribution supports creating shortcuts. If it doesn't, 546 // Ensure that the distribution supports creating shortcuts. If it doesn't,
621 // the following code may result in NOTREACHED() being hit. 547 // the following code may result in NOTREACHED() being hit.
(...skipping 17 matching lines...) Expand all
639 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 565 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
640 566
641 base::FilePath chrome_exe; 567 base::FilePath chrome_exe;
642 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { 568 if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
643 NOTREACHED(); 569 NOTREACHED();
644 return false; 570 return false;
645 } 571 }
646 572
647 const base::string16 command_line = 573 const base::string16 command_line =
648 profiles::internal::CreateProfileShortcutFlags(profile_path); 574 profiles::internal::CreateProfileShortcutFlags(profile_path);
649 ChromeCommandLineFilter filter(chrome_exe, command_line, false); 575 std::vector<base::FilePath> shortcuts;
650 return !ListUserDesktopContents(&filter).empty(); 576 ListDesktopShortcutsWithCommandLine(chrome_exe, command_line, false,
577 &shortcuts);
578 return !shortcuts.empty();
651 } 579 }
652 580
653 // Replaces any reserved characters with spaces, and trims the resulting string 581 // Replaces any reserved characters with spaces, and trims the resulting string
654 // to prevent any leading and trailing spaces. Also makes sure that the 582 // to prevent any leading and trailing spaces. Also makes sure that the
655 // resulting filename doesn't exceed |kMaxProfileShortcutFileNameLength|. 583 // resulting filename doesn't exceed |kMaxProfileShortcutFileNameLength|.
656 // TODO(macourteau): find a way to limit the total path's length to MAX_PATH 584 // TODO(macourteau): find a way to limit the total path's length to MAX_PATH
657 // instead of limiting the profile's name to |kMaxProfileShortcutFileNameLength| 585 // instead of limiting the profile's name to |kMaxProfileShortcutFileNameLength|
658 // characters. 586 // characters.
659 base::string16 SanitizeShortcutProfileNameString( 587 base::string16 SanitizeShortcutProfileNameString(
660 const base::string16& profile_name) { 588 const base::string16& profile_name) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 shortcut_name.append(SanitizeShortcutProfileNameString(profile_name)); 636 shortcut_name.append(SanitizeShortcutProfileNameString(profile_name));
709 shortcut_name.append(L" - "); 637 shortcut_name.append(L" - ");
710 shortcut_name.append(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 638 shortcut_name.append(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
711 } else { 639 } else {
712 shortcut_name.append( 640 shortcut_name.append(
713 distribution->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME)); 641 distribution->GetShortcutName(BrowserDistribution::SHORTCUT_CHROME));
714 } 642 }
715 return shortcut_name + installer::kLnkExt; 643 return shortcut_name + installer::kLnkExt;
716 } 644 }
717 645
718 base::string16 GetUniqueShortcutFilenameForProfile(
719 const base::string16& profile_name,
720 const std::set<base::FilePath>& excludes,
721 BrowserDistribution* distribution) {
722 std::set<base::string16> excludes_names;
723 std::transform(excludes.begin(), excludes.end(),
724 std::inserter(excludes_names, excludes_names.begin()),
725 [](const base::FilePath& e) { return e.BaseName().value(); });
726
727 const auto base_name =
728 GetShortcutFilenameForProfile(profile_name, distribution);
729 auto name = base_name;
730 const base::FilePath base_path(base_name);
731 for (int uniquifier = 1; excludes_names.count(name) > 0; ++uniquifier) {
732 const auto suffix = base::StringPrintf(" (%d)", uniquifier);
733 name = base_path.InsertBeforeExtensionASCII(suffix).value();
734 }
735 return name;
736 }
737
738 // Corresponds to GetUniqueShortcutFilenameForProfile.
739 ShortcutFilenameMatcher::ShortcutFilenameMatcher(
740 const base::string16& profile_name,
741 BrowserDistribution* distribution)
742 : profile_shortcut_filename_(
743 GetShortcutFilenameForProfile(profile_name, distribution)),
744 lnk_ext_(installer::kLnkExt),
745 profile_shortcut_name_(profile_shortcut_filename_) {
746 DCHECK(profile_shortcut_name_.ends_with(lnk_ext_));
747 profile_shortcut_name_.remove_suffix(lnk_ext_.size());
748 }
749
750 bool ShortcutFilenameMatcher::IsCanonical(
751 const base::string16& filename) const {
752 if (filename == profile_shortcut_filename_)
753 return true;
754
755 base::StringPiece16 shortcut_suffix(filename);
756 if (!shortcut_suffix.starts_with(profile_shortcut_name_))
757 return false;
758 shortcut_suffix.remove_prefix(profile_shortcut_name_.size());
759
760 if (!shortcut_suffix.ends_with(lnk_ext_))
761 return false;
762 shortcut_suffix.remove_suffix(lnk_ext_.size());
763
764 if (shortcut_suffix.size() < 4 || !shortcut_suffix.starts_with(L" (") ||
765 !shortcut_suffix.ends_with(L")")) {
766 return false;
767 }
768 return std::all_of(shortcut_suffix.begin() + 2, shortcut_suffix.end() - 1,
769 iswdigit);
770 }
771
772 base::string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) { 646 base::string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) {
773 return base::StringPrintf(L"--%ls=\"%ls\"", 647 return base::StringPrintf(L"--%ls=\"%ls\"",
774 base::ASCIIToUTF16( 648 base::ASCIIToUTF16(
775 switches::kProfileDirectory).c_str(), 649 switches::kProfileDirectory).c_str(),
776 profile_path.BaseName().value().c_str()); 650 profile_path.BaseName().value().c_str());
777 } 651 }
778 652
779 } // namespace internal 653 } // namespace internal
780 } // namespace profiles 654 } // namespace profiles
781 655
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 // Ensure the profile's icon file has been created. 877 // Ensure the profile's icon file has been created.
1004 CreateOrUpdateProfileIcon(profile->GetPath()); 878 CreateOrUpdateProfileIcon(profile->GetPath());
1005 } 879 }
1006 break; 880 break;
1007 } 881 }
1008 default: 882 default:
1009 NOTREACHED(); 883 NOTREACHED();
1010 break; 884 break;
1011 } 885 }
1012 } 886 }
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_shortcut_manager_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698