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