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 19class PrefService; 20 21namespace net { 22 23class DrainableIOBuffer; 24class FileStream; 25class IOBuffer; 26class IOBufferWithSize; 27 28} // namespace net 29 30namespace 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. 38class 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