Home | History | Annotate | Download | only in messaging
      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_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
      6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
      7 
      8 #include <queue>
      9 #include <string>
     10 
     11 #include "base/files/file.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "base/process/process.h"
     16 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
     17 #include "ui/gfx/native_widget_types.h"
     18 
     19 class PrefService;
     20 
     21 namespace net {
     22 
     23 class DrainableIOBuffer;
     24 class FileStream;
     25 class IOBuffer;
     26 class IOBufferWithSize;
     27 
     28 }  // namespace net
     29 
     30 namespace extensions {
     31 
     32 // Manages the native side of a connection between an extension and a native
     33 // process.
     34 //
     35 // This class must only be created, called, and deleted on the IO thread.
     36 // Public methods typically accept callbacks which will be invoked on the UI
     37 // thread.
     38 class NativeMessageProcessHost
     39 #if defined(OS_POSIX)
     40     : public base::MessageLoopForIO::Watcher
     41 #endif  // !defined(OS_POSIX)
     42 {
     43  public:
     44   // Interface for the object that receives messages from the native process.
     45   class Client {
     46    public:
     47     virtual ~Client() {}
     48     // Called on the UI thread.
     49     virtual void PostMessageFromNativeProcess(int port_id,
     50                                               const std::string& message) = 0;
     51     virtual void CloseChannel(int port_id,
     52                               const std::string& error_message) = 0;
     53   };
     54 
     55   // Result returned from IsHostAllowed().
     56   enum PolicyPermission {
     57     DISALLOW,           // The host is not allowed.
     58     ALLOW_SYSTEM_ONLY,  // Allowed only when installed on system level.
     59     ALLOW_ALL,          // Allowed when installed on system or user level.
     60   };
     61 
     62   virtual ~NativeMessageProcessHost();
     63 
     64   // Returns policy permissions for the host with the specified name.
     65   static PolicyPermission IsHostAllowed(const PrefService* pref_service,
     66                                         const std::string& native_host_name);
     67 
     68   static scoped_ptr<NativeMessageProcessHost> Create(
     69       gfx::NativeView native_view,
     70       base::WeakPtr<Client> weak_client_ui,
     71       const std::string& source_extension_id,
     72       const std::string& native_host_name,
     73       int destination_port,
     74       bool allow_user_level);
     75 
     76   // Create using specified |launcher|. Used in tests.
     77   static scoped_ptr<NativeMessageProcessHost> CreateWithLauncher(
     78       base::WeakPtr<Client> weak_client_ui,
     79       const std::string& source_extension_id,
     80       const std::string& native_host_name,
     81       int destination_port,
     82       scoped_ptr<NativeProcessLauncher> launcher);
     83 
     84   // Send a message with the specified payload.
     85   void Send(const std::string& json);
     86 
     87 #if defined(OS_POSIX)
     88   // MessageLoopForIO::Watcher interface
     89   virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
     90   virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
     91 #endif  // !defined(OS_POSIX)
     92 
     93   // Try and read a single message from |read_file_|. This should only be called
     94   // in unittests when you know there is data in the file.
     95   void ReadNowForTesting();
     96 
     97  private:
     98   NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui,
     99                            const std::string& source_extension_id,
    100                            const std::string& native_host_name,
    101                            int destination_port,
    102                            scoped_ptr<NativeProcessLauncher> launcher);
    103 
    104   // Starts the host process.
    105   void LaunchHostProcess();
    106 
    107   // Callback for NativeProcessLauncher::Launch().
    108   void OnHostProcessLaunched(NativeProcessLauncher::LaunchResult result,
    109                              base::ProcessHandle process_handle,
    110                              base::File read_file,
    111                              base::File write_file);
    112 
    113   // Helper methods to read incoming messages.
    114   void WaitRead();
    115   void DoRead();
    116   void OnRead(int result);
    117   void HandleReadResult(int result);
    118   void ProcessIncomingData(const char* data, int data_size);
    119 
    120   // Helper methods to write outgoing messages.
    121   void DoWrite();
    122   void HandleWriteResult(int result);
    123   void OnWritten(int result);
    124 
    125   // Closes the connection. Called from OnError() and destructor.
    126   void Close(const std::string& error_message);
    127 
    128   // The Client messages will be posted to. Should only be accessed from the
    129   // UI thread.
    130   base::WeakPtr<Client> weak_client_ui_;
    131 
    132   // ID of the calling extension.
    133   std::string source_extension_id_;
    134 
    135   // Name of the native messaging host.
    136   std::string native_host_name_;
    137 
    138   // The id of the port on the other side of this connection. This is passed to
    139   // |weak_client_ui_| when posting messages.
    140   int destination_port_;
    141 
    142   // Launcher used to launch the native process.
    143   scoped_ptr<NativeProcessLauncher> launcher_;
    144 
    145   // Set to true after the native messaging connection has been stopped, e.g.
    146   // due to an error.
    147   bool closed_;
    148 
    149   base::ProcessHandle process_handle_;
    150 
    151   // Input stream reader.
    152   scoped_ptr<net::FileStream> read_stream_;
    153 
    154 #if defined(OS_POSIX)
    155   base::PlatformFile read_file_;
    156   base::MessageLoopForIO::FileDescriptorWatcher read_watcher_;
    157 #endif  // !defined(OS_POSIX)
    158 
    159   // Write stream.
    160   scoped_ptr<net::FileStream> write_stream_;
    161 
    162   // Read buffer passed to FileStream::Read().
    163   scoped_refptr<net::IOBuffer> read_buffer_;
    164 
    165   // Set to true when a read is pending.
    166   bool read_pending_;
    167 
    168   // Buffer for incomplete incoming messages.
    169   std::string incoming_data_;
    170 
    171   // Queue for outgoing messages.
    172   std::queue<scoped_refptr<net::IOBufferWithSize> > write_queue_;
    173 
    174   // The message that's currently being sent.
    175   scoped_refptr<net::DrainableIOBuffer> current_write_buffer_;
    176 
    177   // Set to true when a write is pending.
    178   bool write_pending_;
    179 
    180   DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost);
    181 };
    182 
    183 }  // namespace extensions
    184 
    185 #endif  // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
    186