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 #ifndef CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_ 6 #define CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_ 7 8 #include "build/build_config.h" 9 10 #include <string> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/files/file_path.h" 15 #include "base/memory/ref_counted.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/process/process.h" 18 #include "content/public/common/child_process_host_delegate.h" 19 #include "ipc/ipc_channel.h" 20 #include "printing/pdf_render_settings.h" 21 22 class CommandLine; 23 24 namespace base { 25 class MessageLoopProxy; 26 class ScopedTempDir; 27 } // namespace base 28 29 namespace content { 30 class ChildProcessHost; 31 } 32 33 namespace printing { 34 class Emf; 35 struct PageRange; 36 struct PrinterCapsAndDefaults; 37 } // namespace printing 38 39 // Acts as the service-side host to a utility child process. A 40 // utility process is a short-lived sandboxed process that is created to run 41 // a specific task. 42 class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate { 43 public: 44 // Consumers of ServiceUtilityProcessHost must implement this interface to 45 // get results back. All functions are called on the thread passed along 46 // to ServiceUtilityProcessHost. 47 class Client : public base::RefCountedThreadSafe<Client> { 48 public: Client()49 Client() {} 50 51 // Called when the child process died before a reply was receieved. OnChildDied()52 virtual void OnChildDied() {} 53 54 // Called when at least one page in the specified PDF has been rendered 55 // successfully into |metafile|. OnRenderPDFPagesToMetafileSucceeded(const printing::Emf & metafile,int highest_rendered_page_number,double scale_factor)56 virtual void OnRenderPDFPagesToMetafileSucceeded( 57 const printing::Emf& metafile, 58 int highest_rendered_page_number, 59 double scale_factor) {} 60 // Called when no page in the passed in PDF could be rendered. OnRenderPDFPagesToMetafileFailed()61 virtual void OnRenderPDFPagesToMetafileFailed() {} 62 63 // Called when the printer capabilities and defaults have been 64 // retrieved successfully. OnGetPrinterCapsAndDefaultsSucceeded(const std::string & printer_name,const printing::PrinterCapsAndDefaults & caps_and_defaults)65 virtual void OnGetPrinterCapsAndDefaultsSucceeded( 66 const std::string& printer_name, 67 const printing::PrinterCapsAndDefaults& caps_and_defaults) {} 68 69 // Called when the printer capabilities and defaults could not be 70 // retrieved successfully. OnGetPrinterCapsAndDefaultsFailed(const std::string & printer_name)71 virtual void OnGetPrinterCapsAndDefaultsFailed( 72 const std::string& printer_name) {} 73 74 protected: ~Client()75 virtual ~Client() {} 76 77 private: 78 friend class base::RefCountedThreadSafe<Client>; 79 friend class ServiceUtilityProcessHost; 80 81 // Invoked when a metafile file is ready. 82 void MetafileAvailable(const base::FilePath& metafile_path, 83 int highest_rendered_page_number, 84 double scale_factor); 85 86 DISALLOW_COPY_AND_ASSIGN(Client); 87 }; 88 89 ServiceUtilityProcessHost(Client* client, 90 base::MessageLoopProxy* client_message_loop_proxy); 91 virtual ~ServiceUtilityProcessHost(); 92 93 // Starts a process to render the specified pages in the given PDF file into 94 // a metafile. Currently only implemented for Windows. If the PDF has fewer 95 // pages than the specified page ranges, it will render as many as available. 96 bool StartRenderPDFPagesToMetafile( 97 const base::FilePath& pdf_path, 98 const printing::PdfRenderSettings& render_settings, 99 const std::vector<printing::PageRange>& page_ranges); 100 101 // Starts a process to get capabilities and defaults for the specified 102 // printer. Used on Windows to isolate the service process from printer driver 103 // crashes by executing this in a separate process. The process does not run 104 // in a sandbox. 105 bool StartGetPrinterCapsAndDefaults(const std::string& printer_name); 106 107 protected: 108 // Allows this method to be overridden for tests. 109 virtual base::FilePath GetUtilityProcessCmd(); 110 111 // ChildProcessHostDelegate implementation: 112 virtual void OnChildDisconnected() OVERRIDE; 113 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 114 115 private: 116 // Starts a process. Returns true iff it succeeded. |exposed_dir| is the 117 // path to the exposed to the sandbox. This is ignored if |no_sandbox| is 118 // true. 119 bool StartProcess(bool no_sandbox, const base::FilePath& exposed_dir); 120 121 // Launch the child process synchronously. 122 // TODO(sanjeevr): Determine whether we need to make the launch asynchronous. 123 // |exposed_dir| is the path to tbe exposed to the sandbox. This is ignored 124 // if |no_sandbox| is true. 125 bool Launch(CommandLine* cmd_line, 126 bool no_sandbox, 127 const base::FilePath& exposed_dir); 128 handle()129 base::ProcessHandle handle() const { return handle_; } 130 131 // Messages handlers: 132 void OnRenderPDFPagesToMetafileSucceeded(int highest_rendered_page_number, 133 double scale_factor); 134 void OnRenderPDFPagesToMetafileFailed(); 135 void OnGetPrinterCapsAndDefaultsSucceeded( 136 const std::string& printer_name, 137 const printing::PrinterCapsAndDefaults& caps_and_defaults); 138 void OnGetPrinterCapsAndDefaultsFailed(const std::string& printer_name); 139 140 scoped_ptr<content::ChildProcessHost> child_process_host_; 141 base::ProcessHandle handle_; 142 // A pointer to our client interface, who will be informed of progress. 143 scoped_refptr<Client> client_; 144 scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy_; 145 bool waiting_for_reply_; 146 // The path to the temp file where the metafile will be written to. 147 base::FilePath metafile_path_; 148 // The temporary folder created for the metafile. 149 scoped_ptr<base::ScopedTempDir> scratch_metafile_dir_; 150 // Start time of operation. 151 base::Time start_time_; 152 153 DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost); 154 }; 155 156 #endif // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_ 157