| 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 |