OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/common/chrome_application_mac.h" | 5 #import "content/common/chrome_application_mac.h" |
| 6 #import "content/common/cloud_print_class_mac.h" |
6 | 7 |
7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/mac/foundation_util.h" |
8 | 10 |
9 @interface CrApplication () | 11 @interface CrApplication () |
10 - (void)setHandlingSendEvent:(BOOL)handlingSendEvent; | 12 - (void)setHandlingSendEvent:(BOOL)handlingSendEvent; |
| 13 - (void)setCloudPrintHandlerInternal; |
| 14 - (void)submitPrint:(NSAppleEventDescriptor*)event; |
11 @end | 15 @end |
12 | 16 |
13 @implementation CrApplication | 17 @implementation CrApplication |
14 // Initialize NSApplication using the custom subclass. Check whether NSApp | 18 // Initialize NSApplication using the custom subclass. Check whether NSApp |
15 // was already initialized using another class, because that would break | 19 // was already initialized using another class, because that would break |
16 // some things. | 20 // some things. |
17 + (NSApplication*)sharedApplication { | 21 + (NSApplication*)sharedApplication { |
18 NSApplication* app = [super sharedApplication]; | 22 NSApplication* app = [super sharedApplication]; |
19 if (![NSApp isKindOfClass:self]) { | 23 if (![NSApp isKindOfClass:self]) { |
20 LOG(ERROR) << "NSApp should be of type " << [[self className] UTF8String] | 24 LOG(ERROR) << "NSApp should be of type " << [[self className] UTF8String] |
21 << ", not " << [[NSApp className] UTF8String]; | 25 << ", not " << [[NSApp className] UTF8String]; |
22 DCHECK(false) << "NSApp is of wrong type"; | 26 DCHECK(false) << "NSApp is of wrong type"; |
23 } | 27 } |
24 return app; | 28 return app; |
25 } | 29 } |
26 | 30 |
27 - (id)init { | 31 - (id)init { |
28 if ((self = [super init])) { | 32 if ((self = [super init])) { |
29 eventHooks_.reset([[NSMutableArray alloc] init]); | 33 eventHooks_.reset([[NSMutableArray alloc] init]); |
30 } | 34 } |
31 return self; | 35 return self; |
32 } | 36 } |
33 | 37 |
| 38 // Sets the Cloud Print Handler. Used only by service process. |
| 39 - (void)setCloudPrintHandlerInternal { |
| 40 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| 41 [em setEventHandler:self |
| 42 andSelector:@selector(submitPrint:) |
| 43 forEventClass:cloudPrintClass |
| 44 andEventID:cloudPrintClass]; |
| 45 } |
| 46 |
| 47 // Event handler for Cloud Print Event. Forwards print job recieved to Chrome, |
| 48 // launching Chrome if necessary. Used to beat CUPS sandboxing. |
| 49 - (void)submitPrint:(NSAppleEventDescriptor*)event { |
| 50 // TODO: Resolve dependency on flag. |
| 51 const char silent[] = "--no-startup-window"; |
| 52 // Set up flag so that it can be passed along with Apple Event. |
| 53 CFStringRef silentLaunchFlag = |
| 54 CFStringCreateWithCString(NULL,silent,kCFStringEncodingUTF8); |
| 55 CFStringRef flags[] = { silentLaunchFlag }; |
| 56 // Argv array that will be passed. |
| 57 CFArrayRef passArgv = |
| 58 CFArrayCreate(NULL, (const void**) flags, 1, &kCFTypeArrayCallBacks); |
| 59 FSRef ref; |
| 60 OSStatus status = noErr; |
| 61 CFURLRef* kDontWantURL = NULL; |
| 62 // Get Chrome's bundle ID. |
| 63 std::string bundleID = base::mac::BaseBundleID(); |
| 64 CFStringRef bundleIDCF = |
| 65 CFStringCreateWithCString(NULL, bundleID.c_str(), kCFStringEncodingUTF8); |
| 66 // Use Launch Services to locate Chrome using its bundleID. |
| 67 status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, |
| 68 NULL, &ref, kDontWantURL); |
| 69 |
| 70 if (status != noErr) { |
| 71 LOG(ERROR) << "Failed to make path ref"; |
| 72 LOG(ERROR) << GetMacOSStatusErrorString(status); |
| 73 LOG(ERROR) << GetMacOSStatusCommentString(status); |
| 74 } |
| 75 // Actually create the Apple Event. |
| 76 NSAppleEventDescriptor* sendEvent = [NSAppleEventDescriptor |
| 77 appleEventWithEventClass: |
| 78 cloudPrintClass |
| 79 eventID:cloudPrintClass |
| 80 targetDescriptor:nil |
| 81 returnID:kAutoGenerateReturnID |
| 82 transactionID:kAnyTransactionID]; |
| 83 // Pull the parameters out of AppleEvent sent to us and attach them |
| 84 // to our Apple Event. |
| 85 NSAppleEventDescriptor* parameters = |
| 86 [event paramDescriptorForKeyword:cloudPrintClass]; |
| 87 [sendEvent setParamDescriptor:parameters forKeyword:cloudPrintClass]; |
| 88 LSApplicationParameters params = { 0, |
| 89 kLSLaunchDefaults, |
| 90 &ref, |
| 91 NULL, |
| 92 NULL, |
| 93 passArgv, |
| 94 NULL }; |
| 95 params.initialEvent = (AppleEvent *) [sendEvent aeDesc]; |
| 96 // Send the Apple Event Using launch services, launching Chrome if necessary. |
| 97 status = LSOpenApplication(¶ms, NULL); |
| 98 |
| 99 if (status != noErr) { |
| 100 LOG(ERROR) << "Unable to launch"; |
| 101 LOG(ERROR) << GetMacOSStatusErrorString(status); |
| 102 LOG(ERROR) << GetMacOSStatusCommentString(status); |
| 103 } |
| 104 } |
| 105 |
| 106 |
34 - (BOOL)isHandlingSendEvent { | 107 - (BOOL)isHandlingSendEvent { |
35 return handlingSendEvent_; | 108 return handlingSendEvent_; |
36 } | 109 } |
37 | 110 |
38 - (void)setHandlingSendEvent:(BOOL)handlingSendEvent { | 111 - (void)setHandlingSendEvent:(BOOL)handlingSendEvent { |
39 handlingSendEvent_ = handlingSendEvent; | 112 handlingSendEvent_ = handlingSendEvent; |
40 } | 113 } |
41 | 114 |
42 - (void)clearIsHandlingSendEvent { | 115 - (void)clearIsHandlingSendEvent { |
43 [self setHandlingSendEvent:NO]; | 116 [self setHandlingSendEvent:NO]; |
(...skipping 11 matching lines...) Expand all Loading... |
55 [eventHooks_ addObject:handler]; | 128 [eventHooks_ addObject:handler]; |
56 } | 129 } |
57 | 130 |
58 - (void)removeEventHook:(id<CrApplicationEventHookProtocol>)handler { | 131 - (void)removeEventHook:(id<CrApplicationEventHookProtocol>)handler { |
59 [eventHooks_ removeObject:handler]; | 132 [eventHooks_ removeObject:handler]; |
60 } | 133 } |
61 | 134 |
62 @end | 135 @end |
63 | 136 |
64 namespace chrome_application_mac { | 137 namespace chrome_application_mac { |
| 138 CrApplication* var; |
65 | 139 |
66 ScopedSendingEvent::ScopedSendingEvent() | 140 ScopedSendingEvent::ScopedSendingEvent() |
67 : app_(static_cast<CrApplication*>([CrApplication sharedApplication])), | 141 : app_(static_cast<CrApplication*>([CrApplication sharedApplication])), |
68 handling_([app_ isHandlingSendEvent]) { | 142 handling_([app_ isHandlingSendEvent]) { |
69 [app_ setHandlingSendEvent:YES]; | 143 [app_ setHandlingSendEvent:YES]; |
70 } | 144 } |
71 | 145 |
72 ScopedSendingEvent::~ScopedSendingEvent() { | 146 ScopedSendingEvent::~ScopedSendingEvent() { |
73 [app_ setHandlingSendEvent:handling_]; | 147 [app_ setHandlingSendEvent:handling_]; |
74 } | 148 } |
75 | 149 |
76 void RegisterCrApp() { | 150 void RegisterCrApp() { |
77 [CrApplication sharedApplication]; | 151 var = (CrApplication*) [CrApplication sharedApplication]; |
78 } | 152 } |
79 | 153 |
| 154 void SetCloudPrintHandler() { |
| 155 [var setCloudPrintHandlerInternal]; |
| 156 } |
| 157 |
| 158 |
80 } // namespace chrome_application_mac | 159 } // namespace chrome_application_mac |
| 160 |
OLD | NEW |