Mojo: Introduce more new message APIs

Per the lazy serialization proposal[1].

Adds MojoSerializeMessage and MojoGetSerializedMessageContents.
Reworks MojoReadMessageNew to match the new spec of what will eventually
replace MojoReadMessage. Deletes MojoGetMessageBuffer.

Adapts bindings serialization and message code to new API behavior.

BUG=725321

Change-Id: I0c5302e018b63e47e4c89a3f4783ac0dc802172d
Reviewed-on: https://chromium-review.googlesource.com/528556
Reviewed-by: Jay Civelli <[email protected]>
Commit-Queue: Ken Rockot <[email protected]>
Cr-Commit-Position: refs/heads/master@{#479224}
diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc
index 50d6d67..445d0f2 100644
--- a/mojo/public/cpp/bindings/lib/message.cc
+++ b/mojo/public/cpp/bindings/lib/message.cc
@@ -44,9 +44,7 @@
       associated_endpoint_handles_(
           std::move(other.associated_endpoint_handles_)) {}
 
-Message::~Message() {
-  CloseHandles();
-}
+Message::~Message() {}
 
 Message& Message::operator=(Message&& other) {
   Reset();
@@ -57,7 +55,6 @@
 }
 
 void Message::Reset() {
-  CloseHandles();
   handles_.clear();
   associated_endpoint_handles_.clear();
   buffer_.reset();
@@ -70,7 +67,7 @@
 
 void Message::InitializeFromMojoMessage(ScopedMessageHandle message,
                                         uint32_t num_bytes,
-                                        std::vector<Handle>* handles) {
+                                        std::vector<ScopedHandle>* handles) {
   DCHECK(!buffer_);
   buffer_.reset(new internal::MessageBuffer(std::move(message), num_bytes));
   handles_.swap(*handles);
@@ -138,6 +135,10 @@
       MOJO_ALLOC_MESSAGE_FLAG_NONE,
       &new_message);
   CHECK_EQ(rv, MOJO_RESULT_OK);
+
+  // The handles are now owned by the message object.
+  for (auto& handle : handles_)
+    ignore_result(handle.release());
   handles_.clear();
 
   void* new_buffer = nullptr;
@@ -155,14 +156,6 @@
   buffer_->NotifyBadMessage(error);
 }
 
-void Message::CloseHandles() {
-  for (std::vector<Handle>::iterator it = handles_.begin();
-       it != handles_.end(); ++it) {
-    if (it->is_valid())
-      CloseRaw(*it);
-  }
-}
-
 void Message::SerializeAssociatedEndpointHandles(
     AssociatedGroupController* group_controller) {
   if (associated_endpoint_handles_.empty())
@@ -246,28 +239,18 @@
 }
 
 MojoResult ReadMessage(MessagePipeHandle handle, Message* message) {
-  MojoResult rv;
-
-  std::vector<Handle> handles;
   ScopedMessageHandle mojo_message;
-  uint32_t num_bytes = 0, num_handles = 0;
-  rv = ReadMessageNew(handle,
-                      &mojo_message,
-                      &num_bytes,
-                      nullptr,
-                      &num_handles,
-                      MOJO_READ_MESSAGE_FLAG_NONE);
-  if (rv == MOJO_RESULT_RESOURCE_EXHAUSTED) {
-    DCHECK_GT(num_handles, 0u);
-    handles.resize(num_handles);
-    rv = ReadMessageNew(handle,
-                        &mojo_message,
-                        &num_bytes,
-                        reinterpret_cast<MojoHandle*>(handles.data()),
-                        &num_handles,
-                        MOJO_READ_MESSAGE_FLAG_NONE);
-  }
+  MojoResult rv =
+      ReadMessageNew(handle, &mojo_message, MOJO_READ_MESSAGE_FLAG_NONE);
+  if (rv != MOJO_RESULT_OK)
+    return rv;
 
+  uint32_t num_bytes = 0;
+  void* buffer;
+  std::vector<ScopedHandle> handles;
+  rv = GetSerializedMessageContents(
+      mojo_message.get(), &buffer, &num_bytes, &handles,
+      MOJO_GET_SERIALIZED_MESSAGE_CONTENTS_FLAG_NONE);
   if (rv != MOJO_RESULT_OK)
     return rv;