diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index ccc72a1..bf6f2fe 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -39,7 +39,8 @@
     src/android/os/cts/IParcelFileDescriptorPeer.aidl \
     src/android/os/cts/IEmptyService.aidl \
     src/android/os/cts/ISeccompIsolatedService.aidl \
-    src/android/os/cts/ISecondary.aidl
+    src/android/os/cts/ISecondary.aidl \
+    src/android/os/cts/ISharedMemoryService.aidl
 
 LOCAL_PACKAGE_NAME := CtsOsTestCases
 
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index 846251f..a227cc3 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -76,6 +76,10 @@
             android:name="android.os.cts.CrossProcessExceptionService"
             android:process=":green"
             android:exported="true" />
+        <service
+            android:name="android.os.cts.SharedMemoryService"
+            android:process=":sharedmem"
+            android:exported="false" />
 
         <service android:name="android.os.cts.LocalService">
             <intent-filter>
diff --git a/tests/tests/os/src/android/os/cts/ISharedMemoryService.aidl b/tests/tests/os/src/android/os/cts/ISharedMemoryService.aidl
new file mode 100644
index 0000000..651c62a
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ISharedMemoryService.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import android.os.SharedMemory;
+
+interface ISharedMemoryService {
+    void setup(in SharedMemory memory, int prot);
+    byte read(int index);
+    void write(int index, byte value);
+}
diff --git a/tests/tests/os/src/android/os/cts/MemoryFileTest.java b/tests/tests/os/src/android/os/cts/MemoryFileTest.java
index def73b2..6e6eba8 100644
--- a/tests/tests/os/src/android/os/cts/MemoryFileTest.java
+++ b/tests/tests/os/src/android/os/cts/MemoryFileTest.java
@@ -56,7 +56,7 @@
             byte[] data = new byte[512];
             mMemoryFile.writeBytes(data, srcOffset, destOffset, count);
             fail("MemoryFile should throw IndexOutOfBoundsException here.");
-        } catch (IndexOutOfBoundsException e) {
+        } catch (IndexOutOfBoundsException | IllegalArgumentException e) {
             // expected
         }
     }
@@ -101,13 +101,10 @@
         mMemoryFile = new MemoryFile("Test File", 512);
         assertEquals(512, mMemoryFile.length());
 
-        mMemoryFile = new MemoryFile("Test File", 0);
-        assertEquals(0, mMemoryFile.length());
-
         try {
             mMemoryFile = new MemoryFile("Test File", -512);
             fail();
-        } catch (IOException expected) {
+        } catch (IOException | IllegalArgumentException expected) {
         }
     }
 
@@ -142,7 +139,7 @@
             byte[] data = new byte[512];
             mMemoryFile.readBytes(data, srcOffset, destOffset, count);
             fail("MemoryFile should throw IndexOutOfBoundsException here.");
-        } catch (IndexOutOfBoundsException e) {
+        } catch (IndexOutOfBoundsException | IllegalArgumentException e) {
             // expected
         }
     }
