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