Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4777)

Unified Diff: chrome/browser/extensions/api/messaging/native_message_process_host.h

Issue 10818013: Native Messaging! (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Added Example Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
new file mode 100644
index 0000000000000000000000000000000000000000..ec6908eb3bccee977c7ec3da10ea3114bba26da8
--- /dev/null
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host.h
@@ -0,0 +1,179 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
+#define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
+
+#include "base/file_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/message_loop.h"
+#include "base/process.h"
+#include "content/public/browser/browser_thread.h"
+
+namespace extensions {
+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.
+// Public methods typically accept callbacks which will be invoked on the UI
+// thread.
+class NativeMessageProcessHost
+#if defined(OS_WIN)
+ : public MessageLoopForIO::IOHandler {
+#else
+ : public MessageLoopForIO::Watcher {
+#endif // defined(OS_WIN)
+ public:
+ class ScopedNativeProcessClose;
+
+#if defined(OS_WIN)
+ typedef HANDLE FileHandle;
+ typedef win::base::ScopedHandle ScopedFileHandle;
+#else
+ typedef int FileHandle;
+ typedef file_util::ScopedFD ScopedFileHandle;
+#endif // defined(OS_WIN)
+
+ typedef scoped_ptr_malloc<NativeMessageProcessHost, ScopedNativeProcessClose>
+ ScopedNativeMessageProcessHost;
Matt Perry 2012/09/06 00:40:01 nit: since this typedef is contained in the class,
eaugusti 2012/09/13 17:24:28 Done.
+
+ typedef base::Callback<void(ScopedNativeMessageProcessHost host)>
+ CreateCallback;
+
+ // Append any new types to the end. Changing the ordering will break native
+ // apps.
+ enum MessageType {
+ TYPE_SEND_MESSAGE_REQUEST, // Used when an extension is sending a one-off
+ // message to a native app.
+ TYPE_SEND_MESSAGE_RESPONSE, // Used by a native app to respond to a one-off
+ // message.
+ TYPE_CONNECT, // Used when an extension wants to establish a persistent
+ // connection with a native app.
+ TYPE_CONNECT_MESSAGE, // Used for messages after a connection has already
+ // been established.
+ NUM_MESSAGE_TYPES // The number of types of messages.
+ };
+
+ // Interface for classes that which to recieve messages from the native
+ // process.
+ class Client {
+ public:
+ virtual ~Client() {}
+ // Called on the UI thread.
+ virtual void PostMessageFromNativeProcess(int port_id,
+ const std::string& message) = 0;
+ virtual void CloseChannel(int port_id, bool error) = 0;
+ };
+
+ // Desctruction functor that ensures a NativeMessageProcessHost is destroyed
+ // on the FILE thread.
+ class ScopedNativeProcessClose {
+ public:
+ inline void operator()(extensions::NativeMessageProcessHost* x) const {
+ content::BrowserThread::DeleteSoon(content::BrowserThread::FILE,
+ FROM_HERE, x);
+ }
+ };
+
+
+ ~NativeMessageProcessHost();
+
+ // |type| must be TYPE_CONNECT or TYPE_SEND_MESSAGE_REQUEST.
+ // |callback| will be called with a NULL on error.
+ static void Create(base::WeakPtr<Client> weak_client_ui,
+ const std::string& native_app_name,
+ const std::string& connection_message,
+ int destination_port,
+ MessageType type,
+ CreateCallback callback);
+
+ // Create a NativeMessageProcessHost using the specified launcher. This allows
+ // for easy testing.
+ static void CreateWithLauncher(base::WeakPtr<Client> weak_client_ui,
+ const std::string& native_app_name,
+ const std::string& connection_message,
+ int destination_port,
+ MessageType type,
+ CreateCallback callback,
+ const NativeProcessLauncher& launcher);
+
+ // TYPE_SEND_MESSAGE_REQUEST will be sent via the connection message in
+ // NativeMessageProcessHost::Create, so only TYPE_CONNECT_MESSAGE is expected.
+ void Send(const std::string& json) {
+ SendImpl(TYPE_CONNECT_MESSAGE, json);
+ }
+
+ // Try and read a single message from |read_file_|. This should only be called
+ // in unittests when you know there is data in the file.
+ void ReadNowForTesting();
+
+ private:
+ NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui,
+ int destination_port,
+ base::ProcessHandle native_process_handle,
+ FileHandle read_fd,
+ FileHandle write_fd,
+ bool is_send_message);
+
+ // Initialize any IO watching that needs to occur between the native process.
+ void InitIO();
+
+ // Send a message to the native process with the specified type and payload.
+ void SendImpl(MessageType type, const std::string& json);
+
+ // Write a message/data to the native process.
+ 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);
+
+#if defined(OS_POSIX)
+ // MessageLoopForIO::Watcher
+ virtual void OnFileCanReadWithoutBlocking(int fd);
+ // We don't need to watch for writes.
+ virtual void OnFileCanWriteWithoutBlocking(int fd) {}
+
+ MessageLoopForIO::FileDescriptorWatcher read_watcher_;
+#endif // defined(OS_POSIX)
+
+#if defined(OS_WIN)
+ // MessageLoopForIO::IOHandler
+ virtual void OnIOCompleted(IOContext* context,
+ DWORD bytes_transfered,
+ DWORD error);
+
+ MessageLoopForIO::IOContext read_context_;
+ MessageLoopForIO::IOContext write_context_;
+#endif // defined(OS_WIN)
+
+
+ // The Client messages will be posted to. Should only be accessed from the
+ // UI thread.
+ base::WeakPtr<Client> weak_client_ui_;
+
+ // The id of the port on the other side of this connection. This is passed to
+ // |weak_client_ui_| when posting messages.
+ int destination_port_;
+
+ base::ProcessHandle native_process_handle_;
+
+ FileHandle read_file_;
+ FileHandle write_file_;
+ ScopedFileHandle scoped_read_file_;
+ ScopedFileHandle scoped_write_file_;
+
+ // Only looking for one response.
+ bool is_send_message_;
+
+ DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H__

Powered by Google App Engine
This is Rietveld 408576698