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 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "base/path_service.h" | 23 #include "base/path_service.h" |
24 #include "base/process/process_handle.h" | 24 #include "base/process/process_handle.h" |
25 #include "base/strings/string16.h" | 25 #include "base/strings/string16.h" |
26 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
27 #include "base/strings/string_split.h" | 27 #include "base/strings/string_split.h" |
28 #include "base/strings/string_util.h" | 28 #include "base/strings/string_util.h" |
29 #include "base/strings/sys_string_conversions.h" | 29 #include "base/strings/sys_string_conversions.h" |
30 #include "base/strings/utf_string_conversions.h" | 30 #include "base/strings/utf_string_conversions.h" |
31 #include "base/version.h" | 31 #include "base/version.h" |
32 #include "chrome/browser/browser_process.h" | 32 #include "chrome/browser/browser_process.h" |
| 33 #include "chrome/browser/extensions/extension_ui_util.h" |
33 #import "chrome/browser/mac/dock.h" | 34 #import "chrome/browser/mac/dock.h" |
34 #include "chrome/browser/profiles/profile.h" | 35 #include "chrome/browser/profiles/profile.h" |
35 #include "chrome/browser/profiles/profile_manager.h" | 36 #include "chrome/browser/profiles/profile_manager.h" |
36 #include "chrome/browser/shell_integration.h" | 37 #include "chrome/browser/shell_integration.h" |
37 #include "chrome/browser/ui/app_list/app_list_service.h" | 38 #include "chrome/browser/ui/app_list/app_list_service.h" |
38 #include "chrome/browser/ui/cocoa/key_equivalent_constants.h" | 39 #include "chrome/browser/ui/cocoa/key_equivalent_constants.h" |
39 #include "chrome/common/channel_info.h" | 40 #include "chrome/common/channel_info.h" |
40 #include "chrome/common/chrome_constants.h" | 41 #include "chrome/common/chrome_constants.h" |
41 #include "chrome/common/chrome_paths.h" | 42 #include "chrome/common/chrome_paths.h" |
42 #include "chrome/common/chrome_switches.h" | 43 #include "chrome/common/chrome_switches.h" |
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 } | 609 } |
609 | 610 |
610 void RevealAppShimInFinderForAppOnFileThread( | 611 void RevealAppShimInFinderForAppOnFileThread( |
611 scoped_ptr<web_app::ShortcutInfo> shortcut_info, | 612 scoped_ptr<web_app::ShortcutInfo> shortcut_info, |
612 const base::FilePath& app_path) { | 613 const base::FilePath& app_path) { |
613 web_app::WebAppShortcutCreator shortcut_creator( | 614 web_app::WebAppShortcutCreator shortcut_creator( |
614 app_path, shortcut_info.get(), extensions::FileHandlersInfo()); | 615 app_path, shortcut_info.get(), extensions::FileHandlersInfo()); |
615 shortcut_creator.RevealAppShimInFinder(); | 616 shortcut_creator.RevealAppShimInFinder(); |
616 } | 617 } |
617 | 618 |
| 619 // Mac-specific version of web_app::ShouldCreateShortcutFor() used during batch |
| 620 // upgrades to ensure all shortcuts a user may still have are repaired when |
| 621 // required by a Chrome upgrade. |
| 622 bool ShouldUpgradeShortcutFor(Profile* profile, |
| 623 const extensions::Extension* extension) { |
| 624 if (extension->location() == extensions::Manifest::COMPONENT || |
| 625 !extensions::ui_util::CanDisplayInAppLauncher(extension, profile)) { |
| 626 return false; |
| 627 } |
| 628 |
| 629 return extension->is_app(); |
| 630 } |
| 631 |
618 } // namespace | 632 } // namespace |
619 | 633 |
620 @interface CrCreateAppShortcutCheckboxObserver : NSObject { | 634 @interface CrCreateAppShortcutCheckboxObserver : NSObject { |
621 @private | 635 @private |
622 NSButton* checkbox_; | 636 NSButton* checkbox_; |
623 NSButton* continueButton_; | 637 NSButton* continueButton_; |
624 } | 638 } |
625 | 639 |
626 - (id)initWithCheckbox:(NSButton*)checkbox | 640 - (id)initWithCheckbox:(NSButton*)checkbox |
627 continueButton:(NSButton*)continueButton; | 641 continueButton:(NSButton*)continueButton; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 base::DeleteFile(bundle_path, true); | 844 base::DeleteFile(bundle_path, true); |
831 | 845 |
832 // Delete the internal one. | 846 // Delete the internal one. |
833 DeletePathAndParentIfEmpty(GetInternalShortcutPath()); | 847 DeletePathAndParentIfEmpty(GetInternalShortcutPath()); |
834 } | 848 } |
835 | 849 |
836 bool WebAppShortcutCreator::UpdateShortcuts() { | 850 bool WebAppShortcutCreator::UpdateShortcuts() { |
837 std::vector<base::FilePath> paths; | 851 std::vector<base::FilePath> paths; |
838 paths.push_back(app_data_dir_); | 852 paths.push_back(app_data_dir_); |
839 | 853 |
| 854 // Remember whether the copy in the profile directory exists. If it doesn't |
| 855 // and others do, it should be re-created. Otherwise, it's a signal that a |
| 856 // shortcut has never been created. |
| 857 bool profile_copy_exists = base::PathExists(GetInternalShortcutPath()); |
| 858 |
840 // Try to update the copy under ~/Applications. If that does not exist, check | 859 // Try to update the copy under ~/Applications. If that does not exist, check |
841 // if a matching bundle can be found elsewhere. | 860 // if a matching bundle can be found elsewhere. |
842 base::FilePath app_path = GetApplicationsShortcutPath(); | 861 base::FilePath app_path = GetApplicationsShortcutPath(); |
843 | 862 |
844 // Never look in ~/Applications or search the system for a bundle ID in a test | 863 // Never look in ~/Applications or search the system for a bundle ID in a test |
845 // since that relies on global system state and potentially cruft that may be | 864 // since that relies on global system state and potentially cruft that may be |
846 // leftover from prior/crashed test runs. | 865 // leftover from prior/crashed test runs. |
847 // TODO(tapted): Remove this check when tests that arrive here via setting | 866 // TODO(tapted): Remove this check when tests that arrive here via setting |
848 // |g_app_shims_allow_update_and_launch_in_tests| can properly mock out all | 867 // |g_app_shims_allow_update_and_launch_in_tests| can properly mock out all |
849 // the calls below. | 868 // the calls below. |
850 if (!g_app_shims_allow_update_and_launch_in_tests) { | 869 if (!g_app_shims_allow_update_and_launch_in_tests) { |
851 if (app_path.empty() || !base::PathExists(app_path)) | 870 if (app_path.empty() || !base::PathExists(app_path)) |
852 app_path = GetAppBundleById(GetBundleIdentifier()); | 871 app_path = GetAppBundleById(GetBundleIdentifier()); |
853 | 872 |
854 if (app_path.empty()) { | 873 if (app_path.empty()) { |
855 if (info_->from_bookmark) { | 874 if (profile_copy_exists && info_->from_bookmark) { |
856 // The bookmark app shortcut has been deleted by the user. Restore it, | 875 // The bookmark app shortcut has been deleted by the user. Restore it, |
857 // as the Mac UI for bookmark apps creates the expectation that the app | 876 // as the Mac UI for bookmark apps creates the expectation that the app |
858 // will be added to Applications. | 877 // will be added to Applications. |
859 app_path = GetApplicationsDirname(); | 878 app_path = GetApplicationsDirname(); |
860 paths.push_back(app_path); | 879 paths.push_back(app_path); |
861 } | 880 } |
862 } else { | 881 } else { |
863 paths.push_back(app_path.DirName()); | 882 paths.push_back(app_path.DirName()); |
864 } | 883 } |
| 884 } else { |
| 885 // If a test has set g_app_shims_allow_update_and_launch_in_tests, it means |
| 886 // it relies on UpdateShortcuts() to create shortcuts. (Tests can't rely on |
| 887 // install-triggered shortcut creation because they can't synchronize with |
| 888 // the UI thread). So, allow shortcuts to be created for this case, even if |
| 889 // none currently exist. TODO(tapted): Remove this when tests are properly |
| 890 // mocked. |
| 891 profile_copy_exists = true; |
865 } | 892 } |
866 | 893 |
| 894 // When upgrading, if no shim exists anywhere on disk, don't create the copy |
| 895 // under the profile directory for the first time. The best way to tell |
| 896 // whether a shortcut has been created is to poke around on disk, so the |
| 897 // upgrade process must send all candidate extensions to the FILE thread. |
| 898 // Then those without shortcuts will get culled here. |
| 899 if (paths.size() == 1 && !profile_copy_exists) |
| 900 return false; |
| 901 |
867 size_t success_count = CreateShortcutsIn(paths); | 902 size_t success_count = CreateShortcutsIn(paths); |
868 if (success_count == 0) | 903 if (success_count == 0) |
869 return false; | 904 return false; |
870 | 905 |
871 UpdateInternalBundleIdentifier(); | 906 UpdateInternalBundleIdentifier(); |
872 return success_count == paths.size() && !app_path.empty(); | 907 return success_count == paths.size() && !app_path.empty(); |
873 } | 908 } |
874 | 909 |
875 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { | 910 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { |
876 base::FilePath path = GetWritableApplicationsDirectory(); | 911 base::FilePath path = GetWritableApplicationsDirectory(); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 if (!registry) | 1212 if (!registry) |
1178 return; | 1213 return; |
1179 | 1214 |
1180 scoped_refptr<Latch> latch = new Latch(callback); | 1215 scoped_refptr<Latch> latch = new Latch(callback); |
1181 | 1216 |
1182 // Update all apps. | 1217 // Update all apps. |
1183 scoped_ptr<extensions::ExtensionSet> candidates = | 1218 scoped_ptr<extensions::ExtensionSet> candidates = |
1184 registry->GenerateInstalledExtensionsSet(); | 1219 registry->GenerateInstalledExtensionsSet(); |
1185 for (auto& extension_refptr : *candidates) { | 1220 for (auto& extension_refptr : *candidates) { |
1186 const extensions::Extension* extension = extension_refptr.get(); | 1221 const extensions::Extension* extension = extension_refptr.get(); |
1187 if (web_app::ShouldCreateShortcutFor(SHORTCUT_CREATION_AUTOMATED, profile, | 1222 if (ShouldUpgradeShortcutFor(profile, extension)) { |
1188 extension)) { | |
1189 web_app::UpdateAllShortcuts(base::string16(), profile, extension, | 1223 web_app::UpdateAllShortcuts(base::string16(), profile, extension, |
1190 latch->NoOpClosure()); | 1224 latch->NoOpClosure()); |
1191 } | 1225 } |
1192 } | 1226 } |
1193 } | 1227 } |
1194 | 1228 |
1195 void RevealAppShimInFinderForApp(Profile* profile, | 1229 void RevealAppShimInFinderForApp(Profile* profile, |
1196 const extensions::Extension* app) { | 1230 const extensions::Extension* app) { |
1197 scoped_ptr<web_app::ShortcutInfo> shortcut_info = | 1231 scoped_ptr<web_app::ShortcutInfo> shortcut_info = |
1198 ShortcutInfoForExtensionAndProfile(app, profile); | 1232 ShortcutInfoForExtensionAndProfile(app, profile); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 web_app::GetShortcutInfoForApp( | 1299 web_app::GetShortcutInfoForApp( |
1266 app, | 1300 app, |
1267 profile, | 1301 profile, |
1268 base::Bind(&web_app::CreateAppShortcutInfoLoaded, | 1302 base::Bind(&web_app::CreateAppShortcutInfoLoaded, |
1269 profile, | 1303 profile, |
1270 app, | 1304 app, |
1271 close_callback)); | 1305 close_callback)); |
1272 } | 1306 } |
1273 | 1307 |
1274 } // namespace chrome | 1308 } // namespace chrome |
OLD | NEW |