| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ |
| 6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ | 6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ |
| 7 | 7 |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/process.h" | 12 #include "base/process.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 | 14 |
| 15 namespace extensions { | 15 namespace extensions { |
| 16 class NativeProcessLauncher; | 16 class NativeProcessLauncher; |
| 17 | 17 |
| 18 // Manages the native side of a connection between an extension and a native | 18 // Manages the native side of a connection between an extension and a native |
| 19 // process. | 19 // process. |
| 20 // | 20 // |
| 21 // This class must only be created, called, and deleted on the FILE thread. | 21 // This class must only be created, called, and deleted on the IO thread. |
| 22 // Public methods typically accept callbacks which will be invoked on the UI | 22 // Public methods typically accept callbacks which will be invoked on the UI |
| 23 // thread. | 23 // thread. |
| 24 class NativeMessageProcessHost | 24 class NativeMessageProcessHost |
| 25 #if defined(OS_WIN) | 25 #if defined(OS_WIN) |
| 26 : public MessageLoopForIO::IOHandler { | 26 : public MessageLoopForIO::IOHandler { |
| 27 #else | 27 #else |
| 28 : public MessageLoopForIO::Watcher { | 28 : public MessageLoopForIO::Watcher { |
| 29 #endif // defined(OS_WIN) | 29 #endif // defined(OS_WIN) |
| 30 public: | 30 public: |
| 31 class ScopedNativeProcessClose; | 31 class ScopedNativeProcessClose; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 62 class Client { | 62 class Client { |
| 63 public: | 63 public: |
| 64 virtual ~Client() {} | 64 virtual ~Client() {} |
| 65 // Called on the UI thread. | 65 // Called on the UI thread. |
| 66 virtual void PostMessageFromNativeProcess(int port_id, | 66 virtual void PostMessageFromNativeProcess(int port_id, |
| 67 const std::string& message) = 0; | 67 const std::string& message) = 0; |
| 68 virtual void CloseChannel(int port_id, bool error) = 0; | 68 virtual void CloseChannel(int port_id, bool error) = 0; |
| 69 }; | 69 }; |
| 70 | 70 |
| 71 // Desctruction functor that ensures a NativeMessageProcessHost is destroyed | 71 // Desctruction functor that ensures a NativeMessageProcessHost is destroyed |
| 72 // on the FILE thread. | 72 // on the IO thread. |
| 73 class ScopedNativeProcessClose { | 73 class ScopedNativeProcessClose { |
| 74 public: | 74 public: |
| 75 inline void operator()(extensions::NativeMessageProcessHost* x) const { | 75 inline void operator()(extensions::NativeMessageProcessHost* x) const { |
| 76 content::BrowserThread::DeleteSoon(content::BrowserThread::FILE, | 76 content::BrowserThread::DeleteSoon(content::BrowserThread::IO, |
| 77 FROM_HERE, x); | 77 FROM_HERE, x); |
| 78 } | 78 } |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 | |
| 82 virtual ~NativeMessageProcessHost(); | 81 virtual ~NativeMessageProcessHost(); |
| 83 | 82 |
| 84 // |type| must be TYPE_CONNECT or TYPE_SEND_MESSAGE_REQUEST. |callback| will | 83 // |type| must be TYPE_CONNECT or TYPE_SEND_MESSAGE_REQUEST. |callback| will |
| 85 // be called with an empty ScopedHost on error. | 84 // be called with an empty ScopedHost on error. |
| 86 static void Create(base::WeakPtr<Client> weak_client_ui, | 85 static void Create(base::WeakPtr<Client> weak_client_ui, |
| 87 const std::string& native_app_name, | 86 const std::string& native_app_name, |
| 88 const std::string& connection_message, | 87 const std::string& connection_message, |
| 89 int destination_port, | 88 int destination_port, |
| 90 MessageType type, | 89 MessageType type, |
| 91 CreateCallback callback); | 90 CreateCallback callback); |
| 92 | 91 |
| 93 // Create a NativeMessageProcessHost using the specified launcher. This allows | 92 // Create a NativeMessageProcessHost using the specified launcher. This allows |
| 94 // for easy testing. | 93 // for easy testing. |
| 95 static void CreateWithLauncher(base::WeakPtr<Client> weak_client_ui, | 94 static void CreateWithLauncher(base::WeakPtr<Client> weak_client_ui, |
| 96 const std::string& native_app_name, | 95 const std::string& native_app_name, |
| 97 const std::string& connection_message, | 96 const std::string& connection_message, |
| 98 int destination_port, | 97 int destination_port, |
| 99 MessageType type, | 98 MessageType type, |
| 100 CreateCallback callback, | 99 CreateCallback callback, |
| 101 const NativeProcessLauncher& launcher); | 100 scoped_ptr<NativeProcessLauncher> launcher); |
| 102 | 101 |
| 103 // TYPE_SEND_MESSAGE_REQUEST will be sent via the connection message in | 102 // TYPE_SEND_MESSAGE_REQUEST will be sent via the connection message in |
| 104 // NativeMessageProcessHost::Create, so only TYPE_CONNECT_MESSAGE is expected. | 103 // NativeMessageProcessHost::Create, so only TYPE_CONNECT_MESSAGE is expected. |
| 105 void Send(const std::string& json) { | 104 void Send(const std::string& json) { |
| 106 SendImpl(TYPE_CONNECT_MESSAGE, json); | 105 SendImpl(TYPE_CONNECT_MESSAGE, json); |
| 107 } | 106 } |
| 108 | 107 |
| 109 // Try and read a single message from |read_file_|. This should only be called | 108 // Try and read a single message from |read_file_|. This should only be called |
| 110 // in unittests when you know there is data in the file. | 109 // in unittests when you know there is data in the file. |
| 111 void ReadNowForTesting(); | 110 void ReadNowForTesting(); |
| 112 | 111 |
| 113 private: | 112 private: |
| 113 enum ReadState { |
| 114 READ_STATE_INVALID, |
| 115 READ_STATE_WAITING_FOR_META, |
| 116 READ_STATE_WAITING_FOR_MESSAGE |
| 117 }; |
| 118 |
| 119 // Check that the app's path is within the proper directory on the FILE |
| 120 // thread. |
| 121 static void CheckPathOnFileThread(base::WeakPtr<Client> weak_client_ui, |
| 122 const std::string& native_app_name, |
| 123 const std::string& connection_message, |
| 124 int destination_port, |
| 125 MessageType type, |
| 126 CreateCallback callback, |
| 127 scoped_ptr<NativeProcessLauncher> launcher); |
| 128 |
| 129 // Finish the launching process. This will be run on the IO thread. |
| 130 static void FinalizeCreate(base::WeakPtr<Client> weak_client_ui, |
| 131 const std::string& connection_message, |
| 132 int destination_port, |
| 133 MessageType type, |
| 134 CreateCallback callback, |
| 135 scoped_ptr<NativeProcessLauncher> launcher, |
| 136 FilePath native_host_program); |
| 114 NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui, | 137 NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui, |
| 115 int destination_port, | 138 int destination_port, |
| 116 base::ProcessHandle native_process_handle, | 139 base::ProcessHandle native_process_handle, |
| 117 FileHandle read_fd, | 140 FileHandle read_fd, |
| 118 FileHandle write_fd, | 141 FileHandle write_fd, |
| 119 bool is_send_message); | 142 bool is_send_message); |
| 120 | 143 |
| 121 // Initialize any IO watching that needs to occur between the native process. | 144 // Initialize any IO watching that needs to occur between the native process. |
| 122 void InitIO(); | 145 void InitIO(); |
| 123 | 146 |
| 147 // Stop any IO operations in progress. |
| 148 void StopIO(); |
| 149 |
| 124 // Send a message to the native process with the specified type and payload. | 150 // Send a message to the native process with the specified type and payload. |
| 125 void SendImpl(MessageType type, const std::string& json); | 151 void SendImpl(MessageType type, const std::string& json); |
| 126 | 152 |
| 127 // Write a message/data to the native process. | 153 // Write a message/data to the native process. |
| 128 bool WriteMessage(MessageType type, const std::string& message); | 154 bool WriteMessage(MessageType type, const std::string& message); |
| 129 bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); | 155 bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); |
| 130 | 156 |
| 131 // Read a message/data from the native process. | 157 // Parse and verify the meta data (type and length) for a message. |
| 132 bool ReadMessage(MessageType* type, std::string* messgae); | 158 bool VerifyMessageMetaData(const char* message_meta_data, |
| 133 bool ReadData(FileHandle file, char* data, size_t bytes_to_write); | 159 MessageType* type, |
| 160 uint32* message_length); |
| 134 | 161 |
| 135 #if defined(OS_POSIX) | 162 #if defined(OS_POSIX) |
| 163 // Read a message from the native process. |
| 164 bool ReadMessage(MessageType* type, std::string* message); |
| 165 |
| 136 // MessageLoopForIO::Watcher | 166 // MessageLoopForIO::Watcher |
| 137 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; | 167 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; |
| 138 // We don't need to watch for writes. | 168 // We don't need to watch for writes. |
| 139 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} | 169 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} |
| 140 | 170 |
| 141 MessageLoopForIO::FileDescriptorWatcher read_watcher_; | 171 MessageLoopForIO::FileDescriptorWatcher read_watcher_; |
| 142 #endif // defined(OS_POSIX) | 172 #elif defined(OS_WIN) |
| 143 | |
| 144 #if defined(OS_WIN) | |
| 145 // MessageLoopForIO::IOHandler | 173 // MessageLoopForIO::IOHandler |
| 146 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 174 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 147 DWORD bytes_transfered, | 175 DWORD bytes_transfered, |
| 148 DWORD error) OVERRIDE; | 176 DWORD error) OVERRIDE; |
| 149 | 177 |
| 150 MessageLoopForIO::IOContext read_context_; | 178 scoped_ptr<MessageLoopForIO::IOContext> read_context_; |
| 151 MessageLoopForIO::IOContext write_context_; | 179 scoped_ptr<MessageLoopForIO::IOContext> write_context_; |
| 152 #endif // defined(OS_WIN) | |
| 153 | 180 |
| 181 ReadState read_state; |
| 182 std::string pending_message_; |
| 183 char pending_message_meta_data_[8]; |
| 184 #endif // defined(OS_POSIX) |
| 154 | 185 |
| 155 // The Client messages will be posted to. Should only be accessed from the | 186 // The Client messages will be posted to. Should only be accessed from the |
| 156 // UI thread. | 187 // UI thread. |
| 157 base::WeakPtr<Client> weak_client_ui_; | 188 base::WeakPtr<Client> weak_client_ui_; |
| 158 | 189 |
| 159 // The id of the port on the other side of this connection. This is passed to | 190 // The id of the port on the other side of this connection. This is passed to |
| 160 // |weak_client_ui_| when posting messages. | 191 // |weak_client_ui_| when posting messages. |
| 161 int destination_port_; | 192 int destination_port_; |
| 162 | 193 |
| 194 // This may be base::kNullProcessHandle during tests. On posix, this is not a |
| 195 // problem. However, on windows this may crash certian calls like |
| 196 // base::GetTerminationStatus(). |
| 163 base::ProcessHandle native_process_handle_; | 197 base::ProcessHandle native_process_handle_; |
| 164 | 198 |
| 165 FileHandle read_file_; | 199 FileHandle read_file_; |
| 166 FileHandle write_file_; | 200 FileHandle write_file_; |
| 167 ScopedFileHandle scoped_read_file_; | 201 ScopedFileHandle scoped_read_file_; |
| 168 ScopedFileHandle scoped_write_file_; | 202 ScopedFileHandle scoped_write_file_; |
| 169 | 203 |
| 170 // Only looking for one response. | 204 // Only looking for one response. |
| 171 bool is_send_message_; | 205 bool is_send_message_; |
| 172 | 206 |
| 173 DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost); | 207 DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost); |
| 174 }; | 208 }; |
| 175 | 209 |
| 176 } // namespace extensions | 210 } // namespace extensions |
| 177 | 211 |
| 178 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H
__ | 212 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H
__ |
| OLD | NEW |