Home | History | Annotate | Download | only in service
      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:
     49     Client() {}
     50 
     51     // Called when the child process died before a reply was receieved.
     52     virtual void OnChildDied() {}
     53 
     54     // Called when at least one page in the specified PDF has been rendered
     55     // successfully into |metafile|.
     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.
     61     virtual void OnRenderPDFPagesToMetafileFailed() {}
     62 
     63     // Called when the printer capabilities and defaults have been
     64     // retrieved successfully.
     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.
     71     virtual void OnGetPrinterCapsAndDefaultsFailed(
     72         const std::string& printer_name) {}
     73 
     74    protected:
     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 
    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 
    151   DISALLOW_COPY_AND_ASSIGN(ServiceUtilityProcessHost);
    152 };
    153 
    154 #endif  // CHROME_SERVICE_SERVICE_UTILITY_PROCESS_HOST_H_
    155