Chromium Code Reviews| Index: chrome/common/service_process_util_mac.mm |
| diff --git a/chrome/common/service_process_util_mac.mm b/chrome/common/service_process_util_mac.mm |
| index 0d6c8d6a9233c9cd69ae56f45b127469118ae300..c36a7fad9957b2f384d3a89171f7b9d08395cb82 100644 |
| --- a/chrome/common/service_process_util_mac.mm |
| +++ b/chrome/common/service_process_util_mac.mm |
| @@ -30,6 +30,14 @@ |
| #include "components/version_info/version_info.h" |
| #include "ipc/unix_domain_socket_util.h" |
| +@interface NSFileManager (YosemiteSDK) |
| +- (BOOL)getRelationship:(NSURLRelationship*)outRelationship |
| + ofDirectory:(NSSearchPathDirectory)directory |
| + inDomain:(NSSearchPathDomainMask)domainMask |
| + toItemAtURL:(NSURL*)url |
| + error:(NSError**)error; |
| +@end |
| + |
| using ::base::FilePathWatcher; |
| namespace { |
| @@ -61,10 +69,6 @@ NSString* GetServiceProcessLaunchDSocketKey() { |
| return @"ServiceProcessSocket"; |
| } |
| -bool GetParentFSRef(const FSRef& child, FSRef* parent) { |
| - return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr; |
| -} |
| - |
| bool RemoveFromLaunchd() { |
| // We're killing a file. |
| base::ThreadRestrictions::AssertIOAllowed(); |
| @@ -83,7 +87,7 @@ class ExecFilePathWatcherCallback { |
| void NotifyPathChanged(const base::FilePath& path, bool error); |
| private: |
| - FSRef executable_fsref_; |
| + base::scoped_nsobject<NSURL> executable_fsref_; |
| }; |
| base::FilePath GetServiceProcessSocketName() { |
| @@ -324,7 +328,10 @@ bool ServiceProcessState::StateData::WatchExecutable() { |
| } |
| bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) { |
| - return base::mac::FSRefFromPath(path.value(), &executable_fsref_); |
| + NSString* path_string = base::mac::FilePathToNSString(path); |
| + NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO]; |
| + executable_fsref_.reset([[path_url fileReferenceURL] retain]); |
| + return executable_fsref_.get() != nil; |
| } |
| void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path, |
| @@ -339,38 +346,62 @@ void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path, |
| bool needs_restart = false; |
| bool good_bundle = false; |
| - FSRef macos_fsref; |
| - if (GetParentFSRef(executable_fsref_, &macos_fsref)) { |
| - FSRef contents_fsref; |
| - if (GetParentFSRef(macos_fsref, &contents_fsref)) { |
| - FSRef bundle_fsref; |
| - if (GetParentFSRef(contents_fsref, &bundle_fsref)) { |
| - base::ScopedCFTypeRef<CFURLRef> bundle_url( |
| - CFURLCreateFromFSRef(kCFAllocatorDefault, &bundle_fsref)); |
| - if (bundle_url.get()) { |
| - base::ScopedCFTypeRef<CFBundleRef> bundle( |
| - CFBundleCreate(kCFAllocatorDefault, bundle_url)); |
| - // Check to see if the bundle still has a minimal structure. |
| - good_bundle = CFBundleGetIdentifier(bundle) != NULL; |
| - } |
| - } |
| - } |
| + // Go from bundle/Contents/MacOS/executable to bundle. |
| + NSURL* bundle_url = [[[executable_fsref_ URLByDeletingLastPathComponent] |
| + URLByDeletingLastPathComponent] URLByDeletingLastPathComponent]; |
| + if (bundle_url) { |
| + base::ScopedCFTypeRef<CFBundleRef> bundle( |
| + CFBundleCreate(kCFAllocatorDefault, base::mac::NSToCFCast(bundle_url))); |
| + good_bundle = CFBundleGetIdentifier(bundle) != NULL; |
| } |
| + |
| if (!good_bundle) { |
| needs_shutdown = true; |
| } else { |
| - Boolean in_trash; |
| - OSErr err = FSDetermineIfRefIsEnclosedByFolder(kOnAppropriateDisk, |
| - kTrashFolderType, |
| - &executable_fsref_, |
| - &in_trash); |
| - if (err == noErr && in_trash) { |
| + bool in_trash = false; |
| + NSFileManager* file_manager = [NSFileManager defaultManager]; |
| + // Apple deprecated FSDetermineIfRefIsEnclosedByFolder() when deploying to |
| + // 10.8, but didn't ad getRelationship:... until 10.10. So fall back to |
|
Nico
2016/10/10 19:14:14
s/ad/add/
(who wrote this comment?! :-P)
erikchen
2016/10/10 22:49:30
Done.
|
| + // the deprecated function while running on 10.9 (and delete the else block |
| + // when Chromium requires OS X 10.10+). |
| + if ([file_manager respondsToSelector:@selector(getRelationship: |
| + ofDirectory: |
| + inDomain: |
| + toItemAtURL: |
| + error:)]) { |
| + NSURLRelationship relationship; |
| + if ([file_manager getRelationship:&relationship |
| + ofDirectory:NSTrashDirectory |
| + inDomain:0 |
| + toItemAtURL:executable_fsref_ |
| + error:nil]) { |
| + in_trash = relationship == NSURLRelationshipContains; |
| + } |
| + } else { |
| + DCHECK(base::mac::IsAtMostOS10_9()); |
| + Boolean fs_in_trash; |
| + FSRef ref; |
| + if (CFURLGetFSRef(base::mac::NSToCFCast(executable_fsref_.get()), &ref)) { |
| +// This is ok because it only happens on 10.9 and won't be needed once |
|
erikchen
2016/10/07 00:18:44
clang format. *shrug*
Nico
2016/10/10 19:14:14
If you move the comment after the pragma. But as-i
erikchen
2016/10/10 22:49:30
Done.
|
| +// we stop supporting that. |
| +#pragma clang diagnostic push |
| +#pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| + OSErr err = FSDetermineIfRefIsEnclosedByFolder( |
| + kOnAppropriateDisk, kTrashFolderType, &ref, &fs_in_trash); |
| +#pragma clang diagnostic pop |
| + if (err == noErr && fs_in_trash) |
| + in_trash = true; |
| + } |
| + } |
| + if (in_trash) { |
| needs_shutdown = true; |
| } else { |
| bool was_moved = true; |
| - FSRef path_ref; |
| - if (base::mac::FSRefFromPath(path.value(), &path_ref)) { |
| - if (FSCompareFSRefs(&path_ref, &executable_fsref_) == noErr) { |
| + NSString* path_string = base::mac::FilePathToNSString(path); |
| + NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO]; |
| + NSURL* path_ref = [path_url fileReferenceURL]; |
| + if (path_ref != nil) { |
| + if ([path_ref isEqual:executable_fsref_]) { |
| was_moved = false; |
| } |
| } |
| @@ -388,8 +419,9 @@ void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path, |
| Launchd::User, Launchd::Agent, name)); |
| if (plist.get()) { |
| NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist); |
| - std::string new_path = base::mac::PathFromFSRef(executable_fsref_); |
| - NSString* ns_new_path = base::SysUTF8ToNSString(new_path); |
| + NSURL* new_path = [executable_fsref_ filePathURL]; |
| + DCHECK([new_path isFileURL]); |
| + NSString* ns_new_path = [new_path path]; |
| [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM]; |
| base::scoped_nsobject<NSMutableArray> args([[ns_plist |
| objectForKey:@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]); |