EDK: Add Core::GetRights().

Don't actually plumb it out yet. I'll do that separately.

R=azani@chromium.org

Review URL: https://codereview.chromium.org/1993983002 .
diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc
index 65eb073..f1c869f 100644
--- a/mojo/edk/system/core.cc
+++ b/mojo/edk/system/core.cc
@@ -175,6 +175,17 @@
   return h.dispatcher->Close();
 }
 
+MojoResult Core::GetRights(MojoHandle handle,
+                           UserPointer<MojoHandleRights> rights) {
+  Handle h;
+  MojoResult result = GetHandle(handle, &h);
+  if (result != MOJO_RESULT_OK)
+    return result;
+
+  rights.Put(h.rights);
+  return MOJO_RESULT_OK;
+}
+
 MojoResult Core::Wait(MojoHandle handle,
                       MojoHandleSignals signals,
                       MojoDeadline deadline,
diff --git a/mojo/edk/system/core.h b/mojo/edk/system/core.h
index 74c5f47..a97010f 100644
--- a/mojo/edk/system/core.h
+++ b/mojo/edk/system/core.h
@@ -116,6 +116,7 @@
   // This method corresponds to the API function defined in
   // "mojo/public/c/system/handle.h":
   MojoResult Close(MojoHandle handle);
+  MojoResult GetRights(MojoHandle handle, UserPointer<MojoHandleRights> rights);
 
   // These methods correspond to the API functions defined in
   // "mojo/public/c/system/wait.h":
diff --git a/mojo/edk/system/core_test_base.cc b/mojo/edk/system/core_test_base.cc
index 1f982ec..0bddeaa 100644
--- a/mojo/edk/system/core_test_base.cc
+++ b/mojo/edk/system/core_test_base.cc
@@ -208,6 +208,9 @@
 
 // CoreTestBase ----------------------------------------------------------------
 
+// static
+constexpr MojoHandleRights CoreTestBase::kDefaultMockHandleRights;
+
 CoreTestBase::CoreTestBase()
     : platform_support_(embedder::CreateSimplePlatformSupport()) {}
 
diff --git a/mojo/edk/system/core_test_base.h b/mojo/edk/system/core_test_base.h
index a3dd3fd..4dde782 100644
--- a/mojo/edk/system/core_test_base.h
+++ b/mojo/edk/system/core_test_base.h
@@ -32,6 +32,13 @@
  public:
   using MockHandleInfo = CoreTestBase_MockHandleInfo;
 
+  static constexpr MojoHandleRights kDefaultMockHandleRights =
+      MOJO_HANDLE_RIGHT_DUPLICATE | MOJO_HANDLE_RIGHT_TRANSFER |
+      MOJO_HANDLE_RIGHT_READ | MOJO_HANDLE_RIGHT_WRITE |
+      MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS |
+      MOJO_HANDLE_RIGHT_MAP_READABLE | MOJO_HANDLE_RIGHT_MAP_WRITABLE |
+      MOJO_HANDLE_RIGHT_MAP_EXECUTABLE;
+
   CoreTestBase();
   ~CoreTestBase() override;
 
diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc
index 1b3c1fa..745b5af 100644
--- a/mojo/edk/system/core_unittest.cc
+++ b/mojo/edk/system/core_unittest.cc
@@ -44,6 +44,10 @@
   EXPECT_EQ(1u, info.GetCtorCallCount());
   EXPECT_NE(h, MOJO_HANDLE_INVALID);
 
+  MojoHandleRights rights = 0;
+  EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h, MakeUserPointer(&rights)));
+  EXPECT_EQ(kDefaultMockHandleRights, rights);
+
   EXPECT_EQ(0u, info.GetWriteMessageCallCount());
   EXPECT_EQ(MOJO_RESULT_OK,
             core()->WriteMessage(h, NullUserPointer(), 0, NullUserPointer(), 0,
@@ -204,6 +208,17 @@
     EXPECT_EQ(1u, info.GetCloseCallCount());
   }
 
+  // |GetRights()|:
+  {
+    MojoHandleRights rights = 0;
+    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+              core()->GetRights(MOJO_HANDLE_INVALID, MakeUserPointer(&rights)));
+    EXPECT_EQ(0u, rights);
+    EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
+              core()->GetRights(10, MakeUserPointer(&rights)));
+    EXPECT_EQ(0u, rights);
+  }
+
   // |Wait()|:
   {
     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
@@ -556,6 +571,16 @@
 TEST_F(CoreTest, InvalidArgumentsDeath) {
   const char kMemoryCheckFailedRegex[] = "Check failed";
 
+  // |GetRights()|:
+  {
+    MockHandleInfo info;
+    MojoHandle h = CreateMockHandle(&info);
+    EXPECT_DEATH_IF_SUPPORTED(core()->GetRights(h, NullUserPointer()),
+                              kMemoryCheckFailedRegex);
+
+    EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
+  }
+
   // |WaitMany()|:
   {
     MojoHandle handle = MOJO_HANDLE_INVALID;
@@ -632,7 +657,7 @@
 //    same/different signals)
 
 TEST_F(CoreTest, MessagePipe) {
-  MojoHandle h[2];
+  MojoHandle h[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID};
   MojoHandleSignalsState hss[2];
   uint32_t result_index;
 
@@ -644,6 +669,18 @@
   EXPECT_NE(h[1], MOJO_HANDLE_INVALID);
   EXPECT_NE(h[0], h[1]);
 
+  // Both should have the correct rights.
+  static const MojoHandleRights kMessagePipeHandleRights =
+      MOJO_HANDLE_RIGHT_TRANSFER | MOJO_HANDLE_RIGHT_READ |
+      MOJO_HANDLE_RIGHT_WRITE | MOJO_HANDLE_RIGHT_GET_OPTIONS |
+      MOJO_HANDLE_RIGHT_SET_OPTIONS;
+  MojoHandleRights rights = MOJO_HANDLE_RIGHT_NONE;
+  EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h[0], MakeUserPointer(&rights)));
+  EXPECT_EQ(kMessagePipeHandleRights, rights);
+  rights = MOJO_HANDLE_RIGHT_NONE;
+  EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(h[1], MakeUserPointer(&rights)));
+  EXPECT_EQ(kMessagePipeHandleRights, rights);
+
   // Neither should be readable.
   MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE,
                                   MOJO_HANDLE_SIGNAL_READABLE};
