Convert mojo::system::ChannelEndpointClient to use our new refcounting stuff (instead of base's).

R=vardhan@google.com

Review URL: https://codereview.chromium.org/1396783004 .
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
index d27661c..ae8b1c4 100644
--- a/mojo/edk/system/channel.cc
+++ b/mojo/edk/system/channel.cc
@@ -176,14 +176,14 @@
 RefPtr<ChannelEndpoint> Channel::SerializeEndpointWithLocalPeer(
     void* destination,
     MessageInTransitQueue* message_queue,
-    ChannelEndpointClient* endpoint_client,
+    RefPtr<ChannelEndpointClient>&& endpoint_client,
     unsigned endpoint_client_port) {
   DCHECK(destination);
   // Allow |endpoint_client| to be null, for use by
   // |SerializeEndpointWithClosedPeer()|.
 
   auto endpoint = MakeRefCounted<ChannelEndpoint>(
-      endpoint_client, endpoint_client_port, message_queue);
+      std::move(endpoint_client), endpoint_client_port, message_queue);
 
   SerializedEndpoint* s = static_cast<SerializedEndpoint*>(destination);
   s->receiver_endpoint_id = AttachAndRunEndpoint(endpoint.Clone());
@@ -206,11 +206,11 @@
   // TODO(vtl): If we were to own/track the relayer directly (rather than owning
   // it via its |ChannelEndpoint|s), then we might be able to make
   // |ChannelEndpoint|'s |client_| pointer a raw pointer.
-  scoped_refptr<EndpointRelayer> relayer(new EndpointRelayer());
+  auto relayer = MakeRefCounted<EndpointRelayer>();
   auto endpoint =
-      MakeRefCounted<ChannelEndpoint>(relayer.get(), 0, message_queue);
+      MakeRefCounted<ChannelEndpoint>(relayer.Clone(), 0, message_queue);
   relayer->Init(endpoint.Clone(), peer_endpoint.Clone());
-  peer_endpoint->ReplaceClient(relayer.get(), 1);
+  peer_endpoint->ReplaceClient(std::move(relayer), 1);
 
   SerializedEndpoint* s = static_cast<SerializedEndpoint*>(destination);
   s->receiver_endpoint_id = AttachAndRunEndpoint(std::move(endpoint));
@@ -218,8 +218,7 @@
            << s->receiver_endpoint_id << ")";
 }
 
-scoped_refptr<IncomingEndpoint> Channel::DeserializeEndpoint(
-    const void* source) {
+RefPtr<IncomingEndpoint> Channel::DeserializeEndpoint(const void* source) {
   const SerializedEndpoint* s = static_cast<const SerializedEndpoint*>(source);
   ChannelEndpointId local_id = s->receiver_endpoint_id;
   // No need to check the validity of |local_id| -- if it's not valid, it simply
@@ -237,8 +236,7 @@
 
   DVLOG(2) << "Deserializing endpoint (new local ID = " << local_id << ")";
 
-  scoped_refptr<IncomingEndpoint> rv;
-  rv.swap(it->second);
+  RefPtr<IncomingEndpoint> rv = std::move(it->second);
   incoming_endpoints_.erase(it);
   return rv;
 }
@@ -469,7 +467,7 @@
 
   // Create/initialize an |IncomingEndpoint| and thus an endpoint (outside the
   // lock).
-  scoped_refptr<IncomingEndpoint> incoming_endpoint(new IncomingEndpoint());
+  auto incoming_endpoint = MakeRefCounted<IncomingEndpoint>();
   RefPtr<ChannelEndpoint> endpoint = incoming_endpoint->Init();
 
   bool success = true;
diff --git a/mojo/edk/system/channel.h b/mojo/edk/system/channel.h
index f04b2d4..3857a14 100644
--- a/mojo/edk/system/channel.h
+++ b/mojo/edk/system/channel.h
@@ -10,7 +10,6 @@
 #include <memory>
 #include <unordered_map>
 
-#include "base/memory/ref_counted.h"
 #include "base/threading/thread_checker.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/system/channel_endpoint.h"
@@ -153,7 +152,7 @@
   RefPtr<ChannelEndpoint> SerializeEndpointWithLocalPeer(
       void* destination,
       MessageInTransitQueue* message_queue,
-      ChannelEndpointClient* endpoint_client,
+      RefPtr<ChannelEndpointClient>&& endpoint_client,
       unsigned endpoint_client_port);
   void SerializeEndpointWithRemotePeer(void* destination,
                                        MessageInTransitQueue* message_queue,
@@ -165,7 +164,7 @@
   // |GetSerializedEndpointSize()| bytes. This returns the deserialized
   // |IncomingEndpoint| (which can be converted into a |MessagePipe|) or null on
   // error.
-  scoped_refptr<IncomingEndpoint> DeserializeEndpoint(const void* source);
+  RefPtr<IncomingEndpoint> DeserializeEndpoint(const void* source);
 
   // See |RawChannel::GetSerializedPlatformHandleSize()|.
   size_t GetSerializedPlatformHandleSize() const;
@@ -266,7 +265,7 @@
   LocalChannelEndpointIdGenerator local_id_generator_ MOJO_GUARDED_BY(mutex_);
 
   using IdToIncomingEndpointMap =
-      std::unordered_map<ChannelEndpointId, scoped_refptr<IncomingEndpoint>>;
+      std::unordered_map<ChannelEndpointId, RefPtr<IncomingEndpoint>>;
   // Map from local IDs to incoming endpoints (i.e., those received inside other
   // messages, but not yet claimed via |DeserializeEndpoint()|).
   IdToIncomingEndpointMap incoming_endpoints_ MOJO_GUARDED_BY(mutex_);
diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc
index 70b8034..b2ced62 100644
--- a/mojo/edk/system/channel_endpoint.cc
+++ b/mojo/edk/system/channel_endpoint.cc
@@ -35,14 +35,14 @@
   return false;
 }
 
-bool ChannelEndpoint::ReplaceClient(ChannelEndpointClient* client,
+bool ChannelEndpoint::ReplaceClient(RefPtr<ChannelEndpointClient>&& client,
                                     unsigned client_port) {
   DCHECK(client);
 
   MutexLocker locker(&mutex_);
   DCHECK(client_);
-  DCHECK(client != client_.get() || client_port != client_port_);
-  client_ = client;
+  DCHECK(client != client_ || client_port != client_port_);
+  client_ = std::move(client);
   client_port_ = client_port;
   return state_ != State::DEAD;
 }
@@ -102,7 +102,7 @@
 }
 
 void ChannelEndpoint::DetachFromChannel() {
-  scoped_refptr<ChannelEndpointClient> client;
+  RefPtr<ChannelEndpointClient> client;
   unsigned client_port = 0;
   {
     MutexLocker locker(&mutex_);
@@ -131,11 +131,11 @@
     client->OnDetachFromChannel(client_port);
 }
 
-ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client,
+ChannelEndpoint::ChannelEndpoint(RefPtr<ChannelEndpointClient>&& client,
                                  unsigned client_port,
                                  MessageInTransitQueue* message_queue)
     : state_(State::PAUSED),
-      client_(client),
+      client_(std::move(client)),
       client_port_(client_port),
       channel_(nullptr) {
   DCHECK(client_ || message_queue);
@@ -171,7 +171,7 @@
     std::unique_ptr<MessageInTransit> message) {
   DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT_CLIENT);
 
-  scoped_refptr<ChannelEndpointClient> client;
+  RefPtr<ChannelEndpointClient> client;
   unsigned client_port = 0;
 
   // This loop is to make |ReplaceClient()| work. We can't call the client's
diff --git a/mojo/edk/system/channel_endpoint.h b/mojo/edk/system/channel_endpoint.h
index 387b02c..af537e5 100644
--- a/mojo/edk/system/channel_endpoint.h
+++ b/mojo/edk/system/channel_endpoint.h
@@ -7,11 +7,11 @@
 
 #include <memory>
 
-#include "base/memory/ref_counted.h"
 #include "mojo/edk/system/channel_endpoint_id.h"
 #include "mojo/edk/system/message_in_transit_queue.h"
 #include "mojo/edk/system/mutex.h"
 #include "mojo/edk/system/ref_counted.h"
+#include "mojo/edk/system/ref_ptr.h"
 #include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
@@ -127,7 +127,8 @@
   // This returns true in the typical case, and false if this endpoint has been
   // detached from the channel, in which case the caller should probably call
   // its (new) client's |OnDetachFromChannel()|.
-  bool ReplaceClient(ChannelEndpointClient* client, unsigned client_port);
+  bool ReplaceClient(RefPtr<ChannelEndpointClient>&& client,
+                     unsigned client_port);
 
   // Called before the |ChannelEndpointClient| gives up its reference to this
   // object.
@@ -160,11 +161,10 @@
   // in which case |message_queue| should not be null. In that case, this
   // endpoint will simply send queued messages upon being attached to a
   // |Channel| and immediately detach itself.
-  ChannelEndpoint(ChannelEndpointClient* client,
+  ChannelEndpoint(RefPtr<ChannelEndpointClient>&& client,
                   unsigned client_port,
                   MessageInTransitQueue* message_queue = nullptr);
 
-  friend class base::RefCountedThreadSafe<ChannelEndpoint>;
   ~ChannelEndpoint();
 
   bool WriteMessageNoLock(std::unique_ptr<MessageInTransit> message)
@@ -192,10 +192,9 @@
 
   // |client_| must be valid whenever it is non-null. Before |*client_| gives up
   // its reference to this object, it must call |DetachFromClient()|.
-  // NOTE: This is a |scoped_refptr<>|, rather than a raw pointer, since the
-  // |Channel| needs to keep the |MessagePipe| alive for the "proxy-proxy" case.
-  // Possibly we'll be able to eliminate that case when we have full
-  // multiprocess support.
+  // NOTE: This is a |RefPtr<>|, rather than a raw pointer, since the |Channel|
+  // needs to keep the client (e.g., |MessagePipe|) alive for the "proxy-proxy"
+  // case.
   // WARNING: |ChannelEndpointClient| methods must not be called under |mutex_|.
   // Thus to make such a call, a reference must first be taken under |mutex_|
   // and the lock released.
@@ -205,7 +204,7 @@
   // WARNING: Beware of interactions with |ReplaceClient()|. By the time the
   // call is made, the client may have changed. This must be detected and dealt
   // with.
-  scoped_refptr<ChannelEndpointClient> client_ MOJO_GUARDED_BY(mutex_);
+  RefPtr<ChannelEndpointClient> client_ MOJO_GUARDED_BY(mutex_);
   unsigned client_port_ MOJO_GUARDED_BY(mutex_);
 
   // |channel_| must be valid whenever it is non-null. Before |*channel_| gives
diff --git a/mojo/edk/system/channel_endpoint_client.h b/mojo/edk/system/channel_endpoint_client.h
index d2260f1..fea942d 100644
--- a/mojo/edk/system/channel_endpoint_client.h
+++ b/mojo/edk/system/channel_endpoint_client.h
@@ -5,7 +5,7 @@
 #ifndef MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_CLIENT_H_
 #define MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_CLIENT_H_
 
-#include "base/memory/ref_counted.h"
+#include "mojo/edk/system/ref_counted.h"
 #include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
@@ -30,7 +30,7 @@
 // |ChannelEndpoint| has apparently relinquished its pointer to the
 // |ChannelEndpointClient|).
 class ChannelEndpointClient
-    : public base::RefCountedThreadSafe<ChannelEndpointClient> {
+    : public RefCountedThreadSafe<ChannelEndpointClient> {
  public:
   // Called by |ChannelEndpoint| in response to its |OnReadMessage()|, which is
   // called by |Channel| when it receives a message for the |ChannelEndpoint|.
@@ -46,10 +46,10 @@
   virtual void OnDetachFromChannel(unsigned port) = 0;
 
  protected:
-  ChannelEndpointClient() {}
+  FRIEND_REF_COUNTED_THREAD_SAFE(ChannelEndpointClient);
 
+  ChannelEndpointClient() {}
   virtual ~ChannelEndpointClient() {}
-  friend class base::RefCountedThreadSafe<ChannelEndpointClient>;
 
  private:
   MOJO_DISALLOW_COPY_AND_ASSIGN(ChannelEndpointClient);
diff --git a/mojo/edk/system/channel_endpoint_unittest.cc b/mojo/edk/system/channel_endpoint_unittest.cc
index 2a971c0..e82a005 100644
--- a/mojo/edk/system/channel_endpoint_unittest.cc
+++ b/mojo/edk/system/channel_endpoint_unittest.cc
@@ -48,15 +48,13 @@
 };
 
 TEST_F(ChannelEndpointTest, Basic) {
-  scoped_refptr<test::TestChannelEndpointClient> client0(
-      new test::TestChannelEndpointClient());
-  auto endpoint0 = MakeRefCounted<ChannelEndpoint>(client0.get(), 0);
+  auto client0 = MakeRefCounted<test::TestChannelEndpointClient>();
+  auto endpoint0 = MakeRefCounted<ChannelEndpoint>(client0.Clone(), 0);
   client0->Init(0, endpoint0.Clone());
   channel(0)->SetBootstrapEndpoint(std::move(endpoint0));
 
-  scoped_refptr<test::TestChannelEndpointClient> client1(
-      new test::TestChannelEndpointClient());
-  auto endpoint1 = MakeRefCounted<ChannelEndpoint>(client1.get(), 1);
+  auto client1 = MakeRefCounted<test::TestChannelEndpointClient>();
+  auto endpoint1 = MakeRefCounted<ChannelEndpoint>(client1.Clone(), 1);
   client1->Init(1, endpoint1.Clone());
   channel(1)->SetBootstrapEndpoint(endpoint1.Clone());
 
@@ -92,9 +90,8 @@
 // are all sent/received (and in the correct order). (Note: Due to the way
 // bootstrap endpoints work, the receiving side has to be set up first.)
 TEST_F(ChannelEndpointTest, Prequeued) {
-  scoped_refptr<test::TestChannelEndpointClient> client0(
-      new test::TestChannelEndpointClient());
-  auto endpoint0 = MakeRefCounted<ChannelEndpoint>(client0.get(), 0);
+  auto client0 = MakeRefCounted<test::TestChannelEndpointClient>();
+  auto endpoint0 = MakeRefCounted<ChannelEndpoint>(client0.Clone(), 0);
   client0->Init(0, endpoint0.Clone());
 
   channel(0)->SetBootstrapEndpoint(std::move(endpoint0));
@@ -102,10 +99,9 @@
   prequeued_messages.AddMessage(test::MakeTestMessage(1));
   prequeued_messages.AddMessage(test::MakeTestMessage(2));
 
-  scoped_refptr<test::TestChannelEndpointClient> client1(
-      new test::TestChannelEndpointClient());
+  auto client1 = MakeRefCounted<test::TestChannelEndpointClient>();
   auto endpoint1 =
-      MakeRefCounted<ChannelEndpoint>(client1.get(), 1, &prequeued_messages);
+      MakeRefCounted<ChannelEndpoint>(client1.Clone(), 1, &prequeued_messages);
   client1->Init(1, endpoint1.Clone());
 
   EXPECT_TRUE(endpoint1->EnqueueMessage(test::MakeTestMessage(3)));
diff --git a/mojo/edk/system/channel_unittest.cc b/mojo/edk/system/channel_unittest.cc
index 13aa3a9..ec668cb 100644
--- a/mojo/edk/system/channel_unittest.cc
+++ b/mojo/edk/system/channel_unittest.cc
@@ -10,6 +10,7 @@
 #include "mojo/edk/system/channel_endpoint_id.h"
 #include "mojo/edk/system/channel_test_base.h"
 #include "mojo/edk/system/message_pipe.h"
+#include "mojo/edk/system/ref_ptr.h"
 #include "mojo/edk/system/test_utils.h"
 #include "mojo/edk/system/waiter.h"
 
@@ -41,8 +42,7 @@
                               &ChannelTest::CreateAndInitChannelOnIOThread, 0);
 
   RefPtr<ChannelEndpoint> channel_endpoint;
-  scoped_refptr<MessagePipe> mp(
-      MessagePipe::CreateLocalProxy(&channel_endpoint));
+  auto mp = MessagePipe::CreateLocalProxy(&channel_endpoint);
 
   mp->Close(0);
 
@@ -61,8 +61,7 @@
                               &ChannelTest::CreateAndInitChannelOnIOThread, 0);
 
   RefPtr<ChannelEndpoint> channel_endpoint;
-  scoped_refptr<MessagePipe> mp(
-      MessagePipe::CreateLocalProxy(&channel_endpoint));
+  auto mp = MessagePipe::CreateLocalProxy(&channel_endpoint);
 
   channel(0)->SetBootstrapEndpoint(std::move(channel_endpoint));
 
@@ -96,8 +95,7 @@
                               &ChannelTest::CreateAndInitChannelOnIOThread, 0);
 
   RefPtr<ChannelEndpoint> channel_endpoint;
-  scoped_refptr<MessagePipe> mp(
-      MessagePipe::CreateLocalProxy(&channel_endpoint));
+  auto mp = MessagePipe::CreateLocalProxy(&channel_endpoint);
 
   channel(0)->SetBootstrapEndpoint(std::move(channel_endpoint));
 
@@ -130,8 +128,7 @@
         FROM_HERE, &ChannelTest::CreateAndInitChannelOnIOThread, 0);
 
     RefPtr<ChannelEndpoint> channel_endpoint;
-    scoped_refptr<MessagePipe> mp(
-        MessagePipe::CreateLocalProxy(&channel_endpoint));
+    auto mp = MessagePipe::CreateLocalProxy(&channel_endpoint);
 
     channel(0)->SetBootstrapEndpoint(std::move(channel_endpoint));
 
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index 450897c..30f7085 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -222,9 +222,9 @@
     return MOJO_RESULT_RESOURCE_EXHAUSTED;
   }
 
-  scoped_refptr<MessagePipe> message_pipe(MessagePipe::CreateLocalLocal());
-  dispatcher0->Init(message_pipe, 0);
-  dispatcher1->Init(message_pipe, 1);
+  auto message_pipe = MessagePipe::CreateLocalLocal();
+  dispatcher0->Init(message_pipe.Clone(), 0);
+  dispatcher1->Init(std::move(message_pipe), 1);
 
   message_pipe_handle0.Put(handle_pair.first);
   message_pipe_handle1.Put(handle_pair.second);
@@ -390,9 +390,9 @@
   }
   DCHECK_NE(handle_pair.second, MOJO_HANDLE_INVALID);
 
