| 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 <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/mac/bundle_locations.h" | 10 #include "base/mac/bundle_locations.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 | 52 |
| 53 if (!UpdateIcon(staging_path)) | 53 if (!UpdateIcon(staging_path)) |
| 54 return false; | 54 return false; |
| 55 | 55 |
| 56 FilePath dst_path = GetDestinationPath(app_file_name); | 56 FilePath dst_path = GetDestinationPath(app_file_name); |
| 57 if (!file_util::CopyDirectory(staging_path, dst_path, true)) { | 57 if (!file_util::CopyDirectory(staging_path, dst_path, true)) { |
| 58 LOG(ERROR) << "Copying app to dst path: " << dst_path.value() << " failed"; | 58 LOG(ERROR) << "Copying app to dst path: " << dst_path.value() << " failed"; |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 [[NSWorkspace sharedWorkspace] | 62 RevealGeneratedBundleInFinder(dst_path); |
| 63 selectFile:base::mac::FilePathToNSString(dst_path) | 63 |
| 64 inFileViewerRootedAtPath:nil]; | |
| 65 return true; | 64 return true; |
| 66 } | 65 } |
| 67 | 66 |
| 68 FilePath WebAppShortcutCreator::GetAppLoaderPath() const { | 67 FilePath WebAppShortcutCreator::GetAppLoaderPath() const { |
| 69 return base::mac::PathForFrameworkBundleResource( | 68 return base::mac::PathForFrameworkBundleResource( |
| 70 base::mac::NSToCFCast(@"app_mode_loader.app")); | 69 base::mac::NSToCFCast(@"app_mode_loader.app")); |
| 71 } | 70 } |
| 72 | 71 |
| 73 FilePath WebAppShortcutCreator::GetDestinationPath( | 72 FilePath WebAppShortcutCreator::GetDestinationPath( |
| 74 const FilePath& app_file_name) const { | 73 const FilePath& app_file_name) const { |
| 75 FilePath path; | 74 FilePath path; |
| 76 if (base::mac::GetLocalDirectory(NSApplicationDirectory, &path) && | 75 if (base::mac::GetLocalDirectory(NSApplicationDirectory, &path) && |
| 77 file_util::PathIsWritable(path)) { | 76 file_util::PathIsWritable(path)) { |
| 78 return path; | 77 return path; |
| 79 } | 78 } |
| 80 | 79 |
| 81 if (base::mac::GetUserDirectory(NSApplicationDirectory, &path)) | 80 if (base::mac::GetUserDirectory(NSApplicationDirectory, &path)) |
| 82 return path; | 81 return path; |
| 83 | 82 |
| 84 return FilePath(); | 83 return FilePath(); |
| 85 } | 84 } |
| 86 | 85 |
| 87 bool WebAppShortcutCreator::UpdatePlist(const FilePath& app_path) const { | 86 bool WebAppShortcutCreator::UpdatePlist(const FilePath& app_path) const { |
| 88 NSString* plist_path = base::mac::FilePathToNSString( | 87 NSString* plist_path = base::mac::FilePathToNSString( |
| 89 app_path.Append("Contents").Append("Info.plist")); | 88 app_path.Append("Contents").Append("Info.plist")); |
| 90 NSMutableDictionary* dict = | 89 |
| 90 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); |
| 91 NSString* extension_title = base::SysUTF16ToNSString(info_.title); |
| 92 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); |
| 93 NSString* chrome_bundle_id = base::SysUTF16ToNSString(chrome_bundle_id_); |
| 94 NSDictionary* replacement_dict = |
| 95 [NSDictionary dictionaryWithObjectsAndKeys: |
| 96 extension_id, app_mode::kShortcutIdPlaceholder, |
| 97 extension_title, app_mode::kShortcutNamePlaceholder, |
| 98 extension_url, app_mode::kShortcutURLPlaceholder, |
| 99 chrome_bundle_id, app_mode::kShortcutBrowserBundleIDPlaceholder, |
| 100 nil]; |
| 101 |
| 102 NSMutableDictionary* plist = |
| 91 [NSMutableDictionary dictionaryWithContentsOfFile:plist_path]; | 103 [NSMutableDictionary dictionaryWithContentsOfFile:plist_path]; |
| 104 NSArray* keys = [plist allKeys]; |
| 92 | 105 |
| 93 [dict setObject:GetBundleIdentifier(dict) | 106 // 1. Fill in variables. |
| 107 for (id key in keys) { |
| 108 NSString* value = [plist valueForKey:key]; |
| 109 if (![value isKindOfClass:[NSString class]] || [value length] < 2) |
| 110 continue; |
| 111 |
| 112 // Remove leading and trailing '@'s. |
| 113 NSString* variable = |
| 114 [value substringWithRange:NSMakeRange(1, [value length] - 2)]; |
| 115 |
| 116 NSString* substitution = [replacement_dict valueForKey:variable]; |
| 117 if (substitution) |
| 118 [plist setObject:substitution forKey:key]; |
| 119 } |
| 120 |
| 121 // 2. Fill in other values. |
| 122 [plist setObject:GetBundleIdentifier(plist) |
| 94 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; | 123 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; |
| 95 [dict setObject:base::SysUTF8ToNSString(info_.extension_id) | 124 |
| 96 forKey:app_mode::kCrAppModeShortcutIDKey]; | 125 return [plist writeToFile:plist_path atomically:YES]; |
| 97 [dict setObject:base::SysUTF16ToNSString(info_.title) | |
| 98 forKey:app_mode::kCrAppModeShortcutNameKey]; | |
| 99 [dict setObject:base::SysUTF8ToNSString(info_.url.spec()) | |
| 100 forKey:app_mode::kCrAppModeShortcutURLKey]; | |
| 101 [dict setObject:base::SysUTF16ToNSString(chrome_bundle_id_) | |
| 102 forKey:app_mode::kBrowserBundleIDKey]; | |
| 103 return [dict writeToFile:plist_path atomically:YES]; | |
| 104 } | 126 } |
| 105 | 127 |
| 106 bool WebAppShortcutCreator::UpdateIcon(const FilePath& app_path) const { | 128 bool WebAppShortcutCreator::UpdateIcon(const FilePath& app_path) const { |
| 107 // TODO:(sail) Need to implement this. | 129 // TODO:(sail) Need to implement this. |
| 108 return true; | 130 return true; |
| 109 } | 131 } |
| 110 | 132 |
| 111 NSString* WebAppShortcutCreator::GetBundleIdentifier(NSDictionary* plist) const | 133 NSString* WebAppShortcutCreator::GetBundleIdentifier(NSDictionary* plist) const |
| 112 { | 134 { |
| 113 NSString* bundle_id_template = | 135 NSString* bundle_id_template = |
| 114 base::mac::ObjCCast<NSString>( | 136 base::mac::ObjCCast<NSString>( |
| 115 [plist objectForKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]); | 137 [plist objectForKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]); |
| 116 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); | 138 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); |
| 117 NSString* bundle_id = | 139 NSString* bundle_id = |
| 118 [bundle_id_template | 140 [bundle_id_template |
| 119 stringByReplacingOccurrencesOfString:app_mode::kShortcutIdPlaceholder | 141 stringByReplacingOccurrencesOfString:app_mode::kShortcutIdPlaceholder |
| 120 withString:extension_id]; | 142 withString:extension_id]; |
| 121 return bundle_id; | 143 return bundle_id; |
| 122 } | 144 } |
| 123 | 145 |
| 146 void WebAppShortcutCreator::RevealGeneratedBundleInFinder( |
| 147 const FilePath& generated_bundle) const { |
| 148 [[NSWorkspace sharedWorkspace] |
| 149 selectFile:base::mac::FilePathToNSString(generated_bundle) |
| 150 inFileViewerRootedAtPath:nil]; |
| 151 } |
| 152 |
| 124 } // namespace | 153 } // namespace |
| 125 | 154 |
| 126 namespace web_app { | 155 namespace web_app { |
| 127 namespace internals { | 156 namespace internals { |
| 128 | 157 |
| 129 void CreateShortcutTask(const FilePath& web_app_path, | 158 void CreateShortcutTask(const FilePath& web_app_path, |
| 130 const FilePath& profile_path, | 159 const FilePath& profile_path, |
| 131 const ShellIntegration::ShortcutInfo& shortcut_info) { | 160 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 132 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 161 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 133 string16 bundle_id = UTF8ToUTF16(base::mac::BaseBundleID()); | 162 string16 bundle_id = UTF8ToUTF16(base::mac::BaseBundleID()); |
| 134 WebAppShortcutCreator shortcut_creator(shortcut_info, bundle_id); | 163 WebAppShortcutCreator shortcut_creator(shortcut_info, bundle_id); |
| 135 shortcut_creator.CreateShortcut(); | 164 shortcut_creator.CreateShortcut(); |
| 136 } | 165 } |
| 137 | 166 |
| 138 } // namespace internals | 167 } // namespace internals |
| 139 } // namespace web_app | 168 } // namespace web_app |
| OLD | NEW |