diff options
author | abeera@google.com <abeera@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-15 20:56:17 +0000 |
---|---|---|
committer | abeera@google.com <abeera@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-15 20:56:17 +0000 |
commit | a529af57f7b475e18cb878712c42c95c7c82e56b (patch) | |
tree | ea36e92433fecae3a8febb0635b4c8112a5a2ca3 | |
parent | 3ef7fb0d42affe262ab8cc3637a9982c65a59335 (diff) | |
download | chromium_src-a529af57f7b475e18cb878712c42c95c7c82e56b.zip chromium_src-a529af57f7b475e18cb878712c42c95c7c82e56b.tar.gz chromium_src-a529af57f7b475e18cb878712c42c95c7c82e56b.tar.bz2 |
Virtual Cloud Print Driver for Mac.
Includes code for the driver itself. Also modifies the browser process as well as service process to register Apple Event handlers. Also changes the service process to allow registration of driver.
BUG=
TEST=
Review URL: http://codereview.chromium.org/7485011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96825 0039d316-1c4b-4281-b951-d872f2087c98
26 files changed, 641 insertions, 22 deletions
diff --git a/build/all.gyp b/build/all.gyp index db36aba..d93347c 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -65,6 +65,7 @@ ['OS=="mac" or OS=="linux"', { 'dependencies': [ '../third_party/yasm/yasm.gyp:*#host', + '../cloud_print/virtual_driver/virtual_driver_posix.gyp:*', ], }], ['OS=="mac" or OS=="win"', { @@ -83,7 +84,6 @@ '../courgette/courgette.gyp:*', '../dbus/dbus.gyp:*', '../sandbox/sandbox.gyp:*', - '../cloud_print/virtual_driver/virtual_driver_linux.gyp:*', ], 'conditions': [ ['branding=="Chrome"', { diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 032f72d..f4d8f22 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -21,8 +21,11 @@ #include "chrome/browser/download/download_manager.h" #include "chrome/browser/instant/instant_confirm_dialog.h" #include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/printing/cloud_print/virtual_driver_install_helper.h" +#include "chrome/browser/printing/print_dialog_cloud.h" #include "chrome/browser/printing/print_job_manager.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/service/service_process_control.h" #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/tab_restore_service.h" @@ -51,10 +54,12 @@ #include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" +#include "chrome/common/service_messages.h" #include "chrome/common/url_constants.h" #include "content/browser/browser_thread.h" #include "content/browser/tab_contents/tab_contents.h" #include "content/browser/user_metrics.h" +#include "content/common/cloud_print_class_mac.h" #include "content/common/content_notification_types.h" #include "content/common/notification_service.h" #include "grit/chromium_strings.h" @@ -154,6 +159,9 @@ void RecordLastRunAppBundlePath() { } // anonymous namespace +const AEEventClass kAECloudPrintInstallClass = 'GCPi'; +const AEEventClass kAECloudPrintUninstallClass = 'GCPu'; + @interface AppController (Private) - (void)initMenuState; - (void)initProfileMenu; @@ -162,6 +170,9 @@ void RecordLastRunAppBundlePath() { - (void)openUrls:(const std::vector<GURL>&)urls; - (void)getUrl:(NSAppleEventDescriptor*)event withReply:(NSAppleEventDescriptor*)reply; +- (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event; +- (void)installCloudPrint:(NSAppleEventDescriptor*)event; +- (void)uninstallCloudPrint:(NSAppleEventDescriptor*)event; - (void)windowLayeringDidChange:(NSNotification*)inNotification; - (void)windowChangedToProfile:(Profile*)profile; - (void)checkForAnyKeyWindows; @@ -185,6 +196,19 @@ void RecordLastRunAppBundlePath() { forEventClass:kInternetEventClass andEventID:kAEGetURL]; [em setEventHandler:self + andSelector:@selector(submitCloudPrintJob:) + forEventClass:content::kAECloudPrintClass + andEventID:content::kAECloudPrintClass]; + // Install and uninstall handlers for virtual drivers. + [em setEventHandler:self + andSelector:@selector(installCloudPrint:) + forEventClass:kAECloudPrintInstallClass + andEventID:kAECloudPrintInstallClass]; + [em setEventHandler:self + andSelector:@selector(uninstallCloudPrint:) + forEventClass:kAECloudPrintUninstallClass + andEventID:kAECloudPrintUninstallClass]; + [em setEventHandler:self andSelector:@selector(getUrl:withReply:) forEventClass:'WWW!' // A particularly ancient AppleEvent that dates andEventID:'OURL']; // back to the Spyglass days. @@ -1071,6 +1095,38 @@ void RecordLastRunAppBundlePath() { [self openUrls:gurlVector]; } +// Apple Event handler that receives print event from service +// process, gets the required data and launches Print dialog. +- (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event { + // Pull parameter list out of Apple Event. + NSAppleEventDescriptor *paramList = + [event paramDescriptorForKeyword:content::kAECloudPrintClass]; + + if (paramList != nil) { + // Pull required fields out of parameter list. + NSString* mime = [[paramList descriptorAtIndex:1] stringValue]; + NSString* inputPath = [[paramList descriptorAtIndex:2] stringValue]; + NSString* printTitle = [[paramList descriptorAtIndex:3] stringValue]; + // Convert the title to UTF 16 as required. + string16 title16 = base::SysNSStringToUTF16(printTitle); + print_dialog_cloud::CreatePrintDialogForFile( + FilePath([inputPath UTF8String]), title16, + [mime UTF8String], /*modal=*/false); + } +} + +// Calls the helper class to install the virtual driver to the +// service process. +- (void)installCloudPrint:(NSAppleEventDescriptor*)event { + cloud_print::VirtualDriverInstallHelper::SetUpInstall(); +} + +// Calls the helper class to uninstall the virtual driver to the +// service process. +- (void)uninstallCloudPrint:(NSAppleEventDescriptor*)event { + cloud_print::VirtualDriverInstallHelper::SetUpUninstall(); +} + - (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames { std::vector<GURL> gurlVector; diff --git a/chrome/browser/printing/cloud_print/virtual_driver_install_helper.cc b/chrome/browser/printing/cloud_print/virtual_driver_install_helper.cc new file mode 100644 index 0000000..58d79a4 --- /dev/null +++ b/chrome/browser/printing/cloud_print/virtual_driver_install_helper.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2011 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. + +#include "chrome/browser/printing/cloud_print/virtual_driver_install_helper.h" +#include "chrome/browser/service/service_process_control.h" +#include "chrome/common/service_messages.h" + +namespace cloud_print { + +void VirtualDriverInstallHelper::SetUpInstall() { + scoped_refptr<VirtualDriverInstallHelper> help = + new VirtualDriverInstallHelper(); + ServiceProcessControl::GetInstance()->Launch( + NewRunnableMethod( + help.get(), &VirtualDriverInstallHelper::InstallVirtualDriverTask), + NULL); +} + +void VirtualDriverInstallHelper::SetUpUninstall() { + scoped_refptr<VirtualDriverInstallHelper> help = + new VirtualDriverInstallHelper(); + ServiceProcessControl::GetInstance()->Launch( + NewRunnableMethod( + help.get(), &VirtualDriverInstallHelper::UninstallVirtualDriverTask), + NULL); +} + +void VirtualDriverInstallHelper::InstallVirtualDriverTask() { + ServiceProcessControl* process_control = + ServiceProcessControl::GetInstance(); + DCHECK(process_control->is_connected()); + process_control->Send(new ServiceMsg_EnableVirtualDriver()); +} + +void VirtualDriverInstallHelper::UninstallVirtualDriverTask() { + ServiceProcessControl* process_control = + ServiceProcessControl::GetInstance(); + DCHECK(process_control->is_connected()); + process_control->Send(new ServiceMsg_DisableVirtualDriver()); +} + +} // namespace cloud_print + diff --git a/chrome/browser/printing/cloud_print/virtual_driver_install_helper.h b/chrome/browser/printing/cloud_print/virtual_driver_install_helper.h new file mode 100644 index 0000000..ff5c845 --- /dev/null +++ b/chrome/browser/printing/cloud_print/virtual_driver_install_helper.h @@ -0,0 +1,34 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_BROWSER_PRINTING_CLOUD_PRINT_VIRTUAL_DRIVER_INSTALL_HELPER_H_ +#define CHROME_BROWSER_PRINTING_CLOUD_PRINT_VIRTUAL_DRIVER_INSTALL_HELPER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/observer_list.h" + +namespace cloud_print { + +// Helper class to register the Cloud Print Driver with the service process. +class VirtualDriverInstallHelper + : public base::RefCountedThreadSafe<VirtualDriverInstallHelper> { + public: + // Uses ServiceProcessControl to asynchronously get an instance + // of the Service Process, launching it if necessary, and register + // either InstallVirtualDriverTask or UninstallVirtualDriverTask as the + // Task to be called once we have an instance of the ServiceProcess. + static void SetUpInstall(); + static void SetUpUninstall(); + + private: + void InstallVirtualDriverTask(); + void UninstallVirtualDriverTask(); +}; + +} // namespace cloud_print + +#endif // CHROME_BROWSER_PRINTING_CLOUD_PRINT_VIRTUAL_DRIVER_INSTALL_HELPER_H_ + diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 2144b22..a535e7b 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -827,6 +827,8 @@ '../third_party/libjingle/libjingle.gyp:libjingle', ], 'sources': [ + 'service/chrome_service_application_mac.h', + 'service/chrome_service_application_mac.mm', 'service/service_child_process_host.cc', 'service/service_child_process_host.h', 'service/service_ipc_server.cc', diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c9da2d0..6fcb805 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1817,6 +1817,8 @@ 'browser/printing/cloud_print/cloud_print_setup_source.h', 'browser/printing/cloud_print/cloud_print_url.cc', 'browser/printing/cloud_print/cloud_print_url.h', + 'browser/printing/cloud_print/virtual_driver_install_helper.cc', + 'browser/printing/cloud_print/virtual_driver_install_helper.h', 'browser/printing/print_dialog_cloud.cc', 'browser/printing/print_dialog_cloud.h', 'browser/printing/print_dialog_gtk.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 337c9ca..ca6a2dc 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1402,6 +1402,8 @@ const char kCloudPrintPrintSystemSettings[] = const char kCloudPrintEnableJobPoll[] = "cloud_print.enable_job_poll"; const char kCloudPrintRobotRefreshToken[] = "cloud_print.robot_refresh_token"; const char kCloudPrintRobotEmail[] = "cloud_print.robot_email"; +// Indicates whether the Mac Virtual driver is enabled. +const char kVirtualPrinterDriverEnabled[] = "cloud_print.enable_virtual_driver"; // Preference to store proxy settings. const char kProxy[] = "proxy"; @@ -1473,4 +1475,5 @@ const char kCustomHandlersEnabled[] = "custom_handlers.enabled"; // by the cloud policy subsystem. const char kDevicePolicyRefreshRate[] = "policy.device_refresh_rate"; const char kUserPolicyRefreshRate[] = "policy.user_refresh_rate"; + } // namespace prefs diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e665c5d..829f81b 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -481,6 +481,7 @@ extern const char kCloudPrintPrintSystemSettings[]; extern const char kCloudPrintEnableJobPoll[]; extern const char kCloudPrintRobotRefreshToken[]; extern const char kCloudPrintRobotEmail[]; +extern const char kVirtualPrinterDriverEnabled[]; extern const char kProxy[]; extern const char kMaxConnectionsPerProxy[]; @@ -536,6 +537,7 @@ extern const char kBackgroundModeEnabled[]; extern const char kDevicePolicyRefreshRate[]; extern const char kUserPolicyRefreshRate[]; + } // namespace prefs #endif // CHROME_COMMON_PREF_NAMES_H_ diff --git a/chrome/common/service_messages.h b/chrome/common/service_messages.h index 68f208a..71ac096 100644 --- a/chrome/common/service_messages.h +++ b/chrome/common/service_messages.h @@ -45,6 +45,12 @@ IPC_MESSAGE_CONTROL0(ServiceMsg_Shutdown) // Tell the service process that an update is available. IPC_MESSAGE_CONTROL0(ServiceMsg_UpdateAvailable) +// Tell the service process to enable the Mac Virtual driver. +IPC_MESSAGE_CONTROL0(ServiceMsg_EnableVirtualDriver) + +// Tell the service process to disable the Mac Virtual driver. +IPC_MESSAGE_CONTROL0(ServiceMsg_DisableVirtualDriver) + //----------------------------------------------------------------------------- // Service process host messages: // These are messages from the service process to the browser. diff --git a/chrome/service/chrome_service_application_mac.h b/chrome/service/chrome_service_application_mac.h new file mode 100644 index 0000000..554a19f --- /dev/null +++ b/chrome/service/chrome_service_application_mac.h @@ -0,0 +1,27 @@ +// Copyright (c) 2011 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. + +#ifndef CHROME_SERVICE_CHROME_SERVICE_APPLICATION_MAC_H_ +#define CHROME_SERVICE_CHROME_SERVICE_APPLICATION_MAC_H_ +#pragma once + +#ifdef __OBJC__ + +#import "content/common/chrome_application_mac.h" + +// Top level Mac Application for the service process. +@interface ServiceCrApplication : CrApplication + +@end + +#endif // __OBJC__ + +namespace chrome_service_application_mac { + +// To be used to instantiate ServiceCrApplication from C++ code. +void RegisterServiceCrApp(); +} // namespace chrome_service_application_mac + +#endif // CHROME_SERVICE_CHROME_SERVICE_APPLICATION_MAC_H_ + diff --git a/chrome/service/chrome_service_application_mac.mm b/chrome/service/chrome_service_application_mac.mm new file mode 100644 index 0000000..e7815e9 --- /dev/null +++ b/chrome/service/chrome_service_application_mac.mm @@ -0,0 +1,101 @@ +// Copyright (c) 2011 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/logging.h" +#include "base/mac/foundation_util.h" +#import "content/common/cloud_print_class_mac.h" +#include "chrome/common/chrome_switches.h" + +@interface ServiceCrApplication () +- (void)setCloudPrintHandler; +- (void)submitPrint:(NSAppleEventDescriptor*)event; +@end + +@implementation ServiceCrApplication + +-(void)setCloudPrintHandler { + NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; + [em setEventHandler:self + andSelector:@selector(submitPrint:) + forEventClass:content::kAECloudPrintClass + andEventID:content::kAECloudPrintClass]; +} + +// 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. + CFStringRef silentLaunchFlag = + CFStringCreateWithCString(NULL, silent.c_str(), kCFStringEncodingUTF8); + CFStringRef flags[] = { silentLaunchFlag }; + // Argv array that will be passed. + CFArrayRef passArgv = + CFArrayCreate(NULL, (const void**) flags, 1, &kCFTypeArrayCallBacks); + FSRef ref; + OSStatus status = noErr; + CFURLRef* kDontWantURL = NULL; + // Get Chrome's bundle ID. + std::string bundleID = base::mac::BaseBundleID(); + CFStringRef bundleIDCF = + CFStringCreateWithCString(NULL, bundleID.c_str(), kCFStringEncodingUTF8); + // Use Launch Services to locate Chrome using its bundleID. + status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, + NULL, &ref, kDontWantURL); + + if (status != noErr) { + LOG(ERROR) << "Failed to make path ref"; + LOG(ERROR) << GetMacOSStatusErrorString(status); + LOG(ERROR) << GetMacOSStatusCommentString(status); + return; + } + // Actually create the Apple Event. + NSAppleEventDescriptor* sendEvent = + [NSAppleEventDescriptor + appleEventWithEventClass:content::kAECloudPrintClass + eventID:content::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:content::kAECloudPrintClass]; + [sendEvent setParamDescriptor:parameters + forKeyword:content::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) { + LOG(ERROR) << "Unable to launch"; + LOG(ERROR) << GetMacOSStatusErrorString(status); + LOG(ERROR) << GetMacOSStatusCommentString(status); + } +} + + +@end + + +namespace chrome_service_application_mac { + +void RegisterServiceCrApp() { + ServiceCrApplication* var = + static_cast<ServiceCrApplication*> + ([ServiceCrApplication sharedApplication]); + [var setCloudPrintHandler]; +} + +} // namespace chrome_service_application_mac + diff --git a/chrome/service/service_ipc_server.cc b/chrome/service/service_ipc_server.cc index b3582a2..01b5deb 100644 --- a/chrome/service/service_ipc_server.cc +++ b/chrome/service/service_ipc_server.cc @@ -109,6 +109,10 @@ bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) { OnGetCloudPrintProxyInfo) IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown); IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable); + IPC_MESSAGE_HANDLER(ServiceMsg_EnableVirtualDriver, + OnEnableVirtualDriver); + IPC_MESSAGE_HANDLER(ServiceMsg_DisableVirtualDriver, + OnDisableVirtualDriver); IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -145,3 +149,12 @@ void ServiceIPCServer::OnShutdown() { void ServiceIPCServer::OnUpdateAvailable() { g_service_process->SetUpdateAvailable(); } + +void ServiceIPCServer::OnEnableVirtualDriver() { + g_service_process->EnableVirtualPrintDriver(); +} + +void ServiceIPCServer::OnDisableVirtualDriver() { + g_service_process->DisableVirtualPrintDriver(); +} + diff --git a/chrome/service/service_ipc_server.h b/chrome/service/service_ipc_server.h index eeb1f74..ed1613f 100644 --- a/chrome/service/service_ipc_server.h +++ b/chrome/service/service_ipc_server.h @@ -48,6 +48,8 @@ class ServiceIPCServer : public IPC::Channel::Listener, const std::string& user_email); void OnGetCloudPrintProxyInfo(); void OnDisableCloudPrintProxy(); + void OnEnableVirtualDriver(); + void OnDisableVirtualDriver(); void OnShutdown(); void OnUpdateAvailable(); diff --git a/chrome/service/service_main.cc b/chrome/service/service_main.cc index 9242c17..bd5e66f 100644 --- a/chrome/service/service_main.cc +++ b/chrome/service/service_main.cc @@ -12,7 +12,7 @@ #if defined(OS_WIN) #include "content/common/sandbox_policy.h" #elif defined(OS_MACOSX) -#include "content/common/chrome_application_mac.h" +#include "chrome/service/chrome_service_application_mac.h" #endif // defined(OS_WIN) // Mainline routine for running as the service process. @@ -27,7 +27,7 @@ int ServiceProcessMain(const MainFunctionParams& parameters) { << parameters.command_line_.GetCommandLineString(); #if defined(OS_MACOSX) - chrome_application_mac::RegisterCrApp(); + chrome_service_application_mac::RegisterServiceCrApp(); #endif base::PlatformThread::SetName("CrServiceMain"); diff --git a/chrome/service/service_process.cc b/chrome/service/service_process.cc index e5e0494..8fc8e95 100644 --- a/chrome/service/service_process.cc +++ b/chrome/service/service_process.cc @@ -192,6 +192,16 @@ bool ServiceProcess::Initialize(MessageLoopForUI* message_loop, if (cloud_print_proxy_enabled) { GetCloudPrintProxy()->EnableForUser(lsid); } + // Enable Virtual Printer Driver if needed. + bool virtual_printer_driver_enabled = false; + service_prefs_->GetBoolean(prefs::kVirtualPrinterDriverEnabled, + &virtual_printer_driver_enabled); + + if (virtual_printer_driver_enabled) { + // Register the fact that there is at least one + // service needing the process. + OnServiceEnabled(); + } VLOG(1) << "Starting Service Process IPC Server"; ipc_server_.reset(new ServiceIPCServer( @@ -272,6 +282,20 @@ void ServiceProcess::OnCloudPrintProxyDisabled(bool persist_state) { OnServiceDisabled(); } +void ServiceProcess::EnableVirtualPrintDriver() { + OnServiceEnabled(); + // Save the preference that we have enabled the virtual driver. + service_prefs_->SetBoolean(prefs::kVirtualPrinterDriverEnabled, true); + service_prefs_->WritePrefs(); +} + +void ServiceProcess::DisableVirtualPrintDriver() { + OnServiceDisabled(); + // Save the preference that we have disabled the virtual driver. + service_prefs_->SetBoolean(prefs::kVirtualPrinterDriverEnabled, false); + service_prefs_->WritePrefs(); +} + ServiceURLRequestContextGetter* ServiceProcess::GetServiceURLRequestContextGetter() { DCHECK(request_context_getter_.get()); diff --git a/chrome/service/service_process.h b/chrome/service/service_process.h index ce1fc5a..8379fb8 100644 --- a/chrome/service/service_process.h +++ b/chrome/service/service_process.h @@ -39,6 +39,11 @@ class ServiceProcess : public CloudPrintProxy::Client { bool Initialize(MessageLoopForUI* message_loop, const CommandLine& command_line, ServiceProcessState* state); + + // Functions for Cloud Print virtual driver on Mac. + void EnableVirtualPrintDriver(); + void DisableVirtualPrintDriver(); + bool Teardown(); // TODO(sanjeevr): Change various parts of the code such as // net::ProxyService::CreateSystemProxyConfigService to take in diff --git a/cloud_print/virtual_driver/posix/backend.gyp b/cloud_print/virtual_driver/posix/backend.gyp index 6f25dba..df6e49b 100644 --- a/cloud_print/virtual_driver/posix/backend.gyp +++ b/cloud_print/virtual_driver/posix/backend.gyp @@ -4,27 +4,57 @@ { 'target_defaults': { - 'include_dirs': [ - '../..' - ], - 'variables': { - 'chromium_code': 1 - } + 'variables': { 'chromium_code':1 }, }, - 'targets' : [ + 'targets': [ { 'target_name': 'GCP-driver', 'type': 'executable', 'dependencies': [ '../../../base/base.gyp:base', ], - 'sources' : [ - 'virtual_driver_posix.cc', + 'sources': [ 'printer_driver_util_linux.cc', 'printer_driver_util_posix.h', + 'printer_driver_util_mac.mm', + 'virtual_driver_posix.cc', '../virtual_driver_switches.cc', - '../virtual_driver_switches.h', - ] - }, - ], + ], + 'conditions': [ + ['OS=="mac"', { + 'sources!': ['../virtual_driver_switches.cc'], + 'libraries': ['ScriptingBridge.framework'], + }], + ], + }], + 'conditions': [ + ['OS=="mac"', { + 'targets' : [ + { + 'target_name': 'GCP-install', + 'type': 'executable', + 'dependencies': [ + '../../../base/base.gyp:base', + ], + 'sources' : [ + 'install_cloud_print_driver_mac.mm', + 'installer_util_mac.h', + 'installer_util_mac.mm' + ], + }, + { + 'target_name': 'GCP-uninstall', + 'type': 'executable', + 'dependencies': [ + '../../../base/base.gyp:base', + ], + 'sources' : [ + 'installer_util_mac.h', + 'installer_util_mac.mm', + 'uninstall_cloud_print_driver_mac.mm', + ], + }, + ], + }], + ], } diff --git a/cloud_print/virtual_driver/posix/install_cloud_print_driver_mac.mm b/cloud_print/virtual_driver/posix/install_cloud_print_driver_mac.mm new file mode 100644 index 0000000..0d3f44c2 --- /dev/null +++ b/cloud_print/virtual_driver/posix/install_cloud_print_driver_mac.mm @@ -0,0 +1,20 @@ +// Copyright (c) 2011 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 <ApplicationServices/ApplicationServices.h> +#import <Foundation/NSAutoreleasePool.h> + +#include "cloud_print/virtual_driver/posix/installer_util_mac.h" + +const AEEventClass kAECloudPrintInstallClass= 'GCPi'; + +// Installer for Virtual Driver on Mac. Sends an Apple Event to +// Chrome, launching it if necessary. The Apple Event registers +// the virtual driver with the service process. +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + cloud_print::sendServiceProcessEvent(kAECloudPrintInstallClass); + [pool release]; + return 0; +} diff --git a/cloud_print/virtual_driver/posix/installer_util_mac.h b/cloud_print/virtual_driver/posix/installer_util_mac.h new file mode 100644 index 0000000..9983313 --- /dev/null +++ b/cloud_print/virtual_driver/posix/installer_util_mac.h @@ -0,0 +1,16 @@ +// Copyright (c) 2011 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. + +#ifndef CLOUD_PRINT_VIRTUAL_POSIX_INSTALLER_UTIL_MAC_H_ +#define CLOUD_PRINT_VIRTUAL_POSIX_INSTALLER_UTIL_MAC_H_ +#pragma once + +#import <ApplicationServices/ApplicationServices.h> + +namespace cloud_print { +void sendServiceProcessEvent(const AEEventClass sendClass); +} // namespace cloud_print + +#endif // CLOUD_PRINT_VIRTUAL_POSIX_INSTALLER_UTIL_MAC_H_ + diff --git a/cloud_print/virtual_driver/posix/installer_util_mac.mm b/cloud_print/virtual_driver/posix/installer_util_mac.mm new file mode 100644 index 0000000..c6179c1 --- /dev/null +++ b/cloud_print/virtual_driver/posix/installer_util_mac.mm @@ -0,0 +1,65 @@ +// Copyright (c) 2011 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. + +#include "cloud_print/virtual_driver/posix/installer_util_mac.h" + +#import <ApplicationServices/ApplicationServices.h> +#import <Foundation/NSAutoreleasePool.h> +#import <Foundation/NSAppleEventDescriptor.h> +#import <CoreServices/CoreServices.h> + +#include "base/mac/foundation_util.h" + +#include <stdlib.h> +#include <string> +#include <iostream> + +namespace cloud_print { +// Sends an event of a class Type sendClass to the Chromium +// service process. Used to install and uninstall the Cloud +// Print driver on Mac. +void sendServiceProcessEvent(const AEEventClass sendClass) { + FSRef ref; + OSStatus status = noErr; + CFURLRef* kDontWantURL = NULL; + + std::string bundleID = base::mac::BaseBundleID(); + CFStringRef bundleIDCF = CFStringCreateWithCString(NULL, bundleID.c_str(), + kCFStringEncodingUTF8); + + status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, NULL, + &ref, kDontWantURL); + + if (status != noErr) { + std::cerr << "Failed to make path ref"; + std::cerr << GetMacOSStatusErrorString(status); + std::cerr << GetMacOSStatusCommentString(status); + exit(-1); + } + + NSAppleEventDescriptor* sendEvent = + [NSAppleEventDescriptor appleEventWithEventClass:sendClass + eventID:sendClass + targetDescriptor:nil + returnID:kAutoGenerateReturnID + transactionID:kAnyTransactionID]; + if (sendEvent == nil) { + // Write to system error log using cerr. + std::cerr << "Unable to create Apple Event"; + } + LSApplicationParameters params = { 0, kLSLaunchDefaults, &ref, NULL, NULL, + NULL, NULL }; + AEDesc* initialEvent = const_cast<AEDesc*> ([sendEvent aeDesc]); + params.initialEvent = static_cast<AppleEvent*> (initialEvent); + status = LSOpenApplication(¶ms, NULL); + + if (status != noErr) { + std::cerr << "Unable to launch Chrome to install"; + std::cerr << GetMacOSStatusErrorString(status); + std::cerr << GetMacOSStatusCommentString(status); + exit(-1); + } +} + +} // namespace cloud_print diff --git a/cloud_print/virtual_driver/posix/printer_driver_util_mac.mm b/cloud_print/virtual_driver/posix/printer_driver_util_mac.mm new file mode 100644 index 0000000..d85e3ff --- /dev/null +++ b/cloud_print/virtual_driver/posix/printer_driver_util_mac.mm @@ -0,0 +1,120 @@ +// Copyright (c) 2011 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. + +#include "cloud_print/virtual_driver/posix/printer_driver_util_posix.h" + +#import <ApplicationServices/ApplicationServices.h> +#import <CoreServices/CoreServices.h> +#import <Foundation/NSAutoreleasePool.h> +#import <Foundation/NSAppleEventDescriptor.h> +#import <ScriptingBridge/SBApplication.h> + +#include "base/logging.h" +#include "base/mac/foundation_util.h" + +#include <cups/backend.h> + +#include <stdlib.h> +#include <string> + +// Duplicated is content/common/cloud_print_class_mac.h +const AEEventClass kAECloudPrintClass = 'GCPp'; + +namespace cloud_print { +// Checks to see whether the browser process, whose bundle ID +// is specified by bundle ID, is running. +bool IsBrowserRunning(std::string bundleID) { + SBApplication* app = [SBApplication applicationWithBundleIdentifier: + [NSString stringWithUTF8String:bundleID.c_str()]]; + if ([app isRunning]) { + return true; + } + return false; +} +} // namespace cloud_print + +void LaunchPrintDialog(const std::string& outputPath, + const std::string& jobTitle, + const std::string& user) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + OSStatus status = noErr; + FSRef ref; + // Get the bundleID of the browser. + std::string bundleID = base::mac::BaseBundleID(); + // If the browser is running, send the event to it. + // Otherwise, send the event to the service process. + if (!cloud_print::IsBrowserRunning(bundleID)) { + // Generate the bundle ID for the Service process. + bundleID = bundleID + ".helper"; + } + CFStringRef bundleIDCF = CFStringCreateWithCString( + NULL, + bundleID.c_str(), + kCFStringEncodingUTF8); + CFURLRef* kDontWantURL = NULL; + // Locate the service process with the help of the bundle ID. + status = LSFindApplicationForInfo(kLSUnknownCreator, bundleIDCF, + NULL, &ref, kDontWantURL); + + if (status != noErr) { + LOG(ERROR) << "Couldn't locate the process to send Apple Event"; + exit(CUPS_BACKEND_CANCEL); + } + + // Create the actual Apple Event. + NSAppleEventDescriptor* event = + [NSAppleEventDescriptor appleEventWithEventClass:kAECloudPrintClass + eventID:kAECloudPrintClass + targetDescriptor:nil + returnID:kAutoGenerateReturnID + transactionID:kAnyTransactionID]; + + if(event == nil) { + LOG(ERROR) << "Unable to Create Event"; + exit(CUPS_BACKEND_CANCEL); + } + + // Create the AppleEvent parameters. + NSAppleEventDescriptor* printPath = + [NSAppleEventDescriptor descriptorWithString: + [NSString stringWithUTF8String:outputPath.c_str()]]; + NSAppleEventDescriptor* title = + [NSAppleEventDescriptor descriptorWithString: + [NSString stringWithUTF8String:jobTitle.c_str()]]; + NSAppleEventDescriptor* mime = [NSAppleEventDescriptor + descriptorWithString:@"application/pdf"]; + + // Create and populate the list of parameters. + // Note that the array starts at index 1. + NSAppleEventDescriptor* parameters = [NSAppleEventDescriptor listDescriptor]; + + if(parameters == nil) { + LOG(ERROR) << "Unable to Create Paramters"; + exit(CUPS_BACKEND_CANCEL); + } + + [parameters insertDescriptor:mime atIndex:1]; + [parameters insertDescriptor:printPath atIndex:2]; + [parameters insertDescriptor:title atIndex:3]; + [event setParamDescriptor:parameters forKeyword:kAECloudPrintClass]; + + // Set the application launch parameters. + // We are just using launch services to deliver our Apple Event. + LSApplicationParameters params = { + 0, kLSLaunchDefaults , &ref, NULL, NULL, NULL, NULL }; + + AEDesc* initialEvent = const_cast<AEDesc*> ([event aeDesc]); + params.initialEvent = static_cast<AppleEvent*> (initialEvent); + // Deliver the Apple Event using launch services. + status = LSOpenApplication(¶ms, NULL); + if (status != noErr) { + LOG(ERROR) << "Unable to launch"; + LOG(ERROR) << GetMacOSStatusErrorString(status); + LOG(ERROR) << GetMacOSStatusCommentString(status); + exit(CUPS_BACKEND_CANCEL); + } + + [pool release]; + return; +} diff --git a/cloud_print/virtual_driver/posix/uninstall_cloud_print_driver_mac.mm b/cloud_print/virtual_driver/posix/uninstall_cloud_print_driver_mac.mm new file mode 100644 index 0000000..adb7edc --- /dev/null +++ b/cloud_print/virtual_driver/posix/uninstall_cloud_print_driver_mac.mm @@ -0,0 +1,20 @@ +// Copyright (c) 2011 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 <ApplicationServices/ApplicationServices.h> +#import <Foundation/NSAutoreleasePool.h> + +#include "cloud_print/virtual_driver/posix/installer_util_mac.h" + +const AEEventClass kAECloudPrintUninstallClass = 'GCPu'; + +// Uninstaller for Virtual Driver on Mac. Sends an Apple Event to +// Chrome, launching it if necessary. The Apple Event unregisters +// the virtual driver with the service process. +int main() { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + cloud_print::sendServiceProcessEvent(kAECloudPrintUninstallClass); + [pool release]; + return 0; +} diff --git a/cloud_print/virtual_driver/virtual_driver_linux.gyp b/cloud_print/virtual_driver/virtual_driver_posix.gyp index 53fa411..cb458ec 100644 --- a/cloud_print/virtual_driver/virtual_driver_linux.gyp +++ b/cloud_print/virtual_driver/virtual_driver_posix.gyp @@ -4,7 +4,7 @@ { 'targets': [ { - 'target_name': 'virtual_driver', + 'target_name': 'virtual_driver_posix', 'type': 'none', 'dependencies': [ 'posix/backend.gyp:*', @@ -13,8 +13,3 @@ ], } -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/content/common/cloud_print_class_mac.h b/content/common/cloud_print_class_mac.h new file mode 100644 index 0000000..f562d1d --- /dev/null +++ b/content/common/cloud_print_class_mac.h @@ -0,0 +1,19 @@ +// Copyright (c) 2011 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. + +#ifndef CONTENT_COMMON_CLOUD_PRINT_CLASS_MAC_H_ +#define CONTENT_COMMON_CLOUD_PRINT_CLASS_MAC_H_ +#pragma once + +#import <AppKit/AppKit.h> + +namespace content { + +// Four character constant to identify Cloud print IPC call. +extern const AEEventClass kAECloudPrintClass; + +} // namespace content + +#endif // CONTENT_COMMON_CLOUD_PRINT_CLASS_MAC_H_ + diff --git a/content/common/cloud_print_class_mac.mm b/content/common/cloud_print_class_mac.mm new file mode 100644 index 0000000..2f7f1e0 --- /dev/null +++ b/content/common/cloud_print_class_mac.mm @@ -0,0 +1,11 @@ +// Copyright (c) 2011 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 "content/common/cloud_print_class_mac.h" + +namespace content { + +const AEEventClass kAECloudPrintClass = 'GCPp'; + +} // namespace content diff --git a/content/content_common.gypi b/content/content_common.gypi index 6781a95..59a83aa 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -52,6 +52,8 @@ 'common/chrome_application_mac.h', 'common/chrome_application_mac.mm', 'common/chrome_descriptors.h', + 'common/cloud_print_class_mac.h', + 'common/cloud_print_class_mac.mm', 'common/clipboard_messages.h', 'common/common_param_traits.cc', 'common/common_param_traits.h', |