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 <memory> 9 #include <string> 10 11 #include "base/macros.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/memory/weak_ptr.h" 14 #include "chrome/services/printing/public/mojom/pdf_to_emf_converter.mojom.h" 15 #include "content/public/common/child_process_host_delegate.h" 16 #include "ipc/ipc_platform_file.h" 17 #include "mojo/public/cpp/bindings/pending_remote.h" 18 19 namespace base { 20 class CommandLine; 21 class FilePath; 22 class SingleThreadTaskRunner; 23 } // namespace base 24 25 namespace content { 26 class ChildProcessHost; 27 } 28 29 namespace printing { 30 class MetafilePlayer; 31 struct PdfRenderSettings; 32 struct PrinterCapsAndDefaults; 33 struct PrinterSemanticCapsAndDefaults; 34 } // namespace printing 35 36 // Acts as the service-side host to a utility child process. A 37 // utility process is a short-lived sandboxed process that is created to run 38 // a specific task. 39 // This class is expected to delete itself IFF one of its Start methods has been 40 // called. 41 class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate { 42 public: 43 // Consumers of ServiceUtilityProcessHost must implement this interface to 44 // get results back. All functions are called on the thread passed along 45 // to ServiceUtilityProcessHost. 46 class Client : public base::RefCountedThreadSafe<Client> { 47 public: Client()48 Client() {} 49 50 // Called when the child process died before a reply was receieved. OnChildDied()51 virtual void OnChildDied() {} 52 OnRenderPDFPagesToMetafilePageDone(float scale_factor,const printing::MetafilePlayer & emf)53 virtual void OnRenderPDFPagesToMetafilePageDone( 54 float scale_factor, 55 const printing::MetafilePlayer& emf) {} 56 57 // Called when at all pages in the PDF has been rendered. OnRenderPDFPagesToMetafileDone(bool success)58 virtual void OnRenderPDFPagesToMetafileDone(bool success) {} 59 60 // Called when the printer capabilities and defaults have been 61 // retrieved successfully or if retrieval failed. OnGetPrinterCapsAndDefaults(bool succedded,const std::string & printer_name,const printing::PrinterCapsAndDefaults & caps_and_defaults)62 virtual void OnGetPrinterCapsAndDefaults( 63 bool succedded, 64 const std::string& printer_name, 65 const printing::PrinterCapsAndDefaults& caps_and_defaults) {} 66 67 // Called when the printer capabilities and defaults have been 68 // retrieved successfully or if retrieval failed. OnGetPrinterSemanticCapsAndDefaults(bool succedded,const std::string & printer_name,const printing::PrinterSemanticCapsAndDefaults & caps_and_defaults)69 virtual void OnGetPrinterSemanticCapsAndDefaults( 70 bool succedded, 71 const std::string& printer_name, 72 const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults) {} 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 is ready. 82 // Returns true if metafile successfully loaded from |emf_region|. 83 bool MetafileAvailable(float scale_factor, 84 base::ReadOnlySharedMemoryRegion emf_region); 85 86 DISALLOW_COPY_AND_ASSIGN(Client); 87 }; 88 89 ServiceUtilityProcessHost(Client* client, 90 base::SingleThreadTaskRunner* client_task_runner); 91 ~ServiceUtilityProcessHost() override; 92 GetHost()93 content::ChildProcessHost* GetHost() { return child_process_host_.get(); } 94 95 // Starts a process to render the specified pages in the given PDF file into 96 // a metafile. Currently only implemented for Windows. If the PDF has fewer 97 // pages than the specified page ranges, it will render as many as available. 98 bool StartRenderPDFPagesToMetafile( 99 const base::FilePath& pdf_path, 100 const printing::PdfRenderSettings& render_settings); 101 102 // Starts a process to get capabilities and defaults for the specified 103 // printer. Used on Windows to isolate the service process from printer driver 104 // crashes by executing this in a separate process. The process does not run 105 // in a sandbox. 106 bool StartGetPrinterCapsAndDefaults(const std::string& printer_name); 107 108 // Starts a process to get capabilities and defaults for the specified 109 // printer. Used on Windows to isolate the service process from printer driver 110 // crashes by executing this in a separate process. The process does not run 111 // in a sandbox. Returns result as printing::PrinterSemanticCapsAndDefaults. 112 bool StartGetPrinterSemanticCapsAndDefaults(const std::string& printer_name); 113 114 protected: 115 bool Send(IPC::Message* msg); 116 117 // Allows this method to be overridden for tests. 118 virtual base::FilePath GetUtilityProcessCmd(); 119 120 // ChildProcessHostDelegate implementation: 121 void OnChildDisconnected() override; 122 bool OnMessageReceived(const IPC::Message& message) override; 123 const base::Process& GetProcess() override; 124 void BindHostReceiver(mojo::GenericPendingReceiver receiver) override; 125 126 private: 127 // Starts a process. Returns true iff it succeeded. 128 bool StartProcess(bool sandbox); 129 130 // Launch the child process synchronously. 131 bool Launch(base::CommandLine* cmd_line, bool sandbox); 132 handle()133 base::ProcessHandle handle() const { return process_.Handle(); } 134 135 void OnMetafileSpooled(bool success); 136 void OnPDFToEmfFinished(bool success); 137 138 // PdfToEmfState callbacks: 139 void OnRenderPDFPagesToMetafilesPageCount( 140 mojo::PendingRemote<printing::mojom::PdfToEmfConverter> converter, 141 uint32_t page_count); 142 void OnRenderPDFPagesToMetafilesPageDone( 143 base::ReadOnlySharedMemoryRegion emf_region, 144 float scale_factor); 145 146 // IPC Messages handlers: 147 void OnGetPrinterCapsAndDefaultsSucceeded( 148 const std::string& printer_name, 149 const printing::PrinterCapsAndDefaults& caps_and_defaults); 150 void OnGetPrinterCapsAndDefaultsFailed(const std::string& printer_name); 151 void OnGetPrinterSemanticCapsAndDefaultsSucceeded( 152 const std::string& printer_name, 153 const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults); 154 void OnGetPrinterSemanticCapsAndDefaultsFailed( 155 const std::string& printer_name); 156 157 std::unique_ptr<content::ChildProcessHost> child_process_host_; 158 base::Process process_; 159 // A pointer to our client interface, who will be informed of progress. 160 scoped_refptr<Client> client_; 161 scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_; 162 bool waiting_for_reply_; 163 164 class PdfToEmfState; 165 std::unique_ptr<PdfToEmfState> pdf_to_emf_state_; 166 167 base::WeakPtrFactory<ServiceUtilityProcessHost> weak_ptr_factory_{this}; 168 169 DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost); 170 }; 171 172 #endif // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_ 173