OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #include "base/mac_util.h" | 5 #include "base/mac_util.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/scoped_cftyperef.h" |
11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
12 #include "base/scoped_cftyperef.h" | |
13 #include "base/scoped_nsobject.h" | 13 #include "base/scoped_nsobject.h" |
14 #include "base/sys_string_conversions.h" | 14 #include "base/sys_string_conversions.h" |
15 | 15 |
| 16 using base::mac::ScopedCFTypeRef; |
| 17 |
16 namespace { | 18 namespace { |
17 | 19 |
18 // a count of currently outstanding requests for full screen mode from browser | 20 // a count of currently outstanding requests for full screen mode from browser |
19 // windows, plugins, etc. | 21 // windows, plugins, etc. |
20 int g_full_screen_requests[mac_util::kNumFullScreenModes] = { 0, 0, 0}; | 22 int g_full_screen_requests[mac_util::kNumFullScreenModes] = { 0, 0, 0}; |
21 | 23 |
22 // Sets the appropriate SystemUIMode based on the current full screen requests. | 24 // Sets the appropriate SystemUIMode based on the current full screen requests. |
23 // Since only one SystemUIMode can be active at a given time, full screen | 25 // Since only one SystemUIMode can be active at a given time, full screen |
24 // requests are ordered by priority. If there are no outstanding full screen | 26 // requests are ordered by priority. If there are no outstanding full screen |
25 // requests, reverts to normal mode. If the correct SystemUIMode is already | 27 // requests, reverts to normal mode. If the correct SystemUIMode is already |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 BOOL result = | 73 BOOL result = |
72 [[parent_info objectForKey:@"FileCreator"] isEqualToString:@"lgnw"]; | 74 [[parent_info objectForKey:@"FileCreator"] isEqualToString:@"lgnw"]; |
73 | 75 |
74 return result == YES; | 76 return result == YES; |
75 } | 77 } |
76 | 78 |
77 // Looks into Shared File Lists corresponding to Login Items for the item | 79 // Looks into Shared File Lists corresponding to Login Items for the item |
78 // representing the current application. If such an item is found, returns | 80 // representing the current application. If such an item is found, returns |
79 // retained reference to it. Caller is responsible for releasing the reference. | 81 // retained reference to it. Caller is responsible for releasing the reference. |
80 LSSharedFileListItemRef GetLoginItemForApp() { | 82 LSSharedFileListItemRef GetLoginItemForApp() { |
81 scoped_cftyperef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 83 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
82 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 84 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
83 | 85 |
84 if (!login_items.get()) { | 86 if (!login_items.get()) { |
85 LOG(ERROR) << "Couldn't get a Login Items list."; | 87 LOG(ERROR) << "Couldn't get a Login Items list."; |
86 return NULL; | 88 return NULL; |
87 } | 89 } |
88 | 90 |
89 scoped_nsobject<const NSArray> login_items_array( | 91 scoped_nsobject<const NSArray> login_items_array( |
90 reinterpret_cast<const NSArray*>( | 92 reinterpret_cast<const NSArray*>( |
91 LSSharedFileListCopySnapshot(login_items, NULL))); | 93 LSSharedFileListCopySnapshot(login_items, NULL))); |
92 | 94 |
93 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; | 95 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; |
94 | 96 |
95 for(NSUInteger i = 0; i < [login_items_array count]; ++i) { | 97 for(NSUInteger i = 0; i < [login_items_array count]; ++i) { |
96 LSSharedFileListItemRef item = reinterpret_cast<LSSharedFileListItemRef>( | 98 LSSharedFileListItemRef item = reinterpret_cast<LSSharedFileListItemRef>( |
97 [login_items_array objectAtIndex:i]); | 99 [login_items_array objectAtIndex:i]); |
98 CFURLRef item_url_ref = NULL; | 100 CFURLRef item_url_ref = NULL; |
99 | 101 |
100 if (LSSharedFileListItemResolve(item, 0, &item_url_ref, NULL) == noErr) { | 102 if (LSSharedFileListItemResolve(item, 0, &item_url_ref, NULL) == noErr) { |
101 scoped_cftyperef<CFURLRef> item_url(item_url_ref); | 103 ScopedCFTypeRef<CFURLRef> item_url(item_url_ref); |
102 if (CFEqual(item_url, url)) { | 104 if (CFEqual(item_url, url)) { |
103 CFRetain(item); | 105 CFRetain(item); |
104 return item; | 106 return item; |
105 } | 107 } |
106 } | 108 } |
107 } | 109 } |
108 | 110 |
109 return NULL; | 111 return NULL; |
110 } | 112 } |
111 | 113 |
112 #if !defined(MAC_OS_X_VERSION_10_6) || \ | 114 #if !defined(MAC_OS_X_VERSION_10_6) || \ |
113 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | 115 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 |
114 // kLSSharedFileListLoginItemHidden is supported on | 116 // kLSSharedFileListLoginItemHidden is supported on |
115 // 10.5, but missing from the 10.5 headers. | 117 // 10.5, but missing from the 10.5 headers. |
116 // http://openradar.appspot.com/6482251 | 118 // http://openradar.appspot.com/6482251 |
117 static NSString* kLSSharedFileListLoginItemHidden = | 119 static NSString* kLSSharedFileListLoginItemHidden = |
118 @"com.apple.loginitem.HideOnLaunch"; | 120 @"com.apple.loginitem.HideOnLaunch"; |
119 #endif | 121 #endif |
120 | 122 |
121 bool IsHiddenLoginItem(LSSharedFileListItemRef item) { | 123 bool IsHiddenLoginItem(LSSharedFileListItemRef item) { |
122 scoped_cftyperef<CFBooleanRef> hidden(reinterpret_cast<CFBooleanRef>( | 124 ScopedCFTypeRef<CFBooleanRef> hidden(reinterpret_cast<CFBooleanRef>( |
123 LSSharedFileListItemCopyProperty(item, | 125 LSSharedFileListItemCopyProperty(item, |
124 reinterpret_cast<CFStringRef>(kLSSharedFileListLoginItemHidden)))); | 126 reinterpret_cast<CFStringRef>(kLSSharedFileListLoginItemHidden)))); |
125 | 127 |
126 return hidden && hidden == kCFBooleanTrue; | 128 return hidden && hidden == kCFBooleanTrue; |
127 } | 129 } |
128 | 130 |
129 } // end namespace | 131 } // end namespace |
130 | 132 |
131 namespace mac_util { | 133 namespace mac_util { |
132 | 134 |
133 std::string PathFromFSRef(const FSRef& ref) { | 135 std::string PathFromFSRef(const FSRef& ref) { |
134 scoped_cftyperef<CFURLRef> url( | 136 ScopedCFTypeRef<CFURLRef> url( |
135 CFURLCreateFromFSRef(kCFAllocatorDefault, &ref)); | 137 CFURLCreateFromFSRef(kCFAllocatorDefault, &ref)); |
136 NSString *path_string = [(NSURL *)url.get() path]; | 138 NSString *path_string = [(NSURL *)url.get() path]; |
137 return [path_string fileSystemRepresentation]; | 139 return [path_string fileSystemRepresentation]; |
138 } | 140 } |
139 | 141 |
140 bool FSRefFromPath(const std::string& path, FSRef* ref) { | 142 bool FSRefFromPath(const std::string& path, FSRef* ref) { |
141 OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(), | 143 OSStatus status = FSPathMakeRef((const UInt8*)path.c_str(), |
142 ref, nil); | 144 ref, nil); |
143 return status == noErr; | 145 return status == noErr; |
144 } | 146 } |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 } | 450 } |
449 | 451 |
450 CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, | 452 CFTypeRef GetValueFromDictionary(CFDictionaryRef dict, |
451 CFStringRef key, | 453 CFStringRef key, |
452 CFTypeID expected_type) { | 454 CFTypeID expected_type) { |
453 CFTypeRef value = CFDictionaryGetValue(dict, key); | 455 CFTypeRef value = CFDictionaryGetValue(dict, key); |
454 if (!value) | 456 if (!value) |
455 return value; | 457 return value; |
456 | 458 |
457 if (CFGetTypeID(value) != expected_type) { | 459 if (CFGetTypeID(value) != expected_type) { |
458 scoped_cftyperef<CFStringRef> expected_type_ref( | 460 ScopedCFTypeRef<CFStringRef> expected_type_ref( |
459 CFCopyTypeIDDescription(expected_type)); | 461 CFCopyTypeIDDescription(expected_type)); |
460 scoped_cftyperef<CFStringRef> actual_type_ref( | 462 ScopedCFTypeRef<CFStringRef> actual_type_ref( |
461 CFCopyTypeIDDescription(CFGetTypeID(value))); | 463 CFCopyTypeIDDescription(CFGetTypeID(value))); |
462 LOG(WARNING) << "Expected value for key " | 464 LOG(WARNING) << "Expected value for key " |
463 << base::SysCFStringRefToUTF8(key) | 465 << base::SysCFStringRefToUTF8(key) |
464 << " to be " | 466 << " to be " |
465 << base::SysCFStringRefToUTF8(expected_type_ref) | 467 << base::SysCFStringRefToUTF8(expected_type_ref) |
466 << " but it was " | 468 << " but it was " |
467 << base::SysCFStringRefToUTF8(actual_type_ref) | 469 << base::SysCFStringRefToUTF8(actual_type_ref) |
468 << " instead"; | 470 << " instead"; |
469 return NULL; | 471 return NULL; |
470 } | 472 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 } | 564 } |
563 | 565 |
564 // Converts a NSImage to a CGImageRef. Normally, the system frameworks can do | 566 // Converts a NSImage to a CGImageRef. Normally, the system frameworks can do |
565 // this fine, especially on 10.6. On 10.5, however, CGImage cannot handle | 567 // this fine, especially on 10.6. On 10.5, however, CGImage cannot handle |
566 // converting a PDF-backed NSImage into a CGImageRef. This function will | 568 // converting a PDF-backed NSImage into a CGImageRef. This function will |
567 // rasterize the PDF into a bitmap CGImage. The caller is responsible for | 569 // rasterize the PDF into a bitmap CGImage. The caller is responsible for |
568 // releasing the return value. | 570 // releasing the return value. |
569 CGImageRef CopyNSImageToCGImage(NSImage* image) { | 571 CGImageRef CopyNSImageToCGImage(NSImage* image) { |
570 // This is based loosely on http://www.cocoadev.com/index.pl?CGImageRef . | 572 // This is based loosely on http://www.cocoadev.com/index.pl?CGImageRef . |
571 NSSize size = [image size]; | 573 NSSize size = [image size]; |
572 scoped_cftyperef<CGContextRef> context( | 574 ScopedCFTypeRef<CGContextRef> context( |
573 CGBitmapContextCreate(NULL, // Allow CG to allocate memory. | 575 CGBitmapContextCreate(NULL, // Allow CG to allocate memory. |
574 size.width, | 576 size.width, |
575 size.height, | 577 size.height, |
576 8, // bitsPerComponent | 578 8, // bitsPerComponent |
577 0, // bytesPerRow - CG will calculate by default. | 579 0, // bytesPerRow - CG will calculate by default. |
578 [[NSColorSpace genericRGBColorSpace] CGColorSpace], | 580 [[NSColorSpace genericRGBColorSpace] CGColorSpace], |
579 kCGBitmapByteOrder32Host | | 581 kCGBitmapByteOrder32Host | |
580 kCGImageAlphaPremultipliedFirst)); | 582 kCGImageAlphaPremultipliedFirst)); |
581 if (!context.get()) | 583 if (!context.get()) |
582 return NULL; | 584 return NULL; |
583 | 585 |
584 [NSGraphicsContext saveGraphicsState]; | 586 [NSGraphicsContext saveGraphicsState]; |
585 [NSGraphicsContext setCurrentContext: | 587 [NSGraphicsContext setCurrentContext: |
586 [NSGraphicsContext graphicsContextWithGraphicsPort:context.get() | 588 [NSGraphicsContext graphicsContextWithGraphicsPort:context.get() |
587 flipped:NO]]; | 589 flipped:NO]]; |
588 [image drawInRect:NSMakeRect(0,0, size.width, size.height) | 590 [image drawInRect:NSMakeRect(0,0, size.width, size.height) |
589 fromRect:NSZeroRect | 591 fromRect:NSZeroRect |
590 operation:NSCompositeCopy | 592 operation:NSCompositeCopy |
591 fraction:1.0]; | 593 fraction:1.0]; |
592 [NSGraphicsContext restoreGraphicsState]; | 594 [NSGraphicsContext restoreGraphicsState]; |
593 | 595 |
594 return CGBitmapContextCreateImage(context); | 596 return CGBitmapContextCreateImage(context); |
595 } | 597 } |
596 | 598 |
597 bool CheckLoginItemStatus(bool* is_hidden) { | 599 bool CheckLoginItemStatus(bool* is_hidden) { |
598 scoped_cftyperef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 600 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
599 if (!item.get()) | 601 if (!item.get()) |
600 return false; | 602 return false; |
601 | 603 |
602 if (is_hidden) | 604 if (is_hidden) |
603 *is_hidden = IsHiddenLoginItem(item); | 605 *is_hidden = IsHiddenLoginItem(item); |
604 | 606 |
605 return true; | 607 return true; |
606 } | 608 } |
607 | 609 |
608 void AddToLoginItems(bool hide_on_startup) { | 610 void AddToLoginItems(bool hide_on_startup) { |
609 scoped_cftyperef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 611 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
610 if (item.get() && (IsHiddenLoginItem(item) == hide_on_startup)) { | 612 if (item.get() && (IsHiddenLoginItem(item) == hide_on_startup)) { |
611 return; // Already is a login item with required hide flag. | 613 return; // Already is a login item with required hide flag. |
612 } | 614 } |
613 | 615 |
614 scoped_cftyperef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 616 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
615 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 617 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
616 | 618 |
617 if (!login_items.get()) { | 619 if (!login_items.get()) { |
618 LOG(ERROR) << "Couldn't get a Login Items list."; | 620 LOG(ERROR) << "Couldn't get a Login Items list."; |
619 return; | 621 return; |
620 } | 622 } |
621 | 623 |
622 // Remove the old item, it has wrong hide flag, we'll create a new one. | 624 // Remove the old item, it has wrong hide flag, we'll create a new one. |
623 if (item.get()) { | 625 if (item.get()) { |
624 LSSharedFileListItemRemove(login_items, item); | 626 LSSharedFileListItemRemove(login_items, item); |
625 } | 627 } |
626 | 628 |
627 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; | 629 NSURL* url = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]; |
628 | 630 |
629 BOOL hide = hide_on_startup ? YES : NO; | 631 BOOL hide = hide_on_startup ? YES : NO; |
630 NSDictionary* properties = | 632 NSDictionary* properties = |
631 [NSDictionary | 633 [NSDictionary |
632 dictionaryWithObject:[NSNumber numberWithBool:hide] | 634 dictionaryWithObject:[NSNumber numberWithBool:hide] |
633 forKey:(NSString*)kLSSharedFileListLoginItemHidden]; | 635 forKey:(NSString*)kLSSharedFileListLoginItemHidden]; |
634 | 636 |
635 scoped_cftyperef<LSSharedFileListItemRef> new_item; | 637 ScopedCFTypeRef<LSSharedFileListItemRef> new_item; |
636 new_item.reset(LSSharedFileListInsertItemURL( | 638 new_item.reset(LSSharedFileListInsertItemURL( |
637 login_items, kLSSharedFileListItemLast, NULL, NULL, | 639 login_items, kLSSharedFileListItemLast, NULL, NULL, |
638 reinterpret_cast<CFURLRef>(url), | 640 reinterpret_cast<CFURLRef>(url), |
639 reinterpret_cast<CFDictionaryRef>(properties), NULL)); | 641 reinterpret_cast<CFDictionaryRef>(properties), NULL)); |
640 | 642 |
641 if (!new_item.get()) { | 643 if (!new_item.get()) { |
642 LOG(ERROR) << "Couldn't insert current app into Login Items list."; | 644 LOG(ERROR) << "Couldn't insert current app into Login Items list."; |
643 } | 645 } |
644 } | 646 } |
645 | 647 |
646 void RemoveFromLoginItems() { | 648 void RemoveFromLoginItems() { |
647 scoped_cftyperef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 649 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
648 if (!item.get()) | 650 if (!item.get()) |
649 return; | 651 return; |
650 | 652 |
651 scoped_cftyperef<LSSharedFileListRef> login_items(LSSharedFileListCreate( | 653 ScopedCFTypeRef<LSSharedFileListRef> login_items(LSSharedFileListCreate( |
652 NULL, kLSSharedFileListSessionLoginItems, NULL)); | 654 NULL, kLSSharedFileListSessionLoginItems, NULL)); |
653 | 655 |
654 if (!login_items.get()) { | 656 if (!login_items.get()) { |
655 LOG(ERROR) << "Couldn't get a Login Items list."; | 657 LOG(ERROR) << "Couldn't get a Login Items list."; |
656 return; | 658 return; |
657 } | 659 } |
658 | 660 |
659 LSSharedFileListItemRemove(login_items, item); | 661 LSSharedFileListItemRemove(login_items, item); |
660 } | 662 } |
661 | 663 |
662 bool WasLaunchedAsHiddenLoginItem() { | 664 bool WasLaunchedAsHiddenLoginItem() { |
663 if (!WasLaunchedAsLoginItem()) | 665 if (!WasLaunchedAsLoginItem()) |
664 return false; | 666 return false; |
665 | 667 |
666 scoped_cftyperef<LSSharedFileListItemRef> item(GetLoginItemForApp()); | 668 ScopedCFTypeRef<LSSharedFileListItemRef> item(GetLoginItemForApp()); |
667 if (!item.get()) { | 669 if (!item.get()) { |
668 LOG(ERROR) << "Process launched at Login but can't access Login Item List."; | 670 LOG(ERROR) << "Process launched at Login but can't access Login Item List."; |
669 return false; | 671 return false; |
670 } | 672 } |
671 return IsHiddenLoginItem(item); | 673 return IsHiddenLoginItem(item); |
672 } | 674 } |
673 | 675 |
674 void NSObjectRetain(void* obj) { | 676 void NSObjectRetain(void* obj) { |
675 id<NSObject> nsobj = static_cast<id<NSObject> >(obj); | 677 id<NSObject> nsobj = static_cast<id<NSObject> >(obj); |
676 [nsobj retain]; | 678 [nsobj retain]; |
677 } | 679 } |
678 | 680 |
679 void NSObjectRelease(void* obj) { | 681 void NSObjectRelease(void* obj) { |
680 id<NSObject> nsobj = static_cast<id<NSObject> >(obj); | 682 id<NSObject> nsobj = static_cast<id<NSObject> >(obj); |
681 [nsobj release]; | 683 [nsobj release]; |
682 } | 684 } |
683 | 685 |
684 } // namespace mac_util | 686 } // namespace mac_util |
OLD | NEW |