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