summaryrefslogtreecommitdiffstats
path: root/chrome/service/service_utility_process_host.h
blob: fd1fad91cf6d9b6ca05462a201a86c149a0ee38c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
// Copyright (c) 2012 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_SERVICE_UTILITY_PROCESS_HOST_H_
#define CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_

#include "build/build_config.h"

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/process/process.h"
#include "content/public/common/child_process_host_delegate.h"
#include "ipc/ipc_channel.h"
#include "printing/pdf_render_settings.h"

class CommandLine;

namespace base {
class MessageLoopProxy;
class ScopedTempDir;
}  // namespace base

namespace content {
class ChildProcessHost;
}

namespace printing {
class Emf;
struct PageRange;
struct PrinterCapsAndDefaults;
struct PrinterSemanticCapsAndDefaults;
}  // namespace printing

// Acts as the service-side host to a utility child process. A
// utility process is a short-lived sandboxed process that is created to run
// a specific task.
class ServiceUtilityProcessHost : public content::ChildProcessHostDelegate {
 public:
  // Consumers of ServiceUtilityProcessHost must implement this interface to
  // get results back.  All functions are called on the thread passed along
  // to ServiceUtilityProcessHost.
  class Client : public base::RefCountedThreadSafe<Client> {
   public:
    Client() {}

    // Called when the child process died before a reply was receieved.
    virtual void OnChildDied() {}

    // Called when at least one page in the specified PDF has been rendered
    // successfully into |metafile|.
    virtual void OnRenderPDFPagesToMetafileSucceeded(
        const printing::Emf& metafile,
        int highest_rendered_page_number,
        double scale_factor) {}
    // Called when no page in the passed in PDF could be rendered.
    virtual void OnRenderPDFPagesToMetafileFailed() {}

    // Called when the printer capabilities and defaults have been
    // retrieved successfully or if retrieval failed.
    virtual void OnGetPrinterCapsAndDefaults(
        bool succedded,
        const std::string& printer_name,
        const printing::PrinterCapsAndDefaults& caps_and_defaults) {}

    // Called when the printer capabilities and defaults have been
    // retrieved successfully or if retrieval failed.
    virtual void OnGetPrinterSemanticCapsAndDefaults(
        bool succedded,
        const std::string& printer_name,
        const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults) {}

   protected:
    virtual ~Client() {}

   private:
    friend class base::RefCountedThreadSafe<Client>;
    friend class ServiceUtilityProcessHost;

    // Invoked when a metafile file is ready.
    void MetafileAvailable(const base::FilePath& metafile_path,
                           int highest_rendered_page_number,
                           double scale_factor);

    DISALLOW_COPY_AND_ASSIGN(Client);
  };

  ServiceUtilityProcessHost(Client* client,
                            base::MessageLoopProxy* client_message_loop_proxy);
  virtual ~ServiceUtilityProcessHost();

  // Starts a process to render the specified pages in the given PDF file into
  // a metafile. Currently only implemented for Windows. If the PDF has fewer
  // pages than the specified page ranges, it will render as many as available.
  bool StartRenderPDFPagesToMetafile(
      const base::FilePath& pdf_path,
      const printing::PdfRenderSettings& render_settings,
      const std::vector<printing::PageRange>& page_ranges);

  // Starts a process to get capabilities and defaults for the specified
  // printer. Used on Windows to isolate the service process from printer driver
  // crashes by executing this in a separate process. The process does not run
  // in a sandbox.
  bool StartGetPrinterCapsAndDefaults(const std::string& printer_name);

  // Starts a process to get capabilities and defaults for the specified
  // printer. Used on Windows to isolate the service process from printer driver
  // crashes by executing this in a separate process. The process does not run
  // in a sandbox. Returns result as printing::PrinterSemanticCapsAndDefaults.
  bool StartGetPrinterSemanticCapsAndDefaults(const std::string& printer_name);

 protected:
  // Allows this method to be overridden for tests.
  virtual base::FilePath GetUtilityProcessCmd();

  // ChildProcessHostDelegate implementation:
  virtual void OnChildDisconnected() OVERRIDE;
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
  virtual base::ProcessHandle GetHandle() const OVERRIDE;

 private:
  // Starts a process.  Returns true iff it succeeded. |exposed_dir| is the
  // path to the exposed to the sandbox. This is ignored if |no_sandbox| is
  // true.
  bool StartProcess(bool no_sandbox, const base::FilePath& exposed_dir);

  // Launch the child process synchronously.
  // TODO(sanjeevr): Determine whether we need to make the launch asynchronous.
  // |exposed_dir| is the path to tbe exposed to the sandbox. This is ignored
  // if |no_sandbox| is true.
  bool Launch(CommandLine* cmd_line,
              bool no_sandbox,
              const base::FilePath& exposed_dir);

  base::ProcessHandle handle() const { return handle_; }

  // Messages handlers:
  void OnRenderPDFPagesToMetafileSucceeded(int highest_rendered_page_number,
                                           double scale_factor);
  void OnRenderPDFPagesToMetafileFailed();
  void OnGetPrinterCapsAndDefaultsSucceeded(
      const std::string& printer_name,
      const printing::PrinterCapsAndDefaults& caps_and_defaults);
  void OnGetPrinterCapsAndDefaultsFailed(const std::string& printer_name);
  void OnGetPrinterSemanticCapsAndDefaultsSucceeded(
      const std::string& printer_name,
      const printing::PrinterSemanticCapsAndDefaults& caps_and_defaults);
  void OnGetPrinterSemanticCapsAndDefaultsFailed(
      const std::string& printer_name);

  scoped_ptr<content::ChildProcessHost> child_process_host_;
  base::ProcessHandle handle_;
  // A pointer to our client interface, who will be informed of progress.
  scoped_refptr<Client> client_;
  scoped_refptr<base::MessageLoopProxy> client_message_loop_proxy_;
  bool waiting_for_reply_;
  // The path to the temp file where the metafile will be written to.
  base::FilePath metafile_path_;
  // The temporary folder created for the metafile.
  scoped_ptr<base::ScopedTempDir> scratch_metafile_dir_;
  // Start time of operation.
  base::Time start_time_;

  DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost);
};

#endif  // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_