| 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_;
|
|
|