summaryrefslogtreecommitdiffstats
path: root/chrome/service/service_utility_process_host.h
blob: 0590831e46aa4dff7877df7487797844cf2c089b (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
// 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 "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/public/common/child_process_host_delegate.h"
#include "ipc/ipc_platform_file.h"

namespace base {
class CommandLine;
class File;
class FilePath;
class MessageLoopProxy;
class ScopedTempDir;
}  // namespace base

namespace content {
class ChildProcessHost;
}

namespace printing {
class MetafilePlayer;
class PdfRenderSettings;
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() {}

    virtual void OnRenderPDFPagesToMetafilePageDone(
        double scale_factor,
        const printing::MetafilePlayer& emf) {}

    // Called when at all pages in the PDF has been rendered.
    virtual void OnRenderPDFPagesToMetafileDone(bool success) {}

    // 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.
    // Returns true if metafile successfully loaded from |file|.
    bool MetafileAvailable(double scale_factor, base::File file);

    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);

  // 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:
  bool Send(IPC::Message* msg);

  // 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.
  bool StartProcess(bool no_sandbox);

  // Launch the child process synchronously.
  bool Launch(base::CommandLine* cmd_line, bool no_sandbox);

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

  void OnMetafileSpooled(bool success);
  void OnPDFToEmfFinished(bool success);

  // Messages handlers:
  void OnRenderPDFPagesToMetafilesPageCount(int page_count);
  void OnRenderPDFPagesToMetafilesPageDone(bool success, double scale_factor);
  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_;

  // Start time of operation.
  base::Time start_time_;

  class PdfToEmfState;
  scoped_ptr<PdfToEmfState> pdf_to_emf_state_;

  base::WeakPtrFactory<ServiceUtilityProcessHost> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost);
};

#endif  // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_