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 "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/memory/weak_ptr.h"
13#include "content/public/common/child_process_host_delegate.h"
14#include "ipc/ipc_platform_file.h"
15
16namespace base {
17class CommandLine;
18class File;
19class FilePath;
20class MessageLoopProxy;
21class ScopedTempDir;
22}  // namespace base
23
24namespace content {
25class ChildProcessHost;
26}
27
28namespace printing {
29class MetafilePlayer;
30class PdfRenderSettings;
31struct PageRange;
32struct PrinterCapsAndDefaults;
33struct 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.
39class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate {
40 public:
41  // Consumers of ServiceUtilityProcessHost must implement this interface to
42  // get results back.  All functions are called on the thread passed along
43  // to ServiceUtilityProcessHost.
44  class Client : public base::RefCountedThreadSafe<Client> {
45   public:
46    Client() {}
47
48    // Called when the child process died before a reply was receieved.
49    virtual void OnChildDied() {}
50
51    virtual void OnRenderPDFPagesToMetafilePageDone(
52        double scale_factor,
53        const printing::MetafilePlayer& emf) {}
54
55    // Called when at all pages in the PDF has been rendered.
56    virtual void OnRenderPDFPagesToMetafileDone(bool success) {}
57
58    // Called when the printer capabilities and defaults have been
59    // retrieved successfully or if retrieval failed.
60    virtual void OnGetPrinterCapsAndDefaults(
61        bool succedded,
62        const std::string& printer_name,
63        const printing::PrinterCapsAndDefaults& caps_and_defaults) {}
64
65    // Called when the printer capabilities and defaults have been
66    // retrieved successfully or if retrieval failed.
67    virtual void OnGetPrinterSemanticCapsAndDefaults(
68        bool succedded,
69        const std::string& printer_name,
70        const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults) {}
71
72   protected:
73    virtual ~Client() {}
74
75   private:
76    friend class base::RefCountedThreadSafe<Client>;
77    friend class ServiceUtilityProcessHost;
78
79    // Invoked when a metafile file is ready.
80    // Returns true if metafile successfully loaded from |file|.
81    bool MetafileAvailable(double scale_factor, base::File file);
82
83    DISALLOW_COPY_AND_ASSIGN(Client);
84  };
85
86  ServiceUtilityProcessHost(Client* client,
87                            base::MessageLoopProxy* client_message_loop_proxy);
88  virtual ~ServiceUtilityProcessHost();
89
90  // Starts a process to render the specified pages in the given PDF file into
91  // a metafile. Currently only implemented for Windows. If the PDF has fewer
92  // pages than the specified page ranges, it will render as many as available.
93  bool StartRenderPDFPagesToMetafile(
94      const base::FilePath& pdf_path,
95      const printing::PdfRenderSettings& render_settings);
96
97  // Starts a process to get capabilities and defaults for the specified
98  // printer. Used on Windows to isolate the service process from printer driver
99  // crashes by executing this in a separate process. The process does not run
100  // in a sandbox.
101  bool StartGetPrinterCapsAndDefaults(const std::string& printer_name);
102
103  // Starts a process to get capabilities and defaults for the specified
104  // printer. Used on Windows to isolate the service process from printer driver
105  // crashes by executing this in a separate process. The process does not run
106  // in a sandbox. Returns result as printing::PrinterSemanticCapsAndDefaults.
107  bool StartGetPrinterSemanticCapsAndDefaults(const std::string& printer_name);
108
109 protected:
110  bool Send(IPC::Message* msg);
111
112  // Allows this method to be overridden for tests.
113  virtual base::FilePath GetUtilityProcessCmd();
114
115  // ChildProcessHostDelegate implementation:
116  virtual void OnChildDisconnected() OVERRIDE;
117  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
118  virtual base::ProcessHandle GetHandle() const OVERRIDE;
119
120 private:
121  // Starts a process.  Returns true iff it succeeded.
122  bool StartProcess(bool no_sandbox);
123
124  // Launch the child process synchronously.
125  bool Launch(base::CommandLine* cmd_line, bool no_sandbox);
126
127  base::ProcessHandle handle() const { return handle_; }
128
129  void OnMetafileSpooled(bool success);
130  void OnPDFToEmfFinished(bool success);
131
132  // Messages handlers:
133  void OnRenderPDFPagesToMetafilesPageCount(int page_count);
134  void OnRenderPDFPagesToMetafilesPageDone(bool success, double scale_factor);
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  void OnGetPrinterSemanticCapsAndDefaultsSucceeded(
140      const std::string& printer_name,
141      const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults);
142  void OnGetPrinterSemanticCapsAndDefaultsFailed(
143      const std::string& printer_name);
144
145  scoped_ptr<content::ChildProcessHost> child_process_host_;
146  base::ProcessHandle handle_;
147  // A pointer to our client interface, who will be informed of progress.
148  scoped_refptr<Client> client_;
149  scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy_;
150  bool waiting_for_reply_;
151
152  // Start time of operation.
153  base::Time start_time_;
154
155  class PdfToEmfState;
156  scoped_ptr<PdfToEmfState> pdf_to_emf_state_;
157
158  base::WeakPtrFactory<ServiceUtilityProcessHost> weak_ptr_factory_;
159
160  DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost);
161};
162
163#endif  // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_
164