| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "chrome/service/chrome_service_application_mac.h" |
| |
| #include "base/mac/foundation_util.h" |
| #include "base/mac/mac_logging.h" |
| #include "base/strings/sys_string_conversions.h" |
| #import "chrome/common/cloud_print/cloud_print_class_mac.h" |
| #include "chrome/common/chrome_switches.h" |
| |
| @interface ServiceEventHandler : NSObject |
| + (void)submitPrint:(NSAppleEventDescriptor*)event; |
| @end |
| |
| @implementation ServiceEventHandler |
| |
| // Event handler for Cloud Print Event. Forwards print job received to Chrome, |
| // launching Chrome if necessary. Used to beat CUPS sandboxing. |
| + (void)submitPrint:(NSAppleEventDescriptor*)event { |
| std::string silent = std::string("--") + switches::kNoStartupWindow; |
| // Set up flag so that it can be passed along with the Apple Event. |
| base::ScopedCFTypeRef<CFStringRef> silentLaunchFlag( |
| base::SysUTF8ToCFStringRef(silent)); |
| CFStringRef flags[] = { silentLaunchFlag }; |
| // Argv array that will be passed. |
| base::ScopedCFTypeRef<CFArrayRef> passArgv( |
| CFArrayCreate(NULL, (const void**)flags, 1, &kCFTypeArrayCallBacks)); |
| FSRef ref; |
| // Get Chrome's bundle ID. |
| std::string bundleID = base::mac::BaseBundleID(); |
| base::ScopedCFTypeRef<CFStringRef> bundleIDCF( |
| base::SysUTF8ToCFStringRef(bundleID)); |
| // Use Launch Services to locate Chrome using its bundleID. |
| OSStatus status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, |
| NULL, &ref, NULL); |
| |
| if (status != noErr) { |
| OSSTATUS_LOG(ERROR, status) << "Failed to make path ref"; |
| return; |
| } |
| // Actually create the Apple Event. |
| NSAppleEventDescriptor* sendEvent = |
| [NSAppleEventDescriptor |
| appleEventWithEventClass:cloud_print::kAECloudPrintClass |
| eventID:cloud_print::kAECloudPrintClass |
| targetDescriptor:nil |
| returnID:kAutoGenerateReturnID |
| transactionID:kAnyTransactionID]; |
| // Pull the parameters out of AppleEvent sent to us and attach them |
| // to our Apple Event. |
| NSAppleEventDescriptor* parameters = |
| [event paramDescriptorForKeyword:cloud_print::kAECloudPrintClass]; |
| [sendEvent setParamDescriptor:parameters |
| forKeyword:cloud_print::kAECloudPrintClass]; |
| LSApplicationParameters params = { 0, |
| kLSLaunchDefaults, |
| &ref, |
| NULL, |
| NULL, |
| passArgv, |
| NULL }; |
| AEDesc* initialEvent = const_cast<AEDesc*>([sendEvent aeDesc]); |
| params.initialEvent = static_cast<AppleEvent*>(initialEvent); |
| // Send the Apple Event Using launch services, launching Chrome if necessary. |
| status = LSOpenApplication(¶ms, NULL); |
| if (status != noErr) { |
| OSSTATUS_LOG(ERROR, status) << "Unable to launch"; |
| } |
| } |
| |
| @end |
| |
| namespace chrome_service_mac { |
| |
| void RegisterServiceEventHandler() { |
| NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| [em setEventHandler:[ServiceEventHandler class] |
| andSelector:@selector(submitPrint:) |
| forEventClass:cloud_print::kAECloudPrintClass |
| andEventID:cloud_print::kAECloudPrintClass]; |
| } |
| |
| } // namespace chrome_service_mac |