OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ | |
6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_ | |
7 | |
8 #include "base/file_util.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/memory/weak_ptr.h" | |
11 #include "base/message_loop.h" | |
12 #include "base/process.h" | |
13 #include "content/public/browser/browser_thread.h" | |
14 | |
15 namespace extensions { | |
16 class NativeProcessLauncher; | |
17 | |
18 // Manages the native side of a connection between an extension and a native | |
19 // process. | |
20 // | |
21 // This class must only be created, called, and deleted on the FILE thread. | |
22 // Public methods typically accept callbacks which will be invoked on the UI | |
23 // thread. | |
24 class NativeMessageProcessHost | |
25 #if defined(OS_WIN) | |
26 : public MessageLoopForIO::IOHandler { | |
27 #else | |
28 : public MessageLoopForIO::Watcher { | |
29 #endif // defined(OS_WIN) | |
30 public: | |
31 class ScopedNativeProcessClose; | |
32 | |
33 #if defined(OS_WIN) | |
34 typedef HANDLE FileHandle; | |
35 typedef win::base::ScopedHandle ScopedFileHandle; | |
36 #else | |
37 typedef int FileHandle; | |
38 typedef file_util::ScopedFD ScopedFileHandle; | |
39 #endif // defined(OS_WIN) | |
40 | |
41 typedef scoped_ptr_malloc<NativeMessageProcessHost, ScopedNativeProcessClose> | |
42 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.
| |
43 | |
44 typedef base::Callback<void(ScopedNativeMessageProcessHost host)> | |
45 CreateCallback; | |
46 | |
47 // Append any new types to the end. Changing the ordering will break native | |
48 // apps. | |
49 enum MessageType { | |
50 TYPE_SEND_MESSAGE_REQUEST, // Used when an extension is sending a one-off | |
51 // message to a native app. | |
52 TYPE_SEND_MESSAGE_RESPONSE, // Used by a native app to respond to a one-off | |
53 // message. | |
54 TYPE_CONNECT, // Used when an extension wants to establish a persistent | |
55 // connection with a native app. | |
56 TYPE_CONNECT_MESSAGE, // Used for messages after a connection has already | |
57 // been established. | |
58 NUM_MESSAGE_TYPES // The number of types of messages. | |
59 }; | |
60 | |
61 // Interface for classes that which to recieve messages from the native | |
62 // process. | |
63 class Client { | |
64 public: | |
65 virtual ~Client() {} | |
66 // Called on the UI thread. | |
67 virtual void PostMessageFromNativeProcess(int port_id, | |
68 const std::string& message) = 0; | |
69 virtual void CloseChannel(int port_id, bool error) = 0; | |
70 }; | |
71 | |
72 // Desctruction functor that ensures a NativeMessageProcessHost is destroyed | |
73 // on the FILE thread. | |
74 class ScopedNativeProcessClose { | |
75 public: | |
76 inline void operator()(extensions::NativeMessageProcessHost* x) const { | |
77 content::BrowserThread::DeleteSoon(content::BrowserThread::FILE, | |
78 FROM_HERE, x); | |
79 } | |
80 }; | |
81 | |
82 | |
83 ~NativeMessageProcessHost(); | |
84 | |
85 // |type| must be TYPE_CONNECT or TYPE_SEND_MESSAGE_REQUEST. | |
86 // |callback| will be called with a NULL on error. | |
87 static void Create(base::WeakPtr<Client> weak_client_ui, | |
88 const std::string& native_app_name, | |
89 const std::string& connection_message, | |
90 int destination_port, | |
91 MessageType type, | |
92 CreateCallback callback); | |
93 | |
94 // Create a NativeMessageProcessHost using the specified launcher. This allows | |
95 // for easy testing. | |
96 static void CreateWithLauncher(base::WeakPtr<Client> weak_client_ui, | |
97 const std::string& native_app_name, | |
98 const std::string& connection_message, | |
99 int destination_port, | |
100 MessageType type, | |
101 CreateCallback callback, | |
102 const NativeProcessLauncher& launcher); | |
103 | |
104 // TYPE_SEND_MESSAGE_REQUEST will be sent via the connection message in | |
105 // NativeMessageProcessHost::Create, so only TYPE_CONNECT_MESSAGE is expected. | |
106 void Send(const std::string& json) { | |
107 SendImpl(TYPE_CONNECT_MESSAGE, json); | |
108 } | |
109 | |
110 // Try and read a single message from |read_file_|. This should only be called | |
111 // in unittests when you know there is data in the file. | |
112 void ReadNowForTesting(); | |
113 | |
114 private: | |
115 NativeMessageProcessHost(base::WeakPtr<Client> weak_client_ui, | |
116 int destination_port, | |
117 base::ProcessHandle native_process_handle, | |
118 FileHandle read_fd, | |
119 FileHandle write_fd, | |
120 bool is_send_message); | |
121 | |
122 // Initialize any IO watching that needs to occur between the native process. | |
123 void InitIO(); | |
124 | |
125 // Send a message to the native process with the specified type and payload. | |
126 void SendImpl(MessageType type, const std::string& json); | |
127 | |
128 // Write a message/data to the native process. | |
129 bool WriteMessage(MessageType type, const std::string& message); | |
130 bool WriteData(FileHandle file, const char* data, size_t bytes_to_write); | |
131 | |
132 // Read a message/data from the native process. | |
133 bool ReadMessage(MessageType* type, std::string* messgae); | |
134 bool ReadData(FileHandle file, char* data, size_t bytes_to_write); | |
135 | |
136 #if defined(OS_POSIX) | |
137 // MessageLoopForIO::Watcher | |
138 virtual void OnFileCanReadWithoutBlocking(int fd); | |
139 // We don't need to watch for writes. | |
140 virtual void OnFileCanWriteWithoutBlocking(int fd) {} | |
141 | |
142 MessageLoopForIO::FileDescriptorWatcher read_watcher_; | |
143 #endif // defined(OS_POSIX) | |
144 | |
145 #if defined(OS_WIN) | |
146 // MessageLoopForIO::IOHandler | |
147 virtual void OnIOCompleted(IOContext* context, | |
148 DWORD bytes_transfered, | |
149 DWORD error); | |
150 | |
151 MessageLoopForIO::IOContext read_context_; | |
152 MessageLoopForIO::IOContext write_context_; | |
153 #endif // defined(OS_WIN) | |
154 | |
155 | |
156 // The Client messages will be posted to. Should only be accessed from the | |
157 // UI thread. | |
158 base::WeakPtr<Client> weak_client_ui_; | |
159 | |
160 // The id of the port on the other side of this connection. This is passed to | |
161 // |weak_client_ui_| when posting messages. | |
162 int destination_port_; | |
163 | |
164 base::ProcessHandle native_process_handle_; | |
165 | |
166 FileHandle read_file_; | |
167 FileHandle write_file_; | |
168 ScopedFileHandle scoped_read_file_; | |
169 ScopedFileHandle scoped_write_file_; | |
170 | |
171 // Only looking for one response. | |
172 bool is_send_message_; | |
173 | |
174 DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost); | |
175 }; | |
176 | |
177 } // namespace extensions | |
178 | |
179 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H __ | |
OLD | NEW |