| 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" |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/file_util.h" | 12 #include "base/file_util.h" |
| 13 #include "base/files/file_enumerator.h" | 13 #include "base/files/file_enumerator.h" |
| 14 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
| 15 #include "base/mac/foundation_util.h" | 15 #include "base/mac/foundation_util.h" |
| 16 #include "base/mac/launch_services_util.h" | 16 #include "base/mac/launch_services_util.h" |
| 17 #include "base/mac/mac_util.h" | 17 #include "base/mac/mac_util.h" |
| 18 #include "base/mac/scoped_cftyperef.h" | 18 #include "base/mac/scoped_cftyperef.h" |
| 19 #include "base/mac/scoped_nsobject.h" | 19 #include "base/mac/scoped_nsobject.h" |
| 20 #include "base/path_service.h" | 20 #include "base/path_service.h" |
| 21 #include "base/process/process_handle.h" | 21 #include "base/process/process_handle.h" |
| 22 #include "base/strings/string16.h" | 22 #include "base/strings/string16.h" |
| 23 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 25 #include "base/strings/sys_string_conversions.h" | 25 #include "base/strings/sys_string_conversions.h" |
| 26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
| 27 #import "chrome/browser/mac/dock.h" | 27 #import "chrome/browser/mac/dock.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 28 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/browser/shell_integration.h" |
| 29 #include "chrome/common/chrome_constants.h" | 30 #include "chrome/common/chrome_constants.h" |
| 30 #include "chrome/common/chrome_paths.h" | 31 #include "chrome/common/chrome_paths.h" |
| 31 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
| 32 #include "chrome/common/chrome_version_info.h" | 33 #include "chrome/common/chrome_version_info.h" |
| 33 #import "chrome/common/mac/app_mode_common.h" | 34 #import "chrome/common/mac/app_mode_common.h" |
| 34 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 35 #include "extensions/common/extension.h" | 36 #include "extensions/common/extension.h" |
| 36 #include "grit/chrome_unscaled_resources.h" | 37 #include "grit/chrome_unscaled_resources.h" |
| 37 #include "grit/chromium_strings.h" | 38 #include "grit/chromium_strings.h" |
| 38 #import "skia/ext/skia_utils_mac.h" | 39 #import "skia/ext/skia_utils_mac.h" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | 197 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| 197 DCHECK(!user_data_dir.empty()); | 198 DCHECK(!user_data_dir.empty()); |
| 198 return StartsWithASCII( | 199 return StartsWithASCII( |
| 199 base::SysNSStringToUTF8( | 200 base::SysNSStringToUTF8( |
| 200 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]), | 201 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]), |
| 201 user_data_dir.value(), | 202 user_data_dir.value(), |
| 202 true /* case_sensitive */); | 203 true /* case_sensitive */); |
| 203 } | 204 } |
| 204 | 205 |
| 205 void LaunchShimOnFileThread( | 206 void LaunchShimOnFileThread( |
| 206 const ShellIntegration::ShortcutInfo& shortcut_info) { | 207 const web_app::ShortcutInfo& shortcut_info) { |
| 207 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 208 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 208 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); | 209 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); |
| 209 | 210 |
| 210 if (shim_path.empty() || | 211 if (shim_path.empty() || |
| 211 !base::PathExists(shim_path) || | 212 !base::PathExists(shim_path) || |
| 212 !HasSameUserDataDir(shim_path)) { | 213 !HasSameUserDataDir(shim_path)) { |
| 213 // The user may have deleted the copy in the Applications folder, use the | 214 // The user may have deleted the copy in the Applications folder, use the |
| 214 // one in the web app's |app_data_dir_|. | 215 // one in the web app's |app_data_dir_|. |
| 215 base::FilePath app_data_dir = web_app::GetWebAppDataDirectory( | 216 base::FilePath app_data_dir = web_app::GetWebAppDataDirectory( |
| 216 shortcut_info.profile_path, shortcut_info.extension_id, GURL()); | 217 shortcut_info.profile_path, shortcut_info.extension_id, GURL()); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 base::FileEnumerator::DIRECTORIES); | 382 base::FileEnumerator::DIRECTORIES); |
| 382 for (base::FilePath bundle_path = enumerator.Next(); | 383 for (base::FilePath bundle_path = enumerator.Next(); |
| 383 !bundle_path.empty(); bundle_path = enumerator.Next()) { | 384 !bundle_path.empty(); bundle_path = enumerator.Next()) { |
| 384 if (IsShimForProfile(bundle_path.BaseName(), profile_base_name)) | 385 if (IsShimForProfile(bundle_path.BaseName(), profile_base_name)) |
| 385 bundle_paths.push_back(bundle_path); | 386 bundle_paths.push_back(bundle_path); |
| 386 } | 387 } |
| 387 | 388 |
| 388 return bundle_paths; | 389 return bundle_paths; |
| 389 } | 390 } |
| 390 | 391 |
| 391 ShellIntegration::ShortcutInfo BuildShortcutInfoFromBundle( | 392 web_app::ShortcutInfo BuildShortcutInfoFromBundle( |
| 392 const base::FilePath& bundle_path) { | 393 const base::FilePath& bundle_path) { |
| 393 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path)); | 394 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path)); |
| 394 | 395 |
| 395 ShellIntegration::ShortcutInfo shortcut_info; | 396 web_app::ShortcutInfo shortcut_info; |
| 396 shortcut_info.extension_id = base::SysNSStringToUTF8( | 397 shortcut_info.extension_id = base::SysNSStringToUTF8( |
| 397 [plist valueForKey:app_mode::kCrAppModeShortcutIDKey]); | 398 [plist valueForKey:app_mode::kCrAppModeShortcutIDKey]); |
| 398 shortcut_info.is_platform_app = true; | 399 shortcut_info.is_platform_app = true; |
| 399 shortcut_info.url = GURL(base::SysNSStringToUTF8( | 400 shortcut_info.url = GURL(base::SysNSStringToUTF8( |
| 400 [plist valueForKey:app_mode::kCrAppModeShortcutURLKey])); | 401 [plist valueForKey:app_mode::kCrAppModeShortcutURLKey])); |
| 401 shortcut_info.title = base::SysNSStringToUTF16( | 402 shortcut_info.title = base::SysNSStringToUTF16( |
| 402 [plist valueForKey:app_mode::kCrAppModeShortcutNameKey]); | 403 [plist valueForKey:app_mode::kCrAppModeShortcutNameKey]); |
| 403 shortcut_info.profile_name = base::SysNSStringToUTF8( | 404 shortcut_info.profile_name = base::SysNSStringToUTF8( |
| 404 [plist valueForKey:app_mode::kCrAppModeProfileNameKey]); | 405 [plist valueForKey:app_mode::kCrAppModeProfileNameKey]); |
| 405 | 406 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 421 | 422 |
| 422 namespace chrome { | 423 namespace chrome { |
| 423 | 424 |
| 424 void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow /*parent_window*/, | 425 void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow /*parent_window*/, |
| 425 Profile* profile, | 426 Profile* profile, |
| 426 const extensions::Extension* app, | 427 const extensions::Extension* app, |
| 427 const base::Closure& close_callback) { | 428 const base::Closure& close_callback) { |
| 428 // Normally we would show a dialog, but since we always create the app | 429 // Normally we would show a dialog, but since we always create the app |
| 429 // shortcut in ~/Applications there are no options for the user to choose. | 430 // shortcut in ~/Applications there are no options for the user to choose. |
| 430 web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER, | 431 web_app::CreateShortcuts(web_app::SHORTCUT_CREATION_BY_USER, |
| 431 ShellIntegration::ShortcutLocations(), | 432 web_app::ShortcutLocations(), |
| 432 profile, | 433 profile, |
| 433 app); | 434 app); |
| 434 if (!close_callback.is_null()) | 435 if (!close_callback.is_null()) |
| 435 close_callback.Run(); | 436 close_callback.Run(); |
| 436 } | 437 } |
| 437 | 438 |
| 438 } // namespace chrome | 439 } // namespace chrome |
| 439 | 440 |
| 440 namespace web_app { | 441 namespace web_app { |
| 441 | 442 |
| 442 WebAppShortcutCreator::WebAppShortcutCreator( | 443 WebAppShortcutCreator::WebAppShortcutCreator( |
| 443 const base::FilePath& app_data_dir, | 444 const base::FilePath& app_data_dir, |
| 444 const ShellIntegration::ShortcutInfo& shortcut_info) | 445 const web_app::ShortcutInfo& shortcut_info) |
| 445 : app_data_dir_(app_data_dir), | 446 : app_data_dir_(app_data_dir), |
| 446 info_(shortcut_info) {} | 447 info_(shortcut_info) {} |
| 447 | 448 |
| 448 WebAppShortcutCreator::~WebAppShortcutCreator() {} | 449 WebAppShortcutCreator::~WebAppShortcutCreator() {} |
| 449 | 450 |
| 450 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const { | 451 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const { |
| 451 base::FilePath applications_dir = GetApplicationsDirname(); | 452 base::FilePath applications_dir = GetApplicationsDirname(); |
| 452 return applications_dir.empty() ? | 453 return applications_dir.empty() ? |
| 453 base::FilePath() : applications_dir.Append(GetShortcutBasename()); | 454 base::FilePath() : applications_dir.Append(GetShortcutBasename()); |
| 454 } | 455 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 515 |
| 515 base::mac::RemoveQuarantineAttribute(dst_path.Append(app_name)); | 516 base::mac::RemoveQuarantineAttribute(dst_path.Append(app_name)); |
| 516 ++succeeded; | 517 ++succeeded; |
| 517 } | 518 } |
| 518 | 519 |
| 519 return succeeded; | 520 return succeeded; |
| 520 } | 521 } |
| 521 | 522 |
| 522 bool WebAppShortcutCreator::CreateShortcuts( | 523 bool WebAppShortcutCreator::CreateShortcuts( |
| 523 ShortcutCreationReason creation_reason, | 524 ShortcutCreationReason creation_reason, |
| 524 ShellIntegration::ShortcutLocations creation_locations) { | 525 web_app::ShortcutLocations creation_locations) { |
| 525 const base::FilePath applications_dir = GetApplicationsDirname(); | 526 const base::FilePath applications_dir = GetApplicationsDirname(); |
| 526 if (applications_dir.empty() || | 527 if (applications_dir.empty() || |
| 527 !base::DirectoryExists(applications_dir.DirName())) { | 528 !base::DirectoryExists(applications_dir.DirName())) { |
| 528 LOG(ERROR) << "Couldn't find an Applications directory to copy app to."; | 529 LOG(ERROR) << "Couldn't find an Applications directory to copy app to."; |
| 529 return false; | 530 return false; |
| 530 } | 531 } |
| 531 | 532 |
| 532 UpdateAppShortcutsSubdirLocalizedName(applications_dir); | 533 UpdateAppShortcutsSubdirLocalizedName(applications_dir); |
| 533 | 534 |
| 534 // If non-nil, this path is added to the OSX Dock after creating shortcuts. | 535 // If non-nil, this path is added to the OSX Dock after creating shortcuts. |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 787 base::FilePath app_path = GetApplicationsShortcutPath(); | 788 base::FilePath app_path = GetApplicationsShortcutPath(); |
| 788 if (app_path.empty()) | 789 if (app_path.empty()) |
| 789 return; | 790 return; |
| 790 | 791 |
| 791 [[NSWorkspace sharedWorkspace] | 792 [[NSWorkspace sharedWorkspace] |
| 792 selectFile:base::mac::FilePathToNSString(app_path) | 793 selectFile:base::mac::FilePathToNSString(app_path) |
| 793 inFileViewerRootedAtPath:nil]; | 794 inFileViewerRootedAtPath:nil]; |
| 794 } | 795 } |
| 795 | 796 |
| 796 base::FilePath GetAppInstallPath( | 797 base::FilePath GetAppInstallPath( |
| 797 const ShellIntegration::ShortcutInfo& shortcut_info) { | 798 const web_app::ShortcutInfo& shortcut_info) { |
| 798 WebAppShortcutCreator shortcut_creator(base::FilePath(), shortcut_info); | 799 WebAppShortcutCreator shortcut_creator(base::FilePath(), shortcut_info); |
| 799 return shortcut_creator.GetApplicationsShortcutPath(); | 800 return shortcut_creator.GetApplicationsShortcutPath(); |
| 800 } | 801 } |
| 801 | 802 |
| 802 void MaybeLaunchShortcut(const ShellIntegration::ShortcutInfo& shortcut_info) { | 803 void MaybeLaunchShortcut(const web_app::ShortcutInfo& shortcut_info) { |
| 803 if (!apps::IsAppShimsEnabled()) | 804 if (!apps::IsAppShimsEnabled()) |
| 804 return; | 805 return; |
| 805 | 806 |
| 806 content::BrowserThread::PostTask( | 807 content::BrowserThread::PostTask( |
| 807 content::BrowserThread::FILE, FROM_HERE, | 808 content::BrowserThread::FILE, FROM_HERE, |
| 808 base::Bind(&LaunchShimOnFileThread, shortcut_info)); | 809 base::Bind(&LaunchShimOnFileThread, shortcut_info)); |
| 809 } | 810 } |
| 810 | 811 |
| 811 namespace internals { | 812 namespace internals { |
| 812 | 813 |
| 813 bool CreatePlatformShortcuts( | 814 bool CreatePlatformShortcuts( |
| 814 const base::FilePath& app_data_path, | 815 const base::FilePath& app_data_path, |
| 815 const ShellIntegration::ShortcutInfo& shortcut_info, | 816 const web_app::ShortcutInfo& shortcut_info, |
| 816 const extensions::FileHandlersInfo& file_handlers_info, | 817 const extensions::FileHandlersInfo& file_handlers_info, |
| 817 const ShellIntegration::ShortcutLocations& creation_locations, | 818 const web_app::ShortcutLocations& creation_locations, |
| 818 ShortcutCreationReason creation_reason) { | 819 ShortcutCreationReason creation_reason) { |
| 819 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 820 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 820 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 821 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); |
| 821 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations); | 822 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations); |
| 822 } | 823 } |
| 823 | 824 |
| 824 void DeletePlatformShortcuts( | 825 void DeletePlatformShortcuts( |
| 825 const base::FilePath& app_data_path, | 826 const base::FilePath& app_data_path, |
| 826 const ShellIntegration::ShortcutInfo& shortcut_info) { | 827 const web_app::ShortcutInfo& shortcut_info) { |
| 827 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 828 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 828 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 829 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); |
| 829 shortcut_creator.DeleteShortcuts(); | 830 shortcut_creator.DeleteShortcuts(); |
| 830 } | 831 } |
| 831 | 832 |
| 832 void UpdatePlatformShortcuts( | 833 void UpdatePlatformShortcuts( |
| 833 const base::FilePath& app_data_path, | 834 const base::FilePath& app_data_path, |
| 834 const base::string16& old_app_title, | 835 const base::string16& old_app_title, |
| 835 const ShellIntegration::ShortcutInfo& shortcut_info, | 836 const web_app::ShortcutInfo& shortcut_info, |
| 836 const extensions::FileHandlersInfo& file_handlers_info) { | 837 const extensions::FileHandlersInfo& file_handlers_info) { |
| 837 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 838 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 838 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); | 839 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info); |
| 839 shortcut_creator.UpdateShortcuts(); | 840 shortcut_creator.UpdateShortcuts(); |
| 840 } | 841 } |
| 841 | 842 |
| 842 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { | 843 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { |
| 843 const std::string profile_base_name = profile_path.BaseName().value(); | 844 const std::string profile_base_name = profile_path.BaseName().value(); |
| 844 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath( | 845 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath( |
| 845 profile_path.Append(chrome::kWebAppDirname), profile_base_name); | 846 profile_path.Append(chrome::kWebAppDirname), profile_base_name); |
| 846 | 847 |
| 847 for (std::vector<base::FilePath>::const_iterator it = bundles.begin(); | 848 for (std::vector<base::FilePath>::const_iterator it = bundles.begin(); |
| 848 it != bundles.end(); ++it) { | 849 it != bundles.end(); ++it) { |
| 849 ShellIntegration::ShortcutInfo shortcut_info = | 850 web_app::ShortcutInfo shortcut_info = |
| 850 BuildShortcutInfoFromBundle(*it); | 851 BuildShortcutInfoFromBundle(*it); |
| 851 WebAppShortcutCreator shortcut_creator(it->DirName(), shortcut_info); | 852 WebAppShortcutCreator shortcut_creator(it->DirName(), shortcut_info); |
| 852 shortcut_creator.DeleteShortcuts(); | 853 shortcut_creator.DeleteShortcuts(); |
| 853 } | 854 } |
| 854 } | 855 } |
| 855 | 856 |
| 856 } // namespace internals | 857 } // namespace internals |
| 857 | 858 |
| 858 } // namespace web_app | 859 } // namespace web_app |
| OLD | NEW |