Chromium Code Reviews| 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 #import "chrome/browser/web_applications/web_app_mac.h" | 5 #import "chrome/browser/web_applications/web_app_mac.h" | 
| 6 | 6 | 
| 7 #import <Carbon/Carbon.h> | 7 #import <Carbon/Carbon.h> | 
| 8 #import <Cocoa/Cocoa.h> | 8 #import <Cocoa/Cocoa.h> | 
| 9 | 9 | 
| 10 #include "apps/app_shim/app_shim_mac.h" | 10 #include "apps/app_shim/app_shim_mac.h" | 
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 if (!close_callback.is_null()) | 434 if (!close_callback.is_null()) | 
| 435 close_callback.Run(); | 435 close_callback.Run(); | 
| 436 } | 436 } | 
| 437 | 437 | 
| 438 } // namespace chrome | 438 } // namespace chrome | 
| 439 | 439 | 
| 440 namespace web_app { | 440 namespace web_app { | 
| 441 | 441 | 
| 442 WebAppShortcutCreator::WebAppShortcutCreator( | 442 WebAppShortcutCreator::WebAppShortcutCreator( | 
| 443 const base::FilePath& app_data_dir, | 443 const base::FilePath& app_data_dir, | 
| 444 const ShellIntegration::ShortcutInfo& shortcut_info) | 444 const ShellIntegration::ShortcutInfo& shortcut_info, | 
| 445 const extensions::FileHandlersInfo& file_handlers_info) | |
| 445 : app_data_dir_(app_data_dir), | 446 : app_data_dir_(app_data_dir), | 
| 446 info_(shortcut_info) {} | 447 info_(shortcut_info), | 
| 448 file_handlers_info_(file_handlers_info) {} | |
| 447 | 449 | 
| 448 WebAppShortcutCreator::~WebAppShortcutCreator() {} | 450 WebAppShortcutCreator::~WebAppShortcutCreator() {} | 
| 449 | 451 | 
| 450 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const { | 452 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const { | 
| 451 base::FilePath applications_dir = GetApplicationsDirname(); | 453 base::FilePath applications_dir = GetApplicationsDirname(); | 
| 452 return applications_dir.empty() ? | 454 return applications_dir.empty() ? | 
| 453 base::FilePath() : applications_dir.Append(GetShortcutBasename()); | 455 base::FilePath() : applications_dir.Append(GetShortcutBasename()); | 
| 454 } | 456 } | 
| 455 | 457 | 
| 456 base::FilePath WebAppShortcutCreator::GetInternalShortcutPath() const { | 458 base::FilePath WebAppShortcutCreator::GetInternalShortcutPath() const { | 
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 } | 619 } | 
| 618 | 620 | 
| 619 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { | 621 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { | 
| 620 base::FilePath path = GetWritableApplicationsDirectory(); | 622 base::FilePath path = GetWritableApplicationsDirectory(); | 
| 621 if (path.empty()) | 623 if (path.empty()) | 
| 622 return path; | 624 return path; | 
| 623 | 625 | 
| 624 return path.Append(GetLocalizableAppShortcutsSubdirName()); | 626 return path.Append(GetLocalizableAppShortcutsSubdirName()); | 
| 625 } | 627 } | 
| 626 | 628 | 
| 629 void UpdateFileTypes(NSMutableDictionary* plist, | |
| 
 
tapted
2014/04/17 04:37:50
move to anonymous namespace
 
jackhou1
2014/04/22 04:40:19
Done.
 
 | |
| 630 const extensions::FileHandlersInfo& file_handlers_info) { | |
| 631 NSMutableArray* document_types = [NSMutableArray array]; | |
| 
 
tapted
2014/04/17 04:37:50
I think +[.. array] is only defined on NSArray.. M
 
jackhou1
2014/04/22 04:40:19
Done.
 
 | |
| 632 | |
| 633 for (unsigned int i = 0; i < file_handlers_info.handlers->size(); ++i) { | |
| 
 
tapted
2014/04/17 04:37:50
vector::const_iterator?
 
jackhou1
2014/04/22 04:40:19
Done.
 
 | |
| 634 const extensions::FileHandlerInfo& info = | |
| 635 file_handlers_info.handlers->at(i); | |
| 636 | |
| 637 NSMutableArray* file_extensions = [NSMutableArray array]; | |
| 638 for (std::set<std::string>::iterator it = info.extensions.begin(); | |
| 639 it != info.extensions.end(); ++it) { | |
| 640 [file_extensions addObject:base::SysUTF8ToNSString(*it)]; | |
| 641 } | |
| 642 | |
| 643 NSMutableArray* mime_types = [NSMutableArray array]; | |
| 644 for (std::set<std::string>::iterator it = info.types.begin(); | |
| 645 it != info.types.end(); ++it) { | |
| 646 [mime_types addObject:base::SysUTF8ToNSString(*it)]; | |
| 647 } | |
| 648 | |
| 649 [document_types addObject:@{ | |
| 650 // TODO(jackhou): Add the type name and and icon file once the manifest | |
| 
 
tapted
2014/04/17 04:37:50
nit: This.. probably needs more indent because it'
 
jackhou1
2014/04/22 04:40:19
Done.
 
 | |
| 651 // supports these. | |
| 652 // app_mode::kCFBundleTypeNameKey : , | |
| 653 // app_mode::kCFBundleTypeIconFileKey : , | |
| 654 app_mode::kCFBundleTypeExtensionsKey : file_extensions, | |
| 655 app_mode::kCFBundleTypeMIMETypesKey : mime_types, | |
| 656 app_mode::kCFBundleTypeRoleKey : app_mode::kBundleTypeRoleViewer, | |
| 
 
tapted
2014/04/17 04:37:50
nit: not sure if style guide encourages a trailing
 
jackhou1
2014/04/22 04:40:19
Checked style guide. It's not explicit, but all ex
 
 | |
| 657 }]; | |
| 658 } | |
| 659 | |
| 660 [plist setObject:document_types | |
| 661 forKey:app_mode::kCFBundleDocumentTypesKey]; | |
| 662 } | |
| 663 | |
| 627 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { | 664 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { | 
| 628 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); | 665 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); | 
| 629 NSString* extension_title = base::SysUTF16ToNSString(info_.title); | 666 NSString* extension_title = base::SysUTF16ToNSString(info_.title); | 
| 630 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); | 667 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); | 
| 631 NSString* chrome_bundle_id = | 668 NSString* chrome_bundle_id = | 
| 632 base::SysUTF8ToNSString(base::mac::BaseBundleID()); | 669 base::SysUTF8ToNSString(base::mac::BaseBundleID()); | 
| 633 NSDictionary* replacement_dict = | 670 NSDictionary* replacement_dict = | 
| 634 [NSDictionary dictionaryWithObjectsAndKeys: | 671 [NSDictionary dictionaryWithObjectsAndKeys: | 
| 635 extension_id, app_mode::kShortcutIdPlaceholder, | 672 extension_id, app_mode::kShortcutIdPlaceholder, | 
| 636 extension_title, app_mode::kShortcutNamePlaceholder, | 673 extension_title, app_mode::kShortcutNamePlaceholder, | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 if (info_.extension_id == app_mode::kAppListModeId) { | 708 if (info_.extension_id == app_mode::kAppListModeId) { | 
| 672 // Prevent the app list from bouncing in the dock, and getting a run light. | 709 // Prevent the app list from bouncing in the dock, and getting a run light. | 
| 673 [plist setObject:[NSNumber numberWithBool:YES] | 710 [plist setObject:[NSNumber numberWithBool:YES] | 
| 674 forKey:kLSUIElement]; | 711 forKey:kLSUIElement]; | 
| 675 } | 712 } | 
| 676 | 713 | 
| 677 base::FilePath app_name = app_path.BaseName().RemoveExtension(); | 714 base::FilePath app_name = app_path.BaseName().RemoveExtension(); | 
| 678 [plist setObject:base::mac::FilePathToNSString(app_name) | 715 [plist setObject:base::mac::FilePathToNSString(app_name) | 
| 679 forKey:base::mac::CFToNSCast(kCFBundleNameKey)]; | 716 forKey:base::mac::CFToNSCast(kCFBundleNameKey)]; | 
| 680 | 717 | 
| 718 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 719 switches::kEnableAppsFileAssociations)) { | |
| 720 UpdateFileTypes(plist, file_handlers_info_); | |
| 721 } | |
| 722 | |
| 681 return [plist writeToFile:plist_path | 723 return [plist writeToFile:plist_path | 
| 682 atomically:YES]; | 724 atomically:YES]; | 
| 683 } | 725 } | 
| 684 | 726 | 
| 685 bool WebAppShortcutCreator::UpdateDisplayName( | 727 bool WebAppShortcutCreator::UpdateDisplayName( | 
| 686 const base::FilePath& app_path) const { | 728 const base::FilePath& app_path) const { | 
| 687 // OSX searches for the best language in the order of preferred languages. | 729 // OSX searches for the best language in the order of preferred languages. | 
| 688 // Since we only have one localization directory, it will choose this one. | 730 // Since we only have one localization directory, it will choose this one. | 
| 689 base::FilePath localized_dir = GetResourcesPath(app_path).Append("en.lproj"); | 731 base::FilePath localized_dir = GetResourcesPath(app_path).Append("en.lproj"); | 
| 690 if (!base::CreateDirectory(localized_dir)) | 732 if (!base::CreateDirectory(localized_dir)) | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 if (app_path.empty()) | 830 if (app_path.empty()) | 
| 789 return; | 831 return; | 
| 790 | 832 | 
| 791 [[NSWorkspace sharedWorkspace] | 833 [[NSWorkspace sharedWorkspace] | 
| 792 selectFile:base::mac::FilePathToNSString(app_path) | 834 selectFile:base::mac::FilePathToNSString(app_path) | 
| 793 inFileViewerRootedAtPath:nil]; | 835 inFileViewerRootedAtPath:nil]; | 
| 794 } | 836 } | 
| 795 | 837 | 
| 796 base::FilePath GetAppInstallPath( | 838 base::FilePath GetAppInstallPath( | 
| 797 const ShellIntegration::ShortcutInfo& shortcut_info) { | 839 const ShellIntegration::ShortcutInfo& shortcut_info) { | 
| 798 WebAppShortcutCreator shortcut_creator(base::FilePath(), shortcut_info); | 840 WebAppShortcutCreator shortcut_creator( | 
| 841 base::FilePath(), shortcut_info, extensions::FileHandlersInfo(NULL)); | |
| 799 return shortcut_creator.GetApplicationsShortcutPath(); | 842 return shortcut_creator.GetApplicationsShortcutPath(); | 
| 800 } | 843 } | 
| 801 | 844 | 
| 802 void MaybeLaunchShortcut(const ShellIntegration::ShortcutInfo& shortcut_info) { | 845 void MaybeLaunchShortcut(const ShellIntegration::ShortcutInfo& shortcut_info) { | 
| 803 if (!apps::IsAppShimsEnabled()) | 846 if (!apps::IsAppShimsEnabled()) | 
| 804 return; | 847 return; | 
| 805 | 848 | 
| 806 content::BrowserThread::PostTask( | 849 content::BrowserThread::PostTask( | 
| 807 content::BrowserThread::FILE, FROM_HERE, | 850 content::BrowserThread::FILE, FROM_HERE, | 
| 808 base::Bind(&LaunchShimOnFileThread, shortcut_info)); | 851 base::Bind(&LaunchShimOnFileThread, shortcut_info)); | 
| 809 } | 852 } | 
| 810 | 853 | 
| 811 namespace internals { | 854 namespace internals { | 
| 812 | 855 | 
| 813 bool CreatePlatformShortcuts( | 856 bool CreatePlatformShortcuts( | 
| 814 const base::FilePath& app_data_path, | 857 const base::FilePath& app_data_path, | 
| 815 const ShellIntegration::ShortcutInfo& shortcut_info, | 858 const ShellIntegration::ShortcutInfo& shortcut_info, | 
| 816 const extensions::FileHandlersInfo& file_handlers_info, | 859 const extensions::FileHandlersInfo& file_handlers_info, | 
| 817 const ShellIntegration::ShortcutLocations& creation_locations, | 860 const ShellIntegration::ShortcutLocations& creation_locations, | 
| 818 ShortcutCreationReason creation_reason) { | 861 ShortcutCreationReason creation_reason) { | 
| 819 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 862 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 
| 820 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 863 WebAppShortcutCreator shortcut_creator( | 
| 864 app_data_path, shortcut_info, file_handlers_info); | |
| 821 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations); | 865 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations); | 
| 822 } | 866 } | 
| 823 | 867 | 
| 824 void DeletePlatformShortcuts( | 868 void DeletePlatformShortcuts( | 
| 825 const base::FilePath& app_data_path, | 869 const base::FilePath& app_data_path, | 
| 826 const ShellIntegration::ShortcutInfo& shortcut_info) { | 870 const ShellIntegration::ShortcutInfo& shortcut_info) { | 
| 827 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 871 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 
| 828 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 872 WebAppShortcutCreator shortcut_creator( | 
| 873 app_data_path, shortcut_info, extensions::FileHandlersInfo(NULL)); | |
| 829 shortcut_creator.DeleteShortcuts(); | 874 shortcut_creator.DeleteShortcuts(); | 
| 830 } | 875 } | 
| 831 | 876 | 
| 832 void UpdatePlatformShortcuts( | 877 void UpdatePlatformShortcuts( | 
| 833 const base::FilePath& app_data_path, | 878 const base::FilePath& app_data_path, | 
| 834 const base::string16& old_app_title, | 879 const base::string16& old_app_title, | 
| 835 const ShellIntegration::ShortcutInfo& shortcut_info, | 880 const ShellIntegration::ShortcutInfo& shortcut_info, | 
| 836 const extensions::FileHandlersInfo& file_handlers_info) { | 881 const extensions::FileHandlersInfo& file_handlers_info) { | 
| 837 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 882 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 
| 838 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 883 WebAppShortcutCreator shortcut_creator( | 
| 884 app_data_path, shortcut_info, file_handlers_info); | |
| 839 shortcut_creator.UpdateShortcuts(); | 885 shortcut_creator.UpdateShortcuts(); | 
| 840 } | 886 } | 
| 841 | 887 | 
| 842 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { | 888 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { | 
| 843 const std::string profile_base_name = profile_path.BaseName().value(); | 889 const std::string profile_base_name = profile_path.BaseName().value(); | 
| 844 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath( | 890 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath( | 
| 845 profile_path.Append(chrome::kWebAppDirname), profile_base_name); | 891 profile_path.Append(chrome::kWebAppDirname), profile_base_name); | 
| 846 | 892 | 
| 847 for (std::vector<base::FilePath>::const_iterator it = bundles.begin(); | 893 for (std::vector<base::FilePath>::const_iterator it = bundles.begin(); | 
| 848 it != bundles.end(); ++it) { | 894 it != bundles.end(); ++it) { | 
| 849 ShellIntegration::ShortcutInfo shortcut_info = | 895 ShellIntegration::ShortcutInfo shortcut_info = | 
| 850 BuildShortcutInfoFromBundle(*it); | 896 BuildShortcutInfoFromBundle(*it); | 
| 851 WebAppShortcutCreator shortcut_creator(it->DirName(), shortcut_info); | 897 WebAppShortcutCreator shortcut_creator( | 
| 898 it->DirName(), shortcut_info, extensions::FileHandlersInfo(NULL)); | |
| 852 shortcut_creator.DeleteShortcuts(); | 899 shortcut_creator.DeleteShortcuts(); | 
| 853 } | 900 } | 
| 854 } | 901 } | 
| 855 | 902 | 
| 856 } // namespace internals | 903 } // namespace internals | 
| 857 | 904 | 
| 858 } // namespace web_app | 905 } // namespace web_app | 
| OLD | NEW |