-  scoped_refptr<DataPipe> data_pipe(DataPipe::CreateLocal(validated_options));
-  producer_dispatcher->Init(data_pipe);
-  consumer_dispatcher->Init(data_pipe);
+  auto data_pipe = DataPipe::CreateLocal(validated_options);
+  producer_dispatcher->Init(data_pipe.Clone());
+  consumer_dispatcher->Init(std::move(data_pipe));
 
   data_pipe_producer_handle.Put(handle_pair.first);
   data_pipe_consumer_handle.Put(handle_pair.second);
diff --git a/mojo/edk/system/data_pipe.cc b/mojo/edk/system/data_pipe.cc
index 69aced2..ffe3469 100644
--- a/mojo/edk/system/data_pipe.cc
+++ b/mojo/edk/system/data_pipe.cc
@@ -94,14 +94,14 @@
 }
 
 // static
-DataPipe* DataPipe::CreateLocal(
+RefPtr<DataPipe> DataPipe::CreateLocal(
     const MojoCreateDataPipeOptions& validated_options) {
-  return new DataPipe(true, true, validated_options,
-                      util::MakeUnique<LocalDataPipeImpl>());
+  return AdoptRef(new DataPipe(true, true, validated_options,
+                               util::MakeUnique<LocalDataPipeImpl>()));
 }
 
 // static
-DataPipe* DataPipe::CreateRemoteProducerFromExisting(
+RefPtr<DataPipe> DataPipe::CreateRemoteProducerFromExisting(
     const MojoCreateDataPipeOptions& validated_options,
     MessageInTransitQueue* message_queue,
     RefPtr<ChannelEndpoint>&& channel_endpoint) {
@@ -118,12 +118,12 @@
   // ongoing call to |IncomingEndpoint::OnReadMessage()| return false. This will
   // make |ChannelEndpoint::OnReadMessage()| retry, until its |ReplaceClient()|
   // is called.
-  DataPipe* data_pipe = new DataPipe(
+  RefPtr<DataPipe> data_pipe = AdoptRef(new DataPipe(
       false, true, validated_options,
       util::MakeUnique<RemoteProducerDataPipeImpl>(
-          channel_endpoint.Clone(), std::move(buffer), 0, buffer_num_bytes));
+          channel_endpoint.Clone(), std::move(buffer), 0, buffer_num_bytes)));
   if (channel_endpoint) {
-    if (!channel_endpoint->ReplaceClient(data_pipe, 0))
+    if (!channel_endpoint->ReplaceClient(data_pipe.Clone(), 0))
       data_pipe->OnDetachFromChannel(0);
   } else {
     data_pipe->SetProducerClosed();
@@ -132,7 +132,7 @@
 }
 
 // static
-DataPipe* DataPipe::CreateRemoteConsumerFromExisting(
+RefPtr<DataPipe> DataPipe::CreateRemoteConsumerFromExisting(
     const MojoCreateDataPipeOptions& validated_options,
     size_t consumer_num_bytes,
     MessageInTransitQueue* message_queue,
@@ -148,12 +148,12 @@
   // ongoing call to |IncomingEndpoint::OnReadMessage()| return false. This will
   // make |ChannelEndpoint::OnReadMessage()| retry, until its |ReplaceClient()|
   // is called.
-  DataPipe* data_pipe = new DataPipe(
+  RefPtr<DataPipe> data_pipe = AdoptRef(new DataPipe(
       true, false, validated_options,
       util::MakeUnique<RemoteConsumerDataPipeImpl>(
-          channel_endpoint.Clone(), consumer_num_bytes, nullptr, 0));
+          channel_endpoint.Clone(), consumer_num_bytes, nullptr, 0)));
   if (channel_endpoint) {
-    if (!channel_endpoint->ReplaceClient(data_pipe, 0))
+    if (!channel_endpoint->ReplaceClient(data_pipe.Clone(), 0))
       data_pipe->OnDetachFromChannel(0);
   } else {
     data_pipe->SetConsumerClosed();
@@ -165,7 +165,7 @@
 bool DataPipe::ProducerDeserialize(Channel* channel,
                                    const void* source,
                                    size_t size,
-                                   scoped_refptr<DataPipe>* data_pipe) {
+                                   RefPtr<DataPipe>* data_pipe) {
   DCHECK(!*data_pipe);  // Not technically wrong, but unlikely.
 
   bool consumer_open = false;
@@ -196,9 +196,9 @@
       return false;
     }
 
-    *data_pipe = new DataPipe(
+    *data_pipe = AdoptRef(new DataPipe(
         true, false, revalidated_options,
-        util::MakeUnique<RemoteConsumerDataPipeImpl>(nullptr, 0, nullptr, 0));
+        util::MakeUnique<RemoteConsumerDataPipeImpl>(nullptr, 0, nullptr, 0)));
     (*data_pipe)->SetConsumerClosed();
 
     return true;
@@ -213,7 +213,7 @@
 
   const void* endpoint_source = static_cast<const char*>(source) +
                                 sizeof(SerializedDataPipeProducerDispatcher);
-  scoped_refptr<IncomingEndpoint> incoming_endpoint =
+  RefPtr<IncomingEndpoint> incoming_endpoint =
       channel->DeserializeEndpoint(endpoint_source);
   if (!incoming_endpoint)
     return false;
@@ -230,7 +230,7 @@
 bool DataPipe::ConsumerDeserialize(Channel* channel,
                                    const void* source,
                                    size_t size,
-                                   scoped_refptr<DataPipe>* data_pipe) {
+                                   RefPtr<DataPipe>* data_pipe) {
   DCHECK(!*data_pipe);  // Not technically wrong, but unlikely.
 
   if (size !=
@@ -251,7 +251,7 @@
 
   const void* endpoint_source = static_cast<const char*>(source) +
                                 sizeof(SerializedDataPipeConsumerDispatcher);
-  scoped_refptr<IncomingEndpoint> incoming_endpoint =
+  RefPtr<IncomingEndpoint> incoming_endpoint =
       channel->DeserializeEndpoint(endpoint_source);
   if (!incoming_endpoint)
     return false;
diff --git a/mojo/edk/system/data_pipe.h b/mojo/edk/system/data_pipe.h
index b346fae..9eb567a 100644
--- a/mojo/edk/system/data_pipe.h
+++ b/mojo/edk/system/data_pipe.h
@@ -58,7 +58,7 @@
   // |ValidateOptions()|. In particular: |struct_size| is ignored (so
   // |validated_options| must be the current version of the struct) and
   // |capacity_num_bytes| must be nonzero.
-  static DataPipe* CreateLocal(
+  static RefPtr<DataPipe> CreateLocal(
       const MojoCreateDataPipeOptions& validated_options);
 
   // Creates a data pipe with a remote producer and a local consumer, using an
@@ -67,7 +67,7 @@
   // |channel_endpoint| is null, this will create a "half-open" data pipe (with
   // only the consumer open). Note that this may fail, in which case it returns
   // null.
-  static DataPipe* CreateRemoteProducerFromExisting(
+  static RefPtr<DataPipe> CreateRemoteProducerFromExisting(
       const MojoCreateDataPipeOptions& validated_options,
       MessageInTransitQueue* message_queue,
       RefPtr<ChannelEndpoint>&& channel_endpoint);
@@ -78,7 +78,7 @@
   // (|message_queue| may be null). If |channel_endpoint| is null, this will
   // create a "half-open" data pipe (with only the producer open). Note that
   // this may fail, in which case it returns null.
-  static DataPipe* CreateRemoteConsumerFromExisting(
+  static RefPtr<DataPipe> CreateRemoteConsumerFromExisting(
       const MojoCreateDataPipeOptions& validated_options,
       size_t consumer_num_bytes,
       MessageInTransitQueue* message_queue,
@@ -90,7 +90,7 @@
   static bool ProducerDeserialize(Channel* channel,
                                   const void* source,
                                   size_t size,
-                                  scoped_refptr<DataPipe>* data_pipe);
+                                  RefPtr<DataPipe>* data_pipe);
 
   // Used by |DataPipeConsumerDispatcher::Deserialize()|. Returns true on
   // success (in which case, |*data_pipe| is set appropriately) and false on
@@ -98,7 +98,7 @@
   static bool ConsumerDeserialize(Channel* channel,
                                   const void* source,
                                   size_t size,
-                                  scoped_refptr<DataPipe>* data_pipe);
+                                  RefPtr<DataPipe>* data_pipe);
 
   // These are called by the producer dispatcher to implement its methods of
   // corresponding names.
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
index 059f801..cf89b3b 100644
--- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc
+++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
@@ -4,6 +4,8 @@
 
 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "mojo/edk/system/data_pipe.h"
 #include "mojo/edk/system/memory.h"
@@ -11,9 +13,9 @@
 namespace mojo {
 namespace system {
 
-void DataPipeConsumerDispatcher::Init(scoped_refptr<DataPipe> data_pipe) {
+void DataPipeConsumerDispatcher::Init(RefPtr<DataPipe>&& data_pipe) {
   DCHECK(data_pipe);
-  data_pipe_ = data_pipe;
+  data_pipe_ = std::move(data_pipe);
 }
 
 Dispatcher::Type DataPipeConsumerDispatcher::GetType() const {
@@ -25,13 +27,13 @@
 DataPipeConsumerDispatcher::Deserialize(Channel* channel,
                                         const void* source,
                                         size_t size) {
-  scoped_refptr<DataPipe> data_pipe;
+  RefPtr<DataPipe> data_pipe;
   if (!DataPipe::ConsumerDeserialize(channel, source, size, &data_pipe))
     return nullptr;
   DCHECK(data_pipe);
 
   scoped_refptr<DataPipeConsumerDispatcher> dispatcher = Create();
-  dispatcher->Init(data_pipe);
+  dispatcher->Init(std::move(data_pipe));
   return dispatcher;
 }
 
@@ -64,8 +66,7 @@
   mutex().AssertHeld();
 
   scoped_refptr<DataPipeConsumerDispatcher> rv = Create();
-  rv->Init(data_pipe_);
-  data_pipe_ = nullptr;
+  rv->Init(std::move(data_pipe_));
   return scoped_refptr<Dispatcher>(rv.get());
 }
 
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.h b/mojo/edk/system/data_pipe_consumer_dispatcher.h
index 8a541a8..746d02e 100644
--- a/mojo/edk/system/data_pipe_consumer_dispatcher.h
+++ b/mojo/edk/system/data_pipe_consumer_dispatcher.h
@@ -7,6 +7,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "mojo/edk/system/dispatcher.h"
+#include "mojo/edk/system/ref_ptr.h"
 #include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
@@ -24,7 +25,7 @@
   }
 
   // Must be called before any other methods.
-  void Init(scoped_refptr<DataPipe> data_pipe) MOJO_NOT_THREAD_SAFE;
+  void Init(RefPtr<DataPipe>&& data_pipe) MOJO_NOT_THREAD_SAFE;
 
   // |Dispatcher| public methods:
   Type GetType() const override;
@@ -73,7 +74,7 @@
   bool IsBusyNoLock() const override;
 
   // This will be null if closed.
-  scoped_refptr<DataPipe> data_pipe_ MOJO_GUARDED_BY(mutex());
+  RefPtr<DataPipe> data_pipe_ MOJO_GUARDED_BY(mutex());
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(DataPipeConsumerDispatcher);
 };
diff --git a/mojo/edk/system/data_pipe_impl_unittest.cc b/mojo/edk/system/data_pipe_impl_unittest.cc
index d68231a..c3c30dc 100644
--- a/mojo/edk/system/data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/data_pipe_impl_unittest.cc
@@ -213,7 +213,7 @@
   void ConsumerClose() override { dp_->ConsumerClose(); }
 
  private:
-  scoped_refptr<DataPipe> dp_;
+  RefPtr<DataPipe> dp_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(LocalDataPipeImplTestHelper);
 };
@@ -306,10 +306,8 @@
     *to_receive = read_dispatchers[0];
   }
 
-  scoped_refptr<MessagePipe> message_pipe(size_t i) {
-    return message_pipes_[i];
-  }
-  scoped_refptr<DataPipe> dp() { return dp_; }
+  RefPtr<MessagePipe> message_pipe(size_t i) { return message_pipes_[i]; }
+  RefPtr<DataPipe> dp() { return dp_; }
 
  private:
   void EnsureMessagePipeClosed(size_t i) {
@@ -350,9 +348,9 @@
   embedder::SimplePlatformSupport platform_support_;
   mojo::test::TestIOThread io_thread_;
   RefPtr<Channel> channels_[2];
-  scoped_refptr<MessagePipe> message_pipes_[2];
+  RefPtr<MessagePipe> message_pipes_[2];
 
-  scoped_refptr<DataPipe> dp_;
+  RefPtr<DataPipe> dp_;
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(RemoteDataPipeImplTestHelper);
 };
diff --git a/mojo/edk/system/data_pipe_producer_dispatcher.cc b/mojo/edk/system/data_pipe_producer_dispatcher.cc
index 5221713..cb712d3 100644
--- a/mojo/edk/system/data_pipe_producer_dispatcher.cc
+++ b/mojo/edk/system/data_pipe_producer_dispatcher.cc
@@ -4,6 +4,8 @@
 
 #include "mojo/edk/system/data_pipe_producer_dispatcher.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "mojo/edk/system/data_pipe.h"
 #include "mojo/edk/system/memory.h"
@@ -11,9 +13,9 @@
 namespace mojo {
 namespace system {
 
-void DataPipeProducerDispatcher::Init(scoped_refptr<DataPipe> data_pipe) {
+void DataPipeProducerDispatcher::Init(RefPtr<DataPipe>&& data_pipe) {
   DCHECK(data_pipe);
-  data_pipe_ = data_pipe;
+  data_pipe_ = std::move(data_pipe);
 }
 
 Dispatcher::Type DataPipeProducerDispatcher::GetType() const {
@@ -25,13 +27,13 @@
 DataPipeProducerDispatcher::Deserialize(Channel* channel,
                                         const void* source,
                                         size_t size) {
-  scoped_refptr<DataPipe> data_pipe;
+  RefPtr<DataPipe> data_pipe;
   if (!DataPipe::ProducerDeserialize(channel, source, size, &data_pipe))
     return nullptr;
   DCHECK(data_pipe);
 
   scoped_refptr<DataPipeProducerDispatcher> dispatcher = Create();
-  dispatcher->Init(data_pipe);
+  dispatcher->Init(std::move(data_pipe));
   return dispatcher;
 }
 
@@ -64,8 +66,7 @@
   mutex().AssertHeld();
 
   scoped_refptr<DataPipeProducerDispatcher> rv = Create();
-  rv->Init(data_pipe_);
-  data_pipe_ = nullptr;
+  rv->Init(std::move(data_pipe_));
   return scoped_refptr<Dispatcher>(rv.get());
 }
 
diff --git a/mojo/edk/system/data_pipe_producer_dispatcher.h b/mojo/edk/system/data_pipe_producer_dispatcher.h
index 53fa291..aed201f 100644
--- a/mojo/edk/system/data_pipe_producer_dispatcher.h
+++ b/mojo/edk/system/data_pipe_producer_dispatcher.h
@@ -7,6 +7,7 @@
 
 #include "base/memory/ref_counted.h"
 #include "mojo/edk/system/dispatcher.h"
+#include "mojo/edk/system/ref_ptr.h"
 #include "mojo/public/cpp/system/macros.h"
 
 namespace mojo {
@@ -24,7 +25,7 @@
   }
 
   // Must be called before any other methods.
-  void Init(scoped_refptr<DataPipe> data_pipe) MOJO_NOT_THREAD_SAFE;
+  void Init(RefPtr<DataPipe>&& data_pipe) MOJO_NOT_THREAD_SAFE;
 
   // |Dispatcher| public methods:
   Type GetType() const override;
@@ -73,7 +74,7 @@
   bool IsBusyNoLock() const override;
 
   // This will be null if closed.
-  scoped_refptr<DataPipe> data_pipe_ MOJO_GUARDED_BY(mutex());
+  RefPtr<DataPipe> data_pipe_ MOJO_GUARDED_BY(mutex());
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(DataPipeProducerDispatcher);
 };
diff --git a/mojo/edk/system/dispatcher_unittest.cc b/mojo/edk/system/dispatcher_unittest.cc
index b547182..b15682b 100644
--- a/mojo/edk/system/dispatcher_unittest.cc
+++ b/mojo/edk/system/dispatcher_unittest.cc
@@ -28,7 +28,6 @@
   Type GetType() const override { return Type::UNKNOWN; }
 
  private:
-  friend class base::RefCountedThreadSafe<TrivialDispatcher>;
   ~TrivialDispatcher() override {}
 
   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock()
diff --git a/mojo/edk/system/endpoint_relayer.cc b/mojo/edk/system/endpoint_relayer.cc
index d1b82be..0cf4efa 100644
--- a/mojo/edk/system/endpoint_relayer.cc
+++ b/mojo/edk/system/endpoint_relayer.cc
@@ -13,9 +13,6 @@
 namespace mojo {
 namespace system {
 
-EndpointRelayer::EndpointRelayer() {
-}
-
 // static
 unsigned EndpointRelayer::GetPeerPort(unsigned port) {
   DCHECK(port == 0 || port == 1);
@@ -77,6 +74,8 @@
   }
 }
 
+EndpointRelayer::EndpointRelayer() {}
+
 EndpointRelayer::~EndpointRelayer() {
   DCHECK(!endpoints_[0]);
   DCHECK(!endpoints_[1]);
diff --git a/mojo/edk/system/endpoint_relayer.h b/mojo/edk/system/endpoint_relayer.h
index 5a61aa1..f41de96 100644
--- a/mojo/edk/system/endpoint_relayer.h
+++ b/mojo/edk/system/endpoint_relayer.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/memory/ref_counted.h"
 #include "mojo/edk/system/channel_endpoint_client.h"
 #include "mojo/edk/system/mutex.h"
 #include "mojo/edk/system/ref_ptr.h"
@@ -62,7 +61,7 @@
     MOJO_DISALLOW_COPY_AND_ASSIGN(Filter);
   };
 
-  EndpointRelayer();
+  // Note: Use |MakeRefCounted<EndpointRelayer>()|.
 
   // Gets the other port number (i.e., 0 -> 1, 1 -> 0).
   static unsigned GetPeerPort(unsigned port);
@@ -80,6 +79,9 @@
   void OnDetachFromChannel(unsigned port) override;
 
  private:
+  FRIEND_MAKE_REF_COUNTED(EndpointRelayer);
+
+  EndpointRelayer();
   ~EndpointRelayer() override;
 
   Mutex mutex_;
diff --git a/mojo/edk/system/endpoint_relayer_unittest.cc b/mojo/edk/system/endpoint_relayer_unittest.cc
index 94ed254..d88e3ec 100644
--- a/mojo/edk/system/endpoint_relayer_unittest.cc
+++ b/mojo/edk/system/endpoint_relayer_unittest.cc
@@ -11,6 +11,7 @@
 #include "mojo/edk/system/channel_test_base.h"
 #include "mojo/edk/system/message_in_transit_queue.h"
 #include "mojo/edk/system/message_in_transit_test_utils.h"
+#include "mojo/edk/system/ref_ptr.h"
 #include "mojo/edk/system/test_channel_endpoint_client.h"
 #include "mojo/edk/util/make_unique.h"
 #include "mojo/public/cpp/system/macros.h"
@@ -43,17 +44,17 @@
     ChannelEndpointId ida = id_generator.GetNext();
     ChannelEndpointId idb = id_generator.GetNext();
 
-    relayer_ = new EndpointRelayer();
-    endpoint0a_ = MakeRefCounted<ChannelEndpoint>(relayer_.get(), 0);
-    endpoint0b_ = MakeRefCounted<ChannelEndpoint>(relayer_.get(), 1);
+    relayer_ = MakeRefCounted<EndpointRelayer>();
+    endpoint0a_ = MakeRefCounted<ChannelEndpoint>(relayer_.Clone(), 0);
+    endpoint0b_ = MakeRefCounted<ChannelEndpoint>(relayer_.Clone(), 1);
     relayer_->Init(endpoint0a_.Clone(), endpoint0b_.Clone());
     channel(0)->SetBootstrapEndpointWithIds(endpoint0a_.Clone(), ida, ida);
     channel(0)->SetBootstrapEndpointWithIds(endpoint0b_.Clone(), idb, idb);
 
-    client1a_ = new test::TestChannelEndpointClient();
-    client1b_ = new test::TestChannelEndpointClient();
-    endpoint1a_ = MakeRefCounted<ChannelEndpoint>(client1a_.get(), 0);
-    endpoint1b_ = MakeRefCounted<ChannelEndpoint>(client1b_.get(), 0);
+    client1a_ = MakeRefCounted<test::TestChannelEndpointClient>();
+    client1b_ = MakeRefCounted<test::TestChannelEndpointClient>();
+    endpoint1a_ = MakeRefCounted<ChannelEndpoint>(client1a_.Clone(), 0);
+    endpoint1b_ = MakeRefCounted<ChannelEndpoint>(client1b_.Clone(), 0);
     client1a_->Init(0, endpoint1a_.Clone());
     client1b_->Init(0, endpoint1b_.Clone());
     channel(1)->SetBootstrapEndpointWithIds(endpoint1a_.Clone(), ida, ida);
@@ -77,11 +78,11 @@
   ChannelEndpoint* endpoint1b() { return endpoint1b_.get(); }
 
  private:
-  scoped_refptr<EndpointRelayer> relayer_;
+  RefPtr<EndpointRelayer> relayer_;
   RefPtr<ChannelEndpoint> endpoint0a_;
   RefPtr<ChannelEndpoint> endpoint0b_;
-  scoped_refptr<test::TestChannelEndpointClient> client1a_;
-  scoped_refptr<test::TestChannelEndpointClient> client1b_;
+  RefPtr<test::TestChannelEndpointClient> client1a_;
+  RefPtr<test::TestChannelEndpointClient> client1b_;
   RefPtr<ChannelEndpoint> endpoint1a_;
   RefPtr<ChannelEndpoint> endpoint1b_;
 
diff --git a/mojo/edk/system/incoming_endpoint.cc b/mojo/edk/system/incoming_endpoint.cc
index e8b88d1..4fd8789 100644
--- a/mojo/edk/system/incoming_endpoint.cc
+++ b/mojo/edk/system/incoming_endpoint.cc
@@ -16,39 +16,36 @@
 namespace mojo {
 namespace system {
 
-IncomingEndpoint::IncomingEndpoint() {
-}
-
 RefPtr<ChannelEndpoint> IncomingEndpoint::Init() {
-  endpoint_ = MakeRefCounted<ChannelEndpoint>(this, 0);
+  endpoint_ =
+      MakeRefCounted<ChannelEndpoint>(RefPtr<IncomingEndpoint>(this), 0);
   return endpoint_;
 }
 
-scoped_refptr<MessagePipe> IncomingEndpoint::ConvertToMessagePipe() {
+RefPtr<MessagePipe> IncomingEndpoint::ConvertToMessagePipe() {
   MutexLocker locker(&mutex_);
-  scoped_refptr<MessagePipe> message_pipe(
-      MessagePipe::CreateLocalProxyFromExisting(&message_queue_,
-                                                std::move(endpoint_)));
+  RefPtr<MessagePipe> message_pipe = MessagePipe::CreateLocalProxyFromExisting(
+      &message_queue_, std::move(endpoint_));
   DCHECK(message_queue_.IsEmpty());
   return message_pipe;
 }
 
-scoped_refptr<DataPipe> IncomingEndpoint::ConvertToDataPipeProducer(
+RefPtr<DataPipe> IncomingEndpoint::ConvertToDataPipeProducer(
     const MojoCreateDataPipeOptions& validated_options,
     size_t consumer_num_bytes) {
   MutexLocker locker(&mutex_);
-  scoped_refptr<DataPipe> data_pipe(DataPipe::CreateRemoteConsumerFromExisting(
+  auto data_pipe = DataPipe::CreateRemoteConsumerFromExisting(
       validated_options, consumer_num_bytes, &message_queue_,
-      std::move(endpoint_)));
+      std::move(endpoint_));
   DCHECK(message_queue_.IsEmpty());
   return data_pipe;
 }
 
-scoped_refptr<DataPipe> IncomingEndpoint::ConvertToDataPipeConsumer(
+RefPtr<DataPipe> IncomingEndpoint::ConvertToDataPipeConsumer(
     const MojoCreateDataPipeOptions& validated_options) {
   MutexLocker locker(&mutex_);
-  scoped_refptr<DataPipe> data_pipe(DataPipe::CreateRemoteProducerFromExisting(
-      validated_options, &message_queue_, std::move(endpoint_)));
+  auto data_pipe = DataPipe::CreateRemoteProducerFromExisting(
+      validated_options, &message_queue_, std::move(endpoint_));
   DCHECK(message_queue_.IsEmpty());
   return data_pipe;
 }
@@ -75,8 +72,9 @@
   Close();
 }
 
-IncomingEndpoint::~IncomingEndpoint() {
-}
+IncomingEndpoint::IncomingEndpoint() {}
+
+IncomingEndpoint::~IncomingEndpoint() {}
 
 }  // namespace system
 }  // namespace mojo
diff --git a/mojo/edk/system/incoming_endpoint.h b/mojo/edk/system/incoming_endpoint.h
index 626187e..6dbf9a0 100644
--- a/mojo/edk/system/incoming_endpoint.h
+++ b/mojo/edk/system/incoming_endpoint.h
@@ -27,16 +27,16 @@
 // |MessagePipe|s or |DataPipe|s.
 class IncomingEndpoint final : public ChannelEndpointClient {
  public:
-  IncomingEndpoint();
+  // Note: Use |MakeRefCounted<IncomingEndpoint>()|.
 
   // Must be called before any other method.
   RefPtr<ChannelEndpoint> Init() MOJO_NOT_THREAD_SAFE;
 
-  scoped_refptr<MessagePipe> ConvertToMessagePipe();
-  scoped_refptr<DataPipe> ConvertToDataPipeProducer(
+  RefPtr<MessagePipe> ConvertToMessagePipe();
+  RefPtr<DataPipe> ConvertToDataPipeProducer(
       const MojoCreateDataPipeOptions& validated_options,
       size_t consumer_num_bytes);
-  scoped_refptr<DataPipe> ConvertToDataPipeConsumer(
+  RefPtr<DataPipe> ConvertToDataPipeConsumer(
       const MojoCreateDataPipeOptions& validated_options);
 
   // Must be called before destroying this object if |ConvertToMessagePipe()|
@@ -48,6 +48,9 @@
   void OnDetachFromChannel(unsigned port) override;
 
  private:
+  FRIEND_MAKE_REF_COUNTED(IncomingEndpoint);
+
+  IncomingEndpoint();
   ~IncomingEndpoint() override;
 
   Mutex mutex_;
diff --git a/mojo/edk/system/ipc_support_unittest.cc b/mojo/edk/system/ipc_support_unittest.cc
index 11800d4..838c4ce 100644
--- a/mojo/edk/system/ipc_support_unittest.cc
+++ b/mojo/edk/system/ipc_support_unittest.cc
@@ -424,9 +424,9 @@
       MessagePipeDispatcher::kDefaultCreateOptions);
   rv.second = MessagePipeDispatcher::Create(
       MessagePipeDispatcher::kDefaultCreateOptions);
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-  rv.first->Init(mp, 0);
-  rv.second->Init(mp, 1);
+  auto mp = MessagePipe::CreateLocalLocal();
+  rv.first->Init(mp.Clone(), 0);
+  rv.second->Init(std::move(mp), 1);
   return rv;
 }
 
diff --git a/mojo/edk/system/local_data_pipe_impl.cc b/mojo/edk/system/local_data_pipe_impl.cc
index 553d012..1d1f205 100644
--- a/mojo/edk/system/local_data_pipe_impl.cc
+++ b/mojo/edk/system/local_data_pipe_impl.cc
@@ -182,8 +182,9 @@
   s->consumer_num_bytes = current_num_bytes_;
   // Note: We don't use |port|.
   RefPtr<ChannelEndpoint> channel_endpoint =
-      channel->SerializeEndpointWithLocalPeer(destination_for_endpoint, nullptr,
-                                              channel_endpoint_client(), 0);
+      channel->SerializeEndpointWithLocalPeer(
+          destination_for_endpoint, nullptr,
+          RefPtr<ChannelEndpointClient>(channel_endpoint_client()), 0);
   // Note: Keep |*this| alive until the end of this method, to make things
   // slightly easier on ourselves.
   std::unique_ptr<DataPipeImpl> self(
@@ -360,9 +361,9 @@
 
   // Note: We don't use |port|.
   RefPtr<ChannelEndpoint> channel_endpoint =
-      channel->SerializeEndpointWithLocalPeer(destination_for_endpoint,
-                                              &message_queue,
-                                              channel_endpoint_client(), 0);
+      channel->SerializeEndpointWithLocalPeer(
+          destination_for_endpoint, &message_queue,
+          RefPtr<ChannelEndpointClient>(channel_endpoint_client()), 0);
   // Note: Keep |*this| alive until the end of this method, to make things
   // slightly easier on ourselves.
   std::unique_ptr<DataPipeImpl> self(
diff --git a/mojo/edk/system/message_pipe.cc b/mojo/edk/system/message_pipe.cc
index df48078..49fd5a0 100644
--- a/mojo/edk/system/message_pipe.cc
+++ b/mojo/edk/system/message_pipe.cc
@@ -23,31 +23,32 @@
 namespace system {
 
 // static
-MessagePipe* MessagePipe::CreateLocalLocal() MOJO_NO_THREAD_SAFETY_ANALYSIS {
-  MessagePipe* message_pipe = new MessagePipe();
+RefPtr<MessagePipe> MessagePipe::CreateLocalLocal()
+    MOJO_NO_THREAD_SAFETY_ANALYSIS {
+  RefPtr<MessagePipe> message_pipe = AdoptRef(new MessagePipe());
   message_pipe->endpoints_[0].reset(new LocalMessagePipeEndpoint());
   message_pipe->endpoints_[1].reset(new LocalMessagePipeEndpoint());
   return message_pipe;
 }
 
 // static
-MessagePipe* MessagePipe::CreateLocalProxy(
+RefPtr<MessagePipe> MessagePipe::CreateLocalProxy(
     RefPtr<ChannelEndpoint>* channel_endpoint) MOJO_NO_THREAD_SAFETY_ANALYSIS {
   DCHECK(!*channel_endpoint);  // Not technically wrong, but unlikely.
-  MessagePipe* message_pipe = new MessagePipe();
+  RefPtr<MessagePipe> message_pipe = AdoptRef(new MessagePipe());
   message_pipe->endpoints_[0].reset(new LocalMessagePipeEndpoint());
-  *channel_endpoint = MakeRefCounted<ChannelEndpoint>(message_pipe, 1);
+  *channel_endpoint = MakeRefCounted<ChannelEndpoint>(message_pipe.Clone(), 1);
   message_pipe->endpoints_[1].reset(
       new ProxyMessagePipeEndpoint(channel_endpoint->Clone()));
   return message_pipe;
 }
 
 // static
-MessagePipe* MessagePipe::CreateLocalProxyFromExisting(
+RefPtr<MessagePipe> MessagePipe::CreateLocalProxyFromExisting(
     MessageInTransitQueue* message_queue,
     RefPtr<ChannelEndpoint>&& channel_endpoint) MOJO_NO_THREAD_SAFETY_ANALYSIS {
   DCHECK(message_queue);
-  MessagePipe* message_pipe = new MessagePipe();
+  RefPtr<MessagePipe> message_pipe = AdoptRef(new MessagePipe());
   message_pipe->endpoints_[0].reset(
       new LocalMessagePipeEndpoint(message_queue));
   if (channel_endpoint) {
@@ -67,10 +68,10 @@
 }
 
 // static
-MessagePipe* MessagePipe::CreateProxyLocal(
+RefPtr<MessagePipe> MessagePipe::CreateProxyLocal(
     RefPtr<ChannelEndpoint>* channel_endpoint) MOJO_NO_THREAD_SAFETY_ANALYSIS {
   DCHECK(!*channel_endpoint);  // Not technically wrong, but unlikely.
-  MessagePipe* message_pipe = new MessagePipe();
+  RefPtr<MessagePipe> message_pipe = AdoptRef(new MessagePipe());
   *channel_endpoint = MakeRefCounted<ChannelEndpoint>(message_pipe, 0);
   message_pipe->endpoints_[0].reset(
       new ProxyMessagePipeEndpoint(channel_endpoint->Clone()));
@@ -88,7 +89,7 @@
 bool MessagePipe::Deserialize(Channel* channel,
                               const void* source,
                               size_t size,
-                              scoped_refptr<MessagePipe>* message_pipe,
+                              RefPtr<MessagePipe>* message_pipe,
                               unsigned* port) {
   DCHECK(!*message_pipe);  // Not technically wrong, but unlikely.
 
@@ -97,7 +98,7 @@
     return false;
   }
 
-  scoped_refptr<IncomingEndpoint> incoming_endpoint =
+  RefPtr<IncomingEndpoint> incoming_endpoint =
       channel->DeserializeEndpoint(source);
   if (!incoming_endpoint)
     return false;
@@ -251,8 +252,9 @@
     // with a |ProxyMessagePipeEndpoint| hooked up to the |ChannelEndpoint| that
     // the |Channel| returns to us.
     RefPtr<ChannelEndpoint> channel_endpoint =
-        channel->SerializeEndpointWithLocalPeer(destination, message_queue,
-                                                this, port);
+        channel->SerializeEndpointWithLocalPeer(
+            destination, message_queue, RefPtr<ChannelEndpointClient>(this),
+            port);
     replacement_endpoint =
         new ProxyMessagePipeEndpoint(std::move(channel_endpoint));
   } else {
diff --git a/mojo/edk/system/message_pipe.h b/mojo/edk/system/message_pipe.h
index fc54199..d7eefc6 100644
--- a/mojo/edk/system/message_pipe.h
+++ b/mojo/edk/system/message_pipe.h
@@ -39,19 +39,19 @@
 class MessagePipe final : public ChannelEndpointClient {
  public:
   // Creates a |MessagePipe| with two new |LocalMessagePipeEndpoint|s.
-  static MessagePipe* CreateLocalLocal();
+  static RefPtr<MessagePipe> CreateLocalLocal();
 
   // Creates a |MessagePipe| with a |LocalMessagePipeEndpoint| on port 0 and a
   // |ProxyMessagePipeEndpoint| on port 1. |*channel_endpoint| is set to the
   // (newly-created) |ChannelEndpoint| for the latter.
-  static MessagePipe* CreateLocalProxy(
+  static RefPtr<MessagePipe> CreateLocalProxy(
       RefPtr<ChannelEndpoint>* channel_endpoint);
 
   // Similar to |CreateLocalProxy()|, except that it'll do so from an existing
   // |ChannelEndpoint| (whose |ReplaceClient()| it'll call) and take
   // |message_queue|'s contents as already-received incoming messages. If
   // |channel_endpoint| is null, this will create a "half-open" message pipe.
-  static MessagePipe* CreateLocalProxyFromExisting(
+  static RefPtr<MessagePipe> CreateLocalProxyFromExisting(
       MessageInTransitQueue* message_queue,
       RefPtr<ChannelEndpoint>&& channel_endpoint);
 
@@ -61,7 +61,7 @@
   // Note: This is really only needed in tests (outside of tests, this
   // configuration arises from a local message pipe having its port 0
   // "converted" using |ConvertLocalToProxy()|).
-  static MessagePipe* CreateProxyLocal(
+  static RefPtr<MessagePipe> CreateProxyLocal(
       RefPtr<ChannelEndpoint>* channel_endpoint);
 
   // Gets the other port number (i.e., 0 -> 1, 1 -> 0).
@@ -73,7 +73,7 @@
   static bool Deserialize(Channel* channel,
                           const void* source,
                           size_t size,
-                          scoped_refptr<MessagePipe>* message_pipe,
+                          RefPtr<MessagePipe>* message_pipe,
                           unsigned* port);
 
   // Gets the type of the endpoint (used for assertions, etc.).
diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc
index 0292c3b..3aa89c7 100644
--- a/mojo/edk/system/message_pipe_dispatcher.cc
+++ b/mojo/edk/system/message_pipe_dispatcher.cc
@@ -4,6 +4,8 @@
 
 #include "mojo/edk/system/message_pipe_dispatcher.h"
 
+#include <utility>
+
 #include "base/logging.h"
 #include "mojo/edk/system/configuration.h"
 #include "mojo/edk/system/local_message_pipe_endpoint.h"
@@ -53,12 +55,12 @@
   return MOJO_RESULT_OK;
 }
 
-void MessagePipeDispatcher::Init(scoped_refptr<MessagePipe> message_pipe,
+void MessagePipeDispatcher::Init(RefPtr<MessagePipe>&& message_pipe,
                                  unsigned port) {
   DCHECK(message_pipe);
   DCHECK(port == 0 || port == 1);
 
-  message_pipe_ = message_pipe;
+  message_pipe_ = std::move(message_pipe);
   port_ = port;
 }
 
@@ -70,11 +72,10 @@
 scoped_refptr<MessagePipeDispatcher>
 MessagePipeDispatcher::CreateRemoteMessagePipe(
     RefPtr<ChannelEndpoint>* channel_endpoint) {
-  scoped_refptr<MessagePipe> message_pipe(
-      MessagePipe::CreateLocalProxy(channel_endpoint));
+  auto message_pipe = MessagePipe::CreateLocalProxy(channel_endpoint);
   scoped_refptr<MessagePipeDispatcher> dispatcher =
       Create(kDefaultCreateOptions);
-  dispatcher->Init(message_pipe, 0);
+  dispatcher->Init(std::move(message_pipe), 0);
   return dispatcher;
 }
 
@@ -84,7 +85,7 @@
     const void* source,
     size_t size) {
   unsigned port = kInvalidPort;
-  scoped_refptr<MessagePipe> message_pipe;
+  RefPtr<MessagePipe> message_pipe;
   if (!MessagePipe::Deserialize(channel, source, size, &message_pipe, &port))
     return nullptr;
   DCHECK(message_pipe);
@@ -92,7 +93,7 @@
 
   scoped_refptr<MessagePipeDispatcher> dispatcher =
       Create(kDefaultCreateOptions);
-  dispatcher->Init(message_pipe, port);
+  dispatcher->Init(std::move(message_pipe), port);
   return dispatcher;
 }
 
@@ -134,8 +135,7 @@
   // |kDefaultCreateOptions|. Eventually, we'll have to duplicate the options
   // too.
   scoped_refptr<MessagePipeDispatcher> rv = Create(kDefaultCreateOptions);
-  rv->Init(message_pipe_, port_);
-  message_pipe_ = nullptr;
+  rv->Init(std::move(message_pipe_), port_);
   port_ = kInvalidPort;
   return scoped_refptr<Dispatcher>(rv.get());
 }
diff --git a/mojo/edk/system/message_pipe_dispatcher.h b/mojo/edk/system/message_pipe_dispatcher.h
index cfe80a5..bfc7997 100644
--- a/mojo/edk/system/message_pipe_dispatcher.h
+++ b/mojo/edk/system/message_pipe_dispatcher.h
@@ -42,7 +42,7 @@
       MojoCreateMessagePipeOptions* out_options);
 
   // Must be called before any other methods. (This method is not thread-safe.)
-  void Init(scoped_refptr<MessagePipe> message_pipe,
+  void Init(RefPtr<MessagePipe>&& message_pipe,
             unsigned port) MOJO_NOT_THREAD_SAFE;
 
   // |Dispatcher| public methods:
@@ -110,7 +110,7 @@
       MOJO_NOT_THREAD_SAFE;
 
   // This will be null if closed.
-  scoped_refptr<MessagePipe> message_pipe_ MOJO_GUARDED_BY(mutex());
+  RefPtr<MessagePipe> message_pipe_ MOJO_GUARDED_BY(mutex());
   unsigned port_ MOJO_GUARDED_BY(mutex());
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(MessagePipeDispatcher);
diff --git a/mojo/edk/system/message_pipe_dispatcher_unittest.cc b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
index 11707d9..16855be 100644
--- a/mojo/edk/system/message_pipe_dispatcher_unittest.cc
+++ b/mojo/edk/system/message_pipe_dispatcher_unittest.cc
@@ -12,6 +12,7 @@
 #include <string.h>
 
 #include <limits>
+#include <utility>
 
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_vector.h"
@@ -45,9 +46,9 @@
     scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
         MessagePipeDispatcher::kDefaultCreateOptions);
     {
-      scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-      d0->Init(mp, i);      // 0, 1.
-      d1->Init(mp, i ^ 1);  // 1, 0.
+      auto mp = MessagePipe::CreateLocalLocal();
+      d0->Init(mp.Clone(), i);         // 0, 1.
+      d1->Init(std::move(mp), i ^ 1);  // 1, 0.
     }
     Waiter w;
     uint32_t context = 0;
@@ -156,9 +157,9 @@
   scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
       MessagePipeDispatcher::kDefaultCreateOptions);
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-    d0->Init(mp, 0);
-    d1->Init(mp, 1);
+    auto mp = MessagePipe::CreateLocalLocal();
+    d0->Init(mp.Clone(), 0);
+    d1->Init(std::move(mp), 1);
   }
 
   // |WriteMessage|:
@@ -186,9 +187,9 @@
   scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
       MessagePipeDispatcher::kDefaultCreateOptions);
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-    d0->Init(mp, 0);
-    d1->Init(mp, 1);
+    auto mp = MessagePipe::CreateLocalLocal();
+    d0->Init(mp.Clone(), 0);
+    d1->Init(std::move(mp), 1);
   }
 
   // |WriteMessage|:
@@ -226,9 +227,9 @@
     scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
         MessagePipeDispatcher::kDefaultCreateOptions);
     {
-      scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-      d0->Init(mp, i);      // 0, 1.
-      d1->Init(mp, i ^ 1);  // 1, 0.
+      auto mp = MessagePipe::CreateLocalLocal();
+      d0->Init(mp.Clone(), i);         // 0, 1.
+      d1->Init(std::move(mp), i ^ 1);  // 1, 0.
     }
     Waiter w;
     HandleSignalsState hss;
@@ -356,9 +357,9 @@
     scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
         MessagePipeDispatcher::kDefaultCreateOptions);
     {
-      scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-      d0->Init(mp, i);      // 0, 1.
-      d1->Init(mp, i ^ 1);  // 1, 0.
+      auto mp = MessagePipe::CreateLocalLocal();
+      d0->Init(mp.Clone(), i);         // 0, 1.
+      d1->Init(std::move(mp), i ^ 1);  // 1, 0.
     }
 
     // Wait for readable on |d1|, which will become readable after some time.
@@ -439,9 +440,9 @@
     scoped_refptr<MessagePipeDispatcher> d1 = MessagePipeDispatcher::Create(
         MessagePipeDispatcher::kDefaultCreateOptions);
     {
-      scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-      d0->Init(mp, i);      // 0, 1.
-      d1->Init(mp, i ^ 1);  // 1, 0.
+      auto mp = MessagePipe::CreateLocalLocal();
+      d0->Init(mp.Clone(), i);         // 0, 1.
+      d1->Init(std::move(mp), i ^ 1);  // 1, 0.
     }
 
     // Wait for readable on |d1| and close |d1| after some time, which should
@@ -617,9 +618,9 @@
   scoped_refptr<MessagePipeDispatcher> d_read = MessagePipeDispatcher::Create(
       MessagePipeDispatcher::kDefaultCreateOptions);
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
-    d_write->Init(mp, 0);
-    d_read->Init(mp, 1);
+    auto mp = MessagePipe::CreateLocalLocal();
+    d_write->Init(mp.Clone(), 0);
+    d_read->Init(std::move(mp), 1);
   }
 
   size_t messages_written[kNumWriters];
diff --git a/mojo/edk/system/message_pipe_perftest.cc b/mojo/edk/system/message_pipe_perftest.cc
index 4964b83..362172a 100644
--- a/mojo/edk/system/message_pipe_perftest.cc
+++ b/mojo/edk/system/message_pipe_perftest.cc
@@ -45,7 +45,7 @@
   }
 
  protected:
-  void WriteWaitThenRead(scoped_refptr<MessagePipe> mp) {
+  void WriteWaitThenRead(MessagePipe* mp) {
     CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(payload_.data()),
                               static_cast<uint32_t>(payload_.size()), nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE),
@@ -61,13 +61,13 @@
     CHECK_EQ(read_buffer_size, static_cast<uint32_t>(payload_.size()));
   }
 
-  void SendQuitMessage(scoped_refptr<MessagePipe> mp) {
+  void SendQuitMessage(MessagePipe* mp) {
     CHECK_EQ(mp->WriteMessage(0, UserPointer<const void>(""), 0, nullptr,
                               MOJO_WRITE_MESSAGE_FLAG_NONE),
              MOJO_RESULT_OK);
   }
 
-  void Measure(scoped_refptr<MessagePipe> mp) {
+  void Measure(MessagePipe* mp) {
     // Have one ping-pong to ensure channel being established.
     WriteWaitThenRead(mp);
 
@@ -101,7 +101,7 @@
       mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
   CHECK(client_platform_handle.is_valid());
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   channel_thread.Start(client_platform_handle.Pass(), std::move(ep));
 
   std::string buffer(1000000, '\0');
@@ -110,7 +110,7 @@
     // Wait for our end of the message pipe to be readable.
     HandleSignalsState hss;
     MojoResult result =
-        test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss);
+        test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss);
     if (result != MOJO_RESULT_OK) {
       rv = result;
       break;
@@ -149,7 +149,7 @@
   helper()->StartChild("PingPongClient");
 
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   Init(std::move(ep));
 
   // This values are set to align with one at ipc_pertests.cc for comparison.
@@ -158,10 +158,10 @@
 
   for (size_t i = 0; i < 5; i++) {
     SetUpMeasurement(kMessageCount[i], kMsgSize[i]);
-    Measure(mp);
+    Measure(mp.get());
   }
 
-  SendQuitMessage(mp);
+  SendQuitMessage(mp.get());
   mp->Close(0);
   EXPECT_EQ(0, helper()->WaitForChildShutdown());
 }
diff --git a/mojo/edk/system/message_pipe_test_utils.cc b/mojo/edk/system/message_pipe_test_utils.cc
index 3485966..f0d9495 100644
--- a/mojo/edk/system/message_pipe_test_utils.cc
+++ b/mojo/edk/system/message_pipe_test_utils.cc
@@ -17,7 +17,7 @@
 namespace system {
 namespace test {
 
-MojoResult WaitIfNecessary(scoped_refptr<MessagePipe> mp,
+MojoResult WaitIfNecessary(MessagePipe* mp,
                            MojoHandleSignals signals,
                            HandleSignalsState* signals_state) {
   Waiter waiter;
diff --git a/mojo/edk/system/message_pipe_test_utils.h b/mojo/edk/system/message_pipe_test_utils.h
index 81e1239..9982dca 100644
--- a/mojo/edk/system/message_pipe_test_utils.h
+++ b/mojo/edk/system/message_pipe_test_utils.h
@@ -22,7 +22,7 @@
 
 namespace test {
 
-MojoResult WaitIfNecessary(scoped_refptr<MessagePipe> mp,
+MojoResult WaitIfNecessary(MessagePipe* mp,
                            MojoHandleSignals signals,
                            HandleSignalsState* signals_state);
 
diff --git a/mojo/edk/system/message_pipe_unittest.cc b/mojo/edk/system/message_pipe_unittest.cc
index 52ace80..6df7bed 100644
--- a/mojo/edk/system/message_pipe_unittest.cc
+++ b/mojo/edk/system/message_pipe_unittest.cc
@@ -4,7 +4,6 @@
 
 #include "mojo/edk/system/message_pipe.h"
 
-#include "base/memory/ref_counted.h"
 #include "mojo/edk/system/waiter.h"
 #include "mojo/edk/system/waiter_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -30,7 +29,7 @@
 //  - writing a message to a port, closing the other (would be the source) port,
 //    and reading it
 TEST(MessagePipeTest, Basic) {
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+  auto mp = MessagePipe::CreateLocalLocal();
 
   int32_t buffer[2];
   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
@@ -192,7 +191,7 @@
 }
 
 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) {
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+  auto mp = MessagePipe::CreateLocalLocal();
 
   int32_t buffer[1];
   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
@@ -219,7 +218,7 @@
 }
 
 TEST(MessagePipeTest, DiscardMode) {
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+  auto mp = MessagePipe::CreateLocalLocal();
 
   int32_t buffer[2];
   const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
@@ -323,7 +322,7 @@
 }
 
 TEST(MessagePipeTest, BasicWaiting) {
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+  auto mp = MessagePipe::CreateLocalLocal();
   Waiter waiter;
   HandleSignalsState hss;
 
@@ -465,7 +464,7 @@
 
   // Write to wake up waiter waiting for read.
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+    auto mp = MessagePipe::CreateLocalLocal();
     test::SimpleWaiterThread thread(&result, &context);
 
     thread.waiter()->Init();
@@ -495,7 +494,7 @@
 
   // Close to cancel waiter.
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+    auto mp = MessagePipe::CreateLocalLocal();
     test::SimpleWaiterThread thread(&result, &context);
 
     thread.waiter()->Init();
@@ -518,7 +517,7 @@
 
   // Close to cancel waiter using peer closed signal.
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+    auto mp = MessagePipe::CreateLocalLocal();
     test::SimpleWaiterThread thread(&result, &context);
 
     thread.waiter()->Init();
@@ -541,7 +540,7 @@
 
   // Close to make waiter un-wake-up-able.
   {
-    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
+    auto mp = MessagePipe::CreateLocalLocal();
     test::SimpleWaiterThread thread(&result, &context);
 
     thread.waiter()->Init();
diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
index 08de477..7f33e96 100644
--- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc
+++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc
@@ -49,7 +49,7 @@
       mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
   CHECK(client_platform_handle.is_valid());
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   channel_thread.Start(client_platform_handle.Pass(), std::move(ep));
 
   const std::string quitquitquit("quitquitquit");
@@ -58,7 +58,7 @@
     // Wait for our end of the message pipe to be readable.
     HandleSignalsState hss;
     MojoResult result =
-        test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss);
+        test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss);
     if (result != MOJO_RESULT_OK) {
       // It was closed, probably.
       CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION);
@@ -106,7 +106,7 @@
   helper()->StartChild("EchoEcho");
 
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   Init(std::move(ep));
 
   std::string hello("hello");
@@ -117,7 +117,7 @@
 
   HandleSignalsState hss;
   EXPECT_EQ(MOJO_RESULT_OK,
-            test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+            test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
   // The child may or may not have closed its end of the message pipe and died
   // (and we may or may not know it yet), so our end may or may not appear as
   // writable.
@@ -152,7 +152,7 @@
   helper()->StartChild("EchoEcho");
 
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   Init(std::move(ep));
 
   static const size_t kNumMessages = 1001;
@@ -172,8 +172,8 @@
 
   for (size_t i = 0; i < kNumMessages; i++) {
     HandleSignalsState hss;
-    EXPECT_EQ(MOJO_RESULT_OK,
-              test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+    EXPECT_EQ(MOJO_RESULT_OK, test::WaitIfNecessary(
+                                  mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
     // The child may or may not have closed its end of the message pipe and died
     // (and we may or may not know it yet), so our end may or may not appear as
     // writable.
@@ -195,7 +195,7 @@
   // "quitquitquit").
   HandleSignalsState hss;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+            test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
 
@@ -212,12 +212,12 @@
       mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
   CHECK(client_platform_handle.is_valid());
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   channel_thread.Start(client_platform_handle.Pass(), std::move(ep));
 
   // Wait for the first message from our parent.
   HandleSignalsState hss;
-  CHECK_EQ(test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss),
+  CHECK_EQ(test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss),
            MOJO_RESULT_OK);
   // In this test, the parent definitely doesn't close its end of the message
   // pipe before we do.
@@ -269,7 +269,7 @@
 
   // Now wait for our parent to send us a message.
   hss = HandleSignalsState();
-  CHECK_EQ(test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss),
+  CHECK_EQ(test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss),
            MOJO_RESULT_OK);
   CHECK_EQ(hss.satisfied_signals,
            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -306,7 +306,7 @@
   helper()->StartChild("CheckSharedBuffer");
 
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   Init(std::move(ep));
 
   // Make a shared buffer.
@@ -345,7 +345,7 @@
   // Wait for a message from the child.
   HandleSignalsState hss;
   EXPECT_EQ(MOJO_RESULT_OK,
-            test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+            test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
   EXPECT_TRUE((hss.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE));
   EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE));
 
@@ -377,7 +377,7 @@
   // Wait for |mp| to become readable, which should fail.
   hss = HandleSignalsState();
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+            test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
 
@@ -393,11 +393,11 @@
       mojo::test::MultiprocessTestHelper::client_platform_handle.Pass();
   CHECK(client_platform_handle.is_valid());
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   channel_thread.Start(client_platform_handle.Pass(), std::move(ep));
 
   HandleSignalsState hss;
-  CHECK_EQ(test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss),
+  CHECK_EQ(test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss),
            MOJO_RESULT_OK);
   CHECK_EQ(hss.satisfied_signals,
            MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE);
@@ -453,7 +453,7 @@
   helper()->StartChild("CheckPlatformHandleFile");
 
   RefPtr<ChannelEndpoint> ep;
-  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalProxy(&ep));
+  auto mp = MessagePipe::CreateLocalProxy(&ep);
   Init(std::move(ep));
 
   std::vector<scoped_refptr<PlatformHandleDispatcher>> dispatchers;
@@ -494,7 +494,7 @@
   // Wait for it to become readable, which should fail.
   HandleSignalsState hss;
   EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
-            test::WaitIfNecessary(mp, MOJO_HANDLE_SIGNAL_READABLE, &hss));
+            test::WaitIfNecessary(mp.get(), MOJO_HANDLE_SIGNAL_READABLE, &hss));
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
 
diff --git a/mojo/edk/system/ref_counted.h b/mojo/edk/system/ref_counted.h
index d24d471..fad0bc6 100644
--- a/mojo/edk/system/ref_counted.h
+++ b/mojo/edk/system/ref_counted.h
@@ -75,13 +75,13 @@
   RefCountedThreadSafe() {}
   ~RefCountedThreadSafe() {}
 
+ private:
 #ifndef NDEBUG
   template <typename U>
   friend RefPtr<U> AdoptRef(U*);
   void Adopt() { internal::RefCountedThreadSafeBase::Adopt(); }
 #endif
 
- private:
   MOJO_DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
 };
 
diff --git a/mojo/edk/system/remote_data_pipe_impl_unittest.cc b/mojo/edk/system/remote_data_pipe_impl_unittest.cc
index 2053e18..e669b19 100644
--- a/mojo/edk/system/remote_data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/remote_data_pipe_impl_unittest.cc
@@ -64,7 +64,8 @@
   }
 
  protected:
-  static DataPipe* CreateLocal(size_t element_size, size_t num_elements) {
+  static RefPtr<DataPipe> CreateLocal(size_t element_size,
+                                      size_t num_elements) {
     const MojoCreateDataPipeOptions options = {
         static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions)),
         MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
@@ -77,9 +78,7 @@
     return DataPipe::CreateLocal(validated_options);
   }
 
-  scoped_refptr<MessagePipe> message_pipe(size_t i) {
-    return message_pipes_[i];
-  }
+  RefPtr<MessagePipe> message_pipe(size_t i) { return message_pipes_[i]; }
 
   void EnsureMessagePipeClosed(size_t i) {
     if (!message_pipes_[i])
@@ -120,7 +119,7 @@
   embedder::SimplePlatformSupport platform_support_;
   mojo::test::TestIOThread io_thread_;
   RefPtr<Channel> channels_[2];
-  scoped_refptr<MessagePipe> message_pipes_[2];
+  RefPtr<MessagePipe> message_pipes_[2];
 
   MOJO_DISALLOW_COPY_AND_ASSIGN(RemoteDataPipeImplTest);
 };
@@ -173,11 +172,11 @@
   HandleSignalsState hss;
   uint32_t context = 0;
 
-  scoped_refptr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
+  RefPtr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
   // This is the consumer dispatcher we'll send.
   scoped_refptr<DataPipeConsumerDispatcher> consumer =
       DataPipeConsumerDispatcher::Create();
-  consumer->Init(dp);
+  consumer->Init(dp.Clone());
 
   // Write to the producer and close it, before sending the consumer.
   int32_t elements[10] = {123};
@@ -291,11 +290,11 @@
   HandleSignalsState hss;
   uint32_t context = 0;
 
-  scoped_refptr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
+  RefPtr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
   // This is the consumer dispatcher we'll send.
   scoped_refptr<DataPipeConsumerDispatcher> consumer =
       DataPipeConsumerDispatcher::Create();
-  consumer->Init(dp);
+  consumer->Init(dp.Clone());
 
   void* write_ptr = nullptr;
   uint32_t num_bytes = 0u;
@@ -401,11 +400,11 @@
   HandleSignalsState hss;
   uint32_t context = 0;
 
-  scoped_refptr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
+  RefPtr<DataPipe> dp(CreateLocal(sizeof(int32_t), 1000));
   // This is the consumer dispatcher we'll send.
   scoped_refptr<DataPipeConsumerDispatcher> consumer =
       DataPipeConsumerDispatcher::Create();
-  consumer->Init(dp);
+  consumer->Init(dp.Clone());
 
   void* write_ptr = nullptr;
   uint32_t num_bytes = 0u;
diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc
index 9e31b0e..a33a0f9 100644
--- a/mojo/edk/system/remote_message_pipe_unittest.cc
+++ b/mojo/edk/system/remote_message_pipe_unittest.cc
@@ -187,9 +187,9 @@
   // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // Write in one direction: MP 0, port 0 -> ... -> MP 1, port 1.
@@ -286,9 +286,9 @@
   // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // Close MP 0, port 0.
@@ -324,9 +324,9 @@
   // Connect message pipes as in the |Basic| test.
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // Now put another message pipe on the channel.
@@ -336,7 +336,7 @@
   // via |ep0| (i.e., sent using |mp0|, port 0) with this remote ID. Upon
   // receiving this message, |PassIncomingMessagePipe()| is used to obtain the
   // message pipe on the other side.
-  scoped_refptr<MessagePipe> mp2(MessagePipe::CreateLocalLocal());
+  auto mp2 = MessagePipe::CreateLocalLocal();
   ASSERT_TRUE(channels(0));
   size_t max_endpoint_info_size;
   size_t max_platform_handle_count;
@@ -380,10 +380,10 @@
                       endpoint_info_size));
 
   // Warning: The local side of mp3 is port 0, not port 1.
-  scoped_refptr<IncomingEndpoint> incoming_endpoint =
+  RefPtr<IncomingEndpoint> incoming_endpoint =
       channels(1)->DeserializeEndpoint(received_endpoint_info.get());
   ASSERT_TRUE(incoming_endpoint);
-  scoped_refptr<MessagePipe> mp3 = incoming_endpoint->ConvertToMessagePipe();
+  RefPtr<MessagePipe> mp3 = incoming_endpoint->ConvertToMessagePipe();
   ASSERT_TRUE(mp3);
 
   // Write: MP 2, port 0 -> MP 3, port 1.
@@ -497,7 +497,7 @@
   // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
 
   // Write to MP 0, port 0.
   EXPECT_EQ(
@@ -511,7 +511,7 @@
   BootstrapChannelEndpointNoWait(0, std::move(ep0));
 
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
 
   // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
   // it later, it might already be readable.)
@@ -559,7 +559,7 @@
   // MP 0, port 0 and MP 1, port 1 as the "user-facing" endpoints.
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
 
   // Write to MP 0, port 0.
   EXPECT_EQ(
@@ -573,7 +573,7 @@
   mp0->Close(0);
 
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
 
   // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
   // it later, it might already be readable.)
@@ -615,17 +615,17 @@
   uint32_t context = 0;
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // We'll try to pass this dispatcher.
   scoped_refptr<MessagePipeDispatcher> dispatcher =
       MessagePipeDispatcher::Create(
           MessagePipeDispatcher::kDefaultCreateOptions);
-  scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
-  dispatcher->Init(local_mp, 0);
+  auto local_mp = MessagePipe::CreateLocalLocal();
+  dispatcher->Init(local_mp.Clone(), 0);
 
   // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
   // it later, it might already be readable.)
@@ -769,8 +769,8 @@
   scoped_refptr<MessagePipeDispatcher> dispatcher =
       MessagePipeDispatcher::Create(
           MessagePipeDispatcher::kDefaultCreateOptions);
-  scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
-  dispatcher->Init(local_mp, 0);
+  auto local_mp = MessagePipe::CreateLocalLocal();
+  dispatcher->Init(local_mp.Clone(), 0);
 
   hss = local_mp->GetHandleSignalsState(0);
   EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
@@ -797,9 +797,9 @@
   local_mp->Close(1);
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
@@ -906,9 +906,9 @@
   uint32_t context = 0;
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // We'll try to pass this dispatcher.
@@ -1027,9 +1027,9 @@
   HandleSignalsState hss;
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   util::ScopedFILE fp(test_dir.CreateFile());
@@ -1126,11 +1126,11 @@
   for (unsigned i = 0; i < 256; i++) {
     DVLOG(2) << "---------------------------------------- " << i;
     RefPtr<ChannelEndpoint> ep0;
-    scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+    auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
     BootstrapChannelEndpointNoWait(0, std::move(ep0));
 
     RefPtr<ChannelEndpoint> ep1;
-    scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+    auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
     BootstrapChannelEndpointNoWait(1, std::move(ep1));
 
     if (i & 1u) {
@@ -1166,17 +1166,17 @@
   uint32_t context = 0;
 
   RefPtr<ChannelEndpoint> ep0;
-  scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
+  auto mp0 = MessagePipe::CreateLocalProxy(&ep0);
   RefPtr<ChannelEndpoint> ep1;
-  scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
+  auto mp1 = MessagePipe::CreateProxyLocal(&ep1);
   BootstrapChannelEndpoints(std::move(ep0), std::move(ep1));
 
   // We'll try to pass this dispatcher.
   scoped_refptr<MessagePipeDispatcher> dispatcher =
       MessagePipeDispatcher::Create(
           MessagePipeDispatcher::kDefaultCreateOptions);
-  scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
-  dispatcher->Init(local_mp, 0);
+  auto local_mp = MessagePipe::CreateLocalLocal();
+  dispatcher->Init(local_mp.Clone(), 0);
 
   // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
   // it later, it might already be readable.)
diff --git a/mojo/edk/system/simple_dispatcher_unittest.cc b/mojo/edk/system/simple_dispatcher_unittest.cc
index 3c91857..7f52e5e 100644
--- a/mojo/edk/system/simple_dispatcher_unittest.cc
+++ b/mojo/edk/system/simple_dispatcher_unittest.cc
@@ -62,7 +62,6 @@
   Type GetType() const override { return Type::UNKNOWN; }
 
  private:
-  friend class base::RefCountedThreadSafe<MockSimpleDispatcher>;
   ~MockSimpleDispatcher() override {}
 
   scoped_refptr<Dispatcher> CreateEquivalentDispatcherAndCloseImplNoLock()
diff --git a/mojo/edk/system/test_channel_endpoint_client.cc b/mojo/edk/system/test_channel_endpoint_client.cc
index 9f48a80..957fa96 100644
--- a/mojo/edk/system/test_channel_endpoint_client.cc
+++ b/mojo/edk/system/test_channel_endpoint_client.cc
@@ -14,10 +14,6 @@
 namespace system {
 namespace test {
 
-TestChannelEndpointClient::TestChannelEndpointClient()
-    : port_(0), read_event_(nullptr) {
-}
-
 void TestChannelEndpointClient::Init(unsigned port,
                                      RefPtr<ChannelEndpoint>&& endpoint) {
   MutexLocker locker(&mutex_);
@@ -72,6 +68,9 @@
   endpoint_ = nullptr;
 }
 
+TestChannelEndpointClient::TestChannelEndpointClient()
+    : port_(0), read_event_(nullptr) {}
+
 TestChannelEndpointClient::~TestChannelEndpointClient() {
   EXPECT_FALSE(endpoint_);
 }
diff --git a/mojo/edk/system/test_channel_endpoint_client.h b/mojo/edk/system/test_channel_endpoint_client.h
index 9965cf8..592e8ae 100644
--- a/mojo/edk/system/test_channel_endpoint_client.h
+++ b/mojo/edk/system/test_channel_endpoint_client.h
@@ -24,7 +24,7 @@
 
 class TestChannelEndpointClient final : public ChannelEndpointClient {
  public:
-  TestChannelEndpointClient();
+  // Note: Use |MakeRefCounted<TestChannelEndpointClient>()|.
 
   // Initializes with the given port and endpoint.
   void Init(unsigned port, RefPtr<ChannelEndpoint>&& endpoint);
@@ -48,6 +48,9 @@
   void OnDetachFromChannel(unsigned port) override;
 
  private:
+  FRIEND_MAKE_REF_COUNTED(TestChannelEndpointClient);
+
+  TestChannelEndpointClient();
   ~TestChannelEndpointClient() override;
 
   mutable Mutex mutex_;