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

Side by Side Diff: chrome/browser/web_applications/web_app_mac.mm

Issue 1038573002: Fixed thread-unsafe use of gfx::Image in app shortcut creation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 5 years, 8 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 #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 "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 base::FilePath user_data_dir; 212 base::FilePath user_data_dir;
213 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 213 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
214 DCHECK(!user_data_dir.empty()); 214 DCHECK(!user_data_dir.empty());
215 return StartsWithASCII( 215 return StartsWithASCII(
216 base::SysNSStringToUTF8( 216 base::SysNSStringToUTF8(
217 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]), 217 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]),
218 user_data_dir.value(), 218 user_data_dir.value(),
219 true /* case_sensitive */); 219 true /* case_sensitive */);
220 } 220 }
221 221
222 void LaunchShimOnFileThread(const web_app::ShortcutInfo& shortcut_info, 222 void LaunchShimOnFileThread(scoped_ptr<web_app::ShortcutInfo> shortcut_info,
223 bool launched_after_rebuild) { 223 bool launched_after_rebuild) {
224 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 224 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
225 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); 225 base::FilePath shim_path = web_app::GetAppInstallPath(*shortcut_info);
226 226
227 if (shim_path.empty() || 227 if (shim_path.empty() ||
228 !base::PathExists(shim_path) || 228 !base::PathExists(shim_path) ||
229 !HasSameUserDataDir(shim_path)) { 229 !HasSameUserDataDir(shim_path)) {
230 // The user may have deleted the copy in the Applications folder, use the 230 // The user may have deleted the copy in the Applications folder, use the
231 // one in the web app's |app_data_dir_|. 231 // one in the web app's |app_data_dir_|.
232 base::FilePath app_data_dir = web_app::GetWebAppDataDirectory( 232 base::FilePath app_data_dir = web_app::GetWebAppDataDirectory(
233 shortcut_info.profile_path, shortcut_info.extension_id, GURL()); 233 shortcut_info->profile_path, shortcut_info->extension_id, GURL());
234 shim_path = app_data_dir.Append(shim_path.BaseName()); 234 shim_path = app_data_dir.Append(shim_path.BaseName());
235 } 235 }
236 236
237 if (!base::PathExists(shim_path)) 237 if (!base::PathExists(shim_path))
238 return; 238 return;
239 239
240 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); 240 base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
241 command_line.AppendSwitchASCII( 241 command_line.AppendSwitchASCII(
242 app_mode::kLaunchedByChromeProcessId, 242 app_mode::kLaunchedByChromeProcessId,
243 base::IntToString(base::GetCurrentProcId())); 243 base::IntToString(base::GetCurrentProcId()));
244 if (launched_after_rebuild) 244 if (launched_after_rebuild)
245 command_line.AppendSwitch(app_mode::kLaunchedAfterRebuild); 245 command_line.AppendSwitch(app_mode::kLaunchedAfterRebuild);
246 // Launch without activating (kLSLaunchDontSwitch). 246 // Launch without activating (kLSLaunchDontSwitch).
247 base::mac::OpenApplicationWithPath( 247 base::mac::OpenApplicationWithPath(
248 shim_path, command_line, kLSLaunchDefaults | kLSLaunchDontSwitch, NULL); 248 shim_path, command_line, kLSLaunchDefaults | kLSLaunchDontSwitch, NULL);
249 } 249 }
250 250
251 base::FilePath GetAppLoaderPath() { 251 base::FilePath GetAppLoaderPath() {
252 return base::mac::PathForFrameworkBundleResource( 252 return base::mac::PathForFrameworkBundleResource(
253 base::mac::NSToCFCast(@"app_mode_loader.app")); 253 base::mac::NSToCFCast(@"app_mode_loader.app"));
254 } 254 }
255 255
256 void UpdateAndLaunchShimOnFileThread( 256 void UpdatePlatformShortcutsInternal(
257 const base::FilePath& app_data_path,
258 const base::string16& old_app_title,
257 const web_app::ShortcutInfo& shortcut_info, 259 const web_app::ShortcutInfo& shortcut_info,
258 const extensions::FileHandlersInfo& file_handlers_info) { 260 const extensions::FileHandlersInfo& file_handlers_info) {
261 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
262 if (AppShimsDisabledForTest() &&
263 !g_app_shims_allow_update_and_launch_in_tests) {
264 return;
265 }
266
267 web_app::WebAppShortcutCreator shortcut_creator(app_data_path, &shortcut_info,
268 file_handlers_info);
269 shortcut_creator.UpdateShortcuts();
270 }
271
272 void UpdateAndLaunchShimOnFileThread(
273 scoped_ptr<web_app::ShortcutInfo> shortcut_info,
274 const extensions::FileHandlersInfo& file_handlers_info) {
259 base::FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory( 275 base::FilePath shortcut_data_dir = web_app::GetWebAppDataDirectory(
260 shortcut_info.profile_path, shortcut_info.extension_id, GURL()); 276 shortcut_info->profile_path, shortcut_info->extension_id, GURL());
261 web_app::internals::UpdatePlatformShortcuts( 277 UpdatePlatformShortcutsInternal(shortcut_data_dir, base::string16(),
262 shortcut_data_dir, base::string16(), shortcut_info, file_handlers_info); 278 *shortcut_info, file_handlers_info);
263 LaunchShimOnFileThread(shortcut_info, true); 279 LaunchShimOnFileThread(shortcut_info.Pass(), true);
264 } 280 }
265 281
266 void UpdateAndLaunchShim( 282 void UpdateAndLaunchShim(
267 const web_app::ShortcutInfo& shortcut_info, 283 scoped_ptr<web_app::ShortcutInfo> shortcut_info,
268 const extensions::FileHandlersInfo& file_handlers_info) { 284 const extensions::FileHandlersInfo& file_handlers_info) {
269 content::BrowserThread::PostTask( 285 content::BrowserThread::PostTask(
270 content::BrowserThread::FILE, 286 content::BrowserThread::FILE, FROM_HERE,
271 FROM_HERE, 287 base::Bind(&UpdateAndLaunchShimOnFileThread, base::Passed(&shortcut_info),
272 base::Bind( 288 file_handlers_info));
273 &UpdateAndLaunchShimOnFileThread, shortcut_info, file_handlers_info));
274 } 289 }
275 290
276 void RebuildAppAndLaunch(const web_app::ShortcutInfo& shortcut_info) { 291 void RebuildAppAndLaunch(scoped_ptr<web_app::ShortcutInfo> shortcut_info) {
277 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 292 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
278 if (shortcut_info.extension_id == app_mode::kAppListModeId) { 293 if (shortcut_info->extension_id == app_mode::kAppListModeId) {
279 AppListService* app_list_service = 294 AppListService* app_list_service =
280 AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE); 295 AppListService::Get(chrome::HOST_DESKTOP_TYPE_NATIVE);
281 app_list_service->CreateShortcut(); 296 app_list_service->CreateShortcut();
282 app_list_service->Show(); 297 app_list_service->Show();
283 return; 298 return;
284 } 299 }
285 300
286 ProfileManager* profile_manager = g_browser_process->profile_manager(); 301 ProfileManager* profile_manager = g_browser_process->profile_manager();
287 Profile* profile = 302 Profile* profile =
288 profile_manager->GetProfileByPath(shortcut_info.profile_path); 303 profile_manager->GetProfileByPath(shortcut_info->profile_path);
289 if (!profile || !profile_manager->IsValidProfile(profile)) 304 if (!profile || !profile_manager->IsValidProfile(profile))
290 return; 305 return;
291 306
292 extensions::ExtensionRegistry* registry = 307 extensions::ExtensionRegistry* registry =
293 extensions::ExtensionRegistry::Get(profile); 308 extensions::ExtensionRegistry::Get(profile);
294 const extensions::Extension* extension = registry->GetExtensionById( 309 const extensions::Extension* extension = registry->GetExtensionById(
295 shortcut_info.extension_id, extensions::ExtensionRegistry::ENABLED); 310 shortcut_info->extension_id, extensions::ExtensionRegistry::ENABLED);
296 if (!extension || !extension->is_platform_app()) 311 if (!extension || !extension->is_platform_app())
297 return; 312 return;
298 313
299 web_app::GetInfoForApp(extension, profile, base::Bind(&UpdateAndLaunchShim)); 314 web_app::GetInfoForApp(extension, profile, base::Bind(&UpdateAndLaunchShim));
300 } 315 }
301 316
302 base::FilePath GetLocalizableAppShortcutsSubdirName() { 317 base::FilePath GetLocalizableAppShortcutsSubdirName() {
303 static const char kChromiumAppDirName[] = "Chromium Apps.localized"; 318 static const char kChromiumAppDirName[] = "Chromium Apps.localized";
304 static const char kChromeAppDirName[] = "Chrome Apps.localized"; 319 static const char kChromeAppDirName[] = "Chrome Apps.localized";
305 static const char kChromeCanaryAppDirName[] = "Chrome Canary Apps.localized"; 320 static const char kChromeCanaryAppDirName[] = "Chrome Canary Apps.localized";
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 base::FileEnumerator::DIRECTORIES); 476 base::FileEnumerator::DIRECTORIES);
462 for (base::FilePath bundle_path = enumerator.Next(); 477 for (base::FilePath bundle_path = enumerator.Next();
463 !bundle_path.empty(); bundle_path = enumerator.Next()) { 478 !bundle_path.empty(); bundle_path = enumerator.Next()) {
464 if (IsShimForProfile(bundle_path.BaseName(), profile_base_name)) 479 if (IsShimForProfile(bundle_path.BaseName(), profile_base_name))
465 bundle_paths.push_back(bundle_path); 480 bundle_paths.push_back(bundle_path);
466 } 481 }
467 482
468 return bundle_paths; 483 return bundle_paths;
469 } 484 }
470 485
471 web_app::ShortcutInfo BuildShortcutInfoFromBundle( 486 scoped_ptr<web_app::ShortcutInfo> BuildShortcutInfoFromBundle(
472 const base::FilePath& bundle_path) { 487 const base::FilePath& bundle_path) {
473 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path)); 488 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path));
474 489
475 web_app::ShortcutInfo shortcut_info; 490 scoped_ptr<web_app::ShortcutInfo> shortcut_info(new web_app::ShortcutInfo);
476 shortcut_info.extension_id = base::SysNSStringToUTF8( 491 shortcut_info->extension_id = base::SysNSStringToUTF8(
477 [plist valueForKey:app_mode::kCrAppModeShortcutIDKey]); 492 [plist valueForKey:app_mode::kCrAppModeShortcutIDKey]);
478 shortcut_info.is_platform_app = true; 493 shortcut_info->is_platform_app = true;
479 shortcut_info.url = GURL(base::SysNSStringToUTF8( 494 shortcut_info->url = GURL(base::SysNSStringToUTF8(
480 [plist valueForKey:app_mode::kCrAppModeShortcutURLKey])); 495 [plist valueForKey:app_mode::kCrAppModeShortcutURLKey]));
481 shortcut_info.title = base::SysNSStringToUTF16( 496 shortcut_info->title = base::SysNSStringToUTF16(
482 [plist valueForKey:app_mode::kCrAppModeShortcutNameKey]); 497 [plist valueForKey:app_mode::kCrAppModeShortcutNameKey]);
483 shortcut_info.profile_name = base::SysNSStringToUTF8( 498 shortcut_info->profile_name = base::SysNSStringToUTF8(
484 [plist valueForKey:app_mode::kCrAppModeProfileNameKey]); 499 [plist valueForKey:app_mode::kCrAppModeProfileNameKey]);
485 500
486 // Figure out the profile_path. Since the user_data_dir could contain the 501 // Figure out the profile_path. Since the user_data_dir could contain the
487 // path to the web app data dir. 502 // path to the web app data dir.
488 base::FilePath user_data_dir = base::mac::NSStringToFilePath( 503 base::FilePath user_data_dir = base::mac::NSStringToFilePath(
489 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]); 504 [plist valueForKey:app_mode::kCrAppModeUserDataDirKey]);
490 base::FilePath profile_base_name = base::mac::NSStringToFilePath( 505 base::FilePath profile_base_name = base::mac::NSStringToFilePath(
491 [plist valueForKey:app_mode::kCrAppModeProfileDirKey]); 506 [plist valueForKey:app_mode::kCrAppModeProfileDirKey]);
492 if (user_data_dir.DirName().DirName().BaseName() == profile_base_name) 507 if (user_data_dir.DirName().DirName().BaseName() == profile_base_name)
493 shortcut_info.profile_path = user_data_dir.DirName().DirName(); 508 shortcut_info->profile_path = user_data_dir.DirName().DirName();
494 else 509 else
495 shortcut_info.profile_path = user_data_dir.Append(profile_base_name); 510 shortcut_info->profile_path = user_data_dir.Append(profile_base_name);
496 511
497 return shortcut_info; 512 return shortcut_info;
498 } 513 }
499 514
500 web_app::ShortcutInfo RecordAppShimErrorAndBuildShortcutInfo( 515 scoped_ptr<web_app::ShortcutInfo> RecordAppShimErrorAndBuildShortcutInfo(
501 const base::FilePath& bundle_path) { 516 const base::FilePath& bundle_path) {
502 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path)); 517 NSDictionary* plist = ReadPlist(GetPlistPath(bundle_path));
503 NSString* version_string = [plist valueForKey:app_mode::kCrBundleVersionKey]; 518 NSString* version_string = [plist valueForKey:app_mode::kCrBundleVersionKey];
504 if (!version_string) { 519 if (!version_string) {
505 // Older bundles have the Chrome version in the following key. 520 // Older bundles have the Chrome version in the following key.
506 version_string = 521 version_string =
507 [plist valueForKey:app_mode::kCFBundleShortVersionStringKey]; 522 [plist valueForKey:app_mode::kCFBundleShortVersionStringKey];
508 } 523 }
509 base::Version full_version(base::SysNSStringToUTF8(version_string)); 524 base::Version full_version(base::SysNSStringToUTF8(version_string));
510 uint32_t major_version = 0; 525 uint32_t major_version = 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 app_mode::kCFBundleTypeRoleKey : app_mode::kBundleTypeRoleViewer 567 app_mode::kCFBundleTypeRoleKey : app_mode::kBundleTypeRoleViewer
553 }; 568 };
554 [document_types addObject:type_dictionary]; 569 [document_types addObject:type_dictionary];
555 } 570 }
556 571
557 [plist setObject:document_types 572 [plist setObject:document_types
558 forKey:app_mode::kCFBundleDocumentTypesKey]; 573 forKey:app_mode::kCFBundleDocumentTypesKey];
559 } 574 }
560 575
561 void RevealAppShimInFinderForAppOnFileThread( 576 void RevealAppShimInFinderForAppOnFileThread(
562 const web_app::ShortcutInfo& shortcut_info, 577 scoped_ptr<web_app::ShortcutInfo> shortcut_info,
563 const base::FilePath& app_path) { 578 const base::FilePath& app_path) {
564 web_app::WebAppShortcutCreator shortcut_creator( 579 web_app::WebAppShortcutCreator shortcut_creator(
565 app_path, shortcut_info, extensions::FileHandlersInfo()); 580 app_path, shortcut_info.get(), extensions::FileHandlersInfo());
566 shortcut_creator.RevealAppShimInFinder(); 581 shortcut_creator.RevealAppShimInFinder();
567 } 582 }
568 583
569 } // namespace 584 } // namespace
570 585
571 @interface CrCreateAppShortcutCheckboxObserver : NSObject { 586 @interface CrCreateAppShortcutCheckboxObserver : NSObject {
572 @private 587 @private
573 NSButton* checkbox_; 588 NSButton* checkbox_;
574 NSButton* continueButton_; 589 NSButton* continueButton_;
575 } 590 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 context:(void*)context { 624 context:(void*)context {
610 [continueButton_ setEnabled:([checkbox_ state] == NSOnState)]; 625 [continueButton_ setEnabled:([checkbox_ state] == NSOnState)];
611 } 626 }
612 627
613 @end 628 @end
614 629
615 namespace web_app { 630 namespace web_app {
616 631
617 WebAppShortcutCreator::WebAppShortcutCreator( 632 WebAppShortcutCreator::WebAppShortcutCreator(
618 const base::FilePath& app_data_dir, 633 const base::FilePath& app_data_dir,
619 const ShortcutInfo& shortcut_info, 634 const ShortcutInfo* shortcut_info,
620 const extensions::FileHandlersInfo& file_handlers_info) 635 const extensions::FileHandlersInfo& file_handlers_info)
621 : app_data_dir_(app_data_dir), 636 : app_data_dir_(app_data_dir),
622 info_(shortcut_info), 637 info_(shortcut_info),
623 file_handlers_info_(file_handlers_info) {} 638 file_handlers_info_(file_handlers_info) {
639 DCHECK(shortcut_info);
640 }
624 641
625 WebAppShortcutCreator::~WebAppShortcutCreator() {} 642 WebAppShortcutCreator::~WebAppShortcutCreator() {}
626 643
627 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const { 644 base::FilePath WebAppShortcutCreator::GetApplicationsShortcutPath() const {
628 base::FilePath applications_dir = GetApplicationsDirname(); 645 base::FilePath applications_dir = GetApplicationsDirname();
629 return applications_dir.empty() ? 646 return applications_dir.empty() ?
630 base::FilePath() : applications_dir.Append(GetShortcutBasename()); 647 base::FilePath() : applications_dir.Append(GetShortcutBasename());
631 } 648 }
632 649
633 base::FilePath WebAppShortcutCreator::GetInternalShortcutPath() const { 650 base::FilePath WebAppShortcutCreator::GetInternalShortcutPath() const {
634 return app_data_dir_.Append(GetShortcutBasename()); 651 return app_data_dir_.Append(GetShortcutBasename());
635 } 652 }
636 653
637 base::FilePath WebAppShortcutCreator::GetShortcutBasename() const { 654 base::FilePath WebAppShortcutCreator::GetShortcutBasename() const {
638 std::string app_name; 655 std::string app_name;
639 // Check if there should be a separate shortcut made for different profiles. 656 // Check if there should be a separate shortcut made for different profiles.
640 // Such shortcuts will have a |profile_name| set on the ShortcutInfo, 657 // Such shortcuts will have a |profile_name| set on the ShortcutInfo,
641 // otherwise it will be empty. 658 // otherwise it will be empty.
642 if (!info_.profile_name.empty()) { 659 if (!info_->profile_name.empty()) {
643 app_name += info_.profile_path.BaseName().value(); 660 app_name += info_->profile_path.BaseName().value();
644 app_name += ' '; 661 app_name += ' ';
645 } 662 }
646 app_name += info_.extension_id; 663 app_name += info_->extension_id;
647 return base::FilePath(app_name).ReplaceExtension("app"); 664 return base::FilePath(app_name).ReplaceExtension("app");
648 } 665 }
649 666
650 bool WebAppShortcutCreator::BuildShortcut( 667 bool WebAppShortcutCreator::BuildShortcut(
651 const base::FilePath& staging_path) const { 668 const base::FilePath& staging_path) const {
652 // Update the app's plist and icon in a temp directory. This works around 669 // Update the app's plist and icon in a temp directory. This works around
653 // a Finder bug where the app's icon doesn't properly update. 670 // a Finder bug where the app's icon doesn't properly update.
654 if (!base::CopyDirectory(GetAppLoaderPath(), staging_path, true)) { 671 if (!base::CopyDirectory(GetAppLoaderPath(), staging_path, true)) {
655 LOG(ERROR) << "Copying app to staging path: " << staging_path.value() 672 LOG(ERROR) << "Copying app to staging path: " << staging_path.value()
656 << " failed."; 673 << " failed.";
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 731
715 // If non-nil, this path is added to the OSX Dock after creating shortcuts. 732 // If non-nil, this path is added to the OSX Dock after creating shortcuts.
716 NSString* path_to_add_to_dock = nil; 733 NSString* path_to_add_to_dock = nil;
717 734
718 std::vector<base::FilePath> paths; 735 std::vector<base::FilePath> paths;
719 736
720 // The app list shim is not tied to a particular profile, so omit the copy 737 // The app list shim is not tied to a particular profile, so omit the copy
721 // placed under the profile path. For shims, this copy is used when the 738 // placed under the profile path. For shims, this copy is used when the
722 // version under Applications is removed, and not needed for app list because 739 // version under Applications is removed, and not needed for app list because
723 // setting LSUIElement means there is no Dock "running" status to show. 740 // setting LSUIElement means there is no Dock "running" status to show.
724 const bool is_app_list = info_.extension_id == app_mode::kAppListModeId; 741 const bool is_app_list = info_->extension_id == app_mode::kAppListModeId;
725 if (is_app_list) { 742 if (is_app_list) {
726 path_to_add_to_dock = base::SysUTF8ToNSString( 743 path_to_add_to_dock = base::SysUTF8ToNSString(
727 applications_dir.Append(GetShortcutBasename()).AsUTF8Unsafe()); 744 applications_dir.Append(GetShortcutBasename()).AsUTF8Unsafe());
728 } else { 745 } else {
729 paths.push_back(app_data_dir_); 746 paths.push_back(app_data_dir_);
730 } 747 }
731 748
732 bool shortcut_visible = 749 bool shortcut_visible =
733 creation_locations.applications_menu_location != APP_MENU_LOCATION_HIDDEN; 750 creation_locations.applications_menu_location != APP_MENU_LOCATION_HIDDEN;
734 if (shortcut_visible) 751 if (shortcut_visible)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 822
806 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const { 823 base::FilePath WebAppShortcutCreator::GetApplicationsDirname() const {
807 base::FilePath path = GetWritableApplicationsDirectory(); 824 base::FilePath path = GetWritableApplicationsDirectory();
808 if (path.empty()) 825 if (path.empty())
809 return path; 826 return path;
810 827
811 return path.Append(GetLocalizableAppShortcutsSubdirName()); 828 return path.Append(GetLocalizableAppShortcutsSubdirName());
812 } 829 }
813 830
814 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { 831 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const {
815 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); 832 NSString* extension_id = base::SysUTF8ToNSString(info_->extension_id);
816 NSString* extension_title = base::SysUTF16ToNSString(info_.title); 833 NSString* extension_title = base::SysUTF16ToNSString(info_->title);
817 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); 834 NSString* extension_url = base::SysUTF8ToNSString(info_->url.spec());
818 NSString* chrome_bundle_id = 835 NSString* chrome_bundle_id =
819 base::SysUTF8ToNSString(base::mac::BaseBundleID()); 836 base::SysUTF8ToNSString(base::mac::BaseBundleID());
820 NSDictionary* replacement_dict = 837 NSDictionary* replacement_dict =
821 [NSDictionary dictionaryWithObjectsAndKeys: 838 [NSDictionary dictionaryWithObjectsAndKeys:
822 extension_id, app_mode::kShortcutIdPlaceholder, 839 extension_id, app_mode::kShortcutIdPlaceholder,
823 extension_title, app_mode::kShortcutNamePlaceholder, 840 extension_title, app_mode::kShortcutNamePlaceholder,
824 extension_url, app_mode::kShortcutURLPlaceholder, 841 extension_url, app_mode::kShortcutURLPlaceholder,
825 chrome_bundle_id, app_mode::kShortcutBrowserBundleIDPlaceholder, 842 chrome_bundle_id, app_mode::kShortcutBrowserBundleIDPlaceholder,
826 nil]; 843 nil];
827 844
(...skipping 12 matching lines...) Expand all
840 [value substringWithRange:NSMakeRange(1, [value length] - 2)]; 857 [value substringWithRange:NSMakeRange(1, [value length] - 2)];
841 858
842 NSString* substitution = [replacement_dict valueForKey:variable]; 859 NSString* substitution = [replacement_dict valueForKey:variable];
843 if (substitution) 860 if (substitution)
844 [plist setObject:substitution forKey:key]; 861 [plist setObject:substitution forKey:key];
845 } 862 }
846 863
847 // 2. Fill in other values. 864 // 2. Fill in other values.
848 [plist setObject:base::SysUTF8ToNSString(chrome::VersionInfo().Version()) 865 [plist setObject:base::SysUTF8ToNSString(chrome::VersionInfo().Version())
849 forKey:app_mode::kCrBundleVersionKey]; 866 forKey:app_mode::kCrBundleVersionKey];
850 [plist setObject:base::SysUTF8ToNSString(info_.version_for_display) 867 [plist setObject:base::SysUTF8ToNSString(info_->version_for_display)
851 forKey:app_mode::kCFBundleShortVersionStringKey]; 868 forKey:app_mode::kCFBundleShortVersionStringKey];
852 [plist setObject:base::SysUTF8ToNSString(GetBundleIdentifier()) 869 [plist setObject:base::SysUTF8ToNSString(GetBundleIdentifier())
853 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; 870 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)];
854 [plist setObject:base::mac::FilePathToNSString(app_data_dir_) 871 [plist setObject:base::mac::FilePathToNSString(app_data_dir_)
855 forKey:app_mode::kCrAppModeUserDataDirKey]; 872 forKey:app_mode::kCrAppModeUserDataDirKey];
856 [plist setObject:base::mac::FilePathToNSString(info_.profile_path.BaseName()) 873 [plist setObject:base::mac::FilePathToNSString(info_->profile_path.BaseName())
857 forKey:app_mode::kCrAppModeProfileDirKey]; 874 forKey:app_mode::kCrAppModeProfileDirKey];
858 [plist setObject:base::SysUTF8ToNSString(info_.profile_name) 875 [plist setObject:base::SysUTF8ToNSString(info_->profile_name)
859 forKey:app_mode::kCrAppModeProfileNameKey]; 876 forKey:app_mode::kCrAppModeProfileNameKey];
860 [plist setObject:[NSNumber numberWithBool:YES] 877 [plist setObject:[NSNumber numberWithBool:YES]
861 forKey:app_mode::kLSHasLocalizedDisplayNameKey]; 878 forKey:app_mode::kLSHasLocalizedDisplayNameKey];
862 if (info_.extension_id == app_mode::kAppListModeId) { 879 if (info_->extension_id == app_mode::kAppListModeId) {
863 // Prevent the app list from bouncing in the dock, and getting a run light. 880 // Prevent the app list from bouncing in the dock, and getting a run light.
864 [plist setObject:[NSNumber numberWithBool:YES] 881 [plist setObject:[NSNumber numberWithBool:YES]
865 forKey:kLSUIElement]; 882 forKey:kLSUIElement];
866 } 883 }
867 884
868 base::FilePath app_name = app_path.BaseName().RemoveExtension(); 885 base::FilePath app_name = app_path.BaseName().RemoveExtension();
869 [plist setObject:base::mac::FilePathToNSString(app_name) 886 [plist setObject:base::mac::FilePathToNSString(app_name)
870 forKey:base::mac::CFToNSCast(kCFBundleNameKey)]; 887 forKey:base::mac::CFToNSCast(kCFBundleNameKey)];
871 888
872 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 889 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
873 switches::kEnableAppsFileAssociations)) { 890 switches::kEnableAppsFileAssociations)) {
874 UpdateFileTypes(plist, file_handlers_info_); 891 UpdateFileTypes(plist, file_handlers_info_);
875 } 892 }
876 893
877 return [plist writeToFile:plist_path 894 return [plist writeToFile:plist_path
878 atomically:YES]; 895 atomically:YES];
879 } 896 }
880 897
881 bool WebAppShortcutCreator::UpdateDisplayName( 898 bool WebAppShortcutCreator::UpdateDisplayName(
882 const base::FilePath& app_path) const { 899 const base::FilePath& app_path) const {
883 // OSX searches for the best language in the order of preferred languages. 900 // OSX searches for the best language in the order of preferred languages.
884 // Since we only have one localization directory, it will choose this one. 901 // Since we only have one localization directory, it will choose this one.
885 base::FilePath localized_dir = GetResourcesPath(app_path).Append("en.lproj"); 902 base::FilePath localized_dir = GetResourcesPath(app_path).Append("en.lproj");
886 if (!base::CreateDirectory(localized_dir)) 903 if (!base::CreateDirectory(localized_dir))
887 return false; 904 return false;
888 905
889 NSString* bundle_name = base::SysUTF16ToNSString(info_.title); 906 NSString* bundle_name = base::SysUTF16ToNSString(info_->title);
890 NSString* display_name = base::SysUTF16ToNSString(info_.title); 907 NSString* display_name = base::SysUTF16ToNSString(info_->title);
891 if (HasExistingExtensionShim(GetApplicationsDirname(), 908 if (HasExistingExtensionShim(GetApplicationsDirname(), info_->extension_id,
892 info_.extension_id,
893 app_path.BaseName())) { 909 app_path.BaseName())) {
894 display_name = [bundle_name 910 display_name = [bundle_name
895 stringByAppendingString:base::SysUTF8ToNSString( 911 stringByAppendingString:base::SysUTF8ToNSString(
896 " (" + info_.profile_name + ")")]; 912 " (" + info_->profile_name + ")")];
897 } 913 }
898 914
899 NSDictionary* strings_plist = @{ 915 NSDictionary* strings_plist = @{
900 base::mac::CFToNSCast(kCFBundleNameKey) : bundle_name, 916 base::mac::CFToNSCast(kCFBundleNameKey) : bundle_name,
901 app_mode::kCFBundleDisplayNameKey : display_name 917 app_mode::kCFBundleDisplayNameKey : display_name
902 }; 918 };
903 919
904 NSString* localized_path = base::mac::FilePathToNSString( 920 NSString* localized_path = base::mac::FilePathToNSString(
905 localized_dir.Append("InfoPlist.strings")); 921 localized_dir.Append("InfoPlist.strings"));
906 return [strings_plist writeToFile:localized_path 922 return [strings_plist writeToFile:localized_path
907 atomically:YES]; 923 atomically:YES];
908 } 924 }
909 925
910 bool WebAppShortcutCreator::UpdateIcon(const base::FilePath& app_path) const { 926 bool WebAppShortcutCreator::UpdateIcon(const base::FilePath& app_path) const {
911 if (info_.favicon.empty()) 927 if (info_->favicon.empty())
912 return true; 928 return true;
913 929
914 ScopedCarbonHandle icon_family(0); 930 ScopedCarbonHandle icon_family(0);
915 bool image_added = false; 931 bool image_added = false;
916 for (gfx::ImageFamily::const_iterator it = info_.favicon.begin(); 932 for (gfx::ImageFamily::const_iterator it = info_->favicon.begin();
917 it != info_.favicon.end(); ++it) { 933 it != info_->favicon.end(); ++it) {
918 if (it->IsEmpty()) 934 if (it->IsEmpty())
919 continue; 935 continue;
920 936
921 // Missing an icon size is not fatal so don't fail if adding the bitmap 937 // Missing an icon size is not fatal so don't fail if adding the bitmap
922 // doesn't work. 938 // doesn't work.
923 if (!AddGfxImageToIconFamily(icon_family.GetAsIconFamilyHandle(), *it)) 939 if (!AddGfxImageToIconFamily(icon_family.GetAsIconFamilyHandle(), *it))
924 continue; 940 continue;
925 941
926 image_added = true; 942 image_added = true;
927 } 943 }
(...skipping 29 matching lines...) Expand all
957 return base::FilePath(); 973 return base::FilePath();
958 974
959 base::ScopedCFTypeRef<CFURLRef> url(url_ref); 975 base::ScopedCFTypeRef<CFURLRef> url(url_ref);
960 NSString* path_string = [base::mac::CFToNSCast(url.get()) path]; 976 NSString* path_string = [base::mac::CFToNSCast(url.get()) path];
961 return base::FilePath([path_string fileSystemRepresentation]); 977 return base::FilePath([path_string fileSystemRepresentation]);
962 } 978 }
963 979
964 std::string WebAppShortcutCreator::GetBundleIdentifier() const { 980 std::string WebAppShortcutCreator::GetBundleIdentifier() const {
965 // Replace spaces in the profile path with hyphen. 981 // Replace spaces in the profile path with hyphen.
966 std::string normalized_profile_path; 982 std::string normalized_profile_path;
967 base::ReplaceChars(info_.profile_path.BaseName().value(), 983 base::ReplaceChars(info_->profile_path.BaseName().value(), " ", "-",
968 " ", "-", &normalized_profile_path); 984 &normalized_profile_path);
969 985
970 // This matches APP_MODE_APP_BUNDLE_ID in chrome/chrome.gyp. 986 // This matches APP_MODE_APP_BUNDLE_ID in chrome/chrome.gyp.
971 std::string bundle_id = 987 std::string bundle_id = base::mac::BaseBundleID() + std::string(".app.") +
972 base::mac::BaseBundleID() + std::string(".app.") + 988 normalized_profile_path + "-" + info_->extension_id;
973 normalized_profile_path + "-" + info_.extension_id;
974 989
975 return bundle_id; 990 return bundle_id;
976 } 991 }
977 992
978 std::string WebAppShortcutCreator::GetInternalBundleIdentifier() const { 993 std::string WebAppShortcutCreator::GetInternalBundleIdentifier() const {
979 return GetBundleIdentifier() + "-internal"; 994 return GetBundleIdentifier() + "-internal";
980 } 995 }
981 996
982 void WebAppShortcutCreator::RevealAppShimInFinder() const { 997 void WebAppShortcutCreator::RevealAppShimInFinder() const {
983 base::FilePath app_path = GetApplicationsShortcutPath(); 998 base::FilePath app_path = GetApplicationsShortcutPath();
(...skipping 15 matching lines...) Expand all
999 // Check if the Chrome apps folder exists, otherwise go up to ~/Applications. 1014 // Check if the Chrome apps folder exists, otherwise go up to ~/Applications.
1000 if (!base::PathExists(app_path)) 1015 if (!base::PathExists(app_path))
1001 app_path = app_path.DirName(); 1016 app_path = app_path.DirName();
1002 // Since |app_path| is a directory, use openFile to show the contents of 1017 // Since |app_path| is a directory, use openFile to show the contents of
1003 // that directory in Finder. 1018 // that directory in Finder.
1004 [[NSWorkspace sharedWorkspace] 1019 [[NSWorkspace sharedWorkspace]
1005 openFile:base::mac::FilePathToNSString(app_path)]; 1020 openFile:base::mac::FilePathToNSString(app_path)];
1006 } 1021 }
1007 1022
1008 base::FilePath GetAppInstallPath(const ShortcutInfo& shortcut_info) { 1023 base::FilePath GetAppInstallPath(const ShortcutInfo& shortcut_info) {
1009 WebAppShortcutCreator shortcut_creator( 1024 WebAppShortcutCreator shortcut_creator(base::FilePath(), &shortcut_info,
1010 base::FilePath(), shortcut_info, extensions::FileHandlersInfo()); 1025 extensions::FileHandlersInfo());
1011 return shortcut_creator.GetApplicationsShortcutPath(); 1026 return shortcut_creator.GetApplicationsShortcutPath();
1012 } 1027 }
1013 1028
1014 void MaybeLaunchShortcut(const ShortcutInfo& shortcut_info) { 1029 void MaybeLaunchShortcut(scoped_ptr<ShortcutInfo> shortcut_info) {
1015 if (AppShimsDisabledForTest() && 1030 if (AppShimsDisabledForTest() &&
1016 !g_app_shims_allow_update_and_launch_in_tests) { 1031 !g_app_shims_allow_update_and_launch_in_tests) {
1017 return; 1032 return;
1018 } 1033 }
1019 1034
1020 content::BrowserThread::PostTask( 1035 content::BrowserThread::PostTask(
1021 content::BrowserThread::FILE, 1036 content::BrowserThread::FILE, FROM_HERE,
1022 FROM_HERE, 1037 base::Bind(&LaunchShimOnFileThread, base::Passed(&shortcut_info), false));
1023 base::Bind(&LaunchShimOnFileThread, shortcut_info, false));
1024 } 1038 }
1025 1039
1026 bool MaybeRebuildShortcut(const base::CommandLine& command_line) { 1040 bool MaybeRebuildShortcut(const base::CommandLine& command_line) {
1027 if (!command_line.HasSwitch(app_mode::kAppShimError)) 1041 if (!command_line.HasSwitch(app_mode::kAppShimError))
1028 return false; 1042 return false;
1029 1043
1030 base::PostTaskAndReplyWithResult( 1044 base::PostTaskAndReplyWithResult(
1031 content::BrowserThread::GetBlockingPool(), 1045 content::BrowserThread::GetBlockingPool(),
1032 FROM_HERE, 1046 FROM_HERE,
1033 base::Bind(&RecordAppShimErrorAndBuildShortcutInfo, 1047 base::Bind(&RecordAppShimErrorAndBuildShortcutInfo,
1034 command_line.GetSwitchValuePath(app_mode::kAppShimError)), 1048 command_line.GetSwitchValuePath(app_mode::kAppShimError)),
1035 base::Bind(&RebuildAppAndLaunch)); 1049 base::Bind(&RebuildAppAndLaunch));
1036 return true; 1050 return true;
1037 } 1051 }
1038 1052
1039 // Called when the app's ShortcutInfo (with icon) is loaded when creating app 1053 // Called when the app's ShortcutInfo (with icon) is loaded when creating app
1040 // shortcuts. 1054 // shortcuts.
1041 void CreateAppShortcutInfoLoaded( 1055 void CreateAppShortcutInfoLoaded(
1042 Profile* profile, 1056 Profile* profile,
1043 const extensions::Extension* app, 1057 const extensions::Extension* app,
1044 const base::Callback<void(bool)>& close_callback, 1058 const base::Callback<void(bool)>& close_callback,
1045 const ShortcutInfo& shortcut_info) { 1059 scoped_ptr<ShortcutInfo> shortcut_info) {
1046 base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]); 1060 base::scoped_nsobject<NSAlert> alert([[NSAlert alloc] init]);
1047 1061
1048 NSButton* continue_button = [alert 1062 NSButton* continue_button = [alert
1049 addButtonWithTitle:l10n_util::GetNSString(IDS_CREATE_SHORTCUTS_COMMIT)]; 1063 addButtonWithTitle:l10n_util::GetNSString(IDS_CREATE_SHORTCUTS_COMMIT)];
1050 [continue_button setKeyEquivalent:kKeyEquivalentReturn]; 1064 [continue_button setKeyEquivalent:kKeyEquivalentReturn];
1051 1065
1052 NSButton* cancel_button = 1066 NSButton* cancel_button =
1053 [alert addButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)]; 1067 [alert addButtonWithTitle:l10n_util::GetNSString(IDS_CANCEL)];
1054 [cancel_button setKeyEquivalent:kKeyEquivalentEscape]; 1068 [cancel_button setKeyEquivalent:kKeyEquivalentEscape];
1055 1069
(...skipping 11 matching lines...) Expand all
1067 base::scoped_nsobject<CrCreateAppShortcutCheckboxObserver> checkbox_observer( 1081 base::scoped_nsobject<CrCreateAppShortcutCheckboxObserver> checkbox_observer(
1068 [[CrCreateAppShortcutCheckboxObserver alloc] 1082 [[CrCreateAppShortcutCheckboxObserver alloc]
1069 initWithCheckbox:application_folder_checkbox 1083 initWithCheckbox:application_folder_checkbox
1070 continueButton:continue_button]); 1084 continueButton:continue_button]);
1071 [checkbox_observer startObserving]; 1085 [checkbox_observer startObserving];
1072 1086
1073 [alert setAccessoryView:application_folder_checkbox]; 1087 [alert setAccessoryView:application_folder_checkbox];
1074 1088
1075 const int kIconPreviewSizePixels = 128; 1089 const int kIconPreviewSizePixels = 128;
1076 const int kIconPreviewTargetSize = 64; 1090 const int kIconPreviewTargetSize = 64;
1077 const gfx::Image* icon = shortcut_info.favicon.GetBest( 1091 const gfx::Image* icon = shortcut_info->favicon.GetBest(
1078 kIconPreviewSizePixels, kIconPreviewSizePixels); 1092 kIconPreviewSizePixels, kIconPreviewSizePixels);
1079 1093
1080 if (icon && !icon->IsEmpty()) { 1094 if (icon && !icon->IsEmpty()) {
1081 NSImage* icon_image = icon->ToNSImage(); 1095 NSImage* icon_image = icon->ToNSImage();
1082 [icon_image 1096 [icon_image
1083 setSize:NSMakeSize(kIconPreviewTargetSize, kIconPreviewTargetSize)]; 1097 setSize:NSMakeSize(kIconPreviewTargetSize, kIconPreviewTargetSize)];
1084 [alert setIcon:icon_image]; 1098 [alert setIcon:icon_image];
1085 } 1099 }
1086 1100
1087 bool dialog_accepted = false; 1101 bool dialog_accepted = false;
(...skipping 28 matching lines...) Expand all
1116 it->get())) { 1130 it->get())) {
1117 web_app::UpdateAllShortcuts(base::string16(), profile, it->get()); 1131 web_app::UpdateAllShortcuts(base::string16(), profile, it->get());
1118 } 1132 }
1119 } 1133 }
1120 1134
1121 callback.Run(); 1135 callback.Run();
1122 } 1136 }
1123 1137
1124 void RevealAppShimInFinderForApp(Profile* profile, 1138 void RevealAppShimInFinderForApp(Profile* profile,
1125 const extensions::Extension* app) { 1139 const extensions::Extension* app) {
1126 const web_app::ShortcutInfo shortcut_info = 1140 scoped_ptr<web_app::ShortcutInfo> shortcut_info =
1127 ShortcutInfoForExtensionAndProfile(app, profile); 1141 ShortcutInfoForExtensionAndProfile(app, profile);
1128 content::BrowserThread::PostTask( 1142 content::BrowserThread::PostTask(
1129 content::BrowserThread::FILE, FROM_HERE, 1143 content::BrowserThread::FILE, FROM_HERE,
1130 base::Bind(&RevealAppShimInFinderForAppOnFileThread, shortcut_info, 1144 base::Bind(&RevealAppShimInFinderForAppOnFileThread,
1131 app->path())); 1145 base::Passed(&shortcut_info), app->path()));
1132 } 1146 }
1133 1147
1134 namespace internals { 1148 namespace internals {
1135 1149
1136 bool CreatePlatformShortcuts( 1150 bool CreatePlatformShortcuts(
1137 const base::FilePath& app_data_path, 1151 const base::FilePath& app_data_path,
1138 const ShortcutInfo& shortcut_info, 1152 scoped_ptr<ShortcutInfo> shortcut_info,
1139 const extensions::FileHandlersInfo& file_handlers_info, 1153 const extensions::FileHandlersInfo& file_handlers_info,
1140 const ShortcutLocations& creation_locations, 1154 const ShortcutLocations& creation_locations,
1141 ShortcutCreationReason creation_reason) { 1155 ShortcutCreationReason creation_reason) {
1142 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 1156 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
1143 if (AppShimsDisabledForTest()) 1157 if (AppShimsDisabledForTest())
1144 return true; 1158 return true;
1145 1159
1146 WebAppShortcutCreator shortcut_creator( 1160 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info.get(),
1147 app_data_path, shortcut_info, file_handlers_info); 1161 file_handlers_info);
1148 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations); 1162 return shortcut_creator.CreateShortcuts(creation_reason, creation_locations);
1149 } 1163 }
1150 1164
1151 void DeletePlatformShortcuts(const base::FilePath& app_data_path, 1165 void DeletePlatformShortcuts(const base::FilePath& app_data_path,
1152 const ShortcutInfo& shortcut_info) { 1166 scoped_ptr<ShortcutInfo> shortcut_info) {
1153 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 1167 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
1154 WebAppShortcutCreator shortcut_creator( 1168 WebAppShortcutCreator shortcut_creator(app_data_path, shortcut_info.get(),
1155 app_data_path, shortcut_info, extensions::FileHandlersInfo()); 1169 extensions::FileHandlersInfo());
1156 shortcut_creator.DeleteShortcuts(); 1170 shortcut_creator.DeleteShortcuts();
1157 } 1171 }
1158 1172
1159 void UpdatePlatformShortcuts( 1173 void UpdatePlatformShortcuts(
1160 const base::FilePath& app_data_path, 1174 const base::FilePath& app_data_path,
1161 const base::string16& old_app_title, 1175 const base::string16& old_app_title,
1162 const ShortcutInfo& shortcut_info, 1176 scoped_ptr<ShortcutInfo> shortcut_info,
1163 const extensions::FileHandlersInfo& file_handlers_info) { 1177 const extensions::FileHandlersInfo& file_handlers_info) {
1164 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 1178 UpdatePlatformShortcutsInternal(app_data_path, old_app_title, *shortcut_info,
1165 if (AppShimsDisabledForTest() && 1179 file_handlers_info);
1166 !g_app_shims_allow_update_and_launch_in_tests) {
1167 return;
1168 }
1169
1170 WebAppShortcutCreator shortcut_creator(
1171 app_data_path, shortcut_info, file_handlers_info);
1172 shortcut_creator.UpdateShortcuts();
1173 } 1180 }
1174 1181
1175 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { 1182 void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) {
1176 const std::string profile_base_name = profile_path.BaseName().value(); 1183 const std::string profile_base_name = profile_path.BaseName().value();
1177 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath( 1184 std::vector<base::FilePath> bundles = GetAllAppBundlesInPath(
1178 profile_path.Append(chrome::kWebAppDirname), profile_base_name); 1185 profile_path.Append(chrome::kWebAppDirname), profile_base_name);
1179 1186
1180 for (std::vector<base::FilePath>::const_iterator it = bundles.begin(); 1187 for (std::vector<base::FilePath>::const_iterator it = bundles.begin();
1181 it != bundles.end(); ++it) { 1188 it != bundles.end(); ++it) {
1182 web_app::ShortcutInfo shortcut_info = 1189 scoped_ptr<web_app::ShortcutInfo> shortcut_info =
1183 BuildShortcutInfoFromBundle(*it); 1190 BuildShortcutInfoFromBundle(*it);
1184 WebAppShortcutCreator shortcut_creator( 1191 WebAppShortcutCreator shortcut_creator(it->DirName(), shortcut_info.get(),
1185 it->DirName(), shortcut_info, extensions::FileHandlersInfo()); 1192 extensions::FileHandlersInfo());
1186 shortcut_creator.DeleteShortcuts(); 1193 shortcut_creator.DeleteShortcuts();
1187 } 1194 }
1188 } 1195 }
1189 1196
1190 } // namespace internals 1197 } // namespace internals
1191 1198
1192 } // namespace web_app 1199 } // namespace web_app
1193 1200
1194 namespace chrome { 1201 namespace chrome {
1195 1202
1196 void ShowCreateChromeAppShortcutsDialog( 1203 void ShowCreateChromeAppShortcutsDialog(
1197 gfx::NativeWindow /*parent_window*/, 1204 gfx::NativeWindow /*parent_window*/,
1198 Profile* profile, 1205 Profile* profile,
1199 const extensions::Extension* app, 1206 const extensions::Extension* app,
1200 const base::Callback<void(bool)>& close_callback) { 1207 const base::Callback<void(bool)>& close_callback) {
1201 web_app::GetShortcutInfoForApp( 1208 web_app::GetShortcutInfoForApp(
1202 app, 1209 app,
1203 profile, 1210 profile,
1204 base::Bind(&web_app::CreateAppShortcutInfoLoaded, 1211 base::Bind(&web_app::CreateAppShortcutInfoLoaded,
1205 profile, 1212 profile,
1206 app, 1213 app,
1207 close_callback)); 1214 close_callback));
1208 } 1215 }
1209 1216
1210 } // namespace chrome 1217 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/web_applications/web_app_mac.h ('k') | chrome/browser/web_applications/web_app_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698