diff --git a/tests/tests/os/src/android/os/cts/SharedMemoryService.java b/tests/tests/os/src/android/os/cts/SharedMemoryService.java
new file mode 100644
index 0000000..fcc38d5
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/SharedMemoryService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SharedMemory;
+import android.system.ErrnoException;
+
+import java.nio.ByteBuffer;
+
+public class SharedMemoryService extends Service {
+    @Override
+    public IBinder onBind(Intent intent) {
+        return new SharedMemoryServiceImpl();
+    }
+
+    private static class SharedMemoryServiceImpl extends ISharedMemoryService.Stub {
+        private SharedMemory mSharedMemory;
+        private ByteBuffer mMappedBuffer;
+
+        @Override
+        public void setup(SharedMemory memory, int prot) throws RemoteException {
+            mSharedMemory = memory;
+            try {
+                mMappedBuffer = mSharedMemory.map(prot, 0, mSharedMemory.getSize());
+            } catch (ErrnoException ex) {
+                throw new RuntimeException(ex);
+            }
+        }
+
+        @Override
+        public byte read(int index) throws RemoteException {
+            // Although we expect only one client we need to insert memory barriers to ensure
+            // visibility
+            synchronized (mMappedBuffer) {
+                return mMappedBuffer.get(index);
+            }
+        }
+
+        @Override
+        public void write(int index, byte value) throws RemoteException {
+            // Although we expect only one client we need to insert memory barriers to ensure
+            // visibility
+            synchronized (mMappedBuffer) {
+                mMappedBuffer.put(index, value);
+            }
+        }
+    }
+}
diff --git a/tests/tests/os/src/android/os/cts/SharedMemoryTest.java b/tests/tests/os/src/android/os/cts/SharedMemoryTest.java
new file mode 100644
index 0000000..c40cdc8
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/SharedMemoryTest.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import static android.support.test.InstrumentationRegistry.getContext;
+import static android.system.OsConstants.PROT_READ;
+import static android.system.OsConstants.PROT_WRITE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SharedMemory;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+
+import com.google.common.util.concurrent.AbstractFuture;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SharedMemoryTest {
+
+    private Instrumentation mInstrumentation;
+    private Intent mRemoteIntent;
+    private PeerConnection mRemoteConnection;
+    private ISharedMemoryService mRemote;
+
+    public static class PeerConnection extends AbstractFuture<ISharedMemoryService>
+            implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            set(ISharedMemoryService.Stub.asInterface(service));
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+
+        @Override
+        public ISharedMemoryService get() throws InterruptedException, ExecutionException {
+            try {
+                return get(5, TimeUnit.SECONDS);
+            } catch (TimeoutException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        final Context context = mInstrumentation.getContext();
+        // Bring up both remote processes and wire them to each other
+        mRemoteIntent = new Intent();
+        mRemoteIntent.setComponent(new ComponentName(
+                "android.os.cts", "android.os.cts.SharedMemoryService"));
+        mRemoteConnection = new PeerConnection();
+        getContext().bindService(mRemoteIntent, mRemoteConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT);
+        mRemote = mRemoteConnection.get();
+    }
+
+    @After
+    public void tearDown() {
+        final Context context = mInstrumentation.getContext();
+        context.unbindService(mRemoteConnection);
+    }
+
+    @Test
+    public void testReadWrite() throws RemoteException, ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            ByteBuffer buffer = sharedMemory.mapReadWrite();
+            mRemote.setup(sharedMemory, PROT_READ | PROT_WRITE);
+
+            byte expected = 5;
+            buffer.put(0, expected);
+            assertEquals(expected, buffer.get(0));
+            // Memory barrier
+            synchronized (sharedMemory) {}
+            assertEquals(expected, mRemote.read(0));
+            expected = 10;
+            mRemote.write(0, expected);
+            // Memory barrier
+            synchronized (sharedMemory) {}
+            assertEquals(expected, buffer.get(0));
+            SharedMemory.unmap(buffer);
+        }
+    }
+
+    @Test
+    public void testReadOnly() throws RemoteException, ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            ByteBuffer buffer = sharedMemory.mapReadWrite();
+            sharedMemory.setProtect(PROT_READ);
+            mRemote.setup(sharedMemory, PROT_READ);
+
+            byte expected = 15;
+            buffer.put(0, expected);
+            assertEquals(expected, buffer.get(0));
+            // Memory barrier
+            synchronized (sharedMemory) {}
+            assertEquals(expected, mRemote.read(0));
+            expected = 20;
+            try {
+                mRemote.write(0, expected);
+                fail("write shouldn't have worked, should be read only");
+            } catch (Exception e) {}
+
+            buffer.put(0, expected);
+            assertEquals(expected, buffer.get(0));
+            // Memory barrier
+            synchronized (sharedMemory) {}
+            assertEquals(expected, mRemote.read(0));
+        }
+    }
+
+    @Test
+    public void testUseAfterClose() throws RemoteException, ErrnoException {
+        ByteBuffer buffer;
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            buffer = sharedMemory.mapReadWrite();
+            mRemote.setup(sharedMemory, PROT_READ | PROT_WRITE);
+        }
+        byte expected = 5;
+        buffer.put(0, expected);
+        assertEquals(expected, buffer.get(0));
+        // Memory barrier
+        synchronized (buffer) {}
+        assertEquals(expected, mRemote.read(0));
+        expected = 10;
+        mRemote.write(0, expected);
+        // Memory barrier
+        synchronized (buffer) {}
+        assertEquals(expected, buffer.get(0));
+        SharedMemory.unmap(buffer);
+    }
+
+    @Test
+    public void testGetFd() throws ErrnoException {
+        SharedMemory sharedMemory = SharedMemory.create("hello", 1024);
+        assertNotEquals(-1, sharedMemory.getFd());
+        assertNotNull(sharedMemory.getFileDescriptor());
+        assertTrue(sharedMemory.getFileDescriptor().valid());
+        sharedMemory.close();
+        assertEquals(-1, sharedMemory.getFd());
+        assertNotNull(sharedMemory.getFileDescriptor());
+        assertTrue(!sharedMemory.getFileDescriptor().valid());
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testInvalidCreate() throws ErrnoException {
+        SharedMemory.create(null, -1);
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testInvalidMapProt() throws ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            sharedMemory.map(-1, 0, 1);
+        }
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testInvalidSetProt() throws ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            sharedMemory.setProtect(-1);
+        }
+    }
+
+    @Test
+    public void testSetProtAddProt() throws ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            assertTrue(sharedMemory.setProtect(OsConstants.PROT_READ));
+            assertTrue(sharedMemory.setProtect(OsConstants.PROT_READ));
+            assertFalse(sharedMemory.setProtect(OsConstants.PROT_READ | OsConstants.PROT_WRITE));
+            assertTrue(sharedMemory.setProtect(OsConstants.PROT_NONE));
+            assertFalse(sharedMemory.setProtect(OsConstants.PROT_READ));
+        }
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void testMapAfterClose() throws ErrnoException {
+        SharedMemory sharedMemory = SharedMemory.create(null, 1);
+        sharedMemory.close();
+        sharedMemory.mapReadWrite();
+    }
+
+    @Test(expected=ReadOnlyBufferException.class)
+    public void testWriteToReadOnly() throws ErrnoException {
+        try (SharedMemory sharedMemory = SharedMemory.create(null, 1)) {
+            sharedMemory.setProtect(PROT_READ);
+            ByteBuffer buffer = null;
+            try {
+                buffer = sharedMemory.mapReadWrite();
+                fail("Should have thrown an exception");
+            } catch (ErrnoException ex) {
+                assertEquals(OsConstants.EPERM, ex.errno);
+            }
+            buffer = sharedMemory.mapReadOnly();
+            assertTrue(buffer.isReadOnly());
+            buffer.put(0, (byte) 0);
+        }
+    }
+}
