Index: chrome/browser/extensions/api/messaging/native_message_process_host.h |
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.h b/chrome/browser/extensions/api/messaging/native_message_process_host.h |
index d629b089220de77641eca3596ad40710e73c5564..2299961245d14af0573e1e27dfa63f99d48e4fbf 100644 |
--- a/chrome/browser/extensions/api/messaging/native_message_process_host.h |
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host.h |
@@ -18,7 +18,7 @@ class NativeProcessLauncher; |
// Manages the native side of a connection between an extension and a native |
// process. |
// |
-// This class must only be created, called, and deleted on the FILE thread. |
+// This class must only be created, called, and deleted on the IO thread. |
// Public methods typically accept callbacks which will be invoked on the UI |
// thread. |
class NativeMessageProcessHost |
@@ -69,15 +69,17 @@ class NativeMessageProcessHost |
}; |
// Desctruction functor that ensures a NativeMessageProcessHost is destroyed |
- // on the FILE thread. |
+ // on the IO thread. |
class ScopedNativeProcessClose { |
public: |
inline void operator()(extensions::NativeMessageProcessHost* x) const { |
- content::BrowserThread::DeleteSoon(content::BrowserThread::FILE, |
- FROM_HERE, x); |
+ content::BrowserThread::DeleteSoon(content::BrowserThread::IO, |
+ FROM_HERE, x); |
} |
}; |
+ static const int kExitTimeoutMS; |
+ static const uint32 kMaxMessageDataLength; |
virtual ~NativeMessageProcessHost(); |
@@ -98,7 +100,7 @@ class NativeMessageProcessHost |
int destination_port, |
MessageType type, |
CreateCallback callback, |
- const NativeProcessLauncher& launcher); |
+ scoped_ptr<NativeProcessLauncher> launcher); |
// TYPE_SEND_MESSAGE_REQUEST will be sent via the connection message in |
// NativeMessageProcessHost::Create, so only TYPE_CONNECT_MESSAGE is expected. |
@@ -111,6 +113,57 @@ class NativeMessageProcessHost |
void ReadNowForTesting(); |
private: |
+ enum ReadState { |
+ READ_STATE_INVALID, |
+ READ_STATE_WAITING_FOR_META, |
+ READ_STATE_WAITING_FOR_MESSAGE |
+ }; |
+ |
+ struct NativeProcessHostCreationInformation { |
+ NativeProcessHostCreationInformation( |
+ base::WeakPtr<Client> weak_client_ui, |
+ std::string connection_message, |
+ int destination_port, |
+ MessageType type, |
+ CreateCallback callback, |
+ FileHandle read_handle, |
+ FileHandle write_handle, |
+ base::ProcessHandle native_process_handle) |
+ : weak_client_ui(weak_client_ui), |
+ connection_message(connection_message), |
+ destination_port(destination_port), |
+ type(type), |
+ callback(callback), |
+ read_handle(read_handle), |
+ write_handle(write_handle), |
+ native_process_handle(native_process_handle) |
+ {} |
+ |
+ base::WeakPtr<Client> weak_client_ui; |
+ std::string connection_message; |
+ int destination_port; |
+ MessageType type; |
+ CreateCallback callback; |
+ FileHandle read_handle; |
+ FileHandle write_handle; |
+ base::ProcessHandle native_process_handle; |
+ }; |
+ |
+ // Check that the app's path is within the proper directory on the FILE |
+ // thread. |
+ static void LaunchProcessOnFileThread( |
+ base::WeakPtr<Client> weak_client_ui, |
+ const std::string& native_app_name, |
+ const std::string& connection_message, |
+ int destination_port, |
+ MessageType type, |
+ CreateCallback callback, |
+ scoped_ptr<NativeProcessLauncher> launcher); |
+ |
+ // Finish the launching process. This will be run on the IO thread. |
+ static void FinalizeCreate( |
+ NativeProcessHostCreationInformation creation_info); |
+ |
NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui, |
int destination_port, |
base::ProcessHandle native_process_handle, |
@@ -121,6 +174,9 @@ class NativeMessageProcessHost |
// Initialize any IO watching that needs to occur between the native process. |
void InitIO(); |
+ // Stop any IO operations in progress. |
+ void StopIO(); |
+ |
// Send a message to the native process with the specified type and payload. |
void SendImpl(MessageType type, const std::string& json); |
@@ -128,29 +184,34 @@ class NativeMessageProcessHost |
bool WriteMessage(MessageType type, const std::string& message); |
bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); |
- // Read a message/data from the native process. |
- bool ReadMessage(MessageType* type, std::string* messgae); |
- bool ReadData(FileHandle file, char* data, size_t bytes_to_write); |
+ // Parse and verify the meta data (type and length) for a message. |
+ bool VerifyMessageMetaData(const char* message_meta_data, |
+ MessageType* type, |
+ uint32* message_length); |
#if defined(OS_POSIX) |
+ // Read a message from the native process. |
+ bool ReadMessage(MessageType* type, std::string* message); |
+ |
// MessageLoopForIO::Watcher |
virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; |
// We don't need to watch for writes. |
virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} |
MessageLoopForIO::FileDescriptorWatcher read_watcher_; |
-#endif // defined(OS_POSIX) |
- |
-#if defined(OS_WIN) |
+#elif defined(OS_WIN) |
// MessageLoopForIO::IOHandler |
virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
DWORD bytes_transfered, |
DWORD error) OVERRIDE; |
- MessageLoopForIO::IOContext read_context_; |
- MessageLoopForIO::IOContext write_context_; |
-#endif // defined(OS_WIN) |
+ scoped_ptr<MessageLoopForIO::IOContext> read_context_; |
+ scoped_ptr<MessageLoopForIO::IOContext> write_context_; |
+ ReadState read_state; |
+ std::string pending_message_; |
+ char pending_message_meta_data_[8]; |
+#endif // defined(OS_POSIX) |
// The Client messages will be posted to. Should only be accessed from the |
// UI thread. |
@@ -160,6 +221,9 @@ class NativeMessageProcessHost |
// |weak_client_ui_| when posting messages. |
int destination_port_; |
+ // This may be base::kNullProcessHandle during tests. On posix, this is not a |
+ // problem. However, on windows this may crash certian calls like |
+ // base::GetTerminationStatus(). |
base::ProcessHandle native_process_handle_; |
FileHandle read_file_; |