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 "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 EndsWith(shim_path.RemoveExtension().value(), | 152 EndsWith(shim_path.RemoveExtension().value(), |
| 153 extension_id, | 153 extension_id, |
| 154 true /* case_sensitive */)) { | 154 true /* case_sensitive */)) { |
| 155 return true; | 155 return true; |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 return false; | 159 return false; |
| 160 } | 160 } |
| 161 | 161 |
| 162 void DeleteShortcut(base::FilePath app_path) { | |
|
tapted
2013/06/18 06:54:59
const reference
tapted
2013/06/18 06:54:59
Maybe a more descriptive name, to distinguish it f
jackhou1
2013/06/18 08:32:40
Done.
jackhou1
2013/06/18 08:32:40
Done.
| |
| 163 if (app_path.empty()) | |
| 164 return; | |
| 165 | |
| 166 file_util::Delete(app_path, true); | |
| 167 base::FilePath apps_folder = app_path.DirName(); | |
| 168 if (file_util::IsDirectoryEmpty(apps_folder)) | |
| 169 file_util::Delete(apps_folder, false); | |
| 170 } | |
| 171 | |
| 162 } // namespace | 172 } // namespace |
| 163 | 173 |
| 164 namespace web_app { | 174 namespace web_app { |
| 165 | 175 |
| 166 const char kChromeAppDirName[] = "Chrome Apps.localized"; | 176 const char kChromeAppDirName[] = "Chrome Apps.localized"; |
| 167 | 177 |
| 168 WebAppShortcutCreator::WebAppShortcutCreator( | 178 WebAppShortcutCreator::WebAppShortcutCreator( |
| 169 const base::FilePath& user_data_dir, | 179 const base::FilePath& user_data_dir, |
| 170 const ShellIntegration::ShortcutInfo& shortcut_info, | 180 const ShellIntegration::ShortcutInfo& shortcut_info, |
| 171 const string16& chrome_bundle_id) | 181 const std::string& chrome_bundle_id) |
| 172 : user_data_dir_(user_data_dir), | 182 : user_data_dir_(user_data_dir), |
| 173 info_(shortcut_info), | 183 info_(shortcut_info), |
| 174 chrome_bundle_id_(chrome_bundle_id) { | 184 chrome_bundle_id_(chrome_bundle_id) { |
| 175 } | 185 } |
| 176 | 186 |
| 177 WebAppShortcutCreator::~WebAppShortcutCreator() { | 187 WebAppShortcutCreator::~WebAppShortcutCreator() { |
| 178 } | 188 } |
| 179 | 189 |
| 180 base::FilePath WebAppShortcutCreator::GetShortcutPath() const { | 190 base::FilePath WebAppShortcutCreator::GetShortcutName() const { |
| 181 base::FilePath dst_path = GetDestinationPath(); | |
| 182 if (dst_path.empty()) | |
| 183 return dst_path; | |
| 184 | |
| 185 base::FilePath app_name = internals::GetSanitizedFileName(UTF8ToUTF16( | 191 base::FilePath app_name = internals::GetSanitizedFileName(UTF8ToUTF16( |
| 186 info_.profile_path.BaseName().value() + " " + info_.extension_id)); | 192 info_.profile_path.BaseName().value() + " " + info_.extension_id)); |
| 187 return dst_path.Append(app_name.ReplaceExtension("app")); | 193 return app_name.ReplaceExtension("app"); |
| 188 } | 194 } |
| 189 | 195 |
| 190 bool WebAppShortcutCreator::CreateShortcut() { | 196 bool WebAppShortcutCreator::BuildShortcut( |
| 191 base::FilePath app_path = GetShortcutPath(); | 197 const base::FilePath& staging_path) const { |
| 192 base::FilePath app_name = app_path.BaseName(); | |
| 193 base::FilePath dst_path = app_path.DirName(); | |
| 194 if (app_path.empty() || !file_util::DirectoryExists(dst_path.DirName())) { | |
| 195 LOG(ERROR) << "Couldn't find an Applications directory to copy app to."; | |
| 196 return false; | |
| 197 } | |
| 198 if (!file_util::CreateDirectory(dst_path)) { | |
| 199 LOG(ERROR) << "Creating directory " << dst_path.value() << " failed."; | |
| 200 return false; | |
| 201 } | |
| 202 | |
| 203 base::ScopedTempDir scoped_temp_dir; | |
| 204 if (!scoped_temp_dir.CreateUniqueTempDir()) | |
| 205 return false; | |
| 206 base::FilePath staging_path = scoped_temp_dir.path().Append(app_name); | |
| 207 | |
| 208 // Update the app's plist and icon in a temp directory. This works around | 198 // Update the app's plist and icon in a temp directory. This works around |
| 209 // a Finder bug where the app's icon doesn't properly update. | 199 // a Finder bug where the app's icon doesn't properly update. |
| 210 if (!file_util::CopyDirectory(GetAppLoaderPath(), staging_path, true)) { | 200 if (!file_util::CopyDirectory(GetAppLoaderPath(), staging_path, true)) { |
| 211 LOG(ERROR) << "Copying app to staging path: " << staging_path.value() | 201 LOG(ERROR) << "Copying app to staging path: " << staging_path.value() |
| 212 << " failed"; | 202 << " failed"; |
| 213 return false; | 203 return false; |
| 214 } | 204 } |
| 215 | 205 |
| 216 if (!UpdatePlist(staging_path)) | 206 if (!UpdatePlist(staging_path)) |
| 217 return false; | 207 return false; |
| 218 | 208 |
| 219 if (!UpdateDisplayName(staging_path)) | 209 if (!UpdateDisplayName(staging_path)) |
| 220 return false; | 210 return false; |
| 221 | 211 |
| 222 if (!UpdateIcon(staging_path)) | 212 if (!UpdateIcon(staging_path)) |
| 223 return false; | 213 return false; |
| 224 | 214 |
| 225 if (!file_util::CopyDirectory(staging_path, dst_path, true)) { | 215 return true; |
| 226 LOG(ERROR) << "Copying app to dst path: " << dst_path.value() << " failed"; | 216 } |
| 217 | |
| 218 bool WebAppShortcutCreator::CreateShortcutsIn( | |
| 219 const std::vector<base::FilePath>& folders) const { | |
| 220 base::ScopedTempDir scoped_temp_dir; | |
| 221 if (!scoped_temp_dir.CreateUniqueTempDir()) | |
| 222 return false; | |
| 223 | |
| 224 base::FilePath app_name = GetShortcutName(); | |
| 225 base::FilePath staging_path = | |
| 226 scoped_temp_dir.path().Append(app_name); | |
| 227 if (!BuildShortcut(staging_path)) | |
| 228 return false; | |
| 229 | |
| 230 for (std::vector<base::FilePath>::const_iterator it = folders.begin(); | |
| 231 it != folders.end(); ++it) { | |
| 232 const base::FilePath& dst_path = *it; | |
| 233 if (!file_util::CopyDirectory(staging_path, dst_path, true)) { | |
| 234 LOG(ERROR) << "Copying app to dst path: " << dst_path.value() | |
| 235 << " failed"; | |
| 236 return false; | |
| 237 } | |
| 238 | |
| 239 base::mac::RemoveQuarantineAttribute(dst_path.Append(app_name)); | |
| 240 } | |
| 241 | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 bool WebAppShortcutCreator::CreateShortcut() { | |
| 246 base::FilePath dst_path = GetDestinationPath(); | |
| 247 if (dst_path.empty() || !file_util::DirectoryExists(dst_path.DirName())) { | |
| 248 LOG(ERROR) << "Couldn't find an Applications directory to copy app to."; | |
| 249 return false; | |
| 250 } | |
|
tapted
2013/06/18 06:54:59
nit: blank line after for early return
jackhou1
2013/06/18 08:32:40
Done.
| |
| 251 if (!file_util::CreateDirectory(dst_path)) { | |
| 252 LOG(ERROR) << "Creating directory " << dst_path.value() << " failed."; | |
| 227 return false; | 253 return false; |
| 228 } | 254 } |
| 229 | 255 |
| 230 base::mac::RemoveQuarantineAttribute(app_path); | 256 std::vector<base::FilePath> paths; |
| 231 RevealGeneratedBundleInFinder(app_path); | 257 paths.push_back(dst_path); |
| 258 if (!CreateShortcutsIn(paths)) | |
| 259 return false; | |
| 232 | 260 |
| 261 RevealAppShimInFinder(); | |
| 233 return true; | 262 return true; |
| 234 } | 263 } |
| 235 | 264 |
| 265 void WebAppShortcutCreator::DeleteShortcuts() { | |
| 266 base::FilePath dst_path = GetDestinationPath(); | |
| 267 if (!dst_path.empty()) | |
| 268 DeleteShortcut(dst_path.Append(GetShortcutName())); | |
| 269 // In case the user has moved/renamed/copied the app bundle. | |
| 270 DeleteShortcut(GetAppBundleById(GetBundleIdentifier())); | |
| 271 } | |
| 272 | |
| 273 bool WebAppShortcutCreator::UpdateShortcuts() { | |
| 274 base::FilePath dst_path = GetDestinationPath(); | |
| 275 base::FilePath app_path = dst_path.Append(GetShortcutName()); | |
| 276 | |
| 277 // If the path does not exist, check if a matching bundle can be found | |
| 278 // elsewhere. | |
| 279 if (dst_path.empty() || !file_util::PathExists(app_path)) | |
| 280 app_path = GetAppBundleById(GetBundleIdentifier()); | |
| 281 | |
| 282 if (app_path.empty()) | |
| 283 return false; | |
| 284 | |
| 285 file_util::Delete(app_path, true); | |
| 286 | |
| 287 std::vector<base::FilePath> paths; | |
| 288 paths.push_back(app_path.DirName()); | |
| 289 return CreateShortcutsIn(paths); | |
| 290 } | |
| 291 | |
| 236 base::FilePath WebAppShortcutCreator::GetAppLoaderPath() const { | 292 base::FilePath WebAppShortcutCreator::GetAppLoaderPath() const { |
| 237 return base::mac::PathForFrameworkBundleResource( | 293 return base::mac::PathForFrameworkBundleResource( |
| 238 base::mac::NSToCFCast(@"app_mode_loader.app")); | 294 base::mac::NSToCFCast(@"app_mode_loader.app")); |
| 239 } | 295 } |
| 240 | 296 |
| 241 base::FilePath WebAppShortcutCreator::GetDestinationPath() const { | 297 base::FilePath WebAppShortcutCreator::GetDestinationPath() const { |
| 242 base::FilePath path = GetWritableApplicationsDirectory(); | 298 base::FilePath path = GetWritableApplicationsDirectory(); |
| 243 if (path.empty()) | 299 if (path.empty()) |
| 244 return path; | 300 return path; |
| 245 return path.Append(kChromeAppDirName); | 301 return path.Append(kChromeAppDirName); |
| 246 } | 302 } |
| 247 | 303 |
| 248 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { | 304 bool WebAppShortcutCreator::UpdatePlist(const base::FilePath& app_path) const { |
| 249 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); | 305 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); |
| 250 NSString* extension_title = base::SysUTF16ToNSString(info_.title); | 306 NSString* extension_title = base::SysUTF16ToNSString(info_.title); |
| 251 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); | 307 NSString* extension_url = base::SysUTF8ToNSString(info_.url.spec()); |
| 252 NSString* chrome_bundle_id = base::SysUTF16ToNSString(chrome_bundle_id_); | 308 NSString* chrome_bundle_id = base::SysUTF8ToNSString(chrome_bundle_id_); |
| 253 NSDictionary* replacement_dict = | 309 NSDictionary* replacement_dict = |
| 254 [NSDictionary dictionaryWithObjectsAndKeys: | 310 [NSDictionary dictionaryWithObjectsAndKeys: |
| 255 extension_id, app_mode::kShortcutIdPlaceholder, | 311 extension_id, app_mode::kShortcutIdPlaceholder, |
| 256 extension_title, app_mode::kShortcutNamePlaceholder, | 312 extension_title, app_mode::kShortcutNamePlaceholder, |
| 257 extension_url, app_mode::kShortcutURLPlaceholder, | 313 extension_url, app_mode::kShortcutURLPlaceholder, |
| 258 chrome_bundle_id, app_mode::kShortcutBrowserBundleIDPlaceholder, | 314 chrome_bundle_id, app_mode::kShortcutBrowserBundleIDPlaceholder, |
| 259 nil]; | 315 nil]; |
| 260 | 316 |
| 261 NSString* plist_path = base::mac::FilePathToNSString( | 317 NSString* plist_path = base::mac::FilePathToNSString( |
| 262 app_path.Append("Contents").Append("Info.plist")); | 318 app_path.Append("Contents").Append("Info.plist")); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 273 // Remove leading and trailing '@'s. | 329 // Remove leading and trailing '@'s. |
| 274 NSString* variable = | 330 NSString* variable = |
| 275 [value substringWithRange:NSMakeRange(1, [value length] - 2)]; | 331 [value substringWithRange:NSMakeRange(1, [value length] - 2)]; |
| 276 | 332 |
| 277 NSString* substitution = [replacement_dict valueForKey:variable]; | 333 NSString* substitution = [replacement_dict valueForKey:variable]; |
| 278 if (substitution) | 334 if (substitution) |
| 279 [plist setObject:substitution forKey:key]; | 335 [plist setObject:substitution forKey:key]; |
| 280 } | 336 } |
| 281 | 337 |
| 282 // 2. Fill in other values. | 338 // 2. Fill in other values. |
| 283 [plist setObject:GetBundleIdentifier(plist) | 339 [plist setObject:base::SysUTF8ToNSString(GetBundleIdentifier()) |
| 284 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; | 340 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; |
| 285 [plist setObject:base::mac::FilePathToNSString(user_data_dir_) | 341 [plist setObject:base::mac::FilePathToNSString(user_data_dir_) |
| 286 forKey:app_mode::kCrAppModeUserDataDirKey]; | 342 forKey:app_mode::kCrAppModeUserDataDirKey]; |
| 287 [plist setObject:base::mac::FilePathToNSString(info_.profile_path.BaseName()) | 343 [plist setObject:base::mac::FilePathToNSString(info_.profile_path.BaseName()) |
| 288 forKey:app_mode::kCrAppModeProfileDirKey]; | 344 forKey:app_mode::kCrAppModeProfileDirKey]; |
| 289 [plist setObject:base::SysUTF8ToNSString(info_.profile_name) | 345 [plist setObject:base::SysUTF8ToNSString(info_.profile_name) |
| 290 forKey:app_mode::kCrAppModeProfileNameKey]; | 346 forKey:app_mode::kCrAppModeProfileNameKey]; |
| 291 [plist setObject:[NSNumber numberWithBool:YES] | 347 [plist setObject:[NSNumber numberWithBool:YES] |
| 292 forKey:app_mode::kLSHasLocalizedDisplayNameKey]; | 348 forKey:app_mode::kLSHasLocalizedDisplayNameKey]; |
| 293 | 349 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 if (!image_added) | 405 if (!image_added) |
| 350 return false; | 406 return false; |
| 351 | 407 |
| 352 base::FilePath resources_path = GetResourcesPath(app_path); | 408 base::FilePath resources_path = GetResourcesPath(app_path); |
| 353 if (!file_util::CreateDirectory(resources_path)) | 409 if (!file_util::CreateDirectory(resources_path)) |
| 354 return false; | 410 return false; |
| 355 | 411 |
| 356 return icon_family.WriteDataToFile(resources_path.Append("app.icns")); | 412 return icon_family.WriteDataToFile(resources_path.Append("app.icns")); |
| 357 } | 413 } |
| 358 | 414 |
| 359 NSString* WebAppShortcutCreator::GetBundleIdentifier(NSDictionary* plist) const | 415 base::FilePath WebAppShortcutCreator::GetAppBundleById( |
| 360 { | 416 const std::string& bundle_id) const { |
| 361 NSString* bundle_id_template = | 417 base::mac::ScopedCFTypeRef<CFStringRef> bundle_id_cf( |
| 362 base::mac::ObjCCast<NSString>( | 418 base::SysUTF8ToCFStringRef(bundle_id)); |
| 363 [plist objectForKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]); | 419 CFURLRef url_ref = NULL; |
| 364 NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id); | 420 OSStatus status = LSFindApplicationForInfo( |
| 365 NSString* placeholder = | 421 kLSUnknownCreator, bundle_id_cf.get(), NULL, NULL, &url_ref); |
| 366 [NSString stringWithFormat:@"@%@@", app_mode::kShortcutIdPlaceholder]; | 422 base::mac::ScopedCFTypeRef<CFURLRef> url(url_ref); |
|
tapted
2013/06/18 06:54:59
move this below checking status != noErr?
jackhou1
2013/06/18 08:32:40
Done.
| |
| 367 NSString* bundle_id = | 423 |
| 368 [bundle_id_template | 424 if (status != noErr) |
| 369 stringByReplacingOccurrencesOfString:placeholder | 425 return base::FilePath(); |
| 370 withString:extension_id]; | 426 |
| 427 NSString* path_string = [base::mac::CFToNSCast(url.get()) path]; | |
| 428 return base::FilePath([path_string fileSystemRepresentation]); | |
| 429 } | |
| 430 | |
| 431 std::string WebAppShortcutCreator::GetBundleIdentifier() const { | |
| 432 // Replace spaces in the profile path with hyphen. | |
| 433 std::string normalized_profile_path; | |
| 434 ReplaceChars(info_.profile_path.BaseName().value(), | |
| 435 " ", "-", &normalized_profile_path); | |
| 436 | |
| 437 // This matches APP_MODE_APP_BUNDLE_ID in chrome/chrome.gyp. | |
| 438 std::string bundle_id = | |
| 439 chrome_bundle_id_ + std::string(".app.") + | |
| 440 normalized_profile_path + "-" + info_.extension_id; | |
| 441 | |
| 371 return bundle_id; | 442 return bundle_id; |
| 372 } | 443 } |
| 373 | 444 |
| 374 void WebAppShortcutCreator::RevealGeneratedBundleInFinder( | 445 void WebAppShortcutCreator::RevealAppShimInFinder() const { |
| 375 const base::FilePath& generated_bundle) const { | 446 base::FilePath dst_path = GetDestinationPath(); |
| 447 if (dst_path.empty()) | |
| 448 return; | |
| 449 | |
| 450 base::FilePath app_path = dst_path.Append(GetShortcutName()); | |
| 376 [[NSWorkspace sharedWorkspace] | 451 [[NSWorkspace sharedWorkspace] |
| 377 selectFile:base::mac::FilePathToNSString(generated_bundle) | 452 selectFile:base::mac::FilePathToNSString(app_path) |
| 378 inFileViewerRootedAtPath:nil]; | 453 inFileViewerRootedAtPath:nil]; |
| 379 } | 454 } |
| 380 | 455 |
| 381 void LaunchShimOnFileThread( | 456 void LaunchShimOnFileThread( |
| 382 const ShellIntegration::ShortcutInfo& shortcut_info) { | 457 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 383 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 458 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 384 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); | 459 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); |
| 385 if (shim_path.empty()) | 460 if (shim_path.empty()) |
| 386 return; | 461 return; |
| 387 | 462 |
| 388 CommandLine command_line(CommandLine::NO_PROGRAM); | 463 CommandLine command_line(CommandLine::NO_PROGRAM); |
| 389 command_line.AppendSwitch(app_mode::kNoLaunchApp); | 464 command_line.AppendSwitch(app_mode::kNoLaunchApp); |
| 390 base::mac::OpenApplicationWithPath(shim_path, command_line, NULL); | 465 base::mac::OpenApplicationWithPath(shim_path, command_line, NULL); |
| 391 } | 466 } |
| 392 | 467 |
| 393 } // namespace | 468 } // namespace |
| 394 | 469 |
| 395 namespace web_app { | 470 namespace web_app { |
| 396 | 471 |
| 397 base::FilePath GetAppInstallPath( | 472 base::FilePath GetAppInstallPath( |
| 398 const ShellIntegration::ShortcutInfo& shortcut_info) { | 473 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 399 WebAppShortcutCreator shortcut_creator(base::FilePath(), | 474 WebAppShortcutCreator shortcut_creator(base::FilePath(), |
| 400 shortcut_info, | 475 shortcut_info, |
| 401 string16()); | 476 std::string()); |
| 402 return shortcut_creator.GetShortcutPath(); | 477 base::FilePath dst_path = shortcut_creator.GetDestinationPath(); |
| 478 return dst_path.empty() ? | |
| 479 base::FilePath() : dst_path.Append(shortcut_creator.GetShortcutName()); | |
| 403 } | 480 } |
| 404 | 481 |
| 405 void MaybeLaunchShortcut(const ShellIntegration::ShortcutInfo& shortcut_info) { | 482 void MaybeLaunchShortcut(const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 406 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppShims)) | 483 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAppShims)) |
| 407 return; | 484 return; |
| 408 | 485 |
| 409 content::BrowserThread::PostTask( | 486 content::BrowserThread::PostTask( |
| 410 content::BrowserThread::FILE, FROM_HERE, | 487 content::BrowserThread::FILE, FROM_HERE, |
| 411 base::Bind(&LaunchShimOnFileThread, shortcut_info)); | 488 base::Bind(&LaunchShimOnFileThread, shortcut_info)); |
| 412 } | 489 } |
| 413 | 490 |
| 414 namespace internals { | 491 namespace internals { |
| 415 | 492 |
| 416 base::FilePath GetAppBundleByExtensionId(std::string extension_id) { | |
| 417 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | |
| 418 // This matches APP_MODE_APP_BUNDLE_ID in chrome/chrome.gyp. | |
| 419 std::string bundle_id = | |
| 420 base::mac::BaseBundleID() + std::string(".app.") + extension_id; | |
| 421 base::mac::ScopedCFTypeRef<CFStringRef> bundle_id_cf( | |
| 422 base::SysUTF8ToCFStringRef(bundle_id)); | |
| 423 CFURLRef url_ref = NULL; | |
| 424 OSStatus status = LSFindApplicationForInfo( | |
| 425 kLSUnknownCreator, bundle_id_cf.get(), NULL, NULL, &url_ref); | |
| 426 base::mac::ScopedCFTypeRef<CFURLRef> url(url_ref); | |
| 427 | |
| 428 if (status != noErr) | |
| 429 return base::FilePath(); | |
| 430 | |
| 431 NSString* path_string = [base::mac::CFToNSCast(url.get()) path]; | |
| 432 return base::FilePath([path_string fileSystemRepresentation]); | |
| 433 } | |
| 434 | |
| 435 bool CreatePlatformShortcuts( | 493 bool CreatePlatformShortcuts( |
| 436 const base::FilePath& web_app_path, | 494 const base::FilePath& web_app_path, |
| 437 const ShellIntegration::ShortcutInfo& shortcut_info, | 495 const ShellIntegration::ShortcutInfo& shortcut_info, |
| 438 const ShellIntegration::ShortcutLocations& /*creation_locations*/) { | 496 const ShellIntegration::ShortcutLocations& creation_locations) { |
| 439 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 497 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 440 string16 bundle_id = UTF8ToUTF16(base::mac::BaseBundleID()); | 498 WebAppShortcutCreator shortcut_creator( |
| 441 WebAppShortcutCreator shortcut_creator(web_app_path, shortcut_info, | 499 web_app_path, shortcut_info, base::mac::BaseBundleID()); |
| 442 bundle_id); | |
| 443 return shortcut_creator.CreateShortcut(); | 500 return shortcut_creator.CreateShortcut(); |
| 444 } | 501 } |
| 445 | 502 |
| 446 void DeletePlatformShortcuts( | 503 void DeletePlatformShortcuts( |
| 447 const base::FilePath& web_app_path, | 504 const base::FilePath& web_app_path, |
| 448 const ShellIntegration::ShortcutInfo& info) { | 505 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 449 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); | 506 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 450 | 507 WebAppShortcutCreator shortcut_creator( |
| 451 base::FilePath bundle_path = GetAppBundleByExtensionId(info.extension_id); | 508 web_app_path, shortcut_info, base::mac::BaseBundleID()); |
| 452 file_util::Delete(bundle_path, true); | 509 shortcut_creator.DeleteShortcuts(); |
| 453 } | 510 } |
| 454 | 511 |
| 455 void UpdatePlatformShortcuts( | 512 void UpdatePlatformShortcuts( |
| 456 const base::FilePath& web_app_path, | 513 const base::FilePath& web_app_path, |
| 457 const string16& old_app_title, | 514 const string16& old_app_title, |
| 458 const ShellIntegration::ShortcutInfo& shortcut_info) { | 515 const ShellIntegration::ShortcutInfo& shortcut_info) { |
| 459 // TODO(benwells): Implement this when shortcuts / weblings are enabled on | 516 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); |
| 460 // mac. | 517 WebAppShortcutCreator shortcut_creator( |
| 518 web_app_path, shortcut_info, base::mac::BaseBundleID()); | |
| 519 shortcut_creator.UpdateShortcuts(); | |
| 461 } | 520 } |
| 462 | 521 |
| 463 } // namespace internals | 522 } // namespace internals |
| 464 | 523 |
| 465 } // namespace web_app | 524 } // namespace web_app |
| OLD | NEW |