• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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