Chromium Code Reviews| 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 |