Polish MemoryIntArray

1. Add close guard
2. Adopt instead of clone the ahsmem fd to fix a dangling fd
3. Clear only the return flag when writing fd to parcel
4. Immediately destroy remote MemoryIntArray if stale
5. Throw Java exception if someone closed the fd under us

Change-Id: I85533fec336c40e3380e10d5448e18c9616ec341
diff --git a/core/jni/android_util_MemoryIntArray.cpp b/core/jni/android_util_MemoryIntArray.cpp
index f45be12..9513c8b 100644
--- a/core/jni/android_util_MemoryIntArray.cpp
+++ b/core/jni/android_util_MemoryIntArray.cpp
@@ -61,6 +61,11 @@
         return -1;
     }
 
+    if (!ashmem_valid(fd)) {
+        jniThrowIOException(env, errno);
+        return -1;
+    }
+
     int ashmemSize = ashmem_get_size_region(fd);
     if (ashmemSize <= 0) {
         jniThrowException(env, "java/io/IOException", "bad ashmem size");
@@ -98,6 +103,11 @@
         return;
     }
 
+    if (!ashmem_valid(fd)) {
+        jniThrowIOException(env, errno);
+        return;
+    }
+
     int ashmemSize = ashmem_get_size_region(fd);
     if (ashmemSize <= 0) {
         jniThrowException(env, "java/io/IOException", "bad ashmem size");
@@ -128,6 +138,11 @@
         return -1;
     }
 
+    if (!ashmem_valid(fd)) {
+        jniThrowIOException(env, errno);
+        return -1;
+    }
+
     if (ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {
         jniThrowException(env, "java/io/IOException", "ashmem region was purged");
         return -1;
@@ -145,6 +160,11 @@
         return;
     }
 
+    if (!ashmem_valid(fd)) {
+        jniThrowIOException(env, errno);
+        return;
+    }
+
     if (ashmem_pin_region(fd, 0, 0) == ASHMEM_WAS_PURGED) {
         jniThrowException(env, "java/io/IOException", "ashmem region was purged");
         return;
@@ -160,17 +180,13 @@
         return -1;
     }
 
-    // Use ASHMEM_GET_SIZE to find out if the fd refers to an ashmem region.
-    // ASHMEM_GET_SIZE should succeed for all ashmem regions, and the kernel
-    // should return ENOTTY for all other valid file descriptors
+    if (!ashmem_valid(fd)) {
+        jniThrowIOException(env, errno);
+        return -1;
+    }
+
     int ashmemSize = ashmem_get_size_region(fd);
     if (ashmemSize < 0) {
-        if (errno == ENOTTY) {
-            // ENOTTY means that the ioctl does not apply to this object,
-            // i.e., it is not an ashmem region.
-            return -1;
-        }
-        // Some other error, throw exception
         jniThrowIOException(env, errno);
         return -1;
     }