diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-08-14 11:38:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2015-08-14 17:16:47 +0000 |
commit | 3a97ca8dd9b96b599ae2d33e40df0dd2f7ea5859 (patch) | |
tree | 43cc572ba067417c7341db81f71ae7cc6e0fcc3e /chromium/ipc | |
parent | f61ab1ac7f855cd281809255c0aedbb1895e1823 (diff) | |
download | qtwebengine-chromium-3a97ca8dd9b96b599ae2d33e40df0dd2f7ea5859.tar.gz |
BASELINE: Update chromium to 45.0.2454.40
Change-Id: Id2121d9f11a8fc633677236c65a3e41feef589e4
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
Diffstat (limited to 'chromium/ipc')
81 files changed, 1550 insertions, 929 deletions
diff --git a/chromium/ipc/BUILD.gn b/chromium/ipc/BUILD.gn index b756921e7dd..0c50923ef1f 100644 --- a/chromium/ipc/BUILD.gn +++ b/chromium/ipc/BUILD.gn @@ -6,6 +6,14 @@ import("//testing/test.gni") component("ipc") { sources = [ + "attachment_broker.h", + "attachment_broker_messages.h", + "attachment_broker_win.cc", + "attachment_broker_win.h", + "brokerable_attachment.cc", + "brokerable_attachment.h", + "handle_attachment_win.cc", + "handle_attachment_win.h", "ipc_channel.cc", "ipc_channel.h", "ipc_channel_common.cc", @@ -26,6 +34,8 @@ component("ipc") { "ipc_export.h", "ipc_forwarding_message_filter.cc", "ipc_forwarding_message_filter.h", + "ipc_handle_win.cc", + "ipc_handle_win.h", "ipc_listener.h", "ipc_logging.cc", "ipc_logging.h", @@ -35,6 +45,8 @@ component("ipc") { "ipc_message_attachment.h", "ipc_message_attachment_set.cc", "ipc_message_attachment_set.h", + "ipc_message_generator.cc", + "ipc_message_generator.h", "ipc_message_macros.h", "ipc_message_start.h", "ipc_message_utils.cc", @@ -91,6 +103,7 @@ component("ipc") { # TODO(viettrungluu): Needed for base/lazy_instance.h, which is suspect. "//base/third_party/dynamic_annotations", + "//crypto:crypto", ] } diff --git a/chromium/ipc/DEPS b/chromium/ipc/DEPS index eea2192499e..1c97fa3433f 100644 --- a/chromium/ipc/DEPS +++ b/chromium/ipc/DEPS @@ -1,4 +1,5 @@ include_rules = [ + "+crypto", # For ipc_channel_nacl.cc: "+native_client/src/public", ] diff --git a/chromium/ipc/attachment_broker.h b/chromium/ipc/attachment_broker.h new file mode 100644 index 00000000000..715c5e594f5 --- /dev/null +++ b/chromium/ipc/attachment_broker.h @@ -0,0 +1,53 @@ +// Copyright 2015 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 IPC_ATTACHMENT_BROKER_H_ +#define IPC_ATTACHMENT_BROKER_H_ + +#include "base/macros.h" +#include "base/process/process_handle.h" +#include "ipc/brokerable_attachment.h" +#include "ipc/ipc_export.h" + +namespace IPC { + +class AttachmentBroker; +// Classes that inherit from this abstract base class are capable of +// communicating with a broker to send and receive attachments to Chrome IPC +// messages. +class IPC_EXPORT SupportsAttachmentBrokering { + public: + // Returns an AttachmentBroker used to broker attachments of IPC messages to + // other processes. There must be exactly one AttachmentBroker per process. + virtual AttachmentBroker* GetAttachmentBroker() = 0; +}; + +// Responsible for brokering attachments to Chrome IPC messages. On platforms +// that support attachment brokering, every IPC channel should have a reference +// to a AttachmentBroker. +class IPC_EXPORT AttachmentBroker { + public: + AttachmentBroker() {} + virtual ~AttachmentBroker() {} + + // Sends |attachment| to |destination_process|. The implementation uses an + // IPC::Channel to communicate with the broker process. This may be the same + // IPC::Channel that is requesting the brokering of an attachment. + // Returns true on success and false otherwise. + virtual bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + base::ProcessId destination_process) = 0; + + // Returns whether the attachment was available. If the attachment was + // available, populates the output parameter |attachment|. The caller then + // becomes the owner of |attachment|. + virtual bool GetAttachmentWithId(BrokerableAttachment::AttachmentId id, + BrokerableAttachment* attachment) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(AttachmentBroker); +}; + +} // namespace IPC + +#endif // IPC_ATTACHMENT_BROKER_H_ diff --git a/chromium/ipc/attachment_broker_messages.h b/chromium/ipc/attachment_broker_messages.h new file mode 100644 index 00000000000..30ae04e385c --- /dev/null +++ b/chromium/ipc/attachment_broker_messages.h @@ -0,0 +1,53 @@ +// Copyright 2015 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. + +// IPC messages used by the attachment broker. +// Multiply-included message file, hence no include guard. + +#include "ipc/brokerable_attachment.h" +#include "ipc/ipc_message_macros.h" + +#if defined(OS_WIN) +#include "ipc/handle_attachment_win.h" +#endif // defined(OS_WIN) + +// ---------------------------------------------------------------------------- +// Serialization of structs. +// ---------------------------------------------------------------------------- + +#if defined(OS_WIN) +IPC_STRUCT_TRAITS_BEGIN(IPC::internal::HandleAttachmentWin::WireFormat) +IPC_STRUCT_TRAITS_MEMBER(handle) +IPC_STRUCT_TRAITS_MEMBER(destination_process) +IPC_STRUCT_TRAITS_MEMBER(attachment_id) +IPC_STRUCT_TRAITS_END() +#endif // defined(OS_WIN) + +#define IPC_MESSAGE_START AttachmentBrokerMsgStart + +// ---------------------------------------------------------------------------- +// Messages sent from the broker to a non-broker process. +// ---------------------------------------------------------------------------- + +#if defined(OS_WIN) +// Sent from a broker to a non-broker to indicate that a windows HANDLE has been +// brokered. Contains all information necessary for the non-broker to translate +// a BrokerAttachment::AttachmentId to a BrokerAttachment. +IPC_MESSAGE_CONTROL1( + AttachmentBrokerMsg_WinHandleHasBeenDuplicated, + IPC::internal::HandleAttachmentWin::WireFormat /* wire_format */) +#endif // defined(OS_WIN) + +// ---------------------------------------------------------------------------- +// Messages sent from a non-broker process to a broker process. +// ---------------------------------------------------------------------------- + +#if defined(OS_WIN) +// Sent from a non-broker to a broker to request the duplication of a HANDLE +// into a different process (possibly the broker process, or even the original +// process). +IPC_MESSAGE_CONTROL1( + AttachmentBrokerMsg_DuplicateWinHandle, + IPC::internal::HandleAttachmentWin::WireFormat /* wire_format */) +#endif // defined(OS_WIN) diff --git a/chromium/ipc/attachment_broker_win.cc b/chromium/ipc/attachment_broker_win.cc new file mode 100644 index 00000000000..867d2712d61 --- /dev/null +++ b/chromium/ipc/attachment_broker_win.cc @@ -0,0 +1,48 @@ +// Copyright 2015 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. + +#include "ipc/attachment_broker_win.h" + +#include "ipc/attachment_broker_messages.h" +#include "ipc/brokerable_attachment.h" +#include "ipc/handle_attachment_win.h" +#include "ipc/ipc_sender.h" + +namespace IPC { + +AttachmentBrokerWin::AttachmentBrokerWin() { +} + +AttachmentBrokerWin::~AttachmentBrokerWin() { +} + +void AttachmentBrokerWin::OnReceiveDuplicatedHandle( + HANDLE, + BrokerableAttachment::AttachmentId id) { + // TODO(erikchen): Implement me. http://crbug.com/493414 +} + +bool AttachmentBrokerWin::SendAttachmentToProcess( + const BrokerableAttachment* attachment, + base::ProcessId destination_process) { + switch (attachment->GetBrokerableType()) { + case BrokerableAttachment::WIN_HANDLE: + const internal::HandleAttachmentWin* handle_attachment = + static_cast<const internal::HandleAttachmentWin*>(attachment); + internal::HandleAttachmentWin::WireFormat format = + handle_attachment->GetWireFormat(destination_process); + return sender_->Send( + new AttachmentBrokerMsg_DuplicateWinHandle(format)); + } + return false; +} + +bool AttachmentBrokerWin::GetAttachmentWithId( + BrokerableAttachment::AttachmentId id, + BrokerableAttachment* attachment) { + // TODO(erikchen): Implement me. http://crbug.com/493414 + return false; +} + +} // namespace IPC diff --git a/chromium/ipc/attachment_broker_win.h b/chromium/ipc/attachment_broker_win.h new file mode 100644 index 00000000000..1cf4348b681 --- /dev/null +++ b/chromium/ipc/attachment_broker_win.h @@ -0,0 +1,45 @@ +// Copyright 2015 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 IPC_ATTACHMENT_BROKER_WIN_H_ +#define IPC_ATTACHMENT_BROKER_WIN_H_ + +#include "ipc/attachment_broker.h" +#include "ipc/ipc_export.h" + +namespace IPC { + +class Sender; + +// This class is an implementation of AttachmentBroker for the Windows platform. +class IPC_EXPORT AttachmentBrokerWin : public IPC::AttachmentBroker { + public: + AttachmentBrokerWin(); + ~AttachmentBrokerWin() override; + + // In a non-broker process, the single instance of this class listens for + // an IPC from the broker process indicating that a new attachment has been + // duplicated. + void OnReceiveDuplicatedHandle(HANDLE, BrokerableAttachment::AttachmentId id); + + // IPC::AttachmentBroker overrides. + bool SendAttachmentToProcess(const BrokerableAttachment* attachment, + base::ProcessId destination_process) override; + bool GetAttachmentWithId(BrokerableAttachment::AttachmentId id, + BrokerableAttachment* attachment) override; + + // |sender_| is used to send Messages to the broker. |sender_| must live at + // least as long as this instance. + void set_sender(IPC::Sender* sender) { sender_ = sender; } + + private: + // |sender_| is used to send Messages to the broker. |sender_| must live at + // least as long as this instance. + IPC::Sender* sender_; + DISALLOW_COPY_AND_ASSIGN(AttachmentBrokerWin); +}; + +} // namespace IPC + +#endif // IPC_ATTACHMENT_BROKER_WIN_H_ diff --git a/chromium/ipc/brokerable_attachment.cc b/chromium/ipc/brokerable_attachment.cc new file mode 100644 index 00000000000..5caed2842a4 --- /dev/null +++ b/chromium/ipc/brokerable_attachment.cc @@ -0,0 +1,38 @@ +// Copyright 2015 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. + +#include "ipc/brokerable_attachment.h" + +#include "crypto/random.h" + +namespace IPC { + +namespace { + +// In order to prevent mutually untrusted processes from stealing resources from +// one another, the nonce must be secret. This generates a 128-bit, +// cryptographicaly-strong random number. +BrokerableAttachment::AttachmentId GetRandomId() { + BrokerableAttachment::AttachmentId id; + crypto::RandBytes(id.nonce, BrokerableAttachment::kNonceSize); + return id; +} + +} // namespace + +BrokerableAttachment::BrokerableAttachment() : id_(GetRandomId()) { +} + +BrokerableAttachment::~BrokerableAttachment() { +} + +BrokerableAttachment::AttachmentId BrokerableAttachment::GetIdentifier() const { + return id_; +} + +BrokerableAttachment::Type BrokerableAttachment::GetType() const { + return TYPE_BROKERABLE_ATTACHMENT; +} + +} // namespace IPC diff --git a/chromium/ipc/brokerable_attachment.h b/chromium/ipc/brokerable_attachment.h new file mode 100644 index 00000000000..5b8395551cb --- /dev/null +++ b/chromium/ipc/brokerable_attachment.h @@ -0,0 +1,51 @@ +// Copyright 2015 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 IPC_BROKERABLE_ATTACHMENT_H_ +#define IPC_BROKERABLE_ATTACHMENT_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "ipc/ipc_export.h" +#include "ipc/ipc_message_attachment.h" + +namespace IPC { + +// This subclass of MessageAttachment requires an AttachmentBroker to be +// attached to a Chrome IPC message. +class IPC_EXPORT BrokerableAttachment : public MessageAttachment { + public: + static const size_t kNonceSize = 16; + // An id uniquely identifies an attachment sent via a broker. + struct IPC_EXPORT AttachmentId { + uint8_t nonce[kNonceSize]; + }; + + enum BrokerableType { + WIN_HANDLE, + }; + + // The identifier is unique across all Chrome processes. + AttachmentId GetIdentifier() const; + + // Returns TYPE_BROKERABLE_ATTACHMENT + Type GetType() const override; + + virtual BrokerableType GetBrokerableType() const = 0; + + protected: + BrokerableAttachment(); + ~BrokerableAttachment() override; + + private: + // This member uniquely identifies a BrokerableAttachment across all Chrome + // processes. + const AttachmentId id_; + DISALLOW_COPY_AND_ASSIGN(BrokerableAttachment); +}; + +} // namespace IPC + +#endif // IPC_BROKERABLE_ATTACHMENT_H_ diff --git a/chromium/ipc/handle_attachment_win.cc b/chromium/ipc/handle_attachment_win.cc new file mode 100644 index 00000000000..3c18828dd22 --- /dev/null +++ b/chromium/ipc/handle_attachment_win.cc @@ -0,0 +1,34 @@ +// Copyright 2015 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. + +#include "ipc/handle_attachment_win.h" + +#include <windows.h> + +namespace IPC { +namespace internal { + +HandleAttachmentWin::HandleAttachmentWin(const HANDLE& handle) + : handle_(handle) { +} + +HandleAttachmentWin::~HandleAttachmentWin() { +} + +HandleAttachmentWin::BrokerableType HandleAttachmentWin::GetBrokerableType() + const { + return WIN_HANDLE; +} + +HandleAttachmentWin::WireFormat HandleAttachmentWin::GetWireFormat( + const base::ProcessId& destination) const { + WireFormat format; + format.handle = HandleToLong(handle_); + format.attachment_id = GetIdentifier(); + format.destination_process = destination; + return format; +} + +} // namespace internal +} // namespace IPC diff --git a/chromium/ipc/handle_attachment_win.h b/chromium/ipc/handle_attachment_win.h new file mode 100644 index 00000000000..7dd898ad54b --- /dev/null +++ b/chromium/ipc/handle_attachment_win.h @@ -0,0 +1,49 @@ +// Copyright 2015 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 IPC_HANDLE_ATTACHMENT_WIN_H_ +#define IPC_HANDLE_ATTACHMENT_WIN_H_ + +#include <stdint.h> + +#include "base/process/process_handle.h" +#include "ipc/brokerable_attachment.h" +#include "ipc/ipc_export.h" + +namespace IPC { +namespace internal { + +// This class represents a Windows HANDLE attached to a Chrome IPC message. +class IPC_EXPORT HandleAttachmentWin : public BrokerableAttachment { + public: + // The wire format for this handle. + struct IPC_EXPORT WireFormat { + // The HANDLE that is intended for duplication, or the HANDLE that has been + // duplicated, depending on context. + // The type is int32_t instead of HANDLE because HANDLE gets typedefed to + // void*, whose size varies between 32 and 64-bit processes. Using a + // int32_t means that 64-bit processes will need to perform both up-casting + // and down-casting. This is performed using the appropriate Windows apis. + int32_t handle; + // The id of the destination process that the handle is duplicated into. + base::ProcessId destination_process; + AttachmentId attachment_id; + }; + + HandleAttachmentWin(const HANDLE& handle); + + BrokerableType GetBrokerableType() const override; + + // Returns the wire format of this attachment. + WireFormat GetWireFormat(const base::ProcessId& destination) const; + + private: + ~HandleAttachmentWin() override; + HANDLE handle_; +}; + +} // namespace internal +} // namespace IPC + +#endif // IPC_HANDLE_ATTACHMENT_WIN_H_ diff --git a/chromium/ipc/ipc.gyp b/chromium/ipc/ipc.gyp index 1a28fc26c9a..420c891e481 100644 --- a/chromium/ipc/ipc.gyp +++ b/chromium/ipc/ipc.gyp @@ -20,6 +20,7 @@ '../base/base.gyp:base', # TODO(viettrungluu): Needed for base/lazy_instance.h, which is suspect. '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../crypto/crypto.gyp:crypto', ], # TODO(gregoryd): direct_dependent_settings should be shared with the # 64-bit target, but it doesn't work due to a bug in gyp @@ -157,6 +158,7 @@ # TODO(viettrungluu): Needed for base/lazy_instance.h, which is # suspect. '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations_win64', + '../crypto/crypto.gyp:crypto_nacl_win64', ], # TODO(gregoryd): direct_dependent_settings should be shared with the # 32-bit target, but it doesn't work due to a bug in gyp @@ -198,5 +200,22 @@ 'includes': [ '../build/apk_test.gypi' ], }], }], + ['test_isolation_mode != "noop"', { + 'targets': [ + { + 'target_name': 'ipc_tests_run', + 'type': 'none', + 'dependencies': [ + 'ipc_tests', + ], + 'includes': [ + '../build/isolate.gypi', + ], + 'sources': [ + 'ipc_tests.isolate', + ], + }, + ], + }], ], } diff --git a/chromium/ipc/ipc.gypi b/chromium/ipc/ipc.gypi index a10790ed103..9a9407e5def 100644 --- a/chromium/ipc/ipc.gypi +++ b/chromium/ipc/ipc.gypi @@ -11,6 +11,14 @@ # This part is shared between the targets defined below. ['ipc_target==1', { 'sources': [ + 'attachment_broker.h', + 'attachment_broker_messages.h', + 'attachment_broker_win.cc', + 'attachment_broker_win.h', + 'brokerable_attachment.cc', + 'brokerable_attachment.h', + 'handle_attachment_win.cc', + 'handle_attachment_win.h', 'ipc_channel.cc', 'ipc_channel.h', 'ipc_channel_factory.cc', @@ -31,6 +39,8 @@ 'ipc_export.h', 'ipc_forwarding_message_filter.cc', 'ipc_forwarding_message_filter.h', + 'ipc_handle_win.cc', + 'ipc_handle_win.h', 'ipc_listener.h', 'ipc_logging.cc', 'ipc_logging.h', @@ -40,6 +50,8 @@ 'ipc_message_attachment.h', 'ipc_message_attachment_set.cc', 'ipc_message_attachment_set.h', + 'ipc_message_generator.cc', + 'ipc_message_generator.h', 'ipc_message_macros.h', 'ipc_message_start.h', 'ipc_message_utils.cc', diff --git a/chromium/ipc/ipc_channel.h b/chromium/ipc/ipc_channel.h index 65c678b530d..c5c46a78048 100644 --- a/chromium/ipc/ipc_channel.h +++ b/chromium/ipc/ipc_channel.h @@ -20,6 +20,7 @@ namespace IPC { +class AttachmentBroker; class Listener; //------------------------------------------------------------------------------ @@ -118,11 +119,21 @@ class IPC_EXPORT Channel : public Sender { // // TODO(morrita): Replace CreateByModeForProxy() with one of above Create*(). // - static scoped_ptr<Channel> Create( - const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener); - + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. + static scoped_ptr<Channel> Create(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker = nullptr); + + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. static scoped_ptr<Channel> CreateClient( - const IPC::ChannelHandle &channel_handle, Listener* listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker = nullptr); // Channels on Windows are named by default and accessible from other // processes. On POSIX channels are anonymous by default and not accessible @@ -130,18 +141,29 @@ class IPC_EXPORT Channel : public Sender { // On Windows MODE_NAMED_SERVER is equivalent to MODE_SERVER and // MODE_NAMED_CLIENT is equivalent to MODE_CLIENT. static scoped_ptr<Channel> CreateNamedServer( - const IPC::ChannelHandle &channel_handle, Listener* listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker); static scoped_ptr<Channel> CreateNamedClient( - const IPC::ChannelHandle &channel_handle, Listener* listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker); #if defined(OS_POSIX) // An "open" named server accepts connections from ANY client. // The caller must then implement their own access-control based on the // client process' user Id. static scoped_ptr<Channel> CreateOpenNamedServer( - const IPC::ChannelHandle &channel_handle, Listener* listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker); #endif + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. static scoped_ptr<Channel> CreateServer( - const IPC::ChannelHandle &channel_handle, Listener* listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker = nullptr); ~Channel() override; diff --git a/chromium/ipc/ipc_channel_common.cc b/chromium/ipc/ipc_channel_common.cc index 23b85e2834d..5438c661a30 100644 --- a/chromium/ipc/ipc_channel_common.cc +++ b/chromium/ipc/ipc_channel_common.cc @@ -8,36 +8,49 @@ namespace IPC { // static scoped_ptr<Channel> Channel::CreateClient( - const IPC::ChannelHandle &channel_handle, Listener* listener) { - return Channel::Create(channel_handle, Channel::MODE_CLIENT, listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker) { + return Channel::Create(channel_handle, Channel::MODE_CLIENT, listener, + broker); } // static scoped_ptr<Channel> Channel::CreateNamedServer( - const IPC::ChannelHandle &channel_handle, Listener* listener) { - return Channel::Create(channel_handle, Channel::MODE_NAMED_SERVER, listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker) { + return Channel::Create(channel_handle, Channel::MODE_NAMED_SERVER, listener, + broker); } // static scoped_ptr<Channel> Channel::CreateNamedClient( - const IPC::ChannelHandle &channel_handle, Listener* listener) { - return Channel::Create(channel_handle, Channel::MODE_NAMED_CLIENT, listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker) { + return Channel::Create(channel_handle, Channel::MODE_NAMED_CLIENT, listener, + broker); } #if defined(OS_POSIX) // static scoped_ptr<Channel> Channel::CreateOpenNamedServer( - const IPC::ChannelHandle &channel_handle, Listener* listener) { - return Channel::Create(channel_handle, - Channel::MODE_OPEN_NAMED_SERVER, - listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker) { + return Channel::Create(channel_handle, Channel::MODE_OPEN_NAMED_SERVER, + listener, broker); } #endif // static scoped_ptr<Channel> Channel::CreateServer( - const IPC::ChannelHandle &channel_handle, Listener* listener) { - return Channel::Create(channel_handle, Channel::MODE_SERVER, listener); + const IPC::ChannelHandle& channel_handle, + Listener* listener, + AttachmentBroker* broker) { + return Channel::Create(channel_handle, Channel::MODE_SERVER, listener, + broker); } Channel::~Channel() { diff --git a/chromium/ipc/ipc_channel_factory.cc b/chromium/ipc/ipc_channel_factory.cc index c8431c091c8..ac050855cfc 100644 --- a/chromium/ipc/ipc_channel_factory.cc +++ b/chromium/ipc/ipc_channel_factory.cc @@ -11,21 +11,22 @@ namespace { class PlatformChannelFactory : public ChannelFactory { public: PlatformChannelFactory(ChannelHandle handle, - Channel::Mode mode) - : handle_(handle), mode_(mode) { - } + Channel::Mode mode, + AttachmentBroker* broker) + : handle_(handle), mode_(mode), broker_(broker) {} std::string GetName() const override { return handle_.name; } scoped_ptr<Channel> BuildChannel(Listener* listener) override { - return Channel::Create(handle_, mode_, listener); + return Channel::Create(handle_, mode_, listener, broker_); } private: ChannelHandle handle_; Channel::Mode mode_; + AttachmentBroker* broker_; DISALLOW_COPY_AND_ASSIGN(PlatformChannelFactory); }; @@ -33,9 +34,11 @@ class PlatformChannelFactory : public ChannelFactory { } // namespace // static -scoped_ptr<ChannelFactory> ChannelFactory::Create( - const ChannelHandle& handle, Channel::Mode mode) { - return scoped_ptr<ChannelFactory>(new PlatformChannelFactory(handle, mode)); +scoped_ptr<ChannelFactory> ChannelFactory::Create(const ChannelHandle& handle, + Channel::Mode mode, + AttachmentBroker* broker) { + return scoped_ptr<ChannelFactory>( + new PlatformChannelFactory(handle, mode, broker)); } } // namespace IPC diff --git a/chromium/ipc/ipc_channel_factory.h b/chromium/ipc/ipc_channel_factory.h index 84bcf9725c9..71ebe8aaaae 100644 --- a/chromium/ipc/ipc_channel_factory.h +++ b/chromium/ipc/ipc_channel_factory.h @@ -13,6 +13,8 @@ namespace IPC { +class AttachmentBroker; + // Encapsulates how a Channel is created. A ChannelFactory can be // passed to the constructor of ChannelProxy or SyncChannel to tell them // how to create underlying channel. @@ -20,8 +22,9 @@ class IPC_EXPORT ChannelFactory { public: // Creates a factory for "native" channel built through // IPC::Channel::Create(). - static scoped_ptr<ChannelFactory> Create( - const ChannelHandle& handle, Channel::Mode mode); + static scoped_ptr<ChannelFactory> Create(const ChannelHandle& handle, + Channel::Mode mode, + AttachmentBroker* broker); virtual ~ChannelFactory() { } virtual std::string GetName() const = 0; diff --git a/chromium/ipc/ipc_channel_nacl.cc b/chromium/ipc/ipc_channel_nacl.cc index f5b33cea41a..19a32891af1 100644 --- a/chromium/ipc/ipc_channel_nacl.cc +++ b/chromium/ipc/ipc_channel_nacl.cc @@ -122,13 +122,15 @@ void ChannelNacl::ReaderThreadRunner::Run() { ChannelNacl::ChannelNacl(const IPC::ChannelHandle& channel_handle, Mode mode, - Listener* listener) + Listener* listener, + AttachmentBroker* broker) : ChannelReader(listener), mode_(mode), waiting_connect_(true), pipe_(-1), pipe_name_(channel_handle.name), - weak_ptr_factory_(this) { + weak_ptr_factory_(this), + broker_(broker) { if (!CreatePipe(channel_handle)) { // The pipe may have been closed already. const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; @@ -217,6 +219,10 @@ bool ChannelNacl::Send(Message* message) { return true; } +AttachmentBroker* ChannelNacl::GetAttachmentBroker() { + return broker_; +} + void ChannelNacl::DidRecvMsg(scoped_ptr<MessageContents> contents) { // Close sets the pipe to -1. It's possible we'll get a buffer sent to us from // the reader thread after Close is called. If so, we ignore it. @@ -372,10 +378,12 @@ void ChannelNacl::HandleInternalMessage(const Message& msg) { // Channel's methods // static -scoped_ptr<Channel> Channel::Create( - const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { +scoped_ptr<Channel> Channel::Create(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker) { return scoped_ptr<Channel>( - new ChannelNacl(channel_handle, mode, listener)); + new ChannelNacl(channel_handle, mode, listener, broker)); } } // namespace IPC diff --git a/chromium/ipc/ipc_channel_nacl.h b/chromium/ipc/ipc_channel_nacl.h index f0649b26022..82ef6edc9d1 100644 --- a/chromium/ipc/ipc_channel_nacl.h +++ b/chromium/ipc/ipc_channel_nacl.h @@ -35,9 +35,11 @@ class ChannelNacl : public Channel, public internal::ChannelReader { public: // Mirror methods of Channel, see ipc_channel.h for description. + // |broker| must outlive the newly created object. ChannelNacl(const IPC::ChannelHandle& channel_handle, Mode mode, - Listener* listener); + Listener* listener, + AttachmentBroker* broker); ~ChannelNacl() override; // Channel implementation. @@ -46,6 +48,7 @@ class ChannelNacl : public Channel, bool Connect() override; void Close() override; bool Send(Message* message) override; + AttachmentBroker* GetAttachmentBroker() override; // Posted to the main thread by ReaderThreadRunner. void DidRecvMsg(scoped_ptr<MessageContents> contents); @@ -114,6 +117,9 @@ class ChannelNacl : public Channel, base::WeakPtrFactory<ChannelNacl> weak_ptr_factory_; + // |broker_| must outlive this instance. + AttachmentBroker* broker_; + DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelNacl); }; diff --git a/chromium/ipc/ipc_channel_posix.cc b/chromium/ipc/ipc_channel_posix.cc index aac7e795257..8f995fb0111 100644 --- a/chromium/ipc/ipc_channel_posix.cc +++ b/chromium/ipc/ipc_channel_posix.cc @@ -182,7 +182,9 @@ int ChannelPosix::global_pid_ = 0; #endif // OS_LINUX ChannelPosix::ChannelPosix(const IPC::ChannelHandle& channel_handle, - Mode mode, Listener* listener) + Mode mode, + Listener* listener, + AttachmentBroker* broker) : ChannelReader(listener), mode_(mode), peer_pid_(base::kNullProcessId), @@ -191,8 +193,8 @@ ChannelPosix::ChannelPosix(const IPC::ChannelHandle& channel_handle, message_send_bytes_written_(0), pipe_name_(channel_handle.name), in_dtor_(false), - must_unlink_(false) { - memset(input_cmsg_buf_, 0, sizeof(input_cmsg_buf_)); + must_unlink_(false), + broker_(broker) { if (!CreatePipe(channel_handle)) { // The pipe may have been closed already. const char *modestr = (mode_ & MODE_SERVER_FLAG) ? "server" : "client"; @@ -247,19 +249,6 @@ bool ChannelPosix::CreatePipe( if (channel_handle.socket.fd != -1) { // Case 1 from comment above. local_pipe.reset(channel_handle.socket.fd); -#if defined(IPC_USES_READWRITE) - // Test the socket passed into us to make sure it is nonblocking. - // We don't want to call read/write on a blocking socket. - int value = fcntl(local_pipe.get(), F_GETFL); - if (value == -1) { - PLOG(ERROR) << "fcntl(F_GETFL) " << pipe_name_; - return false; - } - if (!(value & O_NONBLOCK)) { - LOG(ERROR) << "Socket " << pipe_name_ << " must be O_NONBLOCK"; - return false; - } -#endif // IPC_USES_READWRITE } else if (mode_ & MODE_NAMED_FLAG) { #if defined(OS_NACL_NONSFI) LOG(FATAL) @@ -333,20 +322,6 @@ bool ChannelPosix::CreatePipe( } } -#if defined(IPC_USES_READWRITE) - // Create a dedicated socketpair() for exchanging file descriptors. - // See comments for IPC_USES_READWRITE for details. - if (mode_ & MODE_CLIENT_FLAG) { - int fd_pipe_fd = 1, remote_fd_pipe_fd = -1; - if (!SocketPair(&fd_pipe_fd, &remote_fd_pipe_fd)) { - return false; - } - - fd_pipe_.reset(fd_pipe_fd); - remote_fd_pipe_.reset(remote_fd_pipe_fd); - } -#endif // IPC_USES_READWRITE - if ((mode_ & MODE_SERVER_FLAG) && (mode_ & MODE_NAMED_FLAG)) { #if defined(OS_NACL_NONSFI) LOG(FATAL) << "IPC channels in nacl_helper_nonsfi " @@ -466,40 +441,11 @@ bool ChannelPosix::ProcessOutgoingMessages() { // DCHECK_LE above already checks that // num_fds < kMaxDescriptorsPerMessage so no danger of overflow. msg->header()->num_fds = static_cast<uint16>(num_fds); - -#if defined(IPC_USES_READWRITE) - if (!IsHelloMessage(*msg)) { - // Only the Hello message sends the file descriptor with the message. - // Subsequently, we can send file descriptors on the dedicated - // fd_pipe_ which makes Seccomp sandbox operation more efficient. - struct iovec fd_pipe_iov = { const_cast<char *>(""), 1 }; - msgh.msg_iov = &fd_pipe_iov; - fd_written = fd_pipe_.get(); - bytes_written = - HANDLE_EINTR(sendmsg(fd_pipe_.get(), &msgh, MSG_DONTWAIT)); - msgh.msg_iov = &iov; - msgh.msg_controllen = 0; - if (bytes_written > 0) { - CloseFileDescriptors(msg); - } - } -#endif // IPC_USES_READWRITE } if (bytes_written == 1) { fd_written = pipe_.get(); -#if defined(IPC_USES_READWRITE) - if ((mode_ & MODE_CLIENT_FLAG) && IsHelloMessage(*msg)) { - DCHECK_EQ(msg->attachment_set()->size(), 1U); - } - if (!msgh.msg_controllen) { - bytes_written = - HANDLE_EINTR(write(pipe_.get(), out_bytes, amt_to_write)); - } else -#endif // IPC_USES_READWRITE - { - bytes_written = HANDLE_EINTR(sendmsg(pipe_.get(), &msgh, MSG_DONTWAIT)); - } + bytes_written = HANDLE_EINTR(sendmsg(pipe_.get(), &msgh, MSG_DONTWAIT)); } if (bytes_written > 0) CloseFileDescriptors(msg); @@ -574,6 +520,10 @@ bool ChannelPosix::Send(Message* message) { return true; } +AttachmentBroker* ChannelPosix::GetAttachmentBroker() { + return broker_; +} + int ChannelPosix::GetClientFileDescriptor() const { base::AutoLock lock(client_pipe_lock_); return client_pipe_.get(); @@ -616,14 +566,11 @@ void ChannelPosix::ResetToAcceptingConnectionState() { read_watcher_.StopWatchingFileDescriptor(); write_watcher_.StopWatchingFileDescriptor(); ResetSafely(&pipe_); -#if defined(IPC_USES_READWRITE) - fd_pipe_.reset(); - remote_fd_pipe_.reset(); -#endif // IPC_USES_READWRITE while (!output_queue_.empty()) { Message* m = output_queue_.front(); output_queue_.pop(); + CloseFileDescriptors(m); delete m; } @@ -798,16 +745,6 @@ void ChannelPosix::QueueHelloMessage() { if (!msg->WriteInt(GetHelloMessageProcId())) { NOTREACHED() << "Unable to pickle hello message proc id"; } -#if defined(IPC_USES_READWRITE) - scoped_ptr<Message> hello; - if (remote_fd_pipe_.is_valid()) { - if (!msg->WriteAttachment( - new internal::PlatformFileAttachment(remote_fd_pipe_.get()))) { - NOTREACHED() << "Unable to pickle hello message file descriptors"; - } - DCHECK_EQ(msg->attachment_set()->size(), 1U); - } -#endif // IPC_USES_READWRITE output_queue_.push(msg.release()); } @@ -824,20 +761,14 @@ ChannelPosix::ReadState ChannelPosix::ReadData( msg.msg_iov = &iov; msg.msg_iovlen = 1; - msg.msg_control = input_cmsg_buf_; + char input_cmsg_buf[kMaxReadFDBuffer]; + msg.msg_control = input_cmsg_buf; // recvmsg() returns 0 if the connection has closed or EAGAIN if no data // is waiting on the pipe. -#if defined(IPC_USES_READWRITE) - if (fd_pipe_.is_valid()) { - *bytes_read = HANDLE_EINTR(read(pipe_.get(), buffer, buffer_len)); - msg.msg_controllen = 0; - } else -#endif // IPC_USES_READWRITE - { - msg.msg_controllen = sizeof(input_cmsg_buf_); - *bytes_read = HANDLE_EINTR(recvmsg(pipe_.get(), &msg, MSG_DONTWAIT)); - } + msg.msg_controllen = sizeof(input_cmsg_buf); + *bytes_read = HANDLE_EINTR(recvmsg(pipe_.get(), &msg, MSG_DONTWAIT)); + if (*bytes_read < 0) { if (errno == EAGAIN) { return READ_PENDING; @@ -868,28 +799,6 @@ ChannelPosix::ReadState ChannelPosix::ReadData( return READ_SUCCEEDED; } -#if defined(IPC_USES_READWRITE) -bool ChannelPosix::ReadFileDescriptorsFromFDPipe() { - char dummy; - struct iovec fd_pipe_iov = { &dummy, 1 }; - - struct msghdr msg = { 0 }; - msg.msg_iov = &fd_pipe_iov; - msg.msg_iovlen = 1; - msg.msg_control = input_cmsg_buf_; - msg.msg_controllen = sizeof(input_cmsg_buf_); - ssize_t bytes_received = - HANDLE_EINTR(recvmsg(fd_pipe_.get(), &msg, MSG_DONTWAIT)); - - if (bytes_received != 1) - return true; // No message waiting. - - if (!ExtractFileDescriptorsFromMsghdr(&msg)) - return false; - return true; -} -#endif - // On Posix, we need to fix up the file descriptors before the input message // is dispatched. // @@ -905,12 +814,7 @@ bool ChannelPosix::WillDispatchInputMessage(Message* msg) { if (header_fds > input_fds_.size()) { // The message has been completely received, but we didn't get // enough file descriptors. -#if defined(IPC_USES_READWRITE) - if (!ReadFileDescriptorsFromFDPipe()) - return false; - if (header_fds > input_fds_.size()) -#endif // IPC_USES_READWRITE - error = "Message needs unreceived descriptors"; + error = "Message needs unreceived descriptors"; } if (header_fds > MessageAttachmentSet::kMaxDescriptorsPerMessage) @@ -1005,7 +909,7 @@ void ChannelPosix::QueueCloseFDMessage(int fd, int hops) { void ChannelPosix::HandleInternalMessage(const Message& msg) { // The Hello message contains only the process id. - PickleIterator iter(msg); + base::PickleIterator iter(msg); switch (msg.type()) { default: @@ -1017,19 +921,6 @@ void ChannelPosix::HandleInternalMessage(const Message& msg) { if (!iter.ReadInt(&pid)) NOTREACHED(); -#if defined(IPC_USES_READWRITE) - if (mode_ & MODE_SERVER_FLAG) { - // With IPC_USES_READWRITE, the Hello message from the client to the - // server also contains the fd_pipe_, which will be used for all - // subsequent file descriptor passing. - DCHECK_EQ(msg.attachment_set()->size(), 1U); - scoped_refptr<MessageAttachment> attachment; - if (!msg.ReadAttachment(&iter, &attachment)) { - NOTREACHED(); - } - fd_pipe_.reset(attachment->TakePlatformFile()); - } -#endif // IPC_USES_READWRITE peer_pid_ = pid; listener()->OnChannelConnected(pid); break; @@ -1112,9 +1003,12 @@ void ChannelPosix::ResetSafely(base::ScopedFD* fd) { // Channel's methods // static -scoped_ptr<Channel> Channel::Create( - const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { - return make_scoped_ptr(new ChannelPosix(channel_handle, mode, listener)); +scoped_ptr<Channel> Channel::Create(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker) { + return make_scoped_ptr( + new ChannelPosix(channel_handle, mode, listener, broker)); } // static @@ -1129,7 +1023,6 @@ std::string Channel::GenerateVerifiedChannelID(const std::string& prefix) { return id.append(GenerateUniqueRandomChannelID()); } - bool Channel::IsNamedServerInitialized( const std::string& channel_id) { return ChannelPosix::IsNamedServerInitialized(channel_id); diff --git a/chromium/ipc/ipc_channel_posix.h b/chromium/ipc/ipc_channel_posix.h index a65283d3bea..879adc34085 100644 --- a/chromium/ipc/ipc_channel_posix.h +++ b/chromium/ipc/ipc_channel_posix.h @@ -20,48 +20,24 @@ #include "ipc/ipc_channel_reader.h" #include "ipc/ipc_message_attachment_set.h" -#if !defined(OS_MACOSX) -// On Linux, the seccomp sandbox makes it very expensive to call -// recvmsg() and sendmsg(). The restriction on calling read() and write(), which -// are cheap, is that we can't pass file descriptors over them. -// -// As we cannot anticipate when the sender will provide us with file -// descriptors, we have to make the decision about whether we call read() or -// recvmsg() before we actually make the call. The easiest option is to -// create a dedicated socketpair() for exchanging file descriptors. Any file -// descriptors are split out of a message, with the non-file-descriptor payload -// going over the normal connection, and the file descriptors being sent -// separately over the other channel. When read()ing from a channel, we'll -// notice if the message was supposed to have come with file descriptors and -// use recvmsg on the other socketpair to retrieve them and combine them -// back with the rest of the message. -// -// Mac can also run in IPC_USES_READWRITE mode if necessary, but at this time -// doesn't take a performance hit from recvmsg and sendmsg, so it doesn't -// make sense to waste resources on having the separate dedicated socketpair. -// It is however useful for debugging between Linux and Mac to be able to turn -// this switch 'on' on the Mac as well. -// -// The HELLO message from the client to the server is always sent using -// sendmsg because it will contain the file descriptor that the server -// needs to send file descriptors in later messages. -#define IPC_USES_READWRITE 1 -#endif - namespace IPC { class IPC_EXPORT ChannelPosix : public Channel, public internal::ChannelReader, public base::MessageLoopForIO::Watcher { public: - ChannelPosix(const IPC::ChannelHandle& channel_handle, Mode mode, - Listener* listener); + // |broker| must outlive the newly created object. + ChannelPosix(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker); ~ChannelPosix() override; // Channel implementation bool Connect() override; void Close() override; bool Send(Message* message) override; + AttachmentBroker* GetAttachmentBroker() override; base::ProcessId GetPeerPID() const override; base::ProcessId GetSelfPID() const override; int GetClientFileDescriptor() const override; @@ -107,14 +83,6 @@ class IPC_EXPORT ChannelPosix : public Channel, bool DidEmptyInputBuffers() override; void HandleInternalMessage(const Message& msg) override; -#if defined(IPC_USES_READWRITE) - // Reads the next message from the fd_pipe_ and appends them to the - // input_fds_ queue. Returns false if there was a message receiving error. - // True means there was a message and it was processed properly, or there was - // no messages. - bool ReadFileDescriptorsFromFDPipe(); -#endif - // Finds the set of file descriptors in the given message. On success, // appends the descriptors to the input_fds_ member and returns true // @@ -161,12 +129,6 @@ class IPC_EXPORT ChannelPosix : public Channel, base::ScopedFD client_pipe_; mutable base::Lock client_pipe_lock_; // Lock that protects |client_pipe_|. -#if defined(IPC_USES_READWRITE) - // Linux/BSD use a dedicated socketpair() for passing file descriptors. - base::ScopedFD fd_pipe_; - base::ScopedFD remote_fd_pipe_; -#endif - // The "name" of our pipe. On Windows this is the global identifier for // the pipe. On POSIX it's used as a key in a local map of file descriptors. std::string pipe_name_; @@ -181,18 +143,14 @@ class IPC_EXPORT ChannelPosix : public Channel, MessageAttachmentSet::kMaxDescriptorsPerMessage; // Buffer size for file descriptors used for recvmsg. On Mac the CMSG macros - // don't seem to be constant so we have to pick a "large enough" value. + // are not constant so we have to pick a "large enough" padding for headers. #if defined(OS_MACOSX) - static const size_t kMaxReadFDBuffer = 1024; + static const size_t kMaxReadFDBuffer = 1024 + sizeof(int) * kMaxReadFDs; #else static const size_t kMaxReadFDBuffer = CMSG_SPACE(sizeof(int) * kMaxReadFDs); #endif - - // Temporary buffer used to receive the file descriptors from recvmsg. - // Code that writes into this should immediately read them out and save - // them to input_fds_, since this buffer will be re-used anytime we call - // recvmsg. - char input_cmsg_buf_[kMaxReadFDBuffer]; + static_assert(kMaxReadFDBuffer <= 8192, + "kMaxReadFDBuffer too big for a stack buffer"); // File descriptors extracted from messages coming off of the channel. The // handles may span messages and come off different channels from the message @@ -221,6 +179,9 @@ class IPC_EXPORT ChannelPosix : public Channel, static int global_pid_; #endif // OS_LINUX + // |broker_| must outlive this instance. + AttachmentBroker* broker_; + DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelPosix); }; diff --git a/chromium/ipc/ipc_channel_posix_unittest.cc b/chromium/ipc/ipc_channel_posix_unittest.cc index aa545402f4b..9209d2c091a 100644 --- a/chromium/ipc/ipc_channel_posix_unittest.cc +++ b/chromium/ipc/ipc_channel_posix_unittest.cc @@ -201,8 +201,8 @@ TEST_F(IPCChannelPosixTest, BasicListen) { IPC::ChannelHandle handle(kChannelName); SetUpSocket(&handle, IPC::Channel::MODE_NAMED_SERVER); unlink(handle.name.c_str()); - scoped_ptr<IPC::ChannelPosix> channel( - new IPC::ChannelPosix(handle, IPC::Channel::MODE_NAMED_SERVER, NULL)); + scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( + handle, IPC::Channel::MODE_NAMED_SERVER, NULL, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_TRUE(channel->AcceptsConnections()); ASSERT_FALSE(channel->HasAcceptedConnection()); @@ -220,8 +220,8 @@ TEST_F(IPCChannelPosixTest, BasicConnected) { base::FileDescriptor fd(pipe_fds[0], false); IPC::ChannelHandle handle(socket_name, fd); - scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - handle, IPC::Channel::MODE_SERVER, NULL)); + scoped_ptr<IPC::ChannelPosix> channel( + new IPC::ChannelPosix(handle, IPC::Channel::MODE_SERVER, NULL, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_FALSE(channel->AcceptsConnections()); channel->Close(); @@ -230,7 +230,7 @@ TEST_F(IPCChannelPosixTest, BasicConnected) { // Make sure that we can use the socket that is created for us by // a standard channel. scoped_ptr<IPC::ChannelPosix> channel2(new IPC::ChannelPosix( - socket_name, IPC::Channel::MODE_SERVER, NULL)); + socket_name, IPC::Channel::MODE_SERVER, NULL, nullptr)); ASSERT_TRUE(channel2->Connect()); ASSERT_FALSE(channel2->AcceptsConnections()); } @@ -243,11 +243,11 @@ TEST_F(IPCChannelPosixTest, SendHangTest) { IPCChannelPosixTestListener in_listener(true); IPC::ChannelHandle in_handle("IN"); scoped_ptr<IPC::ChannelPosix> in_chan(new IPC::ChannelPosix( - in_handle, IPC::Channel::MODE_SERVER, &in_listener)); + in_handle, IPC::Channel::MODE_SERVER, &in_listener, nullptr)); IPC::ChannelHandle out_handle( "OUT", base::FileDescriptor(in_chan->TakeClientFileDescriptor())); scoped_ptr<IPC::ChannelPosix> out_chan(new IPC::ChannelPosix( - out_handle, IPC::Channel::MODE_CLIENT, &out_listener)); + out_handle, IPC::Channel::MODE_CLIENT, &out_listener, nullptr)); ASSERT_TRUE(in_chan->Connect()); ASSERT_TRUE(out_chan->Connect()); in_chan->Close(); // simulate remote process dying at an unfortunate time. @@ -268,11 +268,11 @@ TEST_F(IPCChannelPosixTest, AcceptHangTest) { IPCChannelPosixTestListener in_listener(true); IPC::ChannelHandle in_handle("IN"); scoped_ptr<IPC::ChannelPosix> in_chan(new IPC::ChannelPosix( - in_handle, IPC::Channel::MODE_SERVER, &in_listener)); + in_handle, IPC::Channel::MODE_SERVER, &in_listener, nullptr)); IPC::ChannelHandle out_handle( "OUT", base::FileDescriptor(in_chan->TakeClientFileDescriptor())); scoped_ptr<IPC::ChannelPosix> out_chan(new IPC::ChannelPosix( - out_handle, IPC::Channel::MODE_CLIENT, &out_listener)); + out_handle, IPC::Channel::MODE_CLIENT, &out_listener, nullptr)); ASSERT_TRUE(in_chan->Connect()); in_chan->Close(); // simulate remote process dying at an unfortunate time. ASSERT_FALSE(out_chan->Connect()); @@ -286,7 +286,7 @@ TEST_F(IPCChannelPosixTest, AdvancedConnected) { IPC::ChannelHandle chan_handle(GetConnectionSocketName()); SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener)); + chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_TRUE(channel->AcceptsConnections()); ASSERT_FALSE(channel->HasAcceptedConnection()); @@ -317,7 +317,7 @@ TEST_F(IPCChannelPosixTest, ResetState) { IPC::ChannelHandle chan_handle(GetConnectionSocketName()); SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener)); + chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_TRUE(channel->AcceptsConnections()); ASSERT_FALSE(channel->HasAcceptedConnection()); @@ -353,7 +353,7 @@ TEST_F(IPCChannelPosixTest, BadChannelName) { // Test empty name IPC::ChannelHandle handle(""); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - handle, IPC::Channel::MODE_NAMED_SERVER, NULL)); + handle, IPC::Channel::MODE_NAMED_SERVER, NULL, nullptr)); ASSERT_FALSE(channel->Connect()); // Test name that is too long. @@ -367,7 +367,7 @@ TEST_F(IPCChannelPosixTest, BadChannelName) { EXPECT_GE(strlen(kTooLongName), IPC::kMaxSocketNameLength); IPC::ChannelHandle handle2(kTooLongName); scoped_ptr<IPC::ChannelPosix> channel2(new IPC::ChannelPosix( - handle2, IPC::Channel::MODE_NAMED_SERVER, NULL)); + handle2, IPC::Channel::MODE_NAMED_SERVER, NULL, nullptr)); EXPECT_FALSE(channel2->Connect()); } @@ -378,7 +378,7 @@ TEST_F(IPCChannelPosixTest, MultiConnection) { IPC::ChannelHandle chan_handle(GetConnectionSocketName()); SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener)); + chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_TRUE(channel->AcceptsConnections()); ASSERT_FALSE(channel->HasAcceptedConnection()); @@ -414,9 +414,9 @@ TEST_F(IPCChannelPosixTest, DoubleServer) { IPCChannelPosixTestListener listener2(false); IPC::ChannelHandle chan_handle(GetConnectionSocketName()); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_SERVER, &listener)); + chan_handle, IPC::Channel::MODE_SERVER, &listener, nullptr)); scoped_ptr<IPC::ChannelPosix> channel2(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_SERVER, &listener2)); + chan_handle, IPC::Channel::MODE_SERVER, &listener2, nullptr)); ASSERT_TRUE(channel->Connect()); ASSERT_FALSE(channel2->Connect()); } @@ -426,7 +426,7 @@ TEST_F(IPCChannelPosixTest, BadMode) { IPCChannelPosixTestListener listener(false); IPC::ChannelHandle chan_handle(GetConnectionSocketName()); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_NONE, &listener)); + chan_handle, IPC::Channel::MODE_NONE, &listener, nullptr)); ASSERT_FALSE(channel->Connect()); } @@ -438,7 +438,7 @@ TEST_F(IPCChannelPosixTest, IsNamedServerInitialized) { ASSERT_FALSE(IPC::Channel::IsNamedServerInitialized( connection_socket_name)); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener)); + chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener, nullptr)); ASSERT_TRUE(IPC::Channel::IsNamedServerInitialized( connection_socket_name)); channel->Close(); @@ -454,7 +454,7 @@ MULTIPROCESS_TEST_MAIN(IPCChannelPosixTestConnectionProc) { IPC::ChannelHandle handle(IPCChannelPosixTest::GetConnectionSocketName()); IPCChannelPosixTest::SetUpSocket(&handle, IPC::Channel::MODE_NAMED_CLIENT); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - handle, IPC::Channel::MODE_NAMED_CLIENT, &listener)); + handle, IPC::Channel::MODE_NAMED_CLIENT, &listener, nullptr)); EXPECT_TRUE(channel->Connect()); IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout()); EXPECT_EQ(IPCChannelPosixTestListener::MESSAGE_RECEIVED, listener.status()); @@ -468,7 +468,7 @@ MULTIPROCESS_TEST_MAIN(IPCChannelPosixFailConnectionProc) { IPC::ChannelHandle handle(IPCChannelPosixTest::GetConnectionSocketName()); IPCChannelPosixTest::SetUpSocket(&handle, IPC::Channel::MODE_NAMED_CLIENT); scoped_ptr<IPC::ChannelPosix> channel(new IPC::ChannelPosix( - handle, IPC::Channel::MODE_NAMED_CLIENT, &listener)); + handle, IPC::Channel::MODE_NAMED_CLIENT, &listener, nullptr)); // In this case connect may succeed or fail depending on if the packet // actually gets sent at sendmsg. Since we never delay on send, we may not diff --git a/chromium/ipc/ipc_channel_proxy.cc b/chromium/ipc/ipc_channel_proxy.cc index 57676189b8d..269fd6a8a62 100644 --- a/chromium/ipc/ipc_channel_proxy.cc +++ b/chromium/ipc/ipc_channel_proxy.cc @@ -347,7 +347,6 @@ void ChannelProxy::Context::Send(Message* message) { base::Passed(scoped_ptr<Message>(message)))); } - //----------------------------------------------------------------------------- // static @@ -355,9 +354,10 @@ scoped_ptr<ChannelProxy> ChannelProxy::Create( const IPC::ChannelHandle& channel_handle, Channel::Mode mode, Listener* listener, - const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { + const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, + AttachmentBroker* broker) { scoped_ptr<ChannelProxy> channel(new ChannelProxy(listener, ipc_task_runner)); - channel->Init(channel_handle, mode, true); + channel->Init(channel_handle, mode, true, broker); return channel.Pass(); } @@ -396,7 +396,8 @@ ChannelProxy::~ChannelProxy() { void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle, Channel::Mode mode, - bool create_pipe_now) { + bool create_pipe_now, + AttachmentBroker* broker) { #if defined(OS_POSIX) // When we are creating a server on POSIX, we need its file descriptor // to be created immediately so that it can be accessed and passed @@ -406,8 +407,7 @@ void ChannelProxy::Init(const IPC::ChannelHandle& channel_handle, create_pipe_now = true; } #endif // defined(OS_POSIX) - Init(ChannelFactory::Create(channel_handle, mode), - create_pipe_now); + Init(ChannelFactory::Create(channel_handle, mode, broker), create_pipe_now); } void ChannelProxy::Init(scoped_ptr<ChannelFactory> factory, diff --git a/chromium/ipc/ipc_channel_proxy.h b/chromium/ipc/ipc_channel_proxy.h index 5d38006b5d5..73cb7e023ee 100644 --- a/chromium/ipc/ipc_channel_proxy.h +++ b/chromium/ipc/ipc_channel_proxy.h @@ -82,11 +82,15 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // on the background thread. Any message not handled by the filter will be // dispatched to the listener. The given task runner correspond to a thread // on which IPC::Channel is created and used (e.g. IO thread). + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. static scoped_ptr<ChannelProxy> Create( const IPC::ChannelHandle& channel_handle, Channel::Mode mode, Listener* listener, - const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner); + const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, + AttachmentBroker* broker = nullptr); static scoped_ptr<ChannelProxy> Create( scoped_ptr<ChannelFactory> factory, @@ -99,8 +103,13 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // proxy that was not initialized in its constructor. If create_pipe_now is // true, the pipe is created synchronously. Otherwise it's created on the IO // thread. - void Init(const IPC::ChannelHandle& channel_handle, Channel::Mode mode, - bool create_pipe_now); + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. + void Init(const IPC::ChannelHandle& channel_handle, + Channel::Mode mode, + bool create_pipe_now, + AttachmentBroker* broker = nullptr); void Init(scoped_ptr<ChannelFactory> factory, bool create_pipe_now); // Close the IPC::Channel. This operation completes asynchronously, once the diff --git a/chromium/ipc/ipc_channel_proxy_unittest.cc b/chromium/ipc/ipc_channel_proxy_unittest.cc index 4144a8adba1..ee5dc22626c 100644 --- a/chromium/ipc/ipc_channel_proxy_unittest.cc +++ b/chromium/ipc/ipc_channel_proxy_unittest.cc @@ -423,8 +423,7 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ChannelProxyClient) { base::MessageLoopForIO main_message_loop; ChannelReflectorListener listener; scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( - IPCTestBase::GetChannelName("ChannelProxyClient"), - &listener)); + IPCTestBase::GetChannelName("ChannelProxyClient"), &listener, nullptr)); CHECK(channel->Connect()); listener.Init(channel.get()); diff --git a/chromium/ipc/ipc_channel_proxy_unittest_messages.h b/chromium/ipc/ipc_channel_proxy_unittest_messages.h index 0108f1b7c78..20405eda0ef 100644 --- a/chromium/ipc/ipc_channel_proxy_unittest_messages.h +++ b/chromium/ipc/ipc_channel_proxy_unittest_messages.h @@ -18,7 +18,7 @@ namespace IPC { template <> struct ParamTraits<BadType> { static void Write(Message* m, const BadType& p) {} - static bool Read(const Message* m, PickleIterator* iter, BadType* r) { + static bool Read(const Message* m, base::PickleIterator* iter, BadType* r) { return false; } static void Log(const BadType& p, std::string* l) {} diff --git a/chromium/ipc/ipc_channel_reader.h b/chromium/ipc/ipc_channel_reader.h index 9dec8c17a5d..02006d94ce6 100644 --- a/chromium/ipc/ipc_channel_reader.h +++ b/chromium/ipc/ipc_channel_reader.h @@ -6,6 +6,7 @@ #define IPC_IPC_CHANNEL_READER_H_ #include "base/basictypes.h" +#include "ipc/attachment_broker.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_export.h" @@ -24,7 +25,7 @@ namespace internal { // functionality that would benefit from being factored out. If we add // something like that in the future, it would be more appropriate to add it // here (and rename appropriately) rather than writing a different class. -class ChannelReader { +class ChannelReader : public SupportsAttachmentBrokering { public: explicit ChannelReader(Listener* listener); virtual ~ChannelReader(); diff --git a/chromium/ipc/ipc_channel_unittest.cc b/chromium/ipc/ipc_channel_unittest.cc index b6a02262613..2623154ba39 100644 --- a/chromium/ipc/ipc_channel_unittest.cc +++ b/chromium/ipc/ipc_channel_unittest.cc @@ -34,7 +34,7 @@ TEST_F(IPCChannelTest, BasicMessageTest) { EXPECT_TRUE(m.WriteString(v2)); EXPECT_TRUE(m.WriteString16(v3)); - PickleIterator iter(m); + base::PickleIterator iter(m); int vi; std::string vs; @@ -190,8 +190,7 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) { // Set up IPC channel. scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( - IPCTestBase::GetChannelName("GenericClient"), - &listener)); + IPCTestBase::GetChannelName("GenericClient"), &listener, nullptr)); CHECK(channel->Connect()); listener.Init(channel.get()); IPC::TestChannelListener::SendOneMessage(channel.get(), "hello from child"); diff --git a/chromium/ipc/ipc_channel_win.cc b/chromium/ipc/ipc_channel_win.cc index 27043730695..05b9475a348 100644 --- a/chromium/ipc/ipc_channel_win.cc +++ b/chromium/ipc/ipc_channel_win.cc @@ -19,6 +19,7 @@ #include "base/win/scoped_handle.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_logging.h" +#include "ipc/ipc_message_attachment_set.h" #include "ipc/ipc_message_utils.h" namespace IPC { @@ -34,8 +35,10 @@ ChannelWin::State::~State() { "member."); } -ChannelWin::ChannelWin(const IPC::ChannelHandle &channel_handle, - Mode mode, Listener* listener) +ChannelWin::ChannelWin(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker) : ChannelReader(listener), input_state_(this), output_state_(this), @@ -44,6 +47,7 @@ ChannelWin::ChannelWin(const IPC::ChannelHandle &channel_handle, processing_incoming_(false), validate_client_(false), client_secret_(0), + broker_(broker), weak_factory_(this) { CreatePipe(channel_handle, mode); } @@ -65,7 +69,6 @@ void ChannelWin::Close() { pipe_.Close(); // Make sure all IO has completed. - base::Time start = base::Time::Now(); while (input_state_.is_pending || output_state_.is_pending) { base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); } @@ -78,12 +81,26 @@ void ChannelWin::Close() { } bool ChannelWin::Send(Message* message) { + // TODO(erikchen): Remove this DCHECK once ChannelWin fully supports + // brokerable attachments. http://crbug.com/493414. DCHECK(!message->HasAttachments()); DCHECK(thread_check_->CalledOnValidThread()); DVLOG(2) << "sending message @" << message << " on channel @" << this << " with type " << message->type() << " (" << output_queue_.size() << " in queue)"; + // Sending a brokerable attachment requires a call to Channel::Send(), so + // Send() may be re-entrant. Brokered attachments must be sent before the + // Message itself. + if (message->HasBrokerableAttachments()) { + DCHECK(broker_); + for (const BrokerableAttachment* attachment : + message->attachment_set()->PeekBrokerableAttachments()) { + if (!broker_->SendAttachmentToProcess(attachment, peer_pid_)) + return false; + } + } + #ifdef IPC_MESSAGE_LOG_ENABLED Logging::GetInstance()->OnSendMessage(message, ""); #endif @@ -101,6 +118,10 @@ bool ChannelWin::Send(Message* message) { return true; } +AttachmentBroker* ChannelWin::GetAttachmentBroker() { + return broker_; +} + base::ProcessId ChannelWin::GetPeerPID() const { return peer_pid_; } @@ -161,7 +182,7 @@ bool ChannelWin::WillDispatchInputMessage(Message* msg) { void ChannelWin::HandleInternalMessage(const Message& msg) { DCHECK_EQ(msg.type(), static_cast<unsigned>(Channel::HELLO_MESSAGE_TYPE)); // The hello message contains one parameter containing the PID. - PickleIterator it(msg); + base::PickleIterator it(msg); int32 claimed_pid; bool failed = !it.ReadInt(&claimed_pid); @@ -476,10 +497,12 @@ void ChannelWin::OnIOCompleted( // Channel's methods // static -scoped_ptr<Channel> Channel::Create( - const IPC::ChannelHandle &channel_handle, Mode mode, Listener* listener) { +scoped_ptr<Channel> Channel::Create(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker) { return scoped_ptr<Channel>( - new ChannelWin(channel_handle, mode, listener)); + new ChannelWin(channel_handle, mode, listener, broker)); } // static diff --git a/chromium/ipc/ipc_channel_win.h b/chromium/ipc/ipc_channel_win.h index 04990d4e84e..43cf46dc18f 100644 --- a/chromium/ipc/ipc_channel_win.h +++ b/chromium/ipc/ipc_channel_win.h @@ -27,14 +27,18 @@ class ChannelWin : public Channel, public base::MessageLoopForIO::IOHandler { public: // Mirror methods of Channel, see ipc_channel.h for description. - ChannelWin(const IPC::ChannelHandle &channel_handle, Mode mode, - Listener* listener); + // |broker| must outlive the newly created object. + ChannelWin(const IPC::ChannelHandle& channel_handle, + Mode mode, + Listener* listener, + AttachmentBroker* broker); ~ChannelWin() override; // Channel implementation bool Connect() override; void Close() override; bool Send(Message* message) override; + AttachmentBroker* GetAttachmentBroker() override; base::ProcessId GetPeerPID() const override; base::ProcessId GetSelfPID() const override; @@ -102,8 +106,11 @@ class ChannelWin : public Channel, int32 client_secret_; scoped_ptr<base::ThreadChecker> thread_check_; - base::WeakPtrFactory<ChannelWin> weak_factory_; + // |broker_| must outlive this instance. + AttachmentBroker* broker_; + + base::WeakPtrFactory<ChannelWin> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ChannelWin); }; diff --git a/chromium/ipc/ipc_fuzzing_tests.cc b/chromium/ipc/ipc_fuzzing_tests.cc index 42fa8597e08..d3ff1a0103a 100644 --- a/chromium/ipc/ipc_fuzzing_tests.cc +++ b/chromium/ipc/ipc_fuzzing_tests.cc @@ -44,7 +44,7 @@ TEST(IPCMessageIntegrity, ReadBeyondBufferStr) { EXPECT_TRUE(m.WriteInt(v1)); EXPECT_TRUE(m.WriteInt(v2)); - PickleIterator iter(m); + base::PickleIterator iter(m); std::string vs; EXPECT_FALSE(iter.ReadString(&vs)); } @@ -57,7 +57,7 @@ TEST(IPCMessageIntegrity, ReadBeyondBufferStr16) { EXPECT_TRUE(m.WriteInt(v1)); EXPECT_TRUE(m.WriteInt(v2)); - PickleIterator iter(m); + base::PickleIterator iter(m); base::string16 vs; EXPECT_FALSE(iter.ReadString16(&vs)); } @@ -68,7 +68,7 @@ TEST(IPCMessageIntegrity, ReadBytesBadIterator) { EXPECT_TRUE(m.WriteInt(1)); EXPECT_TRUE(m.WriteInt(2)); - PickleIterator iter(m); + base::PickleIterator iter(m); const char* data = NULL; EXPECT_TRUE(iter.ReadBytes(&data, sizeof(int))); } @@ -84,7 +84,7 @@ TEST(IPCMessageIntegrity, ReadVectorNegativeSize) { EXPECT_TRUE(m.WriteInt(3)); std::vector<double> vec; - PickleIterator iter(m); + base::PickleIterator iter(m); EXPECT_FALSE(ReadParam(&m, &iter, &vec)); } @@ -97,7 +97,7 @@ TEST(IPCMessageIntegrity, ReadVectorTooLarge1) { EXPECT_TRUE(m.WriteInt64(2)); std::vector<int64> vec; - PickleIterator iter(m); + base::PickleIterator iter(m); EXPECT_FALSE(ReadParam(&m, &iter, &vec)); } @@ -111,7 +111,7 @@ TEST(IPCMessageIntegrity, ReadVectorTooLarge2) { EXPECT_TRUE(m.WriteInt64(2)); std::vector<int64> vec; - PickleIterator iter(m); + base::PickleIterator iter(m); EXPECT_FALSE(ReadParam(&m, &iter, &vec)); } @@ -213,7 +213,7 @@ class FuzzerClientListener : public SimpleListener { return false; int msg_value1 = 0; int msg_value2 = 0; - PickleIterator iter(*last_msg_); + base::PickleIterator iter(*last_msg_); if (!iter.ReadInt(&msg_value1)) return false; if (!iter.ReadInt(&msg_value2)) @@ -251,8 +251,7 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(FuzzServerClient) { base::MessageLoopForIO main_message_loop; FuzzerServerListener listener; scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( - IPCTestBase::GetChannelName("FuzzServerClient"), - &listener)); + IPCTestBase::GetChannelName("FuzzServerClient"), &listener, nullptr)); CHECK(channel->Connect()); listener.Init(channel.get()); base::MessageLoop::current()->Run(); diff --git a/chromium/ipc/ipc_handle_win.cc b/chromium/ipc/ipc_handle_win.cc new file mode 100644 index 00000000000..da3b9bb6125 --- /dev/null +++ b/chromium/ipc/ipc_handle_win.cc @@ -0,0 +1,15 @@ +// Copyright 2015 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. + +#include "ipc/ipc_handle_win.h" + +namespace IPC { + +HandleForTransit CreateHandleForTransit(HANDLE handle) { + HandleForTransit hft; + hft.handle = handle; + return hft; +} + +} // namespace IPC diff --git a/chromium/ipc/ipc_handle_win.h b/chromium/ipc/ipc_handle_win.h new file mode 100644 index 00000000000..47779bdefcd --- /dev/null +++ b/chromium/ipc/ipc_handle_win.h @@ -0,0 +1,22 @@ +// Copyright 2015 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 IPC_HANDLE_WIN_H_ +#define IPC_HANDLE_WIN_H_ + +#include <windows.h> + +namespace IPC { + +// This class is a wrapper around HANDLE. It can be passed between Chrome +// processes via Chrome IPC. +struct HandleForTransit { + HANDLE handle; +}; + +HandleForTransit CreateHandleForTransit(HANDLE handle); + +} // namespace IPC + +#endif // IPC_HANDLE_WIN_H_ diff --git a/chromium/ipc/ipc_logging.cc b/chromium/ipc/ipc_logging.cc index 3db4e676d15..da80b14dc95 100644 --- a/chromium/ipc/ipc_logging.cc +++ b/chromium/ipc/ipc_logging.cc @@ -110,7 +110,7 @@ void Logging::SetIPCSender(IPC::Sender* sender) { void Logging::OnReceivedLoggingMessage(const Message& message) { std::vector<LogData> data; - PickleIterator iter(message); + base::PickleIterator iter(message); if (!ReadParam(&message, &iter, &data)) return; diff --git a/chromium/ipc/ipc_message.cc b/chromium/ipc/ipc_message.cc index 2587b0b112b..fcdbb6aa6d5 100644 --- a/chromium/ipc/ipc_message.cc +++ b/chromium/ipc/ipc_message.cc @@ -43,8 +43,7 @@ namespace IPC { Message::~Message() { } -Message::Message() - : Pickle(sizeof(Header)) { +Message::Message() : base::Pickle(sizeof(Header)) { header()->routing = header()->type = 0; header()->flags = GetRefNumUpper24(); #if defined(OS_POSIX) @@ -55,7 +54,7 @@ Message::Message() } Message::Message(int32 routing_id, uint32 type, PriorityValue priority) - : Pickle(sizeof(Header)) { + : base::Pickle(sizeof(Header)) { header()->routing = routing_id; header()->type = type; DCHECK((priority & 0xffffff00) == 0); @@ -67,11 +66,12 @@ Message::Message(int32 routing_id, uint32 type, PriorityValue priority) Init(); } -Message::Message(const char* data, int data_len) : Pickle(data, data_len) { +Message::Message(const char* data, int data_len) + : base::Pickle(data, data_len) { Init(); } -Message::Message(const Message& other) : Pickle(other) { +Message::Message(const Message& other) : base::Pickle(other) { Init(); #if defined(OS_POSIX) attachment_set_ = other.attachment_set_; @@ -88,7 +88,7 @@ void Message::Init() { } Message& Message::operator=(const Message& other) { - *static_cast<Pickle*>(this) = other; + *static_cast<base::Pickle*>(this) = other; #if defined(OS_POSIX) attachment_set_ = other.attachment_set_; #endif @@ -138,7 +138,7 @@ bool Message::WriteAttachment(scoped_refptr<MessageAttachment> attachment) { } bool Message::ReadAttachment( - PickleIterator* iter, + base::PickleIterator* iter, scoped_refptr<MessageAttachment>* attachment) const { int descriptor_index; if (!iter->ReadInt(&descriptor_index)) @@ -157,7 +157,12 @@ bool Message::HasAttachments() const { } bool Message::HasMojoHandles() const { - return attachment_set_.get() && 0 < attachment_set_->num_mojo_handles(); + return attachment_set_.get() && attachment_set_->num_mojo_handles() > 0; +} + +bool Message::HasBrokerableAttachments() const { + return attachment_set_.get() && + attachment_set_->num_brokerable_attachments() > 0; } } // namespace IPC diff --git a/chromium/ipc/ipc_message.h b/chromium/ipc/ipc_message.h index 64d85d4d44c..74bd74157be 100644 --- a/chromium/ipc/ipc_message.h +++ b/chromium/ipc/ipc_message.h @@ -25,7 +25,7 @@ struct LogData; class MessageAttachment; class MessageAttachmentSet; -class IPC_EXPORT Message : public Pickle { +class IPC_EXPORT Message : public base::Pickle { public: enum PriorityValue { PRIORITY_LOW = 1, @@ -163,7 +163,7 @@ class IPC_EXPORT Message : public Pickle { // Find the end of the message data that starts at range_start. Returns NULL // if the entire message is not found in the given data range. static const char* FindNext(const char* range_start, const char* range_end) { - return Pickle::FindNext(sizeof(Header), range_start, range_end); + return base::Pickle::FindNext(sizeof(Header), range_start, range_end); } // WriteAttachment appends |attachment| to the end of the set. It returns @@ -171,12 +171,14 @@ class IPC_EXPORT Message : public Pickle { bool WriteAttachment(scoped_refptr<MessageAttachment> attachment); // ReadAttachment parses an attachment given the parsing state |iter| and // writes it to |*attachment|. It returns true on success. - bool ReadAttachment(PickleIterator* iter, + bool ReadAttachment(base::PickleIterator* iter, scoped_refptr<MessageAttachment>* attachment) const; // Returns true if there are any attachment in this message. bool HasAttachments() const; // Returns true if there are any MojoHandleAttachments in this message. bool HasMojoHandles() const; + // Whether the message has any brokerable attachments. + bool HasBrokerableAttachments() const; #ifdef IPC_MESSAGE_LOG_ENABLED // Adds the outgoing time from Time::Now() at the end of the message and sets @@ -205,8 +207,8 @@ class IPC_EXPORT Message : public Pickle { } // Called to trace when message is received. void TraceMessageEnd() { - TRACE_EVENT_FLOW_END0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), "IPC", - header()->flags); + TRACE_EVENT_FLOW_END_BIND_TO_ENCLOSING0( + TRACE_DISABLED_BY_DEFAULT("ipc.flow"), "IPC", header()->flags); } protected: @@ -219,7 +221,7 @@ class IPC_EXPORT Message : public Pickle { friend class SyncMessage; #pragma pack(push, 4) - struct Header : Pickle::Header { + struct Header : base::Pickle::Header { int32 routing; // ID of the view that this message is destined for uint32 type; // specifies the user-defined message type uint32 flags; // specifies control flags for the message diff --git a/chromium/ipc/ipc_message_attachment.h b/chromium/ipc/ipc_message_attachment.h index ba7f0e83f90..e7553d262cf 100644 --- a/chromium/ipc/ipc_message_attachment.h +++ b/chromium/ipc/ipc_message_attachment.h @@ -18,8 +18,9 @@ class IPC_EXPORT MessageAttachment : public base::RefCounted<MessageAttachment> { public: enum Type { - TYPE_PLATFORM_FILE, // The instance is |PlatformFileAttachment|. - TYPE_MOJO_HANDLE, // The instance is |MojoHandleAttachment|. + TYPE_PLATFORM_FILE, // The instance is |PlatformFileAttachment|. + TYPE_MOJO_HANDLE, // The instance is |MojoHandleAttachment|. + TYPE_BROKERABLE_ATTACHMENT, // The instance is |BrokerableAttachment|. }; virtual Type GetType() const = 0; diff --git a/chromium/ipc/ipc_message_attachment_set.cc b/chromium/ipc/ipc_message_attachment_set.cc index cb74a5aaf07..ed653f3466a 100644 --- a/chromium/ipc/ipc_message_attachment_set.cc +++ b/chromium/ipc/ipc_message_attachment_set.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/logging.h" #include "base/posix/eintr_wrapper.h" +#include "ipc/brokerable_attachment.h" #include "ipc/ipc_message_attachment.h" #if defined(OS_POSIX) @@ -18,6 +19,21 @@ namespace IPC { +namespace { + +unsigned count_attachments_of_type( + const std::vector<scoped_refptr<MessageAttachment>>& attachments, + MessageAttachment::Type type) { + unsigned count = 0; + for (const scoped_refptr<MessageAttachment>& attachment : attachments) { + if (attachment->GetType() == type) + ++count; + } + return count; +} + +} // namespace + MessageAttachmentSet::MessageAttachmentSet() : consumed_descriptor_highwater_(0) { } @@ -39,17 +55,18 @@ MessageAttachmentSet::~MessageAttachmentSet() { } unsigned MessageAttachmentSet::num_descriptors() const { - return std::count_if(attachments_.begin(), attachments_.end(), - [](scoped_refptr<MessageAttachment> i) { - return i->GetType() == MessageAttachment::TYPE_PLATFORM_FILE; - }); + return count_attachments_of_type(attachments_, + MessageAttachment::TYPE_PLATFORM_FILE); } unsigned MessageAttachmentSet::num_mojo_handles() const { - return std::count_if(attachments_.begin(), attachments_.end(), - [](scoped_refptr<MessageAttachment> i) { - return i->GetType() == MessageAttachment::TYPE_MOJO_HANDLE; - }); + return count_attachments_of_type(attachments_, + MessageAttachment::TYPE_MOJO_HANDLE); +} + +unsigned MessageAttachmentSet::num_brokerable_attachments() const { + return count_attachments_of_type( + attachments_, MessageAttachment::TYPE_BROKERABLE_ATTACHMENT); } unsigned MessageAttachmentSet::size() const { @@ -114,6 +131,18 @@ void MessageAttachmentSet::CommitAll() { consumed_descriptor_highwater_ = 0; } +std::vector<const BrokerableAttachment*> +MessageAttachmentSet::PeekBrokerableAttachments() const { + std::vector<const BrokerableAttachment*> output; + for (const scoped_refptr<MessageAttachment>& attachment : attachments_) { + if (attachment->GetType() == + MessageAttachment::TYPE_BROKERABLE_ATTACHMENT) { + output.push_back(static_cast<BrokerableAttachment*>(attachment.get())); + } + } + return output; +} + #if defined(OS_POSIX) void MessageAttachmentSet::PeekDescriptors(base::PlatformFile* buffer) const { diff --git a/chromium/ipc/ipc_message_attachment_set.h b/chromium/ipc/ipc_message_attachment_set.h index 7e848bd3f54..bd113012aff 100644 --- a/chromium/ipc/ipc_message_attachment_set.h +++ b/chromium/ipc/ipc_message_attachment_set.h @@ -18,6 +18,7 @@ namespace IPC { +class BrokerableAttachment; class MessageAttachment; // ----------------------------------------------------------------------------- @@ -37,6 +38,8 @@ class IPC_EXPORT MessageAttachmentSet unsigned num_descriptors() const; // Return the number of mojo handles in the attachment set unsigned num_mojo_handles() const; + // Return the number of brokerable attachments in the attachment set. + unsigned num_brokerable_attachments() const; // Return true if no unconsumed descriptors remain bool empty() const { return 0 == size(); } @@ -56,6 +59,9 @@ class IPC_EXPORT MessageAttachmentSet // which are auto-close. void CommitAll(); + // Returns a vector of all brokerable attachments. + std::vector<const BrokerableAttachment*> PeekBrokerableAttachments() const; + #if defined(OS_POSIX) // This is the maximum number of descriptors per message. We need to know this // because the control message kernel interface has to be given a buffer which diff --git a/chromium/ipc/ipc_message_generator.cc b/chromium/ipc/ipc_message_generator.cc new file mode 100644 index 00000000000..146f0fc6138 --- /dev/null +++ b/chromium/ipc/ipc_message_generator.cc @@ -0,0 +1,33 @@ +// Copyright 2015 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. + +// Get basic type definitions. +#define IPC_MESSAGE_IMPL +#include "ipc/ipc_message_generator.h" + +// Generate constructors. +#include "ipc/struct_constructor_macros.h" +#include "ipc/ipc_message_generator.h" + +// Generate destructors. +#include "ipc/struct_destructor_macros.h" +#include "ipc/ipc_message_generator.h" + +// Generate param traits write methods. +#include "ipc/param_traits_write_macros.h" +namespace IPC { +#include "ipc/ipc_message_generator.h" +} // namespace IPC + +// Generate param traits read methods. +#include "ipc/param_traits_read_macros.h" +namespace IPC { +#include "ipc/ipc_message_generator.h" +} // namespace IPC + +// Generate param traits log methods. +#include "ipc/param_traits_log_macros.h" +namespace IPC { +#include "ipc/ipc_message_generator.h" +} // namespace IPC diff --git a/chromium/ipc/ipc_message_generator.h b/chromium/ipc/ipc_message_generator.h new file mode 100644 index 00000000000..b9d7a3a9754 --- /dev/null +++ b/chromium/ipc/ipc_message_generator.h @@ -0,0 +1,7 @@ +// Copyright 2015 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. + +// Multiply-included file, hence no include guard. + +#include "ipc/attachment_broker_messages.h" diff --git a/chromium/ipc/ipc_message_macros.h b/chromium/ipc/ipc_message_macros.h index e0e16d55925..3f7574fd31a 100644 --- a/chromium/ipc/ipc_message_macros.h +++ b/chromium/ipc/ipc_message_macros.h @@ -457,7 +457,7 @@ void (T::*func)(P*, TA)) { \ Schema::Param p; \ if (Read(msg, &p)) { \ - (obj->*func)(parameter, get<0>(p)); \ + (obj->*func)(parameter, base::get<0>(p)); \ return true; \ } \ return false; \ @@ -469,7 +469,7 @@ void (T::*func)(P*, TA, TB)) { \ Schema::Param p; \ if (Read(msg, &p)) { \ - (obj->*func)(parameter, get<0>(p), get<1>(p)); \ + (obj->*func)(parameter, base::get<0>(p), base::get<1>(p)); \ return true; \ } \ return false; \ @@ -481,7 +481,8 @@ void (T::*func)(P*, TA, TB, TC)) { \ Schema::Param p; \ if (Read(msg, &p)) { \ - (obj->*func)(parameter, get<0>(p), get<1>(p), get<2>(p)); \ + (obj->*func)(parameter, base::get<0>(p), base::get<1>(p), \ + base::get<2>(p)); \ return true; \ } \ return false; \ @@ -494,7 +495,8 @@ void (T::*func)(P*, TA, TB, TC, TD)) { \ Schema::Param p; \ if (Read(msg, &p)) { \ - (obj->*func)(parameter, get<0>(p), get<1>(p), get<2>(p), get<3>(p)); \ + (obj->*func)(parameter, base::get<0>(p), base::get<1>(p), \ + base::get<2>(p), base::get<3>(p)); \ return true; \ } \ return false; \ @@ -507,8 +509,8 @@ void (T::*func)(P*, TA, TB, TC, TD, TE)) { \ Schema::Param p; \ if (Read(msg, &p)) { \ - (obj->*func)(parameter, get<0>(p), get<1>(p), get<2>(p), get<3>(p), \ - get<4>(p)); \ + (obj->*func)(parameter, base::get<0>(p), base::get<1>(p), \ + base::get<2>(p), base::get<3>(p), base::get<4>(p)); \ return true; \ } \ return false; \ @@ -636,7 +638,7 @@ static bool ReadSendParam(const Message* msg, Schema::SendParam* p); \ static bool ReadReplyParam( \ const Message* msg, \ - TupleTypes<ReplyParam>::ValueTuple* p); \ + base::TupleTypes<ReplyParam>::ValueTuple* p); \ static void Log(std::string* name, const Message* msg, std::string* l); \ IPC_SYNC_MESSAGE_METHODS_##out_cnt \ }; @@ -658,7 +660,7 @@ static bool ReadSendParam(const Message* msg, Schema::SendParam* p); \ static bool ReadReplyParam( \ const Message* msg, \ - TupleTypes<ReplyParam>::ValueTuple* p); \ + base::TupleTypes<ReplyParam>::ValueTuple* p); \ static void Log(std::string* name, const Message* msg, std::string* l); \ IPC_SYNC_MESSAGE_METHODS_##out_cnt \ }; @@ -711,8 +713,9 @@ bool msg_class::ReadSendParam(const Message* msg, Schema::SendParam* p) { \ return Schema::ReadSendParam(msg, p); \ } \ - bool msg_class::ReadReplyParam(const Message* msg, \ - TupleTypes<ReplyParam>::ValueTuple* p) { \ + bool msg_class::ReadReplyParam( \ + const Message* msg, \ + base::TupleTypes<ReplyParam>::ValueTuple* p) { \ return Schema::ReadReplyParam(msg, p); \ } @@ -731,8 +734,9 @@ bool msg_class::ReadSendParam(const Message* msg, Schema::SendParam* p) { \ return Schema::ReadSendParam(msg, p); \ } \ - bool msg_class::ReadReplyParam(const Message* msg, \ - TupleTypes<ReplyParam>::ValueTuple* p) { \ + bool msg_class::ReadReplyParam( \ + const Message* msg, \ + base::TupleTypes<ReplyParam>::ValueTuple* p) { \ return Schema::ReadReplyParam(msg, p); \ } @@ -766,12 +770,12 @@ if (!msg || !l) \ return; \ if (msg->is_sync()) { \ - TupleTypes<Schema::SendParam>::ValueTuple p; \ + base::TupleTypes<Schema::SendParam>::ValueTuple p; \ if (Schema::ReadSendParam(msg, &p)) \ IPC::LogParam(p, l); \ AddOutputParamsToLog(msg, l); \ } else { \ - TupleTypes<Schema::ReplyParam>::ValueTuple p; \ + base::TupleTypes<Schema::ReplyParam>::ValueTuple p; \ if (Schema::ReadReplyParam(msg, &p)) \ IPC::LogParam(p, l); \ } \ @@ -816,33 +820,38 @@ #define IPC_TYPE_OUT_1(t1) t1* arg6 #define IPC_TYPE_OUT_2(t1, t2) t1* arg6, t2* arg7 #define IPC_TYPE_OUT_3(t1, t2, t3) t1* arg6, t2* arg7, t3* arg8 -#define IPC_TYPE_OUT_4(t1, t2, t3, t4) t1* arg6, t2* arg7, t3* arg8, t4* arg9 - -#define IPC_TUPLE_IN_0() Tuple<> -#define IPC_TUPLE_IN_1(t1) Tuple<t1> -#define IPC_TUPLE_IN_2(t1, t2) Tuple<t1, t2> -#define IPC_TUPLE_IN_3(t1, t2, t3) Tuple<t1, t2, t3> -#define IPC_TUPLE_IN_4(t1, t2, t3, t4) Tuple<t1, t2, t3, t4> -#define IPC_TUPLE_IN_5(t1, t2, t3, t4, t5) Tuple<t1, t2, t3, t4, t5> - -#define IPC_TUPLE_OUT_0() Tuple<> -#define IPC_TUPLE_OUT_1(t1) Tuple<t1&> -#define IPC_TUPLE_OUT_2(t1, t2) Tuple<t1&, t2&> -#define IPC_TUPLE_OUT_3(t1, t2, t3) Tuple<t1&, t2&, t3&> -#define IPC_TUPLE_OUT_4(t1, t2, t3, t4) Tuple<t1&, t2&, t3&, t4&> - -#define IPC_NAME_IN_0() MakeTuple() -#define IPC_NAME_IN_1(t1) MakeRefTuple(arg1) -#define IPC_NAME_IN_2(t1, t2) MakeRefTuple(arg1, arg2) -#define IPC_NAME_IN_3(t1, t2, t3) MakeRefTuple(arg1, arg2, arg3) -#define IPC_NAME_IN_4(t1, t2, t3, t4) MakeRefTuple(arg1, arg2, arg3, arg4) -#define IPC_NAME_IN_5(t1, t2, t3, t4, t5) MakeRefTuple(arg1, arg2, arg3, arg4, arg5) - -#define IPC_NAME_OUT_0() MakeTuple() -#define IPC_NAME_OUT_1(t1) MakeRefTuple(*arg6) -#define IPC_NAME_OUT_2(t1, t2) MakeRefTuple(*arg6, *arg7) -#define IPC_NAME_OUT_3(t1, t2, t3) MakeRefTuple(*arg6, *arg7, *arg8) -#define IPC_NAME_OUT_4(t1, t2, t3, t4) MakeRefTuple(*arg6, *arg7, *arg8, *arg9) +#define IPC_TYPE_OUT_4(t1, t2, t3, t4) t1* arg6, t2* arg7, t3* arg8, \ + t4* arg9 + +#define IPC_TUPLE_IN_0() base::Tuple<> +#define IPC_TUPLE_IN_1(t1) base::Tuple<t1> +#define IPC_TUPLE_IN_2(t1, t2) base::Tuple<t1, t2> +#define IPC_TUPLE_IN_3(t1, t2, t3) base::Tuple<t1, t2, t3> +#define IPC_TUPLE_IN_4(t1, t2, t3, t4) base::Tuple<t1, t2, t3, t4> +#define IPC_TUPLE_IN_5(t1, t2, t3, t4, t5) base::Tuple<t1, t2, t3, t4, t5> + +#define IPC_TUPLE_OUT_0() base::Tuple<> +#define IPC_TUPLE_OUT_1(t1) base::Tuple<t1&> +#define IPC_TUPLE_OUT_2(t1, t2) base::Tuple<t1&, t2&> +#define IPC_TUPLE_OUT_3(t1, t2, t3) base::Tuple<t1&, t2&, t3&> +#define IPC_TUPLE_OUT_4(t1, t2, t3, t4) base::Tuple<t1&, t2&, t3&, t4&> + +#define IPC_NAME_IN_0() base::MakeTuple() +#define IPC_NAME_IN_1(t1) base::MakeRefTuple(arg1) +#define IPC_NAME_IN_2(t1, t2) base::MakeRefTuple(arg1, arg2) +#define IPC_NAME_IN_3(t1, t2, t3) base::MakeRefTuple(arg1, arg2, arg3) +#define IPC_NAME_IN_4(t1, t2, t3, t4) base::MakeRefTuple(arg1, arg2, \ + arg3, arg4) +#define IPC_NAME_IN_5(t1, t2, t3, t4, t5) base::MakeRefTuple(arg1, arg2, \ + arg3, arg4, arg5) + +#define IPC_NAME_OUT_0() base::MakeTuple() +#define IPC_NAME_OUT_1(t1) base::MakeRefTuple(*arg6) +#define IPC_NAME_OUT_2(t1, t2) base::MakeRefTuple(*arg6, *arg7) +#define IPC_NAME_OUT_3(t1, t2, t3) base::MakeRefTuple(*arg6, *arg7, \ + *arg8) +#define IPC_NAME_OUT_4(t1, t2, t3, t4) base::MakeRefTuple(*arg6, *arg7, \ + *arg8, *arg9) // There are places where the syntax requires a comma if there are input args, // if there are input args and output args, or if there are input args or diff --git a/chromium/ipc/ipc_message_start.h b/chromium/ipc/ipc_message_start.h index d4966bc4196..f5538a91954 100644 --- a/chromium/ipc/ipc_message_start.h +++ b/chromium/ipc/ipc_message_start.h @@ -53,7 +53,6 @@ enum IPCMessageStart { ExtensionMsgStart, VideoCaptureMsgStart, QuotaMsgStart, - ImageMsgStart, TextInputClientMsgStart, ChromeUtilityMsgStart, MediaStreamMsgStart, @@ -112,7 +111,6 @@ enum IPCMessageStart { LayoutTestMsgStart, NetworkHintsMsgStart, BluetoothMsgStart, - NavigatorConnectMsgStart, CastMediaMsgStart, AwMessagePortMsgStart, ExtensionsGuestViewMsgStart, @@ -124,6 +122,8 @@ enum IPCMessageStart { DataReductionProxyStart, ContentSettingsMsgStart, ChromeAppBannerMsgStart, + SafeJsonParserMsgStart, + AttachmentBrokerMsgStart, LastIPCMsgStart // Must come last. }; diff --git a/chromium/ipc/ipc_message_unittest.cc b/chromium/ipc/ipc_message_unittest.cc index 5b3a78d3273..885ac2ebdf0 100644 --- a/chromium/ipc/ipc_message_unittest.cc +++ b/chromium/ipc/ipc_message_unittest.cc @@ -36,7 +36,7 @@ TEST(IPCMessageTest, ListValue) { IPC::WriteParam(&msg, input); base::ListValue output; - PickleIterator iter(msg); + base::PickleIterator iter(msg); EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); EXPECT_TRUE(input.Equals(&output)); @@ -44,7 +44,7 @@ TEST(IPCMessageTest, ListValue) { // Also test the corrupt case. IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); bad_msg.WriteInt(99); - iter = PickleIterator(bad_msg); + iter = base::PickleIterator(bad_msg); EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); } @@ -71,7 +71,7 @@ TEST(IPCMessageTest, DictionaryValue) { IPC::WriteParam(&msg, input); base::DictionaryValue output; - PickleIterator iter(msg); + base::PickleIterator iter(msg); EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)); EXPECT_TRUE(input.Equals(&output)); @@ -79,7 +79,7 @@ TEST(IPCMessageTest, DictionaryValue) { // Also test the corrupt case. IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL); bad_msg.WriteInt(99); - iter = PickleIterator(bad_msg); + iter = base::PickleIterator(bad_msg); EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output)); } diff --git a/chromium/ipc/ipc_message_utils.cc b/chromium/ipc/ipc_message_utils.cc index adb14d1d56c..dbb2572e668 100644 --- a/chromium/ipc/ipc_message_utils.cc +++ b/chromium/ipc/ipc_message_utils.cc @@ -20,6 +20,10 @@ #include "ipc/ipc_platform_file_attachment_posix.h" #endif +#if defined(OS_MACOSX) && !defined(OS_IOS) +#include "base/memory/shared_memory_handle.h" +#endif // defined(OS_MACOSX) && !defined(OS_IOS) + #if defined(OS_WIN) #include <tchar.h> #endif @@ -54,7 +58,9 @@ void LogBytes(const std::vector<CharType>& data, std::string* out) { #endif } -bool ReadValue(const Message* m, PickleIterator* iter, base::Value** value, +bool ReadValue(const Message* m, + base::PickleIterator* iter, + base::Value** value, int recursion); void WriteValue(Message* m, const base::Value* value, int recursion) { @@ -130,8 +136,10 @@ void WriteValue(Message* m, const base::Value* value, int recursion) { // Helper for ReadValue that reads a DictionaryValue into a pre-allocated // object. -bool ReadDictionaryValue(const Message* m, PickleIterator* iter, - base::DictionaryValue* value, int recursion) { +bool ReadDictionaryValue(const Message* m, + base::PickleIterator* iter, + base::DictionaryValue* value, + int recursion) { int size; if (!ReadParam(m, iter, &size)) return false; @@ -150,8 +158,10 @@ bool ReadDictionaryValue(const Message* m, PickleIterator* iter, // Helper for ReadValue that reads a ReadListValue into a pre-allocated // object. -bool ReadListValue(const Message* m, PickleIterator* iter, - base::ListValue* value, int recursion) { +bool ReadListValue(const Message* m, + base::PickleIterator* iter, + base::ListValue* value, + int recursion) { int size; if (!ReadParam(m, iter, &size)) return false; @@ -166,7 +176,9 @@ bool ReadListValue(const Message* m, PickleIterator* iter, return true; } -bool ReadValue(const Message* m, PickleIterator* iter, base::Value** value, +bool ReadValue(const Message* m, + base::PickleIterator* iter, + base::Value** value, int recursion) { if (recursion > kMaxRecursionDepth) { LOG(WARNING) << "Max recursion depth hit in ReadValue."; @@ -261,8 +273,9 @@ void ParamTraits<unsigned char>::Write(Message* m, const param_type& p) { m->WriteBytes(&p, sizeof(param_type)); } -bool ParamTraits<unsigned char>::Read(const Message* m, PickleIterator* iter, - param_type* r) { +bool ParamTraits<unsigned char>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { const char* data; if (!iter->ReadBytes(&data, sizeof(param_type))) return false; @@ -278,7 +291,8 @@ void ParamTraits<unsigned short>::Write(Message* m, const param_type& p) { m->WriteBytes(&p, sizeof(param_type)); } -bool ParamTraits<unsigned short>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<unsigned short>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { const char* data; if (!iter->ReadBytes(&data, sizeof(param_type))) @@ -323,7 +337,8 @@ void ParamTraits<double>::Write(Message* m, const param_type& p) { m->WriteBytes(reinterpret_cast<const char*>(&p), sizeof(param_type)); } -bool ParamTraits<double>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<double>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { const char *data; if (!iter->ReadBytes(&data, sizeof(*r))) { @@ -355,9 +370,9 @@ void ParamTraits<std::vector<char> >::Write(Message* m, const param_type& p) { } } -bool ParamTraits<std::vector<char> >::Read(const Message* m, - PickleIterator* iter, - param_type* r) { +bool ParamTraits<std::vector<char>>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { const char *data; int data_size = 0; if (!iter->ReadData(&data, &data_size) || data_size < 0) @@ -382,9 +397,9 @@ void ParamTraits<std::vector<unsigned char> >::Write(Message* m, } } -bool ParamTraits<std::vector<unsigned char> >::Read(const Message* m, - PickleIterator* iter, - param_type* r) { +bool ParamTraits<std::vector<unsigned char>>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { const char *data; int data_size = 0; if (!iter->ReadData(&data, &data_size) || data_size < 0) @@ -409,9 +424,9 @@ void ParamTraits<std::vector<bool> >::Write(Message* m, const param_type& p) { WriteParam(m, static_cast<bool>(p[i])); } -bool ParamTraits<std::vector<bool> >::Read(const Message* m, - PickleIterator* iter, - param_type* r) { +bool ParamTraits<std::vector<bool>>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { int size; // ReadLength() checks for < 0 itself. if (!iter->ReadLength(&size)) @@ -434,13 +449,36 @@ void ParamTraits<std::vector<bool> >::Log(const param_type& p, std::string* l) { } } +void ParamTraits<BrokerableAttachment::AttachmentId>::Write( + Message* m, + const param_type& p) { + m->WriteBytes(p.nonce, BrokerableAttachment::kNonceSize); +} + +bool ParamTraits<BrokerableAttachment::AttachmentId>::Read( + const Message* m, + base::PickleIterator* iter, + param_type* r) { + const char* data; + if (!iter->ReadBytes(&data, BrokerableAttachment::kNonceSize)) + return false; + memcpy(r->nonce, data, BrokerableAttachment::kNonceSize); + return true; +} + +void ParamTraits<BrokerableAttachment::AttachmentId>::Log(const param_type& p, + std::string* l) { + l->append(base::HexEncode(p.nonce, BrokerableAttachment::kNonceSize)); +} + void ParamTraits<base::DictionaryValue>::Write(Message* m, const param_type& p) { WriteValue(m, &p, 0); } -bool ParamTraits<base::DictionaryValue>::Read( - const Message* m, PickleIterator* iter, param_type* r) { +bool ParamTraits<base::DictionaryValue>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { int type; if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_DICTIONARY) return false; @@ -451,7 +489,7 @@ bool ParamTraits<base::DictionaryValue>::Read( void ParamTraits<base::DictionaryValue>::Log(const param_type& p, std::string* l) { std::string json; - base::JSONWriter::Write(&p, &json); + base::JSONWriter::Write(p, &json); l->append(json); } @@ -474,7 +512,7 @@ void ParamTraits<base::FileDescriptor>::Write(Message* m, const param_type& p) { } bool ParamTraits<base::FileDescriptor>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { *r = base::FileDescriptor(); @@ -504,12 +542,64 @@ void ParamTraits<base::FileDescriptor>::Log(const param_type& p, } #endif // defined(OS_POSIX) +#if defined(OS_MACOSX) && !defined(OS_IOS) +void ParamTraits<base::SharedMemoryHandle>::Write(Message* m, + const param_type& p) { + m->WriteInt(p.GetType()); + + if (p.GetType() == base::SharedMemoryHandle::POSIX) + ParamTraits<base::FileDescriptor>::Write(m, p.GetFileDescriptor()); +} + +bool ParamTraits<base::SharedMemoryHandle>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + base::SharedMemoryHandle::TypeWireFormat type; + if (!iter->ReadInt(&type)) + return false; + + base::SharedMemoryHandle::Type shm_type = base::SharedMemoryHandle::POSIX; + switch (type) { + case base::SharedMemoryHandle::POSIX: + case base::SharedMemoryHandle::MACH: { + shm_type = static_cast<base::SharedMemoryHandle::Type>(type); + break; + } + default: + return false; + } + + if (shm_type == base::SharedMemoryHandle::POSIX) { + base::FileDescriptor file_descriptor; + + bool success = + ParamTraits<base::FileDescriptor>::Read(m, iter, &file_descriptor); + if (!success) + return false; + + *r = base::SharedMemoryHandle(file_descriptor.fd, + file_descriptor.auto_close); + return true; + } + + return true; +} + +void ParamTraits<base::SharedMemoryHandle>::Log(const param_type& p, + std::string* l) { + if (p.GetType() == base::SharedMemoryHandle::POSIX) { + l->append(base::StringPrintf("Mechanism POSIX Fd")); + ParamTraits<base::FileDescriptor>::Log(p.GetFileDescriptor(), l); + } +} +#endif // defined(OS_MACOSX) && !defined(OS_IOS) + void ParamTraits<base::FilePath>::Write(Message* m, const param_type& p) { p.WriteToPickle(m); } bool ParamTraits<base::FilePath>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { return r->ReadFromPickle(iter); } @@ -522,8 +612,9 @@ void ParamTraits<base::ListValue>::Write(Message* m, const param_type& p) { WriteValue(m, &p, 0); } -bool ParamTraits<base::ListValue>::Read( - const Message* m, PickleIterator* iter, param_type* r) { +bool ParamTraits<base::ListValue>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { int type; if (!ReadParam(m, iter, &type) || type != base::Value::TYPE_LIST) return false; @@ -533,7 +624,7 @@ bool ParamTraits<base::ListValue>::Read( void ParamTraits<base::ListValue>::Log(const param_type& p, std::string* l) { std::string json; - base::JSONWriter::Write(&p, &json); + base::JSONWriter::Write(p, &json); l->append(json); } @@ -544,7 +635,7 @@ void ParamTraits<base::NullableString16>::Write(Message* m, } bool ParamTraits<base::NullableString16>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { base::string16 string; if (!ReadParam(m, iter, &string)) @@ -575,7 +666,7 @@ void ParamTraits<base::File::Info>::Write(Message* m, } bool ParamTraits<base::File::Info>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* p) { double last_modified, last_accessed, creation_time; if (!ReadParam(m, iter, &p->size) || @@ -609,7 +700,8 @@ void ParamTraits<base::Time>::Write(Message* m, const param_type& p) { ParamTraits<int64>::Write(m, p.ToInternalValue()); } -bool ParamTraits<base::Time>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<base::Time>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { int64 value; if (!ParamTraits<int64>::Read(m, iter, &value)) @@ -627,7 +719,7 @@ void ParamTraits<base::TimeDelta>::Write(Message* m, const param_type& p) { } bool ParamTraits<base::TimeDelta>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { int64 value; bool ret = ParamTraits<int64>::Read(m, iter, &value); @@ -646,7 +738,7 @@ void ParamTraits<base::TimeTicks>::Write(Message* m, const param_type& p) { } bool ParamTraits<base::TimeTicks>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { int64 value; bool ret = ParamTraits<int64>::Read(m, iter, &value); @@ -660,6 +752,25 @@ void ParamTraits<base::TimeTicks>::Log(const param_type& p, std::string* l) { ParamTraits<int64>::Log(p.ToInternalValue(), l); } +void ParamTraits<base::TraceTicks>::Write(Message* m, const param_type& p) { + ParamTraits<int64>::Write(m, p.ToInternalValue()); +} + +bool ParamTraits<base::TraceTicks>::Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + int64 value; + bool ret = ParamTraits<int64>::Read(m, iter, &value); + if (ret) + *r = base::TraceTicks::FromInternalValue(value); + + return ret; +} + +void ParamTraits<base::TraceTicks>::Log(const param_type& p, std::string* l) { + ParamTraits<int64>::Log(p.ToInternalValue(), l); +} + void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) { #if defined(OS_WIN) // On Windows marshalling pipe handle is not supported. @@ -672,7 +783,7 @@ void ParamTraits<IPC::ChannelHandle>::Write(Message* m, const param_type& p) { } bool ParamTraits<IPC::ChannelHandle>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { return ReadParam(m, iter, &r->name) #if defined(OS_POSIX) @@ -704,7 +815,7 @@ void ParamTraits<LogData>::Write(Message* m, const param_type& p) { } bool ParamTraits<LogData>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { return ReadParam(m, iter, &r->channel) && @@ -745,7 +856,8 @@ void ParamTraits<Message>::Write(Message* m, const Message& p) { m->WriteData(p.payload(), static_cast<uint32>(p.payload_size())); } -bool ParamTraits<Message>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<Message>::Read(const Message* m, + base::PickleIterator* iter, Message* r) { uint32 routing_id, type, flags; if (!iter->ReadUInt32(&routing_id) || @@ -773,7 +885,8 @@ void ParamTraits<HANDLE>::Write(Message* m, const param_type& p) { m->WriteInt(HandleToLong(p)); } -bool ParamTraits<HANDLE>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<HANDLE>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { int32 temp; if (!iter->ReadInt(&temp)) @@ -790,7 +903,8 @@ void ParamTraits<LOGFONT>::Write(Message* m, const param_type& p) { m->WriteData(reinterpret_cast<const char*>(&p), sizeof(LOGFONT)); } -bool ParamTraits<LOGFONT>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<LOGFONT>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { const char *data; int data_size = 0; @@ -814,7 +928,8 @@ void ParamTraits<MSG>::Write(Message* m, const param_type& p) { m->WriteData(reinterpret_cast<const char*>(&p), sizeof(MSG)); } -bool ParamTraits<MSG>::Read(const Message* m, PickleIterator* iter, +bool ParamTraits<MSG>::Read(const Message* m, + base::PickleIterator* iter, param_type* r) { const char *data; int data_size = 0; diff --git a/chromium/ipc/ipc_message_utils.h b/chromium/ipc/ipc_message_utils.h index 6787c8e2eb8..dbbd642ca53 100644 --- a/chromium/ipc/ipc_message_utils.h +++ b/chromium/ipc/ipc_message_utils.h @@ -20,6 +20,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/tuple.h" +#include "ipc/brokerable_attachment.h" #include "ipc/ipc_message_start.h" #include "ipc/ipc_param_traits.h" #include "ipc/ipc_sync_message.h" @@ -55,7 +56,12 @@ class NullableString16; class Time; class TimeDelta; class TimeTicks; +class TraceTicks; struct FileDescriptor; + +#if defined(OS_MACOSX) && !defined(OS_IOS) +class SharedMemoryHandle; +#endif // defined(OS_MACOSX) && !defined(OS_IOS) } namespace IPC { @@ -95,9 +101,8 @@ static inline void WriteParam(Message* m, const P& p) { } template <class P> -static inline bool WARN_UNUSED_RESULT ReadParam(const Message* m, - PickleIterator* iter, - P* p) { +static inline bool WARN_UNUSED_RESULT +ReadParam(const Message* m, base::PickleIterator* iter, P* p) { typedef typename SimilarTypeTraits<P>::Type Type; return ParamTraits<Type>::Read(m, iter, reinterpret_cast<Type* >(p)); } @@ -116,7 +121,9 @@ struct ParamTraits<bool> { static void Write(Message* m, const param_type& p) { m->WriteBool(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadBool(r); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -126,7 +133,7 @@ template <> struct IPC_EXPORT ParamTraits<unsigned char> { typedef unsigned char param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, base::PickleIterator* iter, param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -134,7 +141,9 @@ template <> struct IPC_EXPORT ParamTraits<unsigned short> { typedef unsigned short param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -144,7 +153,9 @@ struct ParamTraits<int> { static void Write(Message* m, const param_type& p) { m->WriteInt(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadInt(r); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -156,7 +167,9 @@ struct ParamTraits<unsigned int> { static void Write(Message* m, const param_type& p) { m->WriteInt(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadInt(reinterpret_cast<int*>(r)); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -168,7 +181,9 @@ struct ParamTraits<long> { static void Write(Message* m, const param_type& p) { m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadLong(r); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -180,7 +195,9 @@ struct ParamTraits<unsigned long> { static void Write(Message* m, const param_type& p) { m->WriteLongUsingDangerousNonPortableLessPersistableForm(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadLong(reinterpret_cast<long*>(r)); } IPC_EXPORT static void Log(const param_type& p, std::string* l); @@ -192,7 +209,8 @@ struct ParamTraits<long long> { static void Write(Message* m, const param_type& p) { m->WriteInt64(static_cast<int64>(p)); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { return iter->ReadInt64(reinterpret_cast<int64*>(r)); } @@ -205,7 +223,8 @@ struct ParamTraits<unsigned long long> { static void Write(Message* m, const param_type& p) { m->WriteInt64(p); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { return iter->ReadInt64(reinterpret_cast<int64*>(r)); } @@ -221,7 +240,9 @@ struct IPC_EXPORT ParamTraits<float> { static void Write(Message* m, const param_type& p) { m->WriteFloat(p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return iter->ReadFloat(r); } static void Log(const param_type& p, std::string* l); @@ -231,7 +252,9 @@ template <> struct IPC_EXPORT ParamTraits<double> { typedef double param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -243,7 +266,8 @@ struct ParamTraits<std::string> { static void Write(Message* m, const param_type& p) { m->WriteString(p); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { return iter->ReadString(r); } @@ -256,7 +280,8 @@ struct ParamTraits<base::string16> { static void Write(Message* m, const param_type& p) { m->WriteString16(p); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { return iter->ReadString16(r); } @@ -267,7 +292,9 @@ template <> struct IPC_EXPORT ParamTraits<std::vector<char> > { typedef std::vector<char> param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message*, PickleIterator* iter, param_type* r); + static bool Read(const Message*, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -275,7 +302,9 @@ template <> struct IPC_EXPORT ParamTraits<std::vector<unsigned char> > { typedef std::vector<unsigned char> param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -283,7 +312,9 @@ template <> struct IPC_EXPORT ParamTraits<std::vector<bool> > { typedef std::vector<bool> param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -295,7 +326,8 @@ struct ParamTraits<std::vector<P> > { for (size_t i = 0; i < p.size(); i++) WriteParam(m, p[i]); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { int size; // ReadLength() checks for < 0 itself. @@ -329,7 +361,8 @@ struct ParamTraits<std::set<P> > { for (iter = p.begin(); iter != p.end(); ++iter) WriteParam(m, *iter); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { int size; if (!iter->ReadLength(&size)) @@ -358,7 +391,8 @@ struct ParamTraits<std::map<K, V, C, A> > { WriteParam(m, iter->second); } } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { int size; if (!ReadParam(m, iter, &size) || size < 0) @@ -385,7 +419,8 @@ struct ParamTraits<std::pair<A, B> > { WriteParam(m, p.first); WriteParam(m, p.second); } - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r) { return ReadParam(m, iter, &r->first) && ReadParam(m, iter, &r->second); } @@ -398,13 +433,24 @@ struct ParamTraits<std::pair<A, B> > { } }; +// IPC ParamTraits ------------------------------------------------------------- +template <> +struct IPC_EXPORT ParamTraits<BrokerableAttachment::AttachmentId> { + typedef BrokerableAttachment::AttachmentId param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, base::PickleIterator* iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + // Base ParamTraits ------------------------------------------------------------ template <> struct IPC_EXPORT ParamTraits<base::DictionaryValue> { typedef base::DictionaryValue param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -428,16 +474,30 @@ template<> struct IPC_EXPORT ParamTraits<base::FileDescriptor> { typedef base::FileDescriptor param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; #endif // defined(OS_POSIX) +#if defined(OS_MACOSX) && !defined(OS_IOS) +template <> +struct IPC_EXPORT ParamTraits<base::SharedMemoryHandle> { + typedef base::SharedMemoryHandle param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, base::PickleIterator* iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; +#endif + template <> struct IPC_EXPORT ParamTraits<base::FilePath> { typedef base::FilePath param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -445,7 +505,9 @@ template <> struct IPC_EXPORT ParamTraits<base::ListValue> { typedef base::ListValue param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -453,7 +515,8 @@ template <> struct IPC_EXPORT ParamTraits<base::NullableString16> { typedef base::NullableString16 param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, + static bool Read(const Message* m, + base::PickleIterator* iter, param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -462,7 +525,9 @@ template <> struct IPC_EXPORT ParamTraits<base::File::Info> { typedef base::File::Info param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -482,7 +547,9 @@ template <> struct IPC_EXPORT ParamTraits<base::Time> { typedef base::Time param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -490,7 +557,9 @@ template <> struct IPC_EXPORT ParamTraits<base::TimeDelta> { typedef base::TimeDelta param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -498,16 +567,30 @@ template <> struct IPC_EXPORT ParamTraits<base::TimeTicks> { typedef base::TimeTicks param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; template <> -struct ParamTraits<Tuple<>> { - typedef Tuple<> param_type; +struct IPC_EXPORT ParamTraits<base::TraceTicks> { + typedef base::TraceTicks param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct ParamTraits<base::Tuple<>> { + typedef base::Tuple<> param_type; static void Write(Message* m, const param_type& p) { } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { return true; } static void Log(const param_type& p, std::string* l) { @@ -515,112 +598,122 @@ struct ParamTraits<Tuple<>> { }; template <class A> -struct ParamTraits<Tuple<A>> { - typedef Tuple<A> param_type; +struct ParamTraits<base::Tuple<A>> { + typedef base::Tuple<A> param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, get<0>(p)); + WriteParam(m, base::get<0>(p)); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { - return ReadParam(m, iter, &get<0>(*r)); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + return ReadParam(m, iter, &base::get<0>(*r)); } static void Log(const param_type& p, std::string* l) { - LogParam(get<0>(p), l); + LogParam(base::get<0>(p), l); } }; template <class A, class B> -struct ParamTraits< Tuple<A, B> > { - typedef Tuple<A, B> param_type; +struct ParamTraits<base::Tuple<A, B>> { + typedef base::Tuple<A, B> param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, get<0>(p)); - WriteParam(m, get<1>(p)); + WriteParam(m, base::get<0>(p)); + WriteParam(m, base::get<1>(p)); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &get<0>(*r)) && - ReadParam(m, iter, &get<1>(*r))); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + return (ReadParam(m, iter, &base::get<0>(*r)) && + ReadParam(m, iter, &base::get<1>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(get<0>(p), l); + LogParam(base::get<0>(p), l); l->append(", "); - LogParam(get<1>(p), l); + LogParam(base::get<1>(p), l); } }; template <class A, class B, class C> -struct ParamTraits< Tuple<A, B, C> > { - typedef Tuple<A, B, C> param_type; +struct ParamTraits<base::Tuple<A, B, C>> { + typedef base::Tuple<A, B, C> param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, get<0>(p)); - WriteParam(m, get<1>(p)); - WriteParam(m, get<2>(p)); + WriteParam(m, base::get<0>(p)); + WriteParam(m, base::get<1>(p)); + WriteParam(m, base::get<2>(p)); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &get<0>(*r)) && - ReadParam(m, iter, &get<1>(*r)) && - ReadParam(m, iter, &get<2>(*r))); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + return (ReadParam(m, iter, &base::get<0>(*r)) && + ReadParam(m, iter, &base::get<1>(*r)) && + ReadParam(m, iter, &base::get<2>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(get<0>(p), l); + LogParam(base::get<0>(p), l); l->append(", "); - LogParam(get<1>(p), l); + LogParam(base::get<1>(p), l); l->append(", "); - LogParam(get<2>(p), l); + LogParam(base::get<2>(p), l); } }; template <class A, class B, class C, class D> -struct ParamTraits< Tuple<A, B, C, D> > { - typedef Tuple<A, B, C, D> param_type; +struct ParamTraits<base::Tuple<A, B, C, D>> { + typedef base::Tuple<A, B, C, D> param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, get<0>(p)); - WriteParam(m, get<1>(p)); - WriteParam(m, get<2>(p)); - WriteParam(m, get<3>(p)); + WriteParam(m, base::get<0>(p)); + WriteParam(m, base::get<1>(p)); + WriteParam(m, base::get<2>(p)); + WriteParam(m, base::get<3>(p)); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &get<0>(*r)) && - ReadParam(m, iter, &get<1>(*r)) && - ReadParam(m, iter, &get<2>(*r)) && - ReadParam(m, iter, &get<3>(*r))); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + return (ReadParam(m, iter, &base::get<0>(*r)) && + ReadParam(m, iter, &base::get<1>(*r)) && + ReadParam(m, iter, &base::get<2>(*r)) && + ReadParam(m, iter, &base::get<3>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(get<0>(p), l); + LogParam(base::get<0>(p), l); l->append(", "); - LogParam(get<1>(p), l); + LogParam(base::get<1>(p), l); l->append(", "); - LogParam(get<2>(p), l); + LogParam(base::get<2>(p), l); l->append(", "); - LogParam(get<3>(p), l); + LogParam(base::get<3>(p), l); } }; template <class A, class B, class C, class D, class E> -struct ParamTraits< Tuple<A, B, C, D, E> > { - typedef Tuple<A, B, C, D, E> param_type; +struct ParamTraits<base::Tuple<A, B, C, D, E>> { + typedef base::Tuple<A, B, C, D, E> param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, get<0>(p)); - WriteParam(m, get<1>(p)); - WriteParam(m, get<2>(p)); - WriteParam(m, get<3>(p)); - WriteParam(m, get<4>(p)); - } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { - return (ReadParam(m, iter, &get<0>(*r)) && - ReadParam(m, iter, &get<1>(*r)) && - ReadParam(m, iter, &get<2>(*r)) && - ReadParam(m, iter, &get<3>(*r)) && - ReadParam(m, iter, &get<4>(*r))); + WriteParam(m, base::get<0>(p)); + WriteParam(m, base::get<1>(p)); + WriteParam(m, base::get<2>(p)); + WriteParam(m, base::get<3>(p)); + WriteParam(m, base::get<4>(p)); + } + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { + return (ReadParam(m, iter, &base::get<0>(*r)) && + ReadParam(m, iter, &base::get<1>(*r)) && + ReadParam(m, iter, &base::get<2>(*r)) && + ReadParam(m, iter, &base::get<3>(*r)) && + ReadParam(m, iter, &base::get<4>(*r))); } static void Log(const param_type& p, std::string* l) { - LogParam(get<0>(p), l); + LogParam(base::get<0>(p), l); l->append(", "); - LogParam(get<1>(p), l); + LogParam(base::get<1>(p), l); l->append(", "); - LogParam(get<2>(p), l); + LogParam(base::get<2>(p), l); l->append(", "); - LogParam(get<3>(p), l); + LogParam(base::get<3>(p), l); l->append(", "); - LogParam(get<4>(p), l); + LogParam(base::get<4>(p), l); } }; @@ -632,7 +725,9 @@ struct ParamTraits<ScopedVector<P> > { for (size_t i = 0; i < p.size(); i++) WriteParam(m, *p[i]); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { int size = 0; if (!iter->ReadLength(&size)) return false; @@ -671,7 +766,9 @@ struct ParamTraits<base::SmallMap<NormalMap, kArraySize, EqualKey, MapInit> > { WriteParam(m, iter->second); } } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { int size; if (!iter->ReadLength(&size)) return false; @@ -699,7 +796,9 @@ struct ParamTraits<scoped_ptr<P> > { if (valid) WriteParam(m, *p); } - static bool Read(const Message* m, PickleIterator* iter, param_type* r) { + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r) { bool valid = false; if (!ReadParam(m, iter, &valid)) return false; @@ -733,7 +832,9 @@ template<> struct IPC_EXPORT ParamTraits<IPC::ChannelHandle> { typedef ChannelHandle param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -741,14 +842,18 @@ template <> struct IPC_EXPORT ParamTraits<LogData> { typedef LogData param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; template <> struct IPC_EXPORT ParamTraits<Message> { static void Write(Message* m, const Message& p); - static bool Read(const Message* m, PickleIterator* iter, Message* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + Message* r); static void Log(const Message& p, std::string* l); }; @@ -759,7 +864,9 @@ template <> struct IPC_EXPORT ParamTraits<HANDLE> { typedef HANDLE param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -767,7 +874,9 @@ template <> struct IPC_EXPORT ParamTraits<LOGFONT> { typedef LOGFONT param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; @@ -775,7 +884,9 @@ template <> struct IPC_EXPORT ParamTraits<MSG> { typedef MSG param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, + base::PickleIterator* iter, + param_type* r); static void Log(const param_type& p, std::string* l); }; #endif // defined(OS_WIN) @@ -788,7 +899,7 @@ template <class ParamType> class MessageSchema { public: typedef ParamType Param; - typedef typename TupleTypes<ParamType>::ParamTuple RefParam; + typedef typename base::TupleTypes<ParamType>::ParamTuple RefParam; static void Write(Message* msg, const RefParam& p) IPC_MSG_NOINLINE; static bool Read(const Message* msg, Param* p) IPC_MSG_NOINLINE; @@ -849,7 +960,7 @@ class ParamDeserializer : public MessageReplyDeserializer { explicit ParamDeserializer(const RefTuple& out) : out_(out) { } bool SerializeOutputParameters(const IPC::Message& msg, - PickleIterator iter) override { + base::PickleIterator iter) override { return ReadParam(&msg, &iter, &out_); } @@ -861,14 +972,14 @@ template <class SendParamType, class ReplyParamType> class SyncMessageSchema { public: typedef SendParamType SendParam; - typedef typename TupleTypes<SendParam>::ParamTuple RefSendParam; + typedef typename base::TupleTypes<SendParam>::ParamTuple RefSendParam; typedef ReplyParamType ReplyParam; static void Write(Message* msg, const RefSendParam& send) IPC_MSG_NOINLINE; static bool ReadSendParam(const Message* msg, SendParam* p) IPC_MSG_NOINLINE; static bool ReadReplyParam( const Message* msg, - typename TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; + typename base::TupleTypes<ReplyParam>::ValueTuple* p) IPC_MSG_NOINLINE; template<class T, class S, class Method> static bool DispatchWithSendParams(bool ok, const SendParam& send_params, @@ -876,7 +987,7 @@ class SyncMessageSchema { Method func) { Message* reply = SyncMessage::GenerateReply(msg); if (ok) { - typename TupleTypes<ReplyParam>::ValueTuple reply_params; + typename base::TupleTypes<ReplyParam>::ValueTuple reply_params; DispatchToMethod(obj, func, send_params, &reply_params); WriteParam(reply, reply_params); LogReplyParamsToMessage(reply_params, msg); @@ -895,7 +1006,7 @@ class SyncMessageSchema { Method func) { Message* reply = SyncMessage::GenerateReply(msg); if (ok) { - Tuple<Message&> t = MakeRefTuple(*reply); + base::Tuple<Message&> t = base::MakeRefTuple(*reply); ConnectMessageAndReply(msg, reply); DispatchToMethod(obj, func, send_params, &t); } else { diff --git a/chromium/ipc/ipc_message_utils_impl.h b/chromium/ipc/ipc_message_utils_impl.h index 0931e30216b..485dca578e9 100644 --- a/chromium/ipc/ipc_message_utils_impl.h +++ b/chromium/ipc/ipc_message_utils_impl.h @@ -18,7 +18,7 @@ void MessageSchema<ParamType>::Write(Message* msg, const RefParam& p) { template <class ParamType> bool MessageSchema<ParamType>::Read(const Message* msg, Param* p) { - PickleIterator iter(*msg); + base::PickleIterator iter(*msg); if (ReadParam(msg, &iter, p)) return true; NOTREACHED() << "Error deserializing message " << msg->type(); @@ -35,14 +35,14 @@ void SyncMessageSchema<SendParamType, ReplyParamType>::Write( template <class SendParamType, class ReplyParamType> bool SyncMessageSchema<SendParamType, ReplyParamType>::ReadSendParam( const Message* msg, SendParam* p) { - PickleIterator iter = SyncMessage::GetDataIterator(msg); + base::PickleIterator iter = SyncMessage::GetDataIterator(msg); return ReadParam(msg, &iter, p); } template <class SendParamType, class ReplyParamType> bool SyncMessageSchema<SendParamType, ReplyParamType>::ReadReplyParam( - const Message* msg, typename TupleTypes<ReplyParam>::ValueTuple* p) { - PickleIterator iter = SyncMessage::GetDataIterator(msg); + const Message* msg, typename base::TupleTypes<ReplyParam>::ValueTuple* p) { + base::PickleIterator iter = SyncMessage::GetDataIterator(msg); return ReadParam(msg, &iter, p); } diff --git a/chromium/ipc/ipc_message_utils_unittest.cc b/chromium/ipc/ipc_message_utils_unittest.cc index 2156eeb1b82..a73e2e7e2fc 100644 --- a/chromium/ipc/ipc_message_utils_unittest.cc +++ b/chromium/ipc/ipc_message_utils_unittest.cc @@ -29,7 +29,7 @@ TEST(IPCMessageUtilsTest, NestedMessages) { ParamTraits<Message>::Write(&outer_msg, nested_msg); // Read back the nested message. - PickleIterator iter(outer_msg); + base::PickleIterator iter(outer_msg); IPC::Message result_msg; ASSERT_TRUE(ParamTraits<Message>::Read(&outer_msg, &iter, &result_msg)); @@ -40,7 +40,7 @@ TEST(IPCMessageUtilsTest, NestedMessages) { EXPECT_EQ(nested_msg.flags(), result_msg.flags()); // Verify nested message content - PickleIterator nested_iter(nested_msg); + base::PickleIterator nested_iter(nested_msg); int result_content = 0; ASSERT_TRUE(ParamTraits<int>::Read(&nested_msg, &nested_iter, &result_content)); @@ -63,7 +63,7 @@ TEST(IPCMessageUtilsTest, ParameterValidation) { ParamTraits<base::FilePath::StringType>::Write(&message, ok_string); ParamTraits<base::FilePath::StringType>::Write(&message, bad_string); - PickleIterator iter(message); + base::PickleIterator iter(message); base::FilePath ok_path; base::FilePath bad_path; ASSERT_TRUE(ParamTraits<base::FilePath>::Read(&message, &iter, &ok_path)); diff --git a/chromium/ipc/ipc_nacl.gyp b/chromium/ipc/ipc_nacl.gyp index 5faf9af1f4c..6dbb5b66d61 100644 --- a/chromium/ipc/ipc_nacl.gyp +++ b/chromium/ipc/ipc_nacl.gyp @@ -26,6 +26,7 @@ }, 'dependencies': [ '../base/base_nacl.gyp:base_nacl', + '../crypto/crypto_nacl.gyp:crypto_nacl', ], }, { @@ -55,6 +56,7 @@ ], 'dependencies': [ '../base/base_nacl.gyp:base_nacl_nonsfi', + '../crypto/crypto_nacl.gyp:crypto_nacl', ], }, ], diff --git a/chromium/ipc/ipc_perftest_support.cc b/chromium/ipc/ipc_perftest_support.cc index ae8be7fb2d1..31a37a7ad03 100644 --- a/chromium/ipc/ipc_perftest_support.cc +++ b/chromium/ipc/ipc_perftest_support.cc @@ -98,7 +98,7 @@ class ChannelReflectorListener : public Listener { bool OnMessageReceived(const Message& message) override { CHECK(channel_); - PickleIterator iter(message); + base::PickleIterator iter(message); int64 time_internal; EXPECT_TRUE(iter.ReadInt64(&time_internal)); int msgid; @@ -167,7 +167,7 @@ class PerformanceChannelListener : public Listener { bool OnMessageReceived(const Message& message) override { CHECK(sender_); - PickleIterator iter(message); + base::PickleIterator iter(message); int64 time_internal; EXPECT_TRUE(iter.ReadInt64(&time_internal)); int msgid; @@ -327,8 +327,8 @@ PingPongTestClient::~PingPongTestClient() { scoped_ptr<Channel> PingPongTestClient::CreateChannel( Listener* listener) { - return Channel::CreateClient( - IPCTestBase::GetChannelName("PerformanceClient"), listener); + return Channel::CreateClient(IPCTestBase::GetChannelName("PerformanceClient"), + listener, nullptr); } int PingPongTestClient::RunMain() { diff --git a/chromium/ipc/ipc_send_fds_test.cc b/chromium/ipc/ipc_send_fds_test.cc index 148eecab125..7669c8fd1cf 100644 --- a/chromium/ipc/ipc_send_fds_test.cc +++ b/chromium/ipc/ipc_send_fds_test.cc @@ -47,7 +47,7 @@ static_assert(kNumFDsToSend == class MyChannelDescriptorListenerBase : public IPC::Listener { public: bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); base::FileDescriptor descriptor; while (IPC::ParamTraits<base::FileDescriptor>::Read( &message, &iter, &descriptor)) { @@ -149,8 +149,7 @@ int SendFdsClientCommon(const std::string& test_client_name, // Set up IPC channel. scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( - IPCTestBase::GetChannelName(test_client_name), - &listener)); + IPCTestBase::GetChannelName(test_client_name), &listener, nullptr)); CHECK(channel->Connect()); // Run message loop. @@ -245,10 +244,10 @@ class PipeChannelHelper { void Init() { IPC::ChannelHandle in_handle("IN"); - in = IPC::Channel::CreateServer(in_handle, &null_listener_); + in = IPC::Channel::CreateServer(in_handle, &null_listener_, nullptr); IPC::ChannelHandle out_handle( "OUT", base::FileDescriptor(in->TakeClientFileDescriptor())); - out = IPC::Channel::CreateClient(out_handle, &cb_listener_); + out = IPC::Channel::CreateClient(out_handle, &cb_listener_, nullptr); // PostTask the connect calls to make sure the callbacks happens // on the right threads. in_thread_->task_runner()->PostTask( diff --git a/chromium/ipc/ipc_sync_channel.cc b/chromium/ipc/ipc_sync_channel.cc index 06cd46f1ea6..35b88a7edeb 100644 --- a/chromium/ipc/ipc_sync_channel.cc +++ b/chromium/ipc/ipc_sync_channel.cc @@ -412,10 +412,11 @@ scoped_ptr<SyncChannel> SyncChannel::Create( Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, bool create_pipe_now, - base::WaitableEvent* shutdown_event) { + base::WaitableEvent* shutdown_event, + AttachmentBroker* broker) { scoped_ptr<SyncChannel> channel = Create(listener, ipc_task_runner, shutdown_event); - channel->Init(channel_handle, mode, create_pipe_now); + channel->Init(channel_handle, mode, create_pipe_now, broker); return channel.Pass(); } diff --git a/chromium/ipc/ipc_sync_channel.h b/chromium/ipc/ipc_sync_channel.h index 35934850ed7..8b4b9a96e36 100644 --- a/chromium/ipc/ipc_sync_channel.h +++ b/chromium/ipc/ipc_sync_channel.h @@ -68,13 +68,17 @@ class IPC_EXPORT SyncChannel : public ChannelProxy { // Creates and initializes a sync channel. If create_pipe_now is specified, // the channel will be initialized synchronously. // The naming pattern follows IPC::Channel. + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. static scoped_ptr<SyncChannel> Create( const IPC::ChannelHandle& channel_handle, IPC::Channel::Mode mode, Listener* listener, const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner, bool create_pipe_now, - base::WaitableEvent* shutdown_event); + base::WaitableEvent* shutdown_event, + AttachmentBroker* broker = nullptr); static scoped_ptr<SyncChannel> Create( scoped_ptr<ChannelFactory> factory, diff --git a/chromium/ipc/ipc_sync_channel_unittest.cc b/chromium/ipc/ipc_sync_channel_unittest.cc index 7e81d5deabc..1e61a68bd61 100644 --- a/chromium/ipc/ipc_sync_channel_unittest.cc +++ b/chromium/ipc/ipc_sync_channel_unittest.cc @@ -155,7 +155,7 @@ class Worker : public Listener, public Sender { virtual SyncChannel* CreateChannel() { scoped_ptr<SyncChannel> channel = SyncChannel::Create( channel_name_, mode_, this, ipc_thread_.task_runner().get(), true, - &shutdown_event_); + &shutdown_event_, nullptr); return channel.release(); } @@ -327,7 +327,7 @@ class TwoStepServer : public Worker { SyncChannel* channel = SyncChannel::Create(channel_name(), mode(), this, ipc_thread().task_runner().get(), create_pipe_now_, - shutdown_event()).release(); + shutdown_event(), nullptr).release(); return channel; } @@ -349,7 +349,7 @@ class TwoStepClient : public Worker { SyncChannel* channel = SyncChannel::Create(channel_name(), mode(), this, ipc_thread().task_runner().get(), create_pipe_now_, - shutdown_event()).release(); + shutdown_event(), nullptr).release(); return channel; } @@ -1138,7 +1138,7 @@ class RestrictedDispatchClient : public Worker { non_restricted_channel_ = SyncChannel::Create( "non_restricted_channel", IPC::Channel::MODE_CLIENT, this, - ipc_thread().task_runner().get(), true, shutdown_event()); + ipc_thread().task_runner().get(), true, shutdown_event(), nullptr); server_->ListenerThread()->task_runner()->PostTask( FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2)); @@ -1525,7 +1525,7 @@ class RestrictedDispatchPipeWorker : public Worker { event2_->Wait(); other_channel_ = SyncChannel::Create( other_channel_name_, IPC::Channel::MODE_CLIENT, this, - ipc_thread().task_runner().get(), true, shutdown_event()); + ipc_thread().task_runner().get(), true, shutdown_event(), nullptr); other_channel_->SetRestrictDispatchChannelGroup(group_); if (!is_first()) { event1_->Signal(); @@ -1601,7 +1601,7 @@ class ReentrantReplyServer1 : public Worker { void Run() override { server2_channel_ = SyncChannel::Create( "reentrant_reply2", IPC::Channel::MODE_CLIENT, this, - ipc_thread().task_runner().get(), true, shutdown_event()); + ipc_thread().task_runner().get(), true, shutdown_event(), nullptr); server_ready_->Signal(); Message* msg = new SyncChannelTestMsg_Reentrant1(); server2_channel_->Send(msg); diff --git a/chromium/ipc/ipc_sync_message.cc b/chromium/ipc/ipc_sync_message.cc index fd6dc471d59..6b59e11b49f 100644 --- a/chromium/ipc/ipc_sync_message.cc +++ b/chromium/ipc/ipc_sync_message.cc @@ -74,10 +74,10 @@ bool SyncMessage::IsMessageReplyTo(const Message& msg, int request_id) { return GetMessageId(msg) == request_id; } -PickleIterator SyncMessage::GetDataIterator(const Message* msg) { - PickleIterator iter(*msg); +base::PickleIterator SyncMessage::GetDataIterator(const Message* msg) { + base::PickleIterator iter(*msg); if (!iter.SkipBytes(kSyncMessageHeaderSize)) - return PickleIterator(); + return base::PickleIterator(); else return iter; } @@ -112,7 +112,7 @@ Message* SyncMessage::GenerateReply(const Message* msg) { bool SyncMessage::ReadSyncHeader(const Message& msg, SyncHeader* header) { DCHECK(msg.is_sync() || msg.is_reply()); - PickleIterator iter(msg); + base::PickleIterator iter(msg); bool result = iter.ReadInt(&header->message_id); if (!result) { NOTREACHED(); diff --git a/chromium/ipc/ipc_sync_message.h b/chromium/ipc/ipc_sync_message.h index 2b00f03b22b..44d0f4f31ae 100644 --- a/chromium/ipc/ipc_sync_message.h +++ b/chromium/ipc/ipc_sync_message.h @@ -60,7 +60,7 @@ class IPC_EXPORT SyncMessage : public Message { // Given a reply message, returns an iterator to the beginning of the data // (i.e. skips over the synchronous specific data). - static PickleIterator GetDataIterator(const Message* msg); + static base::PickleIterator GetDataIterator(const Message* msg); // Given a synchronous message (or its reply), returns its id. static int GetMessageId(const Message& msg); @@ -90,7 +90,7 @@ class IPC_EXPORT MessageReplyDeserializer { // Derived classes need to implement this, using the given iterator (which // is skipped past the header for synchronous messages). virtual bool SerializeOutputParameters(const Message& msg, - PickleIterator iter) = 0; + base::PickleIterator iter) = 0; }; // When sending a synchronous message, this structure contains an object diff --git a/chromium/ipc/ipc_test_base.cc b/chromium/ipc/ipc_test_base.cc index 0d662822691..4de55431b38 100644 --- a/chromium/ipc/ipc_test_base.cc +++ b/chromium/ipc/ipc_test_base.cc @@ -90,8 +90,7 @@ void IPCTestBase::CreateChannelProxy( CHECK(!channel_proxy_.get()); channel_proxy_ = IPC::ChannelProxy::Create( CreateChannelFactory(GetTestChannelHandle(), ipc_task_runner.get()), - listener, - ipc_task_runner); + listener, ipc_task_runner); } void IPCTestBase::DestroyChannelProxy() { @@ -161,5 +160,6 @@ scoped_refptr<base::SequencedTaskRunner> IPCTestBase::task_runner() { scoped_ptr<IPC::ChannelFactory> IPCTestBase::CreateChannelFactory( const IPC::ChannelHandle& handle, base::SequencedTaskRunner* runner) { - return IPC::ChannelFactory::Create(handle, IPC::Channel::MODE_SERVER); + return IPC::ChannelFactory::Create(handle, IPC::Channel::MODE_SERVER, + nullptr); } diff --git a/chromium/ipc/ipc_test_channel_listener.cc b/chromium/ipc/ipc_test_channel_listener.cc index e98f6b7ee15..7d1832dd43b 100644 --- a/chromium/ipc/ipc_test_channel_listener.cc +++ b/chromium/ipc/ipc_test_channel_listener.cc @@ -32,7 +32,7 @@ void TestChannelListener::SendOneMessage(IPC::Sender* sender, bool TestChannelListener::OnMessageReceived(const IPC::Message& message) { - PickleIterator iter(message); + base::PickleIterator iter(message); int ignored; EXPECT_TRUE(iter.ReadInt(&ignored)); diff --git a/chromium/ipc/ipc_test_sink.cc b/chromium/ipc/ipc_test_sink.cc index 53d29fc7845..f0c7a5f58d1 100644 --- a/chromium/ipc/ipc_test_sink.cc +++ b/chromium/ipc/ipc_test_sink.cc @@ -41,7 +41,7 @@ base::ProcessId TestSink::GetSelfPID() const { } bool TestSink::OnMessageReceived(const Message& msg) { - ObserverListBase<Listener>::Iterator it(&filter_list_); + base::ObserverListBase<Listener>::Iterator it(&filter_list_); Listener* observer; while ((observer = it.GetNext()) != NULL) { if (observer->OnMessageReceived(msg)) diff --git a/chromium/ipc/ipc_test_sink.h b/chromium/ipc/ipc_test_sink.h index 75e582db682..a802686db4f 100644 --- a/chromium/ipc/ipc_test_sink.h +++ b/chromium/ipc/ipc_test_sink.h @@ -45,7 +45,7 @@ class Message; // // IPC::Message* msg = test_sink.GetUniqueMessageMatching(IPC_REPLY_ID); // ASSERT_TRUE(msg); -// TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueTuple reply_data; +// base::TupleTypes<ViewHostMsg_Foo::ReplyParam>::ValueTuple reply_data; // EXPECT_TRUE(ViewHostMsg_Foo::ReadReplyParam(msg, &reply_data)); // // You can also register to be notified when messages are posted to the sink. @@ -128,7 +128,7 @@ class TestSink : public Channel { private: // The actual list of received messages. std::vector<Message> messages_; - ObserverList<Listener> filter_list_; + base::ObserverList<Listener> filter_list_; DISALLOW_COPY_AND_ASSIGN(TestSink); }; diff --git a/chromium/ipc/ipc_tests.isolate b/chromium/ipc/ipc_tests.isolate new file mode 100644 index 00000000000..ce9d3d678b4 --- /dev/null +++ b/chromium/ipc/ipc_tests.isolate @@ -0,0 +1,27 @@ +# Copyright 2015 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. +{ + 'conditions': [ + ['OS=="linux" or OS=="mac" or OS=="win"', { + 'variables': { + 'command': [ + '../testing/test_env.py', + '<(PRODUCT_DIR)/ipc_tests<(EXECUTABLE_SUFFIX)', + '--brave-new-test-launcher', + '--test-launcher-bot-mode', + '--asan=<(asan)', + '--msan=<(msan)', + '--tsan=<(tsan)', + ], + 'files': [ + '../testing/test_env.py', + '<(PRODUCT_DIR)/ipc_tests<(EXECUTABLE_SUFFIX)', + ], + }, + }], + ], + 'includes': [ + '../base/base.isolate', + ], +} diff --git a/chromium/ipc/mojo/BUILD.gn b/chromium/ipc/mojo/BUILD.gn index 50241fe4641..d801a7b9c19 100644 --- a/chromium/ipc/mojo/BUILD.gn +++ b/chromium/ipc/mojo/BUILD.gn @@ -18,8 +18,6 @@ component("mojo") { "client_channel.mojom", "ipc_channel_mojo.cc", "ipc_channel_mojo.h", - "ipc_channel_mojo_host.cc", - "ipc_channel_mojo_host.h", "ipc_message_pipe_reader.cc", "ipc_message_pipe_reader.h", "ipc_mojo_bootstrap.cc", diff --git a/chromium/ipc/mojo/async_handle_waiter_unittest.cc b/chromium/ipc/mojo/async_handle_waiter_unittest.cc index 441b4ecd316..46d4c7ef739 100644 --- a/chromium/ipc/mojo/async_handle_waiter_unittest.cc +++ b/chromium/ipc/mojo/async_handle_waiter_unittest.cc @@ -202,7 +202,7 @@ TEST_F(AsyncHandleWaiterTest, RestartWaitingWhileSignaled) { EXPECT_TRUE(handler.IsClosingHandled()); // |HandlerThatReenters::RestartAndClose| already closed it. - ignore_result(pipe_to_read_.release()); + ::ignore_result(pipe_to_read_.release()); } class AsyncHandleWaiterIOObserverTest : public testing::Test { diff --git a/chromium/ipc/mojo/ipc_channel_mojo.cc b/chromium/ipc/mojo/ipc_channel_mojo.cc index e38a7e94ae8..4d5b815824f 100644 --- a/chromium/ipc/mojo/ipc_channel_mojo.cc +++ b/chromium/ipc/mojo/ipc_channel_mojo.cc @@ -16,7 +16,6 @@ #include "ipc/mojo/ipc_mojo_bootstrap.h" #include "ipc/mojo/ipc_mojo_handle_attachment.h" #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" -#include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h" #if defined(OS_POSIX) && !defined(OS_NACL) #include "ipc/ipc_platform_file_attachment_posix.h" @@ -28,46 +27,43 @@ namespace { class MojoChannelFactory : public ChannelFactory { public: - MojoChannelFactory(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, + MojoChannelFactory(scoped_refptr<base::TaskRunner> io_runner, ChannelHandle channel_handle, - Channel::Mode mode) - : delegate_(delegate), - io_runner_(io_runner), + Channel::Mode mode, + AttachmentBroker* broker) + : io_runner_(io_runner), channel_handle_(channel_handle), - mode_(mode) {} + mode_(mode), + broker_(broker) {} std::string GetName() const override { return channel_handle_.name; } scoped_ptr<Channel> BuildChannel(Listener* listener) override { - return ChannelMojo::Create(delegate_, io_runner_, channel_handle_, mode_, - listener); + return ChannelMojo::Create(io_runner_, channel_handle_, mode_, listener, + broker_); } private: - ChannelMojo::Delegate* delegate_; scoped_refptr<base::TaskRunner> io_runner_; ChannelHandle channel_handle_; Channel::Mode mode_; + AttachmentBroker* broker_; }; //------------------------------------------------------------------------------ -class ClientChannelMojo : public ChannelMojo, - public ClientChannel, - public mojo::ErrorHandler { +class ClientChannelMojo : public ChannelMojo, public ClientChannel { public: - ClientChannelMojo(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, + ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& handle, - Listener* listener); + Listener* listener, + AttachmentBroker* broker); ~ClientChannelMojo() override; // MojoBootstrap::Delegate implementation void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; - // mojo::ErrorHandler implementation - void OnConnectionError() override; + // ClientChannel implementation void Init( mojo::ScopedMessagePipeHandle pipe, @@ -76,6 +72,7 @@ class ClientChannelMojo : public ChannelMojo, private: void BindPipe(mojo::ScopedMessagePipeHandle handle); + void OnConnectionError(); mojo::Binding<ClientChannel> binding_; base::WeakPtrFactory<ClientChannelMojo> weak_factory_; @@ -83,11 +80,11 @@ class ClientChannelMojo : public ChannelMojo, DISALLOW_COPY_AND_ASSIGN(ClientChannelMojo); }; -ClientChannelMojo::ClientChannelMojo(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, +ClientChannelMojo::ClientChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& handle, - Listener* listener) - : ChannelMojo(delegate, io_runner, handle, Channel::MODE_CLIENT, listener), + Listener* listener, + AttachmentBroker* broker) + : ChannelMojo(io_runner, handle, Channel::MODE_CLIENT, listener, broker), binding_(this), weak_factory_(this) { } @@ -101,10 +98,6 @@ void ClientChannelMojo::OnPipeAvailable( weak_factory_.GetWeakPtr())); } -void ClientChannelMojo::OnConnectionError() { - listener()->OnChannelError(); -} - void ClientChannelMojo::Init( mojo::ScopedMessagePipeHandle pipe, int32_t peer_pid, @@ -117,26 +110,29 @@ void ClientChannelMojo::BindPipe(mojo::ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); } +void ClientChannelMojo::OnConnectionError() { + listener()->OnChannelError(); +} + //------------------------------------------------------------------------------ -class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler { +class ServerChannelMojo : public ChannelMojo { public: - ServerChannelMojo(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, + ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& handle, - Listener* listener); + Listener* listener, + AttachmentBroker* broker); ~ServerChannelMojo() override; // MojoBootstrap::Delegate implementation void OnPipeAvailable(mojo::embedder::ScopedPlatformHandle handle) override; - // mojo::ErrorHandler implementation - void OnConnectionError() override; // Channel override void Close() override; private: void InitClientChannel(mojo::ScopedMessagePipeHandle peer_handle, mojo::ScopedMessagePipeHandle handle); + void OnConnectionError(); // ClientChannelClient implementation void ClientChannelWasInitialized(int32_t peer_pid); @@ -148,11 +144,11 @@ class ServerChannelMojo : public ChannelMojo, public mojo::ErrorHandler { DISALLOW_COPY_AND_ASSIGN(ServerChannelMojo); }; -ServerChannelMojo::ServerChannelMojo(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, +ServerChannelMojo::ServerChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& handle, - Listener* listener) - : ChannelMojo(delegate, io_runner, handle, Channel::MODE_SERVER, listener), + Listener* listener, + AttachmentBroker* broker) + : ChannelMojo(io_runner, handle, Channel::MODE_SERVER, listener, broker), weak_factory_(this) { } @@ -176,30 +172,31 @@ void ServerChannelMojo::OnPipeAvailable( weak_factory_.GetWeakPtr(), base::Passed(&peer))); } +void ServerChannelMojo::Close() { + client_channel_.reset(); + message_pipe_.reset(); + ChannelMojo::Close(); +} + void ServerChannelMojo::InitClientChannel( mojo::ScopedMessagePipeHandle peer_handle, mojo::ScopedMessagePipeHandle handle) { client_channel_.Bind( mojo::InterfacePtrInfo<ClientChannel>(handle.Pass(), 0u)); - client_channel_.set_error_handler(this); + client_channel_.set_connection_error_handler(base::Bind( + &ServerChannelMojo::OnConnectionError, base::Unretained(this))); client_channel_->Init( peer_handle.Pass(), static_cast<int32_t>(GetSelfPID()), base::Bind(&ServerChannelMojo::ClientChannelWasInitialized, base::Unretained(this))); } -void ServerChannelMojo::ClientChannelWasInitialized(int32_t peer_pid) { - InitMessageReader(message_pipe_.Pass(), peer_pid); -} - void ServerChannelMojo::OnConnectionError() { listener()->OnChannelError(); } -void ServerChannelMojo::Close() { - client_channel_.reset(); - message_pipe_.reset(); - ChannelMojo::Close(); +void ServerChannelMojo::ClientChannelWasInitialized(int32_t peer_pid) { + InitMessageReader(message_pipe_.Pass(), peer_pid); } #if defined(OS_POSIX) && !defined(OS_NACL) @@ -237,24 +234,25 @@ void ChannelMojo::ChannelInfoDeleter::operator()( // static bool ChannelMojo::ShouldBeUsed() { - // TODO(morrita): Remove this if it sticks. - return true; + // TODO(rockot): Investigate performance bottlenecks and hopefully reenable + // this at some point. http://crbug.com/500019 + return false; } // static scoped_ptr<ChannelMojo> ChannelMojo::Create( - ChannelMojo::Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& channel_handle, Mode mode, - Listener* listener) { + Listener* listener, + AttachmentBroker* broker) { switch (mode) { case Channel::MODE_CLIENT: return make_scoped_ptr( - new ClientChannelMojo(delegate, io_runner, channel_handle, listener)); + new ClientChannelMojo(io_runner, channel_handle, listener, broker)); case Channel::MODE_SERVER: return make_scoped_ptr( - new ServerChannelMojo(delegate, io_runner, channel_handle, listener)); + new ServerChannelMojo(io_runner, channel_handle, listener, broker)); default: NOTREACHED(); return nullptr; @@ -263,42 +261,41 @@ scoped_ptr<ChannelMojo> ChannelMojo::Create( // static scoped_ptr<ChannelFactory> ChannelMojo::CreateServerFactory( - ChannelMojo::Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, - const ChannelHandle& channel_handle) { - return make_scoped_ptr(new MojoChannelFactory( - delegate, io_runner, channel_handle, Channel::MODE_SERVER)); + const ChannelHandle& channel_handle, + AttachmentBroker* broker) { + return make_scoped_ptr(new MojoChannelFactory(io_runner, channel_handle, + Channel::MODE_SERVER, broker)); } // static scoped_ptr<ChannelFactory> ChannelMojo::CreateClientFactory( - ChannelMojo::Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, - const ChannelHandle& channel_handle) { - return make_scoped_ptr(new MojoChannelFactory( - delegate, io_runner, channel_handle, Channel::MODE_CLIENT)); + const ChannelHandle& channel_handle, + AttachmentBroker* broker) { + return make_scoped_ptr(new MojoChannelFactory(io_runner, channel_handle, + Channel::MODE_CLIENT, broker)); } -ChannelMojo::ChannelMojo(ChannelMojo::Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, +ChannelMojo::ChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& handle, Mode mode, - Listener* listener) - : mode_(mode), - listener_(listener), + Listener* listener, + AttachmentBroker* broker) + : listener_(listener), peer_pid_(base::kNullProcessId), io_runner_(io_runner), channel_info_(nullptr, ChannelInfoDeleter(nullptr)), + waiting_connect_(true), weak_factory_(this) { // Create MojoBootstrap after all members are set as it touches // ChannelMojo from a different thread. - bootstrap_ = MojoBootstrap::Create(handle, mode, this); + bootstrap_ = MojoBootstrap::Create(handle, mode, this, broker); if (io_runner == base::MessageLoop::current()->task_runner()) { - InitOnIOThread(delegate); + InitOnIOThread(); } else { - io_runner->PostTask(FROM_HERE, - base::Bind(&ChannelMojo::InitOnIOThread, - base::Unretained(this), delegate)); + io_runner->PostTask(FROM_HERE, base::Bind(&ChannelMojo::InitOnIOThread, + base::Unretained(this))); } } @@ -306,13 +303,9 @@ ChannelMojo::~ChannelMojo() { Close(); } -void ChannelMojo::InitOnIOThread(ChannelMojo::Delegate* delegate) { +void ChannelMojo::InitOnIOThread() { ipc_support_.reset( new ScopedIPCSupport(base::MessageLoop::current()->task_runner())); - if (!delegate) - return; - delegate_ = delegate->ToWeakPtr(); - delegate_->OnChannelCreated(weak_factory_.GetWeakPtr()); } void ChannelMojo::CreateMessagingPipe( @@ -371,6 +364,8 @@ void ChannelMojo::Close() { // but the instance has to be deleted outside. base::AutoLock l(lock_); to_be_deleted = message_reader_.Pass(); + // We might Close() before we Connect(). + waiting_connect_ = false; } channel_info_.reset(); @@ -420,6 +415,7 @@ void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe, // care. They cannot be sent anyway. message_reader_.reset(reader.release()); pending_messages_.clear(); + waiting_connect_ = false; } set_peer_pid(peer_pid); @@ -442,7 +438,9 @@ bool ChannelMojo::Send(Message* message) { base::AutoLock l(lock_); if (!message_reader_) { pending_messages_.push_back(message); - return true; + // Counts as OK before the connection is established, but it's an + // error otherwise. + return waiting_connect_; } return message_reader_->Send(make_scoped_ptr(message)); @@ -460,10 +458,6 @@ base::ProcessId ChannelMojo::GetSelfPID() const { return bootstrap_->GetSelfPID(); } -void ChannelMojo::OnClientLaunched(base::ProcessHandle handle) { - bootstrap_->OnClientLaunched(handle); -} - void ChannelMojo::OnMessageReceived(Message& message) { TRACE_EVENT2("ipc,toplevel", "ChannelMojo::OnMessageReceived", "class", IPC_MESSAGE_ID_CLASS(message.type()), @@ -531,6 +525,11 @@ MojoResult ChannelMojo::ReadFromMessageAttachmentSet( attachment.get())->TakeHandle(); handles->push_back(handle.release().value()); } break; + case MessageAttachment::TYPE_BROKERABLE_ATTACHMENT: + // Brokerable attachments are handled by the AttachmentBroker so + // there's no need to do anything here. + NOTREACHED(); + break; } } diff --git a/chromium/ipc/mojo/ipc_channel_mojo.h b/chromium/ipc/mojo/ipc_channel_mojo.h index 3a1d98a8a97..e7b7b767a68 100644 --- a/chromium/ipc/mojo/ipc_channel_mojo.h +++ b/chromium/ipc/mojo/ipc_channel_mojo.h @@ -57,43 +57,41 @@ class IPC_MOJO_EXPORT ChannelMojo base::Callback<void(mojo::ScopedMessagePipeHandle, mojo::embedder::ChannelInfo*)>; - class Delegate { - public: - virtual ~Delegate() {} - virtual base::WeakPtr<Delegate> ToWeakPtr() = 0; - virtual void OnChannelCreated(base::WeakPtr<ChannelMojo> channel) = 0; - }; - // True if ChannelMojo should be used regardless of the flag. static bool ShouldBeUsed(); // Create ChannelMojo. A bootstrap channel is created as well. - // |host| must not be null for server channels. + // |broker| must outlive the newly created channel. static scoped_ptr<ChannelMojo> Create( - Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& channel_handle, Mode mode, - Listener* listener); + Listener* listener, + AttachmentBroker* broker); // Create a factory object for ChannelMojo. // The factory is used to create Mojo-based ChannelProxy family. // |host| must not be null. + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. + // |broker| must outlive the factory and all channels it creates. static scoped_ptr<ChannelFactory> CreateServerFactory( - Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, - const ChannelHandle& channel_handle); + const ChannelHandle& channel_handle, + AttachmentBroker* broker = nullptr); + // TODO(erikchen): Remove default parameter for |broker|. It exists only to + // make the upcoming refactor decomposable into smaller CLs. + // http://crbug.com/493414. + // |broker| must outlive the factory and all channels it creates. static scoped_ptr<ChannelFactory> CreateClientFactory( - Delegate* delegate, scoped_refptr<base::TaskRunner> io_runner, - const ChannelHandle& channel_handle); + const ChannelHandle& channel_handle, + AttachmentBroker* broker = nullptr); ~ChannelMojo() override; - // ChannelMojoHost tells the client handle using this API. - void OnClientLaunched(base::ProcessHandle handle); - // Channel implementation bool Connect() override; void Close() override; @@ -125,11 +123,11 @@ class IPC_MOJO_EXPORT ChannelMojo void OnPipeError(internal::MessagePipeReader* reader) override; protected: - ChannelMojo(Delegate* delegate, - scoped_refptr<base::TaskRunner> io_runner, + ChannelMojo(scoped_refptr<base::TaskRunner> io_runner, const ChannelHandle& channel_handle, Mode mode, - Listener* listener); + Listener* listener, + AttachmentBroker* broker); void CreateMessagingPipe(mojo::embedder::ScopedPlatformHandle handle, const CreateMessagingPipeCallback& callback); @@ -153,7 +151,7 @@ class IPC_MOJO_EXPORT ChannelMojo // notifications invoked by them. typedef internal::MessagePipeReader::DelayedDeleter ReaderDeleter; - void InitOnIOThread(ChannelMojo::Delegate* delegate); + void InitOnIOThread(); static void CreateMessagingPipeOnIOThread( mojo::embedder::ScopedPlatformHandle handle, @@ -164,15 +162,13 @@ class IPC_MOJO_EXPORT ChannelMojo mojo::embedder::ChannelInfo* channel_info); scoped_ptr<MojoBootstrap> bootstrap_; - base::WeakPtr<Delegate> delegate_; - Mode mode_; Listener* listener_; base::ProcessId peer_pid_; scoped_refptr<base::TaskRunner> io_runner_; scoped_ptr<mojo::embedder::ChannelInfo, ChannelInfoDeleter> channel_info_; - // Guards |message_reader_| and |pending_messages_| + // Guards |message_reader_|, |waiting_connect_| and |pending_messages_| // // * The contents of |pending_messages_| can be modified from any thread. // * |message_reader_| is modified only from the IO thread, @@ -180,6 +176,7 @@ class IPC_MOJO_EXPORT ChannelMojo base::Lock lock_; scoped_ptr<internal::MessagePipeReader, ReaderDeleter> message_reader_; ScopedVector<Message> pending_messages_; + bool waiting_connect_; scoped_ptr<ScopedIPCSupport> ipc_support_; diff --git a/chromium/ipc/mojo/ipc_channel_mojo_host.cc b/chromium/ipc/mojo/ipc_channel_mojo_host.cc deleted file mode 100644 index ac914ad2aff..00000000000 --- a/chromium/ipc/mojo/ipc_channel_mojo_host.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2014 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. - -#include "ipc/mojo/ipc_channel_mojo_host.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "ipc/mojo/ipc_channel_mojo.h" - -namespace IPC { - -class ChannelMojoHost::ChannelDelegateTraits { - public: - static void Destruct(const ChannelMojoHost::ChannelDelegate* ptr); -}; - -// The delete class lives on the IO thread to talk to ChannelMojo on -// behalf of ChannelMojoHost. -// -// The object must be touched only on the IO thread. -class ChannelMojoHost::ChannelDelegate - : public base::RefCountedThreadSafe<ChannelMojoHost::ChannelDelegate, - ChannelMojoHost::ChannelDelegateTraits>, - public ChannelMojo::Delegate { - public: - explicit ChannelDelegate( - scoped_refptr<base::SequencedTaskRunner> io_task_runner); - - // ChannelMojo::Delegate - base::WeakPtr<Delegate> ToWeakPtr() override; - void OnChannelCreated(base::WeakPtr<ChannelMojo> channel) override; - - // Returns an weak ptr of ChannelDelegate instead of Delegate - base::WeakPtr<ChannelDelegate> GetWeakPtr(); - void OnClientLaunched(base::ProcessHandle process); - void DeleteThisSoon() const; - - private: - friend class base::DeleteHelper<ChannelDelegate>; - - ~ChannelDelegate() override; - - scoped_refptr<base::SequencedTaskRunner> io_task_runner_; - base::WeakPtr<ChannelMojo> channel_; - base::WeakPtrFactory<ChannelDelegate> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ChannelDelegate); -}; - -ChannelMojoHost::ChannelDelegate::ChannelDelegate( - scoped_refptr<base::SequencedTaskRunner> io_task_runner) - : io_task_runner_(io_task_runner), weak_factory_(this) { -} - -ChannelMojoHost::ChannelDelegate::~ChannelDelegate() { -} - -base::WeakPtr<ChannelMojo::Delegate> -ChannelMojoHost::ChannelDelegate::ToWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -base::WeakPtr<ChannelMojoHost::ChannelDelegate> -ChannelMojoHost::ChannelDelegate::GetWeakPtr() { - return weak_factory_.GetWeakPtr(); -} - -void ChannelMojoHost::ChannelDelegate::OnChannelCreated( - base::WeakPtr<ChannelMojo> channel) { - DCHECK(!channel_); - channel_ = channel; -} - -void ChannelMojoHost::ChannelDelegate::OnClientLaunched( - base::ProcessHandle process) { - if (channel_) - channel_->OnClientLaunched(process); -} - -void ChannelMojoHost::ChannelDelegate::DeleteThisSoon() const { - io_task_runner_->DeleteSoon(FROM_HERE, this); -} - -// -// ChannelMojoHost -// - -ChannelMojoHost::ChannelMojoHost( - scoped_refptr<base::SequencedTaskRunner> io_task_runner) - : io_task_runner_(io_task_runner), - channel_delegate_(new ChannelDelegate(io_task_runner)), - weak_factory_(this) { -} - -ChannelMojoHost::~ChannelMojoHost() { -} - -void ChannelMojoHost::OnClientLaunched(base::ProcessHandle process) { - if (io_task_runner_ == base::MessageLoop::current()->task_runner()) { - channel_delegate_->OnClientLaunched(process); - } else { - io_task_runner_->PostTask(FROM_HERE, - base::Bind(&ChannelDelegate::OnClientLaunched, - channel_delegate_, process)); - } -} - -ChannelMojo::Delegate* ChannelMojoHost::channel_delegate() const { - return channel_delegate_.get(); -} - -// static -void ChannelMojoHost::ChannelDelegateTraits::Destruct( - const ChannelMojoHost::ChannelDelegate* ptr) { - ptr->DeleteThisSoon(); -} - -} // namespace IPC diff --git a/chromium/ipc/mojo/ipc_channel_mojo_host.h b/chromium/ipc/mojo/ipc_channel_mojo_host.h deleted file mode 100644 index db60b12a4cc..00000000000 --- a/chromium/ipc/mojo/ipc_channel_mojo_host.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2014 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 IPC_IPC_CHANNEL_MOJO_HOST_H_ -#define IPC_IPC_CHANNEL_MOJO_HOST_H_ - -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/process/process_handle.h" -#include "ipc/ipc_export.h" -#include "ipc/mojo/ipc_channel_mojo.h" - -namespace base { -class SequencedTaskRunner; -} - -namespace IPC { - -// Through ChannelMojoHost, ChannelMojo gets extra information that -// its client provides, including the child process's process handle. Every -// server process that uses ChannelMojo must have a ChannelMojoHost -// instance and call OnClientLaunched(). -class IPC_MOJO_EXPORT ChannelMojoHost { - public: - explicit ChannelMojoHost( - scoped_refptr<base::SequencedTaskRunner> io_task_runner); - ~ChannelMojoHost(); - - void OnClientLaunched(base::ProcessHandle process); - ChannelMojo::Delegate* channel_delegate() const; - - private: - class ChannelDelegate; - class ChannelDelegateTraits; - - const scoped_refptr<base::SequencedTaskRunner> io_task_runner_; - scoped_refptr<ChannelDelegate> channel_delegate_; - base::WeakPtrFactory<ChannelMojoHost> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ChannelMojoHost); -}; - -} // namespace IPC - -#endif // IPC_IPC_CHANNEL_MOJO_HOST_H_ diff --git a/chromium/ipc/mojo/ipc_channel_mojo_unittest.cc b/chromium/ipc/mojo/ipc_channel_mojo_unittest.cc index 53c6ecfd04d..c82e0119d41 100644 --- a/chromium/ipc/mojo/ipc_channel_mojo_unittest.cc +++ b/chromium/ipc/mojo/ipc_channel_mojo_unittest.cc @@ -17,7 +17,6 @@ #include "ipc/ipc_message.h" #include "ipc/ipc_test_base.h" #include "ipc/ipc_test_channel_listener.h" -#include "ipc/mojo/ipc_channel_mojo_host.h" #include "ipc/mojo/ipc_mojo_handle_attachment.h" #include "ipc/mojo/ipc_mojo_message_helper.h" #include "ipc/mojo/ipc_mojo_param_traits.h" @@ -38,7 +37,7 @@ class ListenerThatExpectsOK : public IPC::Listener { ~ListenerThatExpectsOK() override {} bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); std::string should_be_ok; EXPECT_TRUE(iter.ReadString(&should_be_ok)); EXPECT_EQ(should_be_ok, "OK"); @@ -68,9 +67,9 @@ class ListenerThatExpectsOK : public IPC::Listener { class ChannelClient { public: explicit ChannelClient(IPC::Listener* listener, const char* name) { - channel_ = IPC::ChannelMojo::Create(NULL, main_message_loop_.task_runner(), - IPCTestBase::GetChannelName(name), - IPC::Channel::MODE_CLIENT, listener); + channel_ = IPC::ChannelMojo::Create( + main_message_loop_.task_runner(), IPCTestBase::GetChannelName(name), + IPC::Channel::MODE_CLIENT, listener, nullptr); } void Connect() { @@ -115,20 +114,15 @@ class IPCChannelMojoTest : public IPCChannelMojoTestBase { scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( const IPC::ChannelHandle& handle, base::SequencedTaskRunner* runner) override { - host_.reset(new IPC::ChannelMojoHost(task_runner())); - return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), - task_runner(), handle); + return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle, + nullptr); } bool DidStartClient() override { bool ok = IPCTestBase::DidStartClient(); DCHECK(ok); - host_->OnClientLaunched(client_process().Handle()); return ok; } - - private: - scoped_ptr<IPC::ChannelMojoHost> host_; }; @@ -151,7 +145,13 @@ class TestChannelListenerWithExtraExpectations bool is_connected_called_; }; -TEST_F(IPCChannelMojoTest, ConnectedFromClient) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_ConnectedFromClient DISABLED_ConnectedFromClient +#else +#define MAYBE_ConnectedFromClient ConnectedFromClient +#endif +TEST_F(IPCChannelMojoTest, MAYBE_ConnectedFromClient) { InitWithMojo("IPCChannelMojoTestClient"); // Set up IPC channel and start client. @@ -223,20 +223,15 @@ class IPCChannelMojoErrorTest : public IPCChannelMojoTestBase { scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( const IPC::ChannelHandle& handle, base::SequencedTaskRunner* runner) override { - host_.reset(new IPC::ChannelMojoHost(task_runner())); - return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), - task_runner(), handle); + return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle, + nullptr); } bool DidStartClient() override { bool ok = IPCTestBase::DidStartClient(); DCHECK(ok); - host_->OnClientLaunched(client_process().Handle()); return ok; } - - private: - scoped_ptr<IPC::ChannelMojoHost> host_; }; class ListenerThatQuits : public IPC::Listener { @@ -266,7 +261,13 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoErraticTestClient) { return 0; } -TEST_F(IPCChannelMojoErrorTest, SendFailWithPendingMessages) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_SendFailWithPendingMessages DISABLED_SendFailWithPendingMessages +#else +#define MAYBE_SendFailWithPendingMessages SendFailWithPendingMessages +#endif +TEST_F(IPCChannelMojoErrorTest, MAYBE_SendFailWithPendingMessages) { InitWithMojo("IPCChannelMojoErraticTestClient"); // Set up IPC channel and start client. @@ -325,7 +326,7 @@ class HandleSendingHelper { } static void ReadReceivedPipe(const IPC::Message& message, - PickleIterator* iter) { + base::PickleIterator* iter) { mojo::ScopedMessagePipeHandle pipe; EXPECT_TRUE( IPC::MojoMessageHelper::ReadMessagePipeFrom(&message, iter, &pipe)); @@ -372,7 +373,7 @@ class HandleSendingHelper { } static void ReadReceivedFile(const IPC::Message& message, - PickleIterator* iter) { + base::PickleIterator* iter) { base::ScopedFD fd; scoped_refptr<IPC::MessageAttachment> attachment; EXPECT_TRUE(message.ReadAttachment(iter, &attachment)); @@ -391,7 +392,7 @@ class ListenerThatExpectsMessagePipe : public IPC::Listener { ~ListenerThatExpectsMessagePipe() override {} bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedPipe(message, &iter); base::MessageLoop::current()->Quit(); ListenerThatExpectsOK::SendOK(sender_); @@ -406,7 +407,13 @@ class ListenerThatExpectsMessagePipe : public IPC::Listener { IPC::Sender* sender_; }; -TEST_F(IPCChannelMojoTest, SendMessagePipe) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_SendMessagePipe DISABLED_SendMessagePipe +#else +#define MAYBE_SendMessagePipe SendMessagePipe +#endif +TEST_F(IPCChannelMojoTest, MAYBE_SendMessagePipe) { InitWithMojo("IPCChannelMojoTestSendMessagePipeClient"); ListenerThatExpectsOK listener; @@ -461,7 +468,7 @@ class ListenerThatExpectsMessagePipeUsingParamTrait : public IPC::Listener { ~ListenerThatExpectsMessagePipeUsingParamTrait() override {} bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); mojo::MessagePipeHandle handle; EXPECT_TRUE(IPC::ParamTraits<mojo::MessagePipeHandle>::Read(&message, &iter, &handle)); @@ -497,7 +504,13 @@ void ParamTraitMessagePipeClient(bool receiving_valid_handle, client.Close(); } -TEST_F(IPCChannelMojoTest, ParamTraitValidMessagePipe) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_ParamTraitValidMessagePipe DISABLED_ParamTraitValidMessagePipe +#else +#define MAYBE_ParamTraitValidMessagePipe ParamTraitValidMessagePipe +#endif +TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitValidMessagePipe) { InitWithMojo("ParamTraitValidMessagePipeClient"); ListenerThatExpectsOK listener; @@ -525,7 +538,13 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitValidMessagePipeClient) { return 0; } -TEST_F(IPCChannelMojoTest, ParamTraitInvalidMessagePipe) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_ParamTraitInvalidMessagePipe DISABLED_ParamTraitInvalidMessagePipe +#else +#define MAYBE_ParamTraitInvalidMessagePipe ParamTraitInvalidMessagePipe +#endif +TEST_F(IPCChannelMojoTest, MAYBE_ParamTraitInvalidMessagePipe) { InitWithMojo("ParamTraitInvalidMessagePipeClient"); ListenerThatExpectsOK listener; @@ -551,30 +570,74 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ParamTraitInvalidMessagePipeClient) { return 0; } +TEST_F(IPCChannelMojoTest, SendFailAfterClose) { + InitWithMojo("IPCChannelMojoTestSendOkClient"); + + ListenerThatExpectsOK listener; + CreateChannel(&listener); + ASSERT_TRUE(ConnectChannel()); + ASSERT_TRUE(StartClient()); + + base::MessageLoop::current()->Run(); + this->channel()->Close(); + ASSERT_FALSE(this->channel()->Send(new IPC::Message())); + + EXPECT_TRUE(WaitForClientShutdown()); + DestroyChannel(); +} + +class ListenerSendingOneOk : public IPC::Listener { + public: + ListenerSendingOneOk() { + } + + bool OnMessageReceived(const IPC::Message& message) override { + return true; + } + + void OnChannelConnected(int32 peer_pid) override { + ListenerThatExpectsOK::SendOK(sender_); + base::MessageLoop::current()->Quit(); + } + + void set_sender(IPC::Sender* sender) { sender_ = sender; } + + private: + IPC::Sender* sender_; +}; + +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendOkClient) { + ListenerSendingOneOk listener; + ChannelClient client(&listener, "IPCChannelMojoTestSendOkClient"); + client.Connect(); + listener.set_sender(client.channel()); + + base::MessageLoop::current()->Run(); + + client.Close(); + + return 0; +} + #if defined(OS_WIN) class IPCChannelMojoDeadHandleTest : public IPCChannelMojoTestBase { protected: scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( const IPC::ChannelHandle& handle, base::SequencedTaskRunner* runner) override { - host_.reset(new IPC::ChannelMojoHost(task_runner())); - return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), - task_runner(), handle); + return IPC::ChannelMojo::CreateServerFactory(task_runner(), handle, + nullptr); } bool DidStartClient() override { IPCTestBase::DidStartClient(); - const base::ProcessHandle client = client_process().Handle(); + // const base::ProcessHandle client = client_process().Handle(); // Forces GetFileHandleForProcess() fail. It happens occasionally // in production, so we should exercise it somehow. // TODO(morrita): figure out how to safely test this. See crbug.com/464109. // ::CloseHandle(client); - host_->OnClientLaunched(client); return true; } - - private: - scoped_ptr<IPC::ChannelMojoHost> host_; }; TEST_F(IPCChannelMojoDeadHandleTest, InvalidClientHandle) { @@ -622,7 +685,7 @@ class ListenerThatExpectsFile : public IPC::Listener { ~ListenerThatExpectsFile() override {} bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedFile(message, &iter); base::MessageLoop::current()->Quit(); ListenerThatExpectsOK::SendOK(sender_); @@ -639,8 +702,13 @@ class ListenerThatExpectsFile : public IPC::Listener { IPC::Sender* sender_; }; - -TEST_F(IPCChannelMojoTest, SendPlatformHandle) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_SendPlatformHandle DISABLED_SendPlatformHandle +#else +#define MAYBE_SendPlatformHandle SendPlatformHandle +#endif +TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandle) { InitWithMojo("IPCChannelMojoTestSendPlatformHandleClient"); ListenerThatExpectsOK listener; @@ -681,7 +749,7 @@ class ListenerThatExpectsFileAndPipe : public IPC::Listener { ~ListenerThatExpectsFileAndPipe() override {} bool OnMessageReceived(const IPC::Message& message) override { - PickleIterator iter(message); + base::PickleIterator iter(message); HandleSendingHelper::ReadReceivedFile(message, &iter); HandleSendingHelper::ReadReceivedPipe(message, &iter); base::MessageLoop::current()->Quit(); @@ -697,7 +765,13 @@ class ListenerThatExpectsFileAndPipe : public IPC::Listener { IPC::Sender* sender_; }; -TEST_F(IPCChannelMojoTest, SendPlatformHandleAndPipe) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_SendPlatformHandleAndPipe DISABLED_SendPlatformHandleAndPipe +#else +#define MAYBE_SendPlatformHandleAndPipe SendPlatformHandleAndPipe +#endif +TEST_F(IPCChannelMojoTest, MAYBE_SendPlatformHandleAndPipe) { InitWithMojo("IPCChannelMojoTestSendPlatformHandleAndPipeClient"); ListenerThatExpectsOK listener; diff --git a/chromium/ipc/mojo/ipc_message_pipe_reader.cc b/chromium/ipc/mojo/ipc_message_pipe_reader.cc index 35ba7fd6397..44bd10a8f7f 100644 --- a/chromium/ipc/mojo/ipc_message_pipe_reader.cc +++ b/chromium/ipc/mojo/ipc_message_pipe_reader.cc @@ -152,14 +152,9 @@ void MessagePipeReader::ReadAvailableMessages() { if (read_result == MOJO_RESULT_SHOULD_WAIT) break; if (read_result != MOJO_RESULT_OK) { - // FAILED_PRECONDITION means that all the received messages - // got consumed and the peer is already closed. - if (read_result != MOJO_RESULT_FAILED_PRECONDITION) { - DLOG(WARNING) - << "Pipe got error from ReadMessage(). Closing: " << read_result; - OnPipeError(read_result); - } - + DLOG(WARNING) + << "Pipe got error from ReadMessage(). Closing: " << read_result; + OnPipeError(read_result); Close(); break; } diff --git a/chromium/ipc/mojo/ipc_mojo.gyp b/chromium/ipc/mojo/ipc_mojo.gyp index a392283263d..313ecb2c99c 100644 --- a/chromium/ipc/mojo/ipc_mojo.gyp +++ b/chromium/ipc/mojo/ipc_mojo.gyp @@ -32,8 +32,6 @@ 'async_handle_waiter.h', 'ipc_channel_mojo.cc', 'ipc_channel_mojo.h', - 'ipc_channel_mojo_host.cc', - 'ipc_channel_mojo_host.h', 'ipc_mojo_bootstrap.cc', 'ipc_mojo_bootstrap.h', 'ipc_mojo_handle_attachment.cc', diff --git a/chromium/ipc/mojo/ipc_mojo_bootstrap.cc b/chromium/ipc/mojo/ipc_mojo_bootstrap.cc index d307246033f..91f3940b37a 100644 --- a/chromium/ipc/mojo/ipc_mojo_bootstrap.cc +++ b/chromium/ipc/mojo/ipc_mojo_bootstrap.cc @@ -20,42 +20,42 @@ class MojoServerBootstrap : public MojoBootstrap { public: MojoServerBootstrap(); - void OnClientLaunched(base::ProcessHandle process) override; - private: - void SendClientPipe(); - void SendClientPipeIfReady(); + void SendClientPipe(int32 peer_pid); // Listener implementations bool OnMessageReceived(const Message& message) override; void OnChannelConnected(int32 peer_pid) override; mojo::embedder::ScopedPlatformHandle server_pipe_; - base::ProcessHandle client_process_; bool connected_; DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap); }; -MojoServerBootstrap::MojoServerBootstrap() - : client_process_(base::kNullProcessHandle), connected_(false) { +MojoServerBootstrap::MojoServerBootstrap() : connected_(false) { } -void MojoServerBootstrap::SendClientPipe() { +void MojoServerBootstrap::SendClientPipe(int32 peer_pid) { DCHECK_EQ(state(), STATE_INITIALIZED); - DCHECK_NE(client_process_, base::kNullProcessHandle); DCHECK(connected_); mojo::embedder::PlatformChannelPair channel_pair; server_pipe_ = channel_pair.PassServerHandle(); + + base::Process peer_process = +#if defined(OS_WIN) + base::Process::OpenWithAccess(peer_pid, PROCESS_DUP_HANDLE); +#else + base::Process::Open(peer_pid); +#endif PlatformFileForTransit client_pipe = GetFileHandleForProcess( #if defined(OS_POSIX) channel_pair.PassClientHandle().release().fd, #else channel_pair.PassClientHandle().release().handle, #endif - client_process_, - true); + peer_process.Handle(), true); if (client_pipe == IPC::InvalidPlatformFileForTransit()) { #if !defined(OS_WIN) // GetFileHandleForProcess() only fails on Windows. @@ -73,30 +73,10 @@ void MojoServerBootstrap::SendClientPipe() { set_state(STATE_WAITING_ACK); } -void MojoServerBootstrap::SendClientPipeIfReady() { - // Is the client launched? - if (client_process_ == base::kNullProcessHandle) - return; - // Has the bootstrap channel been made? - if (!connected_) - return; - SendClientPipe(); -} - -void MojoServerBootstrap::OnClientLaunched(base::ProcessHandle process) { - if (HasFailed()) - return; - - DCHECK_EQ(state(), STATE_INITIALIZED); - DCHECK_NE(process, base::kNullProcessHandle); - client_process_ = process; - SendClientPipeIfReady(); -} - void MojoServerBootstrap::OnChannelConnected(int32 peer_pid) { DCHECK_EQ(state(), STATE_INITIALIZED); connected_ = true; - SendClientPipeIfReady(); + SendClientPipe(peer_pid); } bool MojoServerBootstrap::OnMessageReceived(const Message&) { @@ -120,8 +100,6 @@ class MojoClientBootstrap : public MojoBootstrap { public: MojoClientBootstrap(); - void OnClientLaunched(base::ProcessHandle process) override; - private: // Listener implementations bool OnMessageReceived(const Message& message) override; @@ -141,7 +119,7 @@ bool MojoClientBootstrap::OnMessageReceived(const Message& message) { } PlatformFileForTransit pipe; - PickleIterator iter(message); + base::PickleIterator iter(message); if (!ParamTraits<PlatformFileForTransit>::Read(&message, &iter, &pipe)) { LOG(WARNING) << "Failed to read a file handle from bootstrap channel."; message.set_dispatch_error(); @@ -158,11 +136,6 @@ bool MojoClientBootstrap::OnMessageReceived(const Message& message) { return true; } -void MojoClientBootstrap::OnClientLaunched(base::ProcessHandle process) { - // This notification should happen only on server processes. - NOTREACHED(); -} - void MojoClientBootstrap::OnChannelConnected(int32 peer_pid) { } @@ -173,14 +146,16 @@ void MojoClientBootstrap::OnChannelConnected(int32 peer_pid) { // static scoped_ptr<MojoBootstrap> MojoBootstrap::Create(ChannelHandle handle, Channel::Mode mode, - Delegate* delegate) { + Delegate* delegate, + AttachmentBroker* broker) { CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER); scoped_ptr<MojoBootstrap> self = mode == Channel::MODE_CLIENT ? scoped_ptr<MojoBootstrap>(new MojoClientBootstrap()) : scoped_ptr<MojoBootstrap>(new MojoServerBootstrap()); + scoped_ptr<Channel> bootstrap_channel = - Channel::Create(handle, mode, self.get()); + Channel::Create(handle, mode, self.get(), broker); self->Init(bootstrap_channel.Pass(), delegate); return self.Pass(); } diff --git a/chromium/ipc/mojo/ipc_mojo_bootstrap.h b/chromium/ipc/mojo/ipc_mojo_bootstrap.h index 1f71d2e6d4f..f22cedce766 100644 --- a/chromium/ipc/mojo/ipc_mojo_bootstrap.h +++ b/chromium/ipc/mojo/ipc_mojo_bootstrap.h @@ -13,14 +13,15 @@ namespace IPC { +class AttachmentBroker; + // MojoBootstrap establishes a bootstrap pipe between two processes in // Chrome. It creates a native IPC::Channel first, then sends one // side of a newly created pipe to peer process. The pipe is intended // to be wrapped by Mojo MessagePipe. // // Clients should implement MojoBootstrapDelegate to get the pipe -// from MojoBootstrap object. It should also tell the client process handle -// using OnClientLaunched(). +// from MojoBootstrap object. // // This lives on IO thread other than Create(), which can be called from // UI thread as Channel::Create() can be. @@ -38,7 +39,8 @@ class IPC_MOJO_EXPORT MojoBootstrap : public Listener { // mode as |mode|. The result is notified to passed |delegate|. static scoped_ptr<MojoBootstrap> Create(ChannelHandle handle, Channel::Mode mode, - Delegate* delegate); + Delegate* delegate, + AttachmentBroker* broker); MojoBootstrap(); ~MojoBootstrap() override; @@ -49,9 +51,6 @@ class IPC_MOJO_EXPORT MojoBootstrap : public Listener { // GetSelfPID returns the PID associated with |channel_|. base::ProcessId GetSelfPID() const; - // Each client should call this once the process handle becomes known. - virtual void OnClientLaunched(base::ProcessHandle process) = 0; - #if defined(OS_POSIX) && !defined(OS_NACL) int GetClientFileDescriptor() const; base::ScopedFD TakeClientFileDescriptor(); diff --git a/chromium/ipc/mojo/ipc_mojo_bootstrap_unittest.cc b/chromium/ipc/mojo/ipc_mojo_bootstrap_unittest.cc index fbe0fa89589..3eabf1ff958 100644 --- a/chromium/ipc/mojo/ipc_mojo_bootstrap_unittest.cc +++ b/chromium/ipc/mojo/ipc_mojo_bootstrap_unittest.cc @@ -42,12 +42,18 @@ void TestingDelegate::OnBootstrapError() { base::MessageLoop::current()->Quit(); } -TEST_F(IPCMojoBootstrapTest, Connect) { +// Times out on Android; see http://crbug.com/502290 +#if defined(OS_ANDROID) +#define MAYBE_Connect DISABLED_Connect +#else +#define MAYBE_Connect Connect +#endif +TEST_F(IPCMojoBootstrapTest, MAYBE_Connect) { Init("IPCMojoBootstrapTestClient"); TestingDelegate delegate; scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( - GetTestChannelHandle(), IPC::Channel::MODE_SERVER, &delegate); + GetTestChannelHandle(), IPC::Channel::MODE_SERVER, &delegate, nullptr); ASSERT_TRUE(bootstrap->Connect()); #if defined(OS_POSIX) @@ -55,7 +61,6 @@ TEST_F(IPCMojoBootstrapTest, Connect) { #else ASSERT_TRUE(StartClient()); #endif - bootstrap->OnClientLaunched(client_process().Handle()); base::MessageLoop::current()->Run(); @@ -70,8 +75,7 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCMojoBootstrapTestClient) { TestingDelegate delegate; scoped_ptr<IPC::MojoBootstrap> bootstrap = IPC::MojoBootstrap::Create( IPCTestBase::GetChannelName("IPCMojoBootstrapTestClient"), - IPC::Channel::MODE_CLIENT, - &delegate); + IPC::Channel::MODE_CLIENT, &delegate, nullptr); bootstrap->Connect(); diff --git a/chromium/ipc/mojo/ipc_mojo_handle_attachment.cc b/chromium/ipc/mojo/ipc_mojo_handle_attachment.cc index 98ac5c3c5e0..9aae281c4ec 100644 --- a/chromium/ipc/mojo/ipc_mojo_handle_attachment.cc +++ b/chromium/ipc/mojo/ipc_mojo_handle_attachment.cc @@ -25,7 +25,8 @@ MessageAttachment::Type MojoHandleAttachment::GetType() const { base::PlatformFile MojoHandleAttachment::TakePlatformFile() { mojo::embedder::ScopedPlatformHandle platform_handle; MojoResult unwrap_result = mojo::embedder::PassWrappedPlatformHandle( - handle_.release().value(), &platform_handle); + handle_.get().value(), &platform_handle); + handle_.reset(); if (unwrap_result != MOJO_RESULT_OK) { LOG(ERROR) << "Pipe failed to covert handles. Closing: " << unwrap_result; return -1; diff --git a/chromium/ipc/mojo/ipc_mojo_message_helper.cc b/chromium/ipc/mojo/ipc_mojo_message_helper.cc index 38b870dde50..6f33f80f11b 100644 --- a/chromium/ipc/mojo/ipc_mojo_message_helper.cc +++ b/chromium/ipc/mojo/ipc_mojo_message_helper.cc @@ -20,7 +20,7 @@ bool MojoMessageHelper::WriteMessagePipeTo( // static bool MojoMessageHelper::ReadMessagePipeFrom( const Message* message, - PickleIterator* iter, + base::PickleIterator* iter, mojo::ScopedMessagePipeHandle* handle) { scoped_refptr<MessageAttachment> attachment; if (!message->ReadAttachment(iter, &attachment)) { diff --git a/chromium/ipc/mojo/ipc_mojo_message_helper.h b/chromium/ipc/mojo/ipc_mojo_message_helper.h index efb48c33a94..2efa1390aee 100644 --- a/chromium/ipc/mojo/ipc_mojo_message_helper.h +++ b/chromium/ipc/mojo/ipc_mojo_message_helper.h @@ -17,7 +17,7 @@ class IPC_MOJO_EXPORT MojoMessageHelper { static bool WriteMessagePipeTo(Message* message, mojo::ScopedMessagePipeHandle handle); static bool ReadMessagePipeFrom(const Message* message, - PickleIterator* iter, + base::PickleIterator* iter, mojo::ScopedMessagePipeHandle* handle); private: diff --git a/chromium/ipc/mojo/ipc_mojo_param_traits.cc b/chromium/ipc/mojo/ipc_mojo_param_traits.cc index 80c3ca70c92..1bb5256a742 100644 --- a/chromium/ipc/mojo/ipc_mojo_param_traits.cc +++ b/chromium/ipc/mojo/ipc_mojo_param_traits.cc @@ -17,7 +17,7 @@ void ParamTraits<mojo::MessagePipeHandle>::Write(Message* m, } bool ParamTraits<mojo::MessagePipeHandle>::Read(const Message* m, - PickleIterator* iter, + base::PickleIterator* iter, param_type* r) { bool is_valid; if (!ReadParam(m, iter, &is_valid)) diff --git a/chromium/ipc/mojo/ipc_mojo_param_traits.h b/chromium/ipc/mojo/ipc_mojo_param_traits.h index d12e44fccd8..c735fce370d 100644 --- a/chromium/ipc/mojo/ipc_mojo_param_traits.h +++ b/chromium/ipc/mojo/ipc_mojo_param_traits.h @@ -11,7 +11,9 @@ #include "ipc/ipc_param_traits.h" #include "third_party/mojo/src/mojo/public/cpp/system/message_pipe.h" +namespace base { class PickleIterator; +} namespace IPC { @@ -21,7 +23,7 @@ template <> struct IPC_MOJO_EXPORT ParamTraits<mojo::MessagePipeHandle> { typedef mojo::MessagePipeHandle param_type; static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, PickleIterator* iter, param_type* r); + static bool Read(const Message* m, base::PickleIterator* iter, param_type* r); static void Log(const param_type& p, std::string* l); }; diff --git a/chromium/ipc/mojo/ipc_mojo_perftest.cc b/chromium/ipc/mojo/ipc_mojo_perftest.cc index dc96dd19a14..17a43a077e6 100644 --- a/chromium/ipc/mojo/ipc_mojo_perftest.cc +++ b/chromium/ipc/mojo/ipc_mojo_perftest.cc @@ -6,7 +6,6 @@ #include "base/run_loop.h" #include "ipc/ipc_perftest_support.h" #include "ipc/mojo/ipc_channel_mojo.h" -#include "ipc/mojo/ipc_channel_mojo_host.h" #include "third_party/mojo/src/mojo/edk/embedder/test_embedder.h" namespace { @@ -37,20 +36,14 @@ public: scoped_ptr<IPC::ChannelFactory> CreateChannelFactory( const IPC::ChannelHandle& handle, base::SequencedTaskRunner* runner) override { - host_.reset(new IPC::ChannelMojoHost(runner)); - return IPC::ChannelMojo::CreateServerFactory(host_->channel_delegate(), - runner, handle); + return IPC::ChannelMojo::CreateServerFactory(runner, handle, nullptr); } bool DidStartClient() override { bool ok = IPCTestBase::DidStartClient(); DCHECK(ok); - host_->OnClientLaunched(client_process().Handle()); return ok; } - - private: - scoped_ptr<IPC::ChannelMojoHost> host_; }; MojoChannelPerfTest::MojoChannelPerfTest() { @@ -88,8 +81,8 @@ MojoTestClient::MojoTestClient() { scoped_ptr<IPC::Channel> MojoTestClient::CreateChannel( IPC::Listener* listener) { return scoped_ptr<IPC::Channel>(IPC::ChannelMojo::Create( - NULL, task_runner(), IPCTestBase::GetChannelName("PerformanceClient"), - IPC::Channel::MODE_CLIENT, listener)); + task_runner(), IPCTestBase::GetChannelName("PerformanceClient"), + IPC::Channel::MODE_CLIENT, listener, nullptr)); } MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) { diff --git a/chromium/ipc/param_traits_macros.h b/chromium/ipc/param_traits_macros.h index f4248df1116..317f31228d9 100644 --- a/chromium/ipc/param_traits_macros.h +++ b/chromium/ipc/param_traits_macros.h @@ -14,7 +14,8 @@ struct IPC_MESSAGE_EXPORT ParamTraits<struct_name> { \ typedef struct_name param_type; \ static void Write(Message* m, const param_type& p); \ - static bool Read(const Message* m, PickleIterator* iter, param_type* p); \ + static bool Read(const Message* m, base::PickleIterator* iter, \ + param_type* p); \ static void Log(const param_type& p, std::string* l); \ }; \ } @@ -52,7 +53,8 @@ struct IPC_MESSAGE_EXPORT ParamTraits<enum_name> { \ typedef enum_name param_type; \ static void Write(Message* m, const param_type& p); \ - static bool Read(const Message* m, PickleIterator* iter, param_type* p); \ + static bool Read(const Message* m, base::PickleIterator* iter, \ + param_type* p); \ static void Log(const param_type& p, std::string* l); \ }; \ } diff --git a/chromium/ipc/param_traits_read_macros.h b/chromium/ipc/param_traits_read_macros.h index 683a1de261c..a66c89a8d0e 100644 --- a/chromium/ipc/param_traits_read_macros.h +++ b/chromium/ipc/param_traits_read_macros.h @@ -24,7 +24,7 @@ #undef IPC_STRUCT_TRAITS_END #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \ bool ParamTraits<struct_name>:: \ - Read(const Message* m, PickleIterator* iter, param_type* p) { \ + Read(const Message* m, base::PickleIterator* iter, param_type* p) { \ return #define IPC_STRUCT_TRAITS_MEMBER(name) ReadParam(m, iter, &p->name) && #define IPC_STRUCT_TRAITS_PARENT(type) ParamTraits<type>::Read(m, iter, p) && @@ -33,7 +33,7 @@ #undef IPC_ENUM_TRAITS_VALIDATE #define IPC_ENUM_TRAITS_VALIDATE(enum_name, validation_expression) \ bool ParamTraits<enum_name>:: \ - Read(const Message* m, PickleIterator* iter, param_type* p) { \ + Read(const Message* m, base::PickleIterator* iter, param_type* p) { \ int value; \ if (!iter->ReadInt(&value)) \ return false; \ diff --git a/chromium/ipc/sync_socket_unittest.cc b/chromium/ipc/sync_socket_unittest.cc index 82ab0cd0992..0172c2f2982 100644 --- a/chromium/ipc/sync_socket_unittest.cc +++ b/chromium/ipc/sync_socket_unittest.cc @@ -110,8 +110,8 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SyncSocketServerClient) { base::MessageLoopForIO main_message_loop; SyncSocketServerListener listener; scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( - IPCTestBase::GetChannelName("SyncSocketServerClient"), - &listener)); + IPCTestBase::GetChannelName("SyncSocketServerClient"), &listener, + nullptr)); EXPECT_TRUE(channel->Connect()); listener.Init(channel.get()); base::MessageLoop::current()->Run(); |