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 3// found in the LICENSE file. 4 5#import "chrome/service/chrome_service_application_mac.h" 6 7#include "base/mac/foundation_util.h" 8#include "base/mac/mac_logging.h" 9#include "base/strings/sys_string_conversions.h" 10#import "chrome/common/cloud_print/cloud_print_class_mac.h" 11#include "chrome/common/chrome_switches.h" 12 13@interface ServiceEventHandler : NSObject 14+ (void)submitPrint:(NSAppleEventDescriptor*)event; 15@end 16 17@implementation ServiceEventHandler 18 19// Event handler for Cloud Print Event. Forwards print job received to Chrome, 20// launching Chrome if necessary. Used to beat CUPS sandboxing. 21+ (void)submitPrint:(NSAppleEventDescriptor*)event { 22 std::string silent = std::string("--") + switches::kNoStartupWindow; 23 // Set up flag so that it can be passed along with the Apple Event. 24 base::ScopedCFTypeRef<CFStringRef> silentLaunchFlag( 25 base::SysUTF8ToCFStringRef(silent)); 26 CFStringRef flags[] = { silentLaunchFlag }; 27 // Argv array that will be passed. 28 base::ScopedCFTypeRef<CFArrayRef> passArgv( 29 CFArrayCreate(NULL, (const void**)flags, 1, &kCFTypeArrayCallBacks)); 30 FSRef ref; 31 // Get Chrome's bundle ID. 32 std::string bundleID = base::mac::BaseBundleID(); 33 base::ScopedCFTypeRef<CFStringRef> bundleIDCF( 34 base::SysUTF8ToCFStringRef(bundleID)); 35 // Use Launch Services to locate Chrome using its bundleID. 36 OSStatus status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, 37 NULL, &ref, NULL); 38 39 if (status != noErr) { 40 OSSTATUS_LOG(ERROR, status) << "Failed to make path ref"; 41 return; 42 } 43 // Actually create the Apple Event. 44 NSAppleEventDescriptor* sendEvent = 45 [NSAppleEventDescriptor 46 appleEventWithEventClass:cloud_print::kAECloudPrintClass 47 eventID:cloud_print::kAECloudPrintClass 48 targetDescriptor:nil 49 returnID:kAutoGenerateReturnID 50 transactionID:kAnyTransactionID]; 51 // Pull the parameters out of AppleEvent sent to us and attach them 52 // to our Apple Event. 53 NSAppleEventDescriptor* parameters = 54 [event paramDescriptorForKeyword:cloud_print::kAECloudPrintClass]; 55 [sendEvent setParamDescriptor:parameters 56 forKeyword:cloud_print::kAECloudPrintClass]; 57 LSApplicationParameters params = { 0, 58 kLSLaunchDefaults, 59 &ref, 60 NULL, 61 NULL, 62 passArgv, 63 NULL }; 64 AEDesc* initialEvent = const_cast<AEDesc*>([sendEvent aeDesc]); 65 params.initialEvent = static_cast<AppleEvent*>(initialEvent); 66 // Send the Apple Event Using launch services, launching Chrome if necessary. 67 status = LSOpenApplication(¶ms, NULL); 68 if (status != noErr) { 69 OSSTATUS_LOG(ERROR, status) << "Unable to launch"; 70 } 71} 72 73@end 74 75namespace chrome_service_mac { 76 77void RegisterServiceEventHandler() { 78 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; 79 [em setEventHandler:[ServiceEventHandler class] 80 andSelector:@selector(submitPrint:) 81 forEventClass:cloud_print::kAECloudPrintClass 82 andEventID:cloud_print::kAECloudPrintClass]; 83} 84 85} // namespace chrome_service_mac 86