OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include "ipc/mojo/ipc_channel_mojo.h" | 5 #include "ipc/mojo/ipc_channel_mojo.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "ipc/ipc_listener.h" | 10 #include "ipc/ipc_listener.h" |
11 #include "ipc/mojo/ipc_channel_mojo_readers.h" | 11 #include "ipc/mojo/ipc_channel_mojo_readers.h" |
12 #include "ipc/mojo/ipc_mojo_bootstrap.h" | |
12 #include "mojo/embedder/embedder.h" | 13 #include "mojo/embedder/embedder.h" |
13 | 14 |
14 #if defined(OS_POSIX) && !defined(OS_NACL) | 15 #if defined(OS_POSIX) && !defined(OS_NACL) |
15 #include "ipc/file_descriptor_set_posix.h" | 16 #include "ipc/file_descriptor_set_posix.h" |
16 #endif | 17 #endif |
17 | 18 |
18 namespace IPC { | 19 namespace IPC { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
(...skipping 12 matching lines...) Expand all Loading... | |
34 | 35 |
35 virtual void OnChannelError() OVERRIDE { | 36 virtual void OnChannelError() OVERRIDE { |
36 NOTREACHED(); | 37 NOTREACHED(); |
37 } | 38 } |
38 | 39 |
39 virtual void OnBadMessageReceived(const Message& message) OVERRIDE { | 40 virtual void OnBadMessageReceived(const Message& message) OVERRIDE { |
40 NOTREACHED(); | 41 NOTREACHED(); |
41 } | 42 } |
42 }; | 43 }; |
43 | 44 |
44 base::LazyInstance<NullListener> g_null_listener = LAZY_INSTANCE_INITIALIZER; | |
45 | |
46 class MojoChannelFactory : public ChannelFactory { | 45 class MojoChannelFactory : public ChannelFactory { |
47 public: | 46 public: |
48 MojoChannelFactory( | 47 MojoChannelFactory( |
49 ChannelHandle channel_handle, | 48 ChannelHandle channel_handle, |
50 Channel::Mode mode, | 49 Channel::Mode mode, |
51 scoped_refptr<base::TaskRunner> io_thread_task_runner) | 50 scoped_refptr<base::TaskRunner> io_thread_task_runner) |
52 : channel_handle_(channel_handle), | 51 : channel_handle_(channel_handle), |
53 mode_(mode), | 52 mode_(mode), |
54 io_thread_task_runner_(io_thread_task_runner) { | 53 io_thread_task_runner_(io_thread_task_runner) { |
55 } | 54 } |
56 | 55 |
57 virtual std::string GetName() const OVERRIDE { | 56 virtual std::string GetName() const OVERRIDE { |
58 return channel_handle_.name; | 57 return channel_handle_.name; |
59 } | 58 } |
60 | 59 |
61 virtual scoped_ptr<Channel> BuildChannel(Listener* listener) OVERRIDE { | 60 virtual scoped_ptr<Channel> BuildChannel(Listener* listener) OVERRIDE { |
62 return ChannelMojo::Create( | 61 return ChannelMojo::Create( |
63 channel_handle_, | 62 channel_handle_, |
64 mode_, | 63 mode_, |
65 listener, | 64 listener, |
66 io_thread_task_runner_).PassAs<Channel>(); | 65 io_thread_task_runner_).PassAs<Channel>(); |
67 } | 66 } |
68 | 67 |
69 private: | 68 private: |
70 ChannelHandle channel_handle_; | 69 ChannelHandle channel_handle_; |
71 Channel::Mode mode_; | 70 Channel::Mode mode_; |
72 scoped_refptr<base::TaskRunner> io_thread_task_runner_; | 71 scoped_refptr<base::TaskRunner> io_thread_task_runner_; |
73 }; | 72 }; |
74 | 73 |
75 mojo::embedder::PlatformHandle ToPlatformHandle( | 74 //------------------------------------------------------------------------------ |
76 const ChannelHandle& handle) { | 75 |
77 #if defined(OS_POSIX) && !defined(OS_NACL) | 76 // TODO(morrita): This should be built using higher-level Mojo construct |
78 return mojo::embedder::PlatformHandle(handle.socket.fd); | 77 // for clarity and extensibility. |
79 #elif defined(OS_WIN) | 78 class HelloMessage { |
viettrungluu
2014/09/15 22:37:27
I don't think you need (or use) this anywhere?
Hajime Morrita
2014/09/15 23:51:33
Right. Removing.
| |
80 return mojo::embedder::PlatformHandle(handle.pipe.handle); | 79 public: |
81 #else | 80 static Pickle CreateRequest(int32 pid) { |
82 #error "Unsupported Platform!" | 81 Pickle request; |
83 #endif | 82 request.WriteString(kHelloRequestMagic); |
84 } | 83 request.WriteInt(pid); |
84 return request; | |
85 } | |
86 | |
87 static bool ReadRequest(Pickle& pickle, int32* pid) { | |
88 PickleIterator iter(pickle); | |
89 std::string hello; | |
90 if (!iter.ReadString(&hello)) { | |
91 DLOG(WARNING) << "Failed to Read magic string."; | |
92 return false; | |
93 } | |
94 | |
95 if (hello != kHelloRequestMagic) { | |
96 DLOG(WARNING) << "Magic mismatch:" << hello; | |
97 return false; | |
98 } | |
99 | |
100 int read_pid; | |
101 if (!iter.ReadInt(&read_pid)) { | |
102 DLOG(WARNING) << "Failed to Read PID."; | |
103 return false; | |
104 } | |
105 | |
106 *pid = read_pid; | |
107 return true; | |
108 } | |
109 | |
110 static Pickle CreateResponse(int32 pid) { | |
111 Pickle request; | |
112 request.WriteString(kHelloResponseMagic); | |
113 request.WriteInt(pid); | |
114 return request; | |
115 } | |
116 | |
117 static bool ReadResponse(Pickle& pickle, int32* pid) { | |
118 PickleIterator iter(pickle); | |
119 std::string hello; | |
120 if (!iter.ReadString(&hello)) { | |
121 DLOG(WARNING) << "Failed to read magic string."; | |
122 return false; | |
123 } | |
124 | |
125 if (hello != kHelloResponseMagic) { | |
126 DLOG(WARNING) << "Magic mismatch:" << hello; | |
127 return false; | |
128 } | |
129 | |
130 int read_pid; | |
131 if (!iter.ReadInt(&read_pid)) { | |
132 DLOG(WARNING) << "Failed to read PID."; | |
133 return false; | |
134 } | |
135 | |
136 *pid = read_pid; | |
137 return true; | |
138 } | |
139 | |
140 private: | |
141 static const char* kHelloRequestMagic; | |
142 static const char* kHelloResponseMagic; | |
143 }; | |
144 | |
145 const char* HelloMessage::kHelloRequestMagic = "MREQ"; | |
146 const char* HelloMessage::kHelloResponseMagic = "MRES"; | |
85 | 147 |
86 } // namespace | 148 } // namespace |
87 | 149 |
88 //------------------------------------------------------------------------------ | 150 //------------------------------------------------------------------------------ |
89 | 151 |
90 void ChannelMojo::ChannelInfoDeleter::operator()( | 152 void ChannelMojo::ChannelInfoDeleter::operator()( |
91 mojo::embedder::ChannelInfo* ptr) const { | 153 mojo::embedder::ChannelInfo* ptr) const { |
92 mojo::embedder::DestroyChannelOnIOThread(ptr); | 154 mojo::embedder::DestroyChannelOnIOThread(ptr); |
93 } | 155 } |
94 | 156 |
(...skipping 10 matching lines...) Expand all Loading... | |
105 // static | 167 // static |
106 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( | 168 scoped_ptr<ChannelFactory> ChannelMojo::CreateFactory( |
107 const ChannelHandle &channel_handle, Mode mode, | 169 const ChannelHandle &channel_handle, Mode mode, |
108 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 170 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
109 return make_scoped_ptr( | 171 return make_scoped_ptr( |
110 new MojoChannelFactory( | 172 new MojoChannelFactory( |
111 channel_handle, mode, | 173 channel_handle, mode, |
112 io_thread_task_runner)).PassAs<ChannelFactory>(); | 174 io_thread_task_runner)).PassAs<ChannelFactory>(); |
113 } | 175 } |
114 | 176 |
115 ChannelMojo::ChannelMojo(const ChannelHandle& channel_handle, | 177 ChannelMojo::ChannelMojo(const ChannelHandle& handle, |
116 Mode mode, | 178 Mode mode, |
117 Listener* listener, | 179 Listener* listener, |
118 scoped_refptr<base::TaskRunner> io_thread_task_runner) | 180 scoped_refptr<base::TaskRunner> io_thread_task_runner) |
119 : bootstrap_( | 181 : mode_(mode), |
120 Channel::Create(channel_handle, mode, g_null_listener.Pointer())), | |
121 mode_(mode), | |
122 listener_(listener), | 182 listener_(listener), |
123 peer_pid_(base::kNullProcessId), | 183 peer_pid_(base::kNullProcessId), |
124 weak_factory_(this) { | 184 weak_factory_(this) { |
125 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { | 185 if (base::MessageLoopProxy::current() == io_thread_task_runner.get()) { |
126 InitOnIOThread(); | 186 InitBootstrap(handle); |
127 } else { | 187 } else { |
128 io_thread_task_runner->PostTask(FROM_HERE, | 188 io_thread_task_runner->PostTask( |
129 base::Bind(&ChannelMojo::InitOnIOThread, | 189 FROM_HERE, |
130 weak_factory_.GetWeakPtr())); | 190 base::Bind( |
191 &ChannelMojo::InitBootstrap, weak_factory_.GetWeakPtr(), handle)); | |
131 } | 192 } |
132 } | 193 } |
133 | 194 |
134 ChannelMojo::~ChannelMojo() { | 195 ChannelMojo::~ChannelMojo() { |
135 Close(); | 196 Close(); |
136 } | 197 } |
137 | 198 |
138 void ChannelMojo::InitOnIOThread() { | 199 void ChannelMojo::InitBootstrap(ChannelHandle handle) { |
200 DCHECK(base::MessageLoopForIO::IsCurrent()); | |
201 bootstrap_ = MojoBootstrap::Create(handle, mode_, this); | |
202 } | |
203 | |
204 void ChannelMojo::InitControlReader( | |
205 mojo::embedder::ScopedPlatformHandle handle) { | |
206 DCHECK(base::MessageLoopForIO::IsCurrent()); | |
139 mojo::embedder::ChannelInfo* channel_info; | 207 mojo::embedder::ChannelInfo* channel_info; |
140 mojo::ScopedMessagePipeHandle control_pipe = | 208 mojo::ScopedMessagePipeHandle control_pipe = |
141 mojo::embedder::CreateChannelOnIOThread( | 209 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); |
142 mojo::embedder::ScopedPlatformHandle( | |
143 ToPlatformHandle(bootstrap_->TakePipeHandle())), | |
144 &channel_info); | |
145 channel_info_.reset(channel_info); | 210 channel_info_.reset(channel_info); |
146 | 211 |
147 switch (mode_) { | 212 switch (mode_) { |
148 case MODE_SERVER: | 213 case MODE_SERVER: |
149 control_reader_.reset( | 214 control_reader_.reset( |
150 new internal::ServerControlReader(control_pipe.Pass(), this)); | 215 new internal::ServerControlReader(control_pipe.Pass(), this)); |
151 break; | 216 break; |
152 case MODE_CLIENT: | 217 case MODE_CLIENT: |
153 control_reader_.reset( | 218 control_reader_.reset( |
154 new internal::ClientControlReader(control_pipe.Pass(), this)); | 219 new internal::ClientControlReader(control_pipe.Pass(), this)); |
155 break; | 220 break; |
156 default: | 221 default: |
157 NOTREACHED(); | 222 NOTREACHED(); |
158 break; | 223 break; |
159 } | 224 } |
160 } | 225 } |
161 | 226 |
162 bool ChannelMojo::Connect() { | 227 bool ChannelMojo::Connect() { |
163 DCHECK(!message_reader_); | 228 DCHECK(!message_reader_); |
164 return control_reader_->Connect(); | 229 DCHECK(!control_reader_); |
230 return bootstrap_->Connect(); | |
165 } | 231 } |
166 | 232 |
167 void ChannelMojo::Close() { | 233 void ChannelMojo::Close() { |
168 control_reader_.reset(); | 234 control_reader_.reset(); |
169 message_reader_.reset(); | 235 message_reader_.reset(); |
170 channel_info_.reset(); | 236 channel_info_.reset(); |
171 } | 237 } |
172 | 238 |
239 void ChannelMojo::OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) { | |
240 InitControlReader(handle.Pass()); | |
241 control_reader_->Connect(); | |
242 } | |
243 | |
244 void ChannelMojo::OnBootstrapError() { | |
245 listener_->OnChannelError(); | |
246 } | |
247 | |
173 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { | 248 void ChannelMojo::OnConnected(mojo::ScopedMessagePipeHandle pipe) { |
174 message_reader_ = | 249 message_reader_ = |
175 make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this)); | 250 make_scoped_ptr(new internal::MessageReader(pipe.Pass(), this)); |
176 | 251 |
177 for (size_t i = 0; i < pending_messages_.size(); ++i) { | 252 for (size_t i = 0; i < pending_messages_.size(); ++i) { |
178 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); | 253 message_reader_->Send(make_scoped_ptr(pending_messages_[i])); |
179 pending_messages_[i] = NULL; | 254 pending_messages_[i] = NULL; |
180 } | 255 } |
181 | 256 |
182 pending_messages_.clear(); | 257 pending_messages_.clear(); |
(...skipping 17 matching lines...) Expand all Loading... | |
200 } | 275 } |
201 | 276 |
202 return message_reader_->Send(make_scoped_ptr(message)); | 277 return message_reader_->Send(make_scoped_ptr(message)); |
203 } | 278 } |
204 | 279 |
205 base::ProcessId ChannelMojo::GetPeerPID() const { | 280 base::ProcessId ChannelMojo::GetPeerPID() const { |
206 return peer_pid_; | 281 return peer_pid_; |
207 } | 282 } |
208 | 283 |
209 base::ProcessId ChannelMojo::GetSelfPID() const { | 284 base::ProcessId ChannelMojo::GetSelfPID() const { |
210 return bootstrap_->GetSelfPID(); | 285 return base::GetCurrentProcId(); |
211 } | 286 } |
212 | 287 |
213 ChannelHandle ChannelMojo::TakePipeHandle() { | 288 ChannelHandle ChannelMojo::TakePipeHandle() { |
214 return bootstrap_->TakePipeHandle(); | 289 NOTREACHED(); |
290 return ChannelHandle(); | |
291 } | |
292 | |
293 void ChannelMojo::OnClientLaunched(base::ProcessHandle handle) { | |
294 bootstrap_->OnClientLaunched(handle); | |
215 } | 295 } |
216 | 296 |
217 void ChannelMojo::OnMessageReceived(Message& message) { | 297 void ChannelMojo::OnMessageReceived(Message& message) { |
218 listener_->OnMessageReceived(message); | 298 listener_->OnMessageReceived(message); |
219 if (message.dispatch_error()) | 299 if (message.dispatch_error()) |
220 listener_->OnBadMessageReceived(message); | 300 listener_->OnBadMessageReceived(message); |
221 } | 301 } |
222 | 302 |
223 #if defined(OS_POSIX) && !defined(OS_NACL) | 303 #if defined(OS_POSIX) && !defined(OS_NACL) |
224 int ChannelMojo::GetClientFileDescriptor() const { | 304 int ChannelMojo::GetClientFileDescriptor() const { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 handles->push_back(wrapped_handle); | 360 handles->push_back(wrapped_handle); |
281 } | 361 } |
282 } | 362 } |
283 | 363 |
284 return MOJO_RESULT_OK; | 364 return MOJO_RESULT_OK; |
285 } | 365 } |
286 | 366 |
287 #endif // defined(OS_POSIX) && !defined(OS_NACL) | 367 #endif // defined(OS_POSIX) && !defined(OS_NACL) |
288 | 368 |
289 } // namespace IPC | 369 } // namespace IPC |
OLD | NEW |