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

Side by Side Diff: chrome/common/service_process_util_mac.mm

Issue 2398243002: mac: Stop using deprecated FSRef functions in service_process_util_mac.mm (Closed)
Patch Set: Fix tests. Created 4 years, 2 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 <Foundation/Foundation.h> 5 #import <Foundation/Foundation.h>
6 #include <launch.h> 6 #include <launch.h>
7 7
8 #include <memory> 8 #include <memory>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 12 matching lines...) Expand all
23 #include "base/strings/sys_string_conversions.h" 23 #include "base/strings/sys_string_conversions.h"
24 #include "base/threading/thread_restrictions.h" 24 #include "base/threading/thread_restrictions.h"
25 #include "base/version.h" 25 #include "base/version.h"
26 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/mac/launchd.h" 28 #include "chrome/common/mac/launchd.h"
29 #include "chrome/common/service_process_util_posix.h" 29 #include "chrome/common/service_process_util_posix.h"
30 #include "components/version_info/version_info.h" 30 #include "components/version_info/version_info.h"
31 #include "ipc/unix_domain_socket_util.h" 31 #include "ipc/unix_domain_socket_util.h"
32 32
33 @interface NSFileManager (YosemiteSDK)
34 - (BOOL)getRelationship:(NSURLRelationship*)outRelationship
35 ofDirectory:(NSSearchPathDirectory)directory
36 inDomain:(NSSearchPathDomainMask)domainMask
37 toItemAtURL:(NSURL*)url
38 error:(NSError**)error;
39 @end
40
33 using ::base::FilePathWatcher; 41 using ::base::FilePathWatcher;
34 42
35 namespace { 43 namespace {
36 44
37 #define kServiceProcessSessionType "Aqua" 45 #define kServiceProcessSessionType "Aqua"
38 46
39 CFStringRef CopyServiceProcessLaunchDName() { 47 CFStringRef CopyServiceProcessLaunchDName() {
40 base::mac::ScopedNSAutoreleasePool pool; 48 base::mac::ScopedNSAutoreleasePool pool;
41 NSBundle* bundle = base::mac::FrameworkBundle(); 49 NSBundle* bundle = base::mac::FrameworkBundle();
42 return CFStringCreateCopy(kCFAllocatorDefault, 50 return CFStringCreateCopy(kCFAllocatorDefault,
(...skipping 11 matching lines...) Expand all
54 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" " 62 ns_path = [ns_path stringByReplacingOccurrencesOfString:@" "
55 withString:@"_"]; 63 withString:@"_"];
56 label = [label stringByAppendingString:ns_path]; 64 label = [label stringByAppendingString:ns_path];
57 return label; 65 return label;
58 } 66 }
59 67
60 NSString* GetServiceProcessLaunchDSocketKey() { 68 NSString* GetServiceProcessLaunchDSocketKey() {
61 return @"ServiceProcessSocket"; 69 return @"ServiceProcessSocket";
62 } 70 }
63 71
64 bool GetParentFSRef(const FSRef& child, FSRef* parent) {
65 return FSGetCatalogInfo(&child, 0, NULL, NULL, NULL, parent) == noErr;
66 }
67
68 bool RemoveFromLaunchd() { 72 bool RemoveFromLaunchd() {
69 // We're killing a file. 73 // We're killing a file.
70 base::ThreadRestrictions::AssertIOAllowed(); 74 base::ThreadRestrictions::AssertIOAllowed();
71 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); 75 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
72 return Launchd::GetInstance()->DeletePlist(Launchd::User, 76 return Launchd::GetInstance()->DeletePlist(Launchd::User,
73 Launchd::Agent, 77 Launchd::Agent,
74 name); 78 name);
75 } 79 }
76 80
77 class ExecFilePathWatcherCallback { 81 class ExecFilePathWatcherCallback {
78 public: 82 public:
79 ExecFilePathWatcherCallback() {} 83 ExecFilePathWatcherCallback() {}
80 ~ExecFilePathWatcherCallback() {} 84 ~ExecFilePathWatcherCallback() {}
81 85
82 bool Init(const base::FilePath& path); 86 bool Init(const base::FilePath& path);
83 void NotifyPathChanged(const base::FilePath& path, bool error); 87 void NotifyPathChanged(const base::FilePath& path, bool error);
84 88
85 private: 89 private:
86 FSRef executable_fsref_; 90 base::scoped_nsobject<NSURL> executable_fsref_;
87 }; 91 };
88 92
89 base::FilePath GetServiceProcessSocketName() { 93 base::FilePath GetServiceProcessSocketName() {
90 base::FilePath socket_name; 94 base::FilePath socket_name;
91 PathService::Get(base::DIR_TEMP, &socket_name); 95 PathService::Get(base::DIR_TEMP, &socket_name);
92 std::string pipe_name = GetServiceProcessScopedName("srv"); 96 std::string pipe_name = GetServiceProcessScopedName("srv");
93 socket_name = socket_name.Append(pipe_name); 97 socket_name = socket_name.Append(pipe_name);
94 CHECK_LT(socket_name.value().size(), IPC::kMaxSocketNameLength); 98 CHECK_LT(socket_name.value().size(), IPC::kMaxSocketNameLength);
95 return socket_name; 99 return socket_name;
96 } 100 }
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 false, 321 false,
318 base::Bind(&ExecFilePathWatcherCallback::NotifyPathChanged, 322 base::Bind(&ExecFilePathWatcherCallback::NotifyPathChanged,
319 base::Owned(callback.release())))) { 323 base::Owned(callback.release())))) {
320 DLOG(ERROR) << "executable_watcher.watch " << executable_path.value(); 324 DLOG(ERROR) << "executable_watcher.watch " << executable_path.value();
321 return false; 325 return false;
322 } 326 }
323 return true; 327 return true;
324 } 328 }
325 329
326 bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) { 330 bool ExecFilePathWatcherCallback::Init(const base::FilePath& path) {
327 return base::mac::FSRefFromPath(path.value(), &executable_fsref_); 331 NSString* path_string = base::mac::FilePathToNSString(path);
332 NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
333 executable_fsref_.reset([[path_url fileReferenceURL] retain]);
334 return executable_fsref_.get() != nil;
328 } 335 }
329 336
330 void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path, 337 void ExecFilePathWatcherCallback::NotifyPathChanged(const base::FilePath& path,
331 bool error) { 338 bool error) {
332 if (error) { 339 if (error) {
333 NOTREACHED(); // TODO(darin): Do something smarter? 340 NOTREACHED(); // TODO(darin): Do something smarter?
334 return; 341 return;
335 } 342 }
336 343
337 base::mac::ScopedNSAutoreleasePool pool; 344 base::mac::ScopedNSAutoreleasePool pool;
338 bool needs_shutdown = false; 345 bool needs_shutdown = false;
339 bool needs_restart = false; 346 bool needs_restart = false;
340 bool good_bundle = false; 347 bool good_bundle = false;
341 348
342 FSRef macos_fsref; 349 // Go from bundle/Contents/MacOS/executable to bundle.
343 if (GetParentFSRef(executable_fsref_, &macos_fsref)) { 350 NSURL* bundle_url = [[[executable_fsref_ URLByDeletingLastPathComponent]
344 FSRef contents_fsref; 351 URLByDeletingLastPathComponent] URLByDeletingLastPathComponent];
345 if (GetParentFSRef(macos_fsref, &contents_fsref)) { 352 if (bundle_url) {
346 FSRef bundle_fsref; 353 base::ScopedCFTypeRef<CFBundleRef> bundle(
347 if (GetParentFSRef(contents_fsref, &bundle_fsref)) { 354 CFBundleCreate(kCFAllocatorDefault, base::mac::NSToCFCast(bundle_url)));
348 base::ScopedCFTypeRef<CFURLRef> bundle_url( 355 good_bundle = CFBundleGetIdentifier(bundle) != NULL;
349 CFURLCreateFromFSRef(kCFAllocatorDefault, &bundle_fsref));
350 if (bundle_url.get()) {
351 base::ScopedCFTypeRef<CFBundleRef> bundle(
352 CFBundleCreate(kCFAllocatorDefault, bundle_url));
353 // Check to see if the bundle still has a minimal structure.
354 good_bundle = CFBundleGetIdentifier(bundle) != NULL;
355 }
356 }
357 }
358 } 356 }
357
359 if (!good_bundle) { 358 if (!good_bundle) {
360 needs_shutdown = true; 359 needs_shutdown = true;
361 } else { 360 } else {
362 Boolean in_trash; 361 bool in_trash = false;
363 OSErr err = FSDetermineIfRefIsEnclosedByFolder(kOnAppropriateDisk, 362 NSFileManager* file_manager = [NSFileManager defaultManager];
364 kTrashFolderType, 363 // Apple deprecated FSDetermineIfRefIsEnclosedByFolder() when deploying to
365 &executable_fsref_, 364 // 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.
366 &in_trash); 365 // the deprecated function while running on 10.9 (and delete the else block
367 if (err == noErr && in_trash) { 366 // when Chromium requires OS X 10.10+).
367 if ([file_manager respondsToSelector:@selector(getRelationship:
368 ofDirectory:
369 inDomain:
370 toItemAtURL:
371 error:)]) {
372 NSURLRelationship relationship;
373 if ([file_manager getRelationship:&relationship
374 ofDirectory:NSTrashDirectory
375 inDomain:0
376 toItemAtURL:executable_fsref_
377 error:nil]) {
378 in_trash = relationship == NSURLRelationshipContains;
379 }
380 } else {
381 DCHECK(base::mac::IsAtMostOS10_9());
382 Boolean fs_in_trash;
383 FSRef ref;
384 if (CFURLGetFSRef(base::mac::NSToCFCast(executable_fsref_.get()), &ref)) {
385 // 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.
386 // we stop supporting that.
387 #pragma clang diagnostic push
388 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
389 OSErr err = FSDetermineIfRefIsEnclosedByFolder(
390 kOnAppropriateDisk, kTrashFolderType, &ref, &fs_in_trash);
391 #pragma clang diagnostic pop
392 if (err == noErr && fs_in_trash)
393 in_trash = true;
394 }
395 }
396 if (in_trash) {
368 needs_shutdown = true; 397 needs_shutdown = true;
369 } else { 398 } else {
370 bool was_moved = true; 399 bool was_moved = true;
371 FSRef path_ref; 400 NSString* path_string = base::mac::FilePathToNSString(path);
372 if (base::mac::FSRefFromPath(path.value(), &path_ref)) { 401 NSURL* path_url = [NSURL fileURLWithPath:path_string isDirectory:NO];
373 if (FSCompareFSRefs(&path_ref, &executable_fsref_) == noErr) { 402 NSURL* path_ref = [path_url fileReferenceURL];
403 if (path_ref != nil) {
404 if ([path_ref isEqual:executable_fsref_]) {
374 was_moved = false; 405 was_moved = false;
375 } 406 }
376 } 407 }
377 if (was_moved) { 408 if (was_moved) {
378 needs_restart = true; 409 needs_restart = true;
379 } 410 }
380 } 411 }
381 } 412 }
382 if (needs_shutdown || needs_restart) { 413 if (needs_shutdown || needs_restart) {
383 // First deal with the plist. 414 // First deal with the plist.
384 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName()); 415 base::ScopedCFTypeRef<CFStringRef> name(CopyServiceProcessLaunchDName());
385 if (needs_restart) { 416 if (needs_restart) {
386 base::ScopedCFTypeRef<CFMutableDictionaryRef> plist( 417 base::ScopedCFTypeRef<CFMutableDictionaryRef> plist(
387 Launchd::GetInstance()->CreatePlistFromFile( 418 Launchd::GetInstance()->CreatePlistFromFile(
388 Launchd::User, Launchd::Agent, name)); 419 Launchd::User, Launchd::Agent, name));
389 if (plist.get()) { 420 if (plist.get()) {
390 NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist); 421 NSMutableDictionary* ns_plist = base::mac::CFToNSCast(plist);
391 std::string new_path = base::mac::PathFromFSRef(executable_fsref_); 422 NSURL* new_path = [executable_fsref_ filePathURL];
392 NSString* ns_new_path = base::SysUTF8ToNSString(new_path); 423 DCHECK([new_path isFileURL]);
424 NSString* ns_new_path = [new_path path];
393 [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM]; 425 [ns_plist setObject:ns_new_path forKey:@ LAUNCH_JOBKEY_PROGRAM];
394 base::scoped_nsobject<NSMutableArray> args([[ns_plist 426 base::scoped_nsobject<NSMutableArray> args([[ns_plist
395 objectForKey:@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]); 427 objectForKey:@LAUNCH_JOBKEY_PROGRAMARGUMENTS] mutableCopy]);
396 [args replaceObjectAtIndex:0 withObject:ns_new_path]; 428 [args replaceObjectAtIndex:0 withObject:ns_new_path];
397 [ns_plist setObject:args forKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS]; 429 [ns_plist setObject:args forKey:@ LAUNCH_JOBKEY_PROGRAMARGUMENTS];
398 if (!Launchd::GetInstance()->WritePlistToFile(Launchd::User, 430 if (!Launchd::GetInstance()->WritePlistToFile(Launchd::User,
399 Launchd::Agent, 431 Launchd::Agent,
400 name, 432 name,
401 plist)) { 433 plist)) {
402 DLOG(ERROR) << "Unable to rewrite plist."; 434 DLOG(ERROR) << "Unable to rewrite plist.";
(...skipping 27 matching lines...) Expand all
430 CFErrorRef err = NULL; 462 CFErrorRef err = NULL;
431 if (!Launchd::GetInstance()->RemoveJob(label, &err)) { 463 if (!Launchd::GetInstance()->RemoveJob(label, &err)) {
432 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err); 464 base::ScopedCFTypeRef<CFErrorRef> scoped_err(err);
433 DLOG(ERROR) << "RemoveJob " << err; 465 DLOG(ERROR) << "RemoveJob " << err;
434 // Exiting with zero, so launchd doesn't restart the process. 466 // Exiting with zero, so launchd doesn't restart the process.
435 exit(0); 467 exit(0);
436 } 468 }
437 } 469 }
438 } 470 }
439 } 471 }
OLDNEW
« no previous file with comments | « no previous file | chrome/common/service_process_util_mac_unittest.mm » ('j') | chrome/common/service_process_util_mac_unittest.mm » ('J')

Powered by Google App Engine
This is Rietveld 408576698