Chromium Code Reviews| 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_MESSGAE | |
|
Matt Perry
2012/10/24 23:40:31
typo
eaugusti
2012/10/30 22:03:12
Done.
| |
| 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 |
| 144 | |
| 121 // Initialize any IO watching that needs to occur between the native process. | 145 // Initialize any IO watching that needs to occur between the native process. |
| 122 void InitIO(); | 146 void InitIO(); |
| 123 | 147 |
| 148 // Stop any IO operations in progress. | |
| 149 void StopIO(); | |
| 150 | |
| 124 // Send a message to the native process with the specified type and payload. | 151 // Send a message to the native process with the specified type and payload. |
| 125 void SendImpl(MessageType type, const std::string& json); | 152 void SendImpl(MessageType type, const std::string& json); |
| 126 | 153 |
| 127 // Write a message/data to the native process. | 154 // Write a message/data to the native process. |
| 128 bool WriteMessage(MessageType type, const std::string& message); | 155 bool WriteMessage(MessageType type, const std::string& message); |
| 129 bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); | 156 bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); |
| 130 | 157 |
| 131 // Read a message/data from the native process. | 158 // Read a message/data from the native process. |
| 132 bool ReadMessage(MessageType* type, std::string* messgae); | 159 bool ReadMessage(MessageType* type, std::string* messgae); |
| 133 bool ReadData(FileHandle file, char* data, size_t bytes_to_write); | 160 bool ReadData(FileHandle file, char* data, size_t bytes_to_write); |
| 134 | 161 |
| 162 // Parse and verify the meta data (type and length) for a message. | |
| 163 bool VerifyMessageMetaData(const char* message_meta_data, | |
| 164 MessageType* type, | |
| 165 uint32* message_length); | |
| 166 | |
| 135 #if defined(OS_POSIX) | 167 #if defined(OS_POSIX) |
| 136 // MessageLoopForIO::Watcher | 168 // MessageLoopForIO::Watcher |
| 137 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; | 169 virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; |
| 138 // We don't need to watch for writes. | 170 // We don't need to watch for writes. |
| 139 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} | 171 virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} |
| 140 | 172 |
| 141 MessageLoopForIO::FileDescriptorWatcher read_watcher_; | 173 MessageLoopForIO::FileDescriptorWatcher read_watcher_; |
| 142 #endif // defined(OS_POSIX) | 174 #endif // defined(OS_POSIX) |
| 143 | 175 |
| 144 #if defined(OS_WIN) | 176 #if defined(OS_WIN) |
| 145 // MessageLoopForIO::IOHandler | 177 // MessageLoopForIO::IOHandler |
| 146 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 178 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 147 DWORD bytes_transfered, | 179 DWORD bytes_transfered, |
| 148 DWORD error) OVERRIDE; | 180 DWORD error) OVERRIDE; |
| 149 | 181 |
| 150 MessageLoopForIO::IOContext read_context_; | 182 scoped_ptr<MessageLoopForIO::IOContext> read_context_; |
| 151 MessageLoopForIO::IOContext write_context_; | 183 scoped_ptr<MessageLoopForIO::IOContext> write_context_; |
| 184 | |
| 185 ReadState read_state; | |
| 186 std::string pending_message_; | |
| 187 char pending_message_meta_data_[8]; | |
| 152 #endif // defined(OS_WIN) | 188 #endif // defined(OS_WIN) |
| 153 | 189 |
| 154 | |
| 155 // The Client messages will be posted to. Should only be accessed from the | 190 // The Client messages will be posted to. Should only be accessed from the |
| 156 // UI thread. | 191 // UI thread. |
| 157 base::WeakPtr<Client> weak_client_ui_; | 192 base::WeakPtr<Client> weak_client_ui_; |
| 158 | 193 |
| 159 // The id of the port on the other side of this connection. This is passed to | 194 // The id of the port on the other side of this connection. This is passed to |
| 160 // |weak_client_ui_| when posting messages. | 195 // |weak_client_ui_| when posting messages. |
| 161 int destination_port_; | 196 int destination_port_; |
| 162 | 197 |
| 198 // This may be base::kNullProcessHandle during tests. On posix, this is not a | |
| 199 // problem. However, on windows this may crash certian calls like | |
| 200 // base::GetTerminationStatus(). | |
| 163 base::ProcessHandle native_process_handle_; | 201 base::ProcessHandle native_process_handle_; |
| 164 | 202 |
| 165 FileHandle read_file_; | 203 FileHandle read_file_; |
| 166 FileHandle write_file_; | 204 FileHandle write_file_; |
| 167 ScopedFileHandle scoped_read_file_; | 205 ScopedFileHandle scoped_read_file_; |
| 168 ScopedFileHandle scoped_write_file_; | 206 ScopedFileHandle scoped_write_file_; |
| 169 | 207 |
| 170 // Only looking for one response. | 208 // Only looking for one response. |
| 171 bool is_send_message_; | 209 bool is_send_message_; |
| 172 | 210 |
| 173 DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost); | 211 DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost); |
| 174 }; | 212 }; |
| 175 | 213 |
| 176 } // namespace extensions | 214 } // namespace extensions |
| 177 | 215 |
| 178 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H __ | 216 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H __ |
| OLD | NEW |