@@ -976,7 +1013,9 @@
 }
 
 TEST_F(CoreTest, DataPipe) {
-  MojoHandle ph, ch;  // p is for producer and c is for consumer.
+  // p is for producer and c is for consumer.
+  MojoHandle ph = MOJO_HANDLE_INVALID;
+  MojoHandle ch = MOJO_HANDLE_INVALID;
   MojoHandleSignalsState hss;
 
   EXPECT_EQ(MOJO_RESULT_OK,
@@ -987,6 +1026,20 @@
   EXPECT_NE(ch, MOJO_HANDLE_INVALID);
   EXPECT_NE(ph, ch);
 
+  // Both should have the correct rights.
+  static const MojoHandleRights kDataPipeProducerHandleRights =
+      MOJO_HANDLE_RIGHT_TRANSFER | MOJO_HANDLE_RIGHT_WRITE |
+      MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS;
+  static const MojoHandleRights kDataPipeConsumerHandleRights =
+      MOJO_HANDLE_RIGHT_TRANSFER | MOJO_HANDLE_RIGHT_READ |
+      MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS;
+  MojoHandleRights rights = MOJO_HANDLE_RIGHT_NONE;
+  EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(ph, MakeUserPointer(&rights)));
+  EXPECT_EQ(kDataPipeProducerHandleRights, rights);
+  rights = MOJO_HANDLE_RIGHT_NONE;
+  EXPECT_EQ(MOJO_RESULT_OK, core()->GetRights(ch, MakeUserPointer(&rights)));
+  EXPECT_EQ(kDataPipeConsumerHandleRights, rights);
+
   // Producer should be never-readable, but already writable.
   hss = kEmptyMojoHandleSignalsState;
   EXPECT_EQ(
@@ -1681,7 +1734,8 @@
   EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h));
 }
 
-// TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|.
+// TODO(vtl): Test |CreateSharedBuffer()|, |DuplicateBufferHandle()|, and
+// |MapBuffer()|.
 
 }  // namespace
 }  // namespace system