diff options
Diffstat (limited to 'ipc/mojo/ipc_channel_mojo.cc')
-rw-r--r-- | ipc/mojo/ipc_channel_mojo.cc | 286 |
1 files changed, 92 insertions, 194 deletions
diff --git a/ipc/mojo/ipc_channel_mojo.cc b/ipc/mojo/ipc_channel_mojo.cc index 8832d8d..6993648 100644 --- a/ipc/mojo/ipc_channel_mojo.cc +++ b/ipc/mojo/ipc_channel_mojo.cc @@ -29,59 +29,30 @@ #include "ipc/ipc_platform_file_attachment_posix.h" #endif -#if defined(OS_MACOSX) -#include "ipc/mach_port_attachment_mac.h" -#endif - -#if defined(OS_WIN) -#include "ipc/handle_attachment_win.h" -#endif - namespace IPC { namespace { class MojoChannelFactory : public ChannelFactory { public: - MojoChannelFactory(mojo::ScopedMessagePipeHandle handle, Channel::Mode mode) - : handle_(std::move(handle)), mode_(mode) {} + MojoChannelFactory(const std::string& token, Channel::Mode mode) + : token_(token), mode_(mode) {} - std::string GetName() const override { return ""; } + std::string GetName() const override { + return token_; + } scoped_ptr<Channel> BuildChannel(Listener* listener) override { - return ChannelMojo::Create(std::move(handle_), mode_, listener); + return ChannelMojo::Create(token_, mode_, listener); } private: - mojo::ScopedMessagePipeHandle handle_; + const std::string token_; const Channel::Mode mode_; DISALLOW_COPY_AND_ASSIGN(MojoChannelFactory); }; -mojom::SerializedHandlePtr CreateSerializedHandle( - mojo::ScopedHandle handle, - mojom::SerializedHandle::Type type) { - mojom::SerializedHandlePtr serialized_handle = mojom::SerializedHandle::New(); - serialized_handle->the_handle = std::move(handle); - serialized_handle->type = type; - return serialized_handle; -} - -MojoResult WrapPlatformHandle(mojo::edk::ScopedPlatformHandle handle, - mojom::SerializedHandle::Type type, - mojom::SerializedHandlePtr* serialized) { - MojoHandle wrapped_handle; - MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper( - std::move(handle), &wrapped_handle); - if (wrap_result != MOJO_RESULT_OK) - return wrap_result; - - *serialized = CreateSerializedHandle( - mojo::MakeScopedHandle(mojo::Handle(wrapped_handle)), type); - return MOJO_RESULT_OK; -} - #if defined(OS_POSIX) && !defined(OS_NACL) base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { @@ -91,109 +62,6 @@ base::ScopedFD TakeOrDupFile(internal::PlatformFileAttachment* attachment) { #endif -MojoResult WrapAttachmentImpl(MessageAttachment* attachment, - mojom::SerializedHandlePtr* serialized) { - if (attachment->GetType() == MessageAttachment::TYPE_MOJO_HANDLE) { - *serialized = CreateSerializedHandle( - static_cast<internal::MojoHandleAttachment&>(*attachment).TakeHandle(), - mojom::SerializedHandle::Type::MOJO_HANDLE); - return MOJO_RESULT_OK; - } -#if defined(OS_POSIX) && !defined(OS_NACL) - if (attachment->GetType() == MessageAttachment::TYPE_PLATFORM_FILE) { - // We dup() the handles in IPC::Message to transmit. - // IPC::MessageAttachmentSet has intricate lifecycle semantics - // of FDs, so just to dup()-and-own them is the safest option. - base::ScopedFD file = TakeOrDupFile( - static_cast<IPC::internal::PlatformFileAttachment*>(attachment)); - if (!file.is_valid()) { - DPLOG(WARNING) << "Failed to dup FD to transmit."; - return MOJO_RESULT_UNKNOWN; - } - - return WrapPlatformHandle(mojo::edk::ScopedPlatformHandle( - mojo::edk::PlatformHandle(file.release())), - mojom::SerializedHandle::Type::MOJO_HANDLE, - serialized); - } -#endif -#if defined(OS_MACOSX) - DCHECK_EQ(attachment->GetType(), - MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); - DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), - BrokerableAttachment::MACH_PORT); - internal::MachPortAttachmentMac& mach_port_attachment = - static_cast<internal::MachPortAttachmentMac&>(*attachment); - MojoResult result = WrapPlatformHandle( - mojo::edk::ScopedPlatformHandle( - mojo::edk::PlatformHandle(mach_port_attachment.get_mach_port())), - mojom::SerializedHandle::Type::MACH_PORT, serialized); - mach_port_attachment.reset_mach_port_ownership(); - return result; -#elif defined(OS_WIN) - DCHECK_EQ(attachment->GetType(), - MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); - DCHECK_EQ(static_cast<BrokerableAttachment&>(*attachment).GetBrokerableType(), - BrokerableAttachment::WIN_HANDLE); - internal::HandleAttachmentWin& handle_attachment = - static_cast<internal::HandleAttachmentWin&>(*attachment); - MojoResult result = WrapPlatformHandle( - mojo::edk::ScopedPlatformHandle( - mojo::edk::PlatformHandle(handle_attachment.get_handle())), - mojom::SerializedHandle::Type::WIN_HANDLE, serialized); - handle_attachment.reset_handle_ownership(); - return result; -#else - NOTREACHED(); - return MOJO_RESULT_UNKNOWN; -#endif // defined(OS_MACOSX) -} - -MojoResult WrapAttachment(MessageAttachment* attachment, - mojo::Array<mojom::SerializedHandlePtr>* handles) { - mojom::SerializedHandlePtr serialized_handle; - MojoResult wrap_result = WrapAttachmentImpl(attachment, &serialized_handle); - if (wrap_result != MOJO_RESULT_OK) { - LOG(WARNING) << "Pipe failed to wrap handles. Closing: " << wrap_result; - return wrap_result; - } - handles->push_back(std::move(serialized_handle)); - return MOJO_RESULT_OK; -} - -MojoResult UnwrapAttachment(mojom::SerializedHandlePtr handle, - scoped_refptr<MessageAttachment>* attachment) { - if (handle->type == mojom::SerializedHandle::Type::MOJO_HANDLE) { - *attachment = - new IPC::internal::MojoHandleAttachment(std::move(handle->the_handle)); - return MOJO_RESULT_OK; - } - mojo::edk::ScopedPlatformHandle platform_handle; - MojoResult unwrap_result = mojo::edk::PassWrappedPlatformHandle( - handle->the_handle.release().value(), &platform_handle); - if (unwrap_result != MOJO_RESULT_OK) - return unwrap_result; -#if defined(OS_MACOSX) - if (handle->type == mojom::SerializedHandle::Type::MACH_PORT && - platform_handle.get().type == mojo::edk::PlatformHandle::Type::MACH) { - *attachment = new internal::MachPortAttachmentMac( - platform_handle.release().port, - internal::MachPortAttachmentMac::FROM_WIRE); - return MOJO_RESULT_OK; - } -#endif // defined(OS_MACOSX) -#if defined(OS_WIN) - if (handle->type == mojom::SerializedHandle::Type::WIN_HANDLE) { - *attachment = new internal::HandleAttachmentWin( - platform_handle.release().handle, - internal::HandleAttachmentWin::FROM_WIRE); - return MOJO_RESULT_OK; - } -#endif // defined(OS_WIN) - NOTREACHED(); - return MOJO_RESULT_UNKNOWN; -} - } // namespace //------------------------------------------------------------------------------ @@ -206,40 +74,53 @@ bool ChannelMojo::ShouldBeUsed() { } // static -scoped_ptr<ChannelMojo> ChannelMojo::Create( - mojo::ScopedMessagePipeHandle handle, - Mode mode, - Listener* listener) { - return make_scoped_ptr(new ChannelMojo(std::move(handle), mode, listener)); +scoped_ptr<ChannelMojo> ChannelMojo::Create(const std::string& token, + Mode mode, + Listener* listener) { + return make_scoped_ptr( + new ChannelMojo(token, mode, listener)); } // static scoped_ptr<ChannelFactory> ChannelMojo::CreateServerFactory( - mojo::ScopedMessagePipeHandle handle) { + const std::string& token) { return make_scoped_ptr( - new MojoChannelFactory(std::move(handle), Channel::MODE_SERVER)); + new MojoChannelFactory(token, Channel::MODE_SERVER)); } // static scoped_ptr<ChannelFactory> ChannelMojo::CreateClientFactory( - mojo::ScopedMessagePipeHandle handle) { + const std::string& token) { return make_scoped_ptr( - new MojoChannelFactory(std::move(handle), Channel::MODE_CLIENT)); + new MojoChannelFactory(token, Channel::MODE_CLIENT)); } -ChannelMojo::ChannelMojo(mojo::ScopedMessagePipeHandle handle, +ChannelMojo::ChannelMojo(const std::string& token, Mode mode, Listener* listener) - : listener_(listener), waiting_connect_(true), weak_factory_(this) { + : listener_(listener), + peer_pid_(base::kNullProcessId), + waiting_connect_(true), + weak_factory_(this) { // Create MojoBootstrap after all members are set as it touches // ChannelMojo from a different thread. - bootstrap_ = MojoBootstrap::Create(std::move(handle), mode, this); + bootstrap_ = MojoBootstrap::Create(token, mode, this); } ChannelMojo::~ChannelMojo() { Close(); } +scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> +ChannelMojo::CreateMessageReader(mojom::ChannelAssociatedPtrInfo sender, + mojom::ChannelAssociatedRequest receiver) { + mojom::ChannelAssociatedPtr sender_ptr; + sender_ptr.Bind(std::move(sender)); + return scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter>( + new internal::MessagePipeReader(std::move(sender_ptr), + std::move(receiver), this)); +} + bool ChannelMojo::Connect() { DCHECK(!message_reader_); bootstrap_->Connect(); @@ -257,8 +138,8 @@ void ChannelMojo::OnPipesAvailable( mojom::ChannelAssociatedPtrInfo send_channel, mojom::ChannelAssociatedRequest receive_channel, int32_t peer_pid) { - InitMessageReader(std::move(send_channel), std::move(receive_channel), - peer_pid); + set_peer_pid(peer_pid); + InitMessageReader(std::move(send_channel), std::move(receive_channel)); } void ChannelMojo::OnBootstrapError() { @@ -266,13 +147,9 @@ void ChannelMojo::OnBootstrapError() { } void ChannelMojo::InitMessageReader(mojom::ChannelAssociatedPtrInfo sender, - mojom::ChannelAssociatedRequest receiver, - base::ProcessId peer_pid) { - mojom::ChannelAssociatedPtr sender_ptr; - sender_ptr.Bind(std::move(sender)); - scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> reader( - new internal::MessagePipeReader(std::move(sender_ptr), - std::move(receiver), peer_pid, this)); + mojom::ChannelAssociatedRequest receiver) { + scoped_ptr<internal::MessagePipeReader, ChannelMojo::ReaderDeleter> reader = + CreateMessageReader(std::move(sender), std::move(receiver)); for (size_t i = 0; i < pending_messages_.size(); ++i) { bool sent = reader->Send(std::move(pending_messages_[i])); @@ -315,10 +192,7 @@ bool ChannelMojo::Send(Message* message) { } base::ProcessId ChannelMojo::GetPeerPID() const { - if (!message_reader_) - return base::kNullProcessId; - - return message_reader_->GetPeerPid(); + return peer_pid_; } base::ProcessId ChannelMojo::GetSelfPID() const { @@ -329,10 +203,6 @@ void ChannelMojo::OnMessageReceived(const Message& message) { TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived", "class", IPC_MESSAGE_ID_CLASS(message.type()), "line", IPC_MESSAGE_ID_LINE(message.type())); - if (AttachmentBroker* broker = AttachmentBroker::GetGlobal()) { - if (broker->OnMessageReceived(message)) - return; - } listener_->OnMessageReceived(message); if (message.dispatch_error()) listener_->OnBadMessageReceived(message); @@ -351,53 +221,81 @@ base::ScopedFD ChannelMojo::TakeClientFileDescriptor() { // static MojoResult ChannelMojo::ReadFromMessageAttachmentSet( Message* message, - mojo::Array<mojom::SerializedHandlePtr>* handles) { + mojo::Array<mojo::ScopedHandle>* handles) { + // We dup() the handles in IPC::Message to transmit. + // IPC::MessageAttachmentSet has intricate lifecycle semantics + // of FDs, so just to dup()-and-own them is the safest option. if (message->HasAttachments()) { MessageAttachmentSet* set = message->attachment_set(); for (unsigned i = 0; i < set->num_non_brokerable_attachments(); ++i) { - MojoResult result = WrapAttachment( - set->GetNonBrokerableAttachmentAt(i).get(), handles); - if (result != MOJO_RESULT_OK) { - set->CommitAllDescriptors(); - return result; - } - } - for (unsigned i = 0; i < set->num_brokerable_attachments(); ++i) { - MojoResult result = - WrapAttachment(set->GetBrokerableAttachmentAt(i).get(), handles); - if (result != MOJO_RESULT_OK) { - set->CommitAllDescriptors(); - return result; + scoped_refptr<MessageAttachment> attachment = + set->GetNonBrokerableAttachmentAt(i); + switch (attachment->GetType()) { + case MessageAttachment::TYPE_PLATFORM_FILE: +#if defined(OS_POSIX) && !defined(OS_NACL) + { + base::ScopedFD file = + TakeOrDupFile(static_cast<IPC::internal::PlatformFileAttachment*>( + attachment.get())); + if (!file.is_valid()) { + DPLOG(WARNING) << "Failed to dup FD to transmit."; + set->CommitAllDescriptors(); + return MOJO_RESULT_UNKNOWN; + } + + MojoHandle wrapped_handle; + MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper( + mojo::edk::ScopedPlatformHandle( + mojo::edk::PlatformHandle(file.release())), + &wrapped_handle); + if (MOJO_RESULT_OK != wrap_result) { + LOG(WARNING) << "Pipe failed to wrap handles. Closing: " + << wrap_result; + set->CommitAllDescriptors(); + return wrap_result; + } + + handles->push_back( + mojo::MakeScopedHandle(mojo::Handle(wrapped_handle))); + } +#else + NOTREACHED(); +#endif // defined(OS_POSIX) && !defined(OS_NACL) + break; + case MessageAttachment::TYPE_MOJO_HANDLE: { + mojo::ScopedHandle handle = + static_cast<IPC::internal::MojoHandleAttachment*>( + attachment.get())->TakeHandle(); + handles->push_back(std::move(handle)); + } break; + case MessageAttachment::TYPE_BROKERABLE_ATTACHMENT: + // Brokerable attachments are handled by the AttachmentBroker so + // there's no need to do anything here. + NOTREACHED(); + break; } } + set->CommitAllDescriptors(); } + return MOJO_RESULT_OK; } // static MojoResult ChannelMojo::WriteToMessageAttachmentSet( - mojo::Array<mojom::SerializedHandlePtr> handle_buffer, + mojo::Array<mojo::ScopedHandle> handle_buffer, Message* message) { for (size_t i = 0; i < handle_buffer.size(); ++i) { - scoped_refptr<MessageAttachment> unwrapped_attachment; - MojoResult unwrap_result = UnwrapAttachment(std::move(handle_buffer[i]), - &unwrapped_attachment); - if (unwrap_result != MOJO_RESULT_OK) { - LOG(WARNING) << "Pipe failed to unwrap handles. Closing: " - << unwrap_result; - return unwrap_result; - } - DCHECK(unwrapped_attachment); - bool ok = message->attachment_set()->AddAttachment( - std::move(unwrapped_attachment)); + new IPC::internal::MojoHandleAttachment(std::move(handle_buffer[i]))); DCHECK(ok); if (!ok) { LOG(ERROR) << "Failed to add new Mojo handle."; return MOJO_RESULT_UNKNOWN; } } + return MOJO_RESULT_OK; } |