Fixes for libcore.java.nio.BufferTest

- Added missing MappedByteBuffer native methods
- Fixed RandomAccessFile#getChannel permissions
- Disabled ByteBuffer#set/isAccessible parts of
BufferTest
- Marked set/isAccessible for removal (it will
be reimplemented in the framework).

Change-Id: I7d1999b35600ff45dd448a8b3671d9373559c1aa
diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java
index ed337d3..860c071 100644
--- a/luni/src/test/java/libcore/java/nio/BufferTest.java
+++ b/luni/src/test/java/libcore/java/nio/BufferTest.java
@@ -619,7 +619,7 @@
     // http://b/16449607
     public void testDirectByteBufferAlignment() throws Exception {
         ByteBuffer b = ByteBuffer.allocateDirect(10);
-        Field addressField = Buffer.class.getDeclaredField("effectiveDirectAddress");
+        Field addressField = Buffer.class.getDeclaredField("address");
         assertTrue(addressField != null);
         addressField.setAccessible(true);
         long address = addressField.getLong(b);
@@ -889,7 +889,7 @@
         ByteBuffer b2 = b1.duplicate();
         NioUtils.freeDirectBuffer(b1);
         for (ByteBuffer b: new ByteBuffer[] { b1, b2 }) {
-            assertFalse(b.isAccessible());
+          //assertFalse(b.isAccessible());
             try {
                 b.compact();
                 fail();
@@ -907,6 +907,7 @@
         }
     }
 
+    /* setAccessible is not available in OpenJdk's buffers.
     public void testAccess() {
         ByteBuffer b1 = ByteBuffer.allocate(1);
         ByteBuffer b2 = b1.duplicate();
@@ -990,7 +991,7 @@
             testAsMethods(b);
             testGetMethods(b);
         }
-    }
+        }*/
 
     private void testPutMethods(ByteBuffer b) {
         b.position(0);
diff --git a/ojluni/src/main/java/java/io/RandomAccessFile.java b/ojluni/src/main/java/java/io/RandomAccessFile.java
index bb93e88..d2b06d3 100755
--- a/ojluni/src/main/java/java/io/RandomAccessFile.java
+++ b/ojluni/src/main/java/java/io/RandomAccessFile.java
@@ -30,7 +30,6 @@
 import sun.misc.IoTrace;
 import android.system.ErrnoException;
 import dalvik.system.CloseGuard;
-import java.nio.NioUtils;
 import libcore.io.IoBridge;
 import libcore.io.Libcore;
 import static android.system.OsConstants.*;
@@ -289,7 +288,17 @@
     public final FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
-                channel = NioUtils.newFileChannel(this, fd, mode);
+                channel = FileChannelImpl.open(fd, path, true, rw, this);
+                /*
+                 * FileDescriptor could be shared by FileInputStream or
+                 * FileOutputStream.
+                 * Ensure that FD is GC'ed only when all the streams/channels
+                 * are done using it.
+                 * Increment fd's use count. Invoking the channel's close()
+                 * method will result in decrementing the use count set for
+                 * the channel.
+                 */
+                // fd.incrementAndGetUseCount();
             }
             return channel;
         }
diff --git a/ojluni/src/main/java/java/nio/ByteBuffer.java b/ojluni/src/main/java/java/nio/ByteBuffer.java
index 0e66299..6739610 100644
--- a/ojluni/src/main/java/java/nio/ByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/ByteBuffer.java
@@ -2035,6 +2035,8 @@
     public abstract DoubleBuffer asDoubleBuffer();
 
     // ----- BEGIN android -----
+    // TODO(pszczepaniak): Remove these after adding this functionality
+    // in the framework
     /**
      * @hide
      */
@@ -2048,5 +2050,4 @@
         throw new UnsupportedOperationException();
     }
     // ----- END android -----
-
 }
diff --git a/ojluni/src/main/java/java/nio/DirectByteBuffer.java b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
index ff2382a..cd0d201 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -105,9 +105,6 @@
             unsafe.freeMemory(address);
             address = 0;
             Bits.unreserveMemory(size, capacity);
-            // ----- BEGIN android -----
-            DirectByteBuffer.this.freed = true;
-            // ----- END android -----
         }
 
     }
@@ -1035,6 +1032,8 @@
     }
 
     // ----- BEGIN android -----
+    // TODO(pszczepaniak): Remove these after adding this functionality
+    // in the framework
     private boolean accessible = true;
     private boolean freed = false;
     /**
@@ -1050,5 +1049,4 @@
         return accessible && !freed;
     }
     // ----- END android -----
-
 }
diff --git a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
index 9ac1220..0cdcd91 100755
--- a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
@@ -37,6 +37,11 @@
 import sun.misc.IoTrace;
 import sun.security.action.GetPropertyAction;
 
+// ----- BEGIN android -----
+import android.system.ErrnoException;
+import libcore.io.Libcore;
+// ----- END android -----
+
 public class FileChannelImpl
     extends FileChannel
 {
@@ -848,13 +853,33 @@
             if (!isOpen())
                 return null;
             if (size() < position + size) { // Extend file size
+                /* ----- BEGIN android -----
                 if (!writable) {
                     throw new IOException("Channel not open for writing " +
                         "- cannot extend file to required size");
                 }
-                int rv;
+                ----- END android ----- */
+                int rv = 0;
                 do {
-                    rv = nd.truncate(fd, position + size);
+                    // ----- BEGIN android -----
+                    //int rv = nd.truncate(fd, position + size);
+                    try {
+                        rv = nd.truncate(fd, position + size);
+                    } catch (IOException r) {
+                        try {
+                            // If we're dealing with non-regular files, for example,
+                            // character devices such as /dev/zero. In those
+                            // cases, we ignore the failed truncation and continue
+                            // on.
+                            if (android.system.OsConstants.S_ISREG(Libcore.os.fstat(fd).st_mode)) {
+                                throw r;
+                            }
+                        } catch (ErrnoException e) {
+                            e.rethrowAsIOException();
+                        }
+                        break;
+                    }
+                    // ----- END android -----
                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
             }
             if (size == 0) {
diff --git a/ojluni/src/main/native/MappedByteBuffer.c b/ojluni/src/main/native/MappedByteBuffer.c
new file mode 100644
index 0000000..70e833b
--- /dev/null
+++ b/ojluni/src/main/native/MappedByteBuffer.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+#include "java_nio_MappedByteBuffer.h"
+#include <sys/mman.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "JNIHelp.h"
+
+#define NATIVE_METHOD(className, functionName, signature) \
+{ #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) }
+
+JNIEXPORT jboolean JNICALL
+Java_java_nio_MappedByteBuffer_isLoaded0(JNIEnv *env, jobject obj, jlong address,
+                                         jlong len, jint numPages)
+{
+    jboolean loaded = JNI_TRUE;
+    int result = 0;
+    int i = 0;
+    void *a = (void *) jlong_to_ptr(address);
+#ifdef __linux__
+    unsigned char *vec = (unsigned char *)malloc(numPages * sizeof(char));
+#else
+    char *vec = (char *)malloc(numPages * sizeof(char));
+#endif
+
+    if (vec == NULL) {
+        JNU_ThrowOutOfMemoryError(env, NULL);
+        return JNI_FALSE;
+    }
+
+    result = mincore(a, (size_t)len, vec);
+    if (result == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "mincore failed");
+        free(vec);
+        return JNI_FALSE;
+    }
+
+    for (i=0; i<numPages; i++) {
+        if (vec[i] == 0) {
+            loaded = JNI_FALSE;
+            break;
+        }
+    }
+    free(vec);
+    return loaded;
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBuffer_load0(JNIEnv *env, jobject obj, jlong address,
+                                     jlong len)
+{
+    char *a = (char *)jlong_to_ptr(address);
+    int result = madvise((caddr_t)a, (size_t)len, MADV_WILLNEED);
+    if (result == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "madvise failed");
+    }
+}
+
+
+JNIEXPORT void JNICALL
+Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo,
+                                      jlong address, jlong len)
+{
+    void* a = (void *)jlong_to_ptr(address);
+    int result = msync(a, (size_t)len, MS_SYNC);
+    if (result == -1) {
+        JNU_ThrowIOExceptionWithLastError(env, "msync failed");
+    }
+}
+
+
+static JNINativeMethod gMethods[] = {
+  NATIVE_METHOD(MappedByteBuffer, isLoaded0, "(JJI)Z"),
+  NATIVE_METHOD(MappedByteBuffer, load0, "(JJ)V"),
+  NATIVE_METHOD(MappedByteBuffer, force0, "(Ljava/io/FileDescriptor;JJ)V"),
+};
+
+void register_java_nio_MappedByteBuffer(JNIEnv* env) {
+  jniRegisterNativeMethods(env, "java/nio/MappedByteBuffer", gMethods, NELEM(gMethods));
+}
diff --git a/ojluni/src/main/native/Register.cpp b/ojluni/src/main/native/Register.cpp
index ce77073..229e7b8 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -51,6 +51,7 @@
 extern void register_java_net_PlainSocketImpl(JNIEnv*);
 extern void register_java_net_SocketInputStream(JNIEnv*);
 extern void register_java_net_SocketOutputStream(JNIEnv*);
+extern void register_java_nio_MappedByteBuffer(JNIEnv* env);
 extern void register_java_util_zip_Adler32(JNIEnv* env);
 extern void register_java_util_zip_CRC32(JNIEnv*);
 extern void register_java_util_zip_Deflater(JNIEnv*);
@@ -70,6 +71,7 @@
 extern void register_sun_nio_ch_SocketChannelImpl(JNIEnv* env);
 extern void register_sun_nio_ch_InheritedChannel(JNIEnv* env);
 extern void register_sun_nio_ch_EPollArrayWrapper(JNIEnv* env);
+
 extern jint net_JNI_OnLoad(JavaVM*, void*);
 
 }
@@ -127,6 +129,7 @@
     register_sun_nio_ch_Net(env);
     register_sun_nio_ch_DatagramChannelImpl(env);
     register_sun_nio_ch_EPollArrayWrapper(env);
+    register_java_nio_MappedByteBuffer(env);
     net_JNI_OnLoad(vm, NULL);
     return JNI_VERSION_1_6;
 }
diff --git a/ojluni/src/main/native/java_nio_MappedByteBuffer.h b/ojluni/src/main/native/java_nio_MappedByteBuffer.h
new file mode 100644
index 0000000..f1b0070
--- /dev/null
+++ b/ojluni/src/main/native/java_nio_MappedByteBuffer.h
@@ -0,0 +1,37 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class java_nio_MappedByteBuffer */
+
+#ifndef _Included_java_nio_MappedByteBuffer
+#define _Included_java_nio_MappedByteBuffer
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     java_nio_MappedByteBuffer
+ * Method:    isLoaded0
+ * Signature: (JJI)Z
+ */
+JNIEXPORT jboolean JNICALL Java_java_nio_MappedByteBuffer_isLoaded0
+  (JNIEnv *, jobject, jlong, jlong, jint);
+
+/*
+ * Class:     java_nio_MappedByteBuffer
+ * Method:    load0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_java_nio_MappedByteBuffer_load0
+  (JNIEnv *, jobject, jlong, jlong);
+
+/*
+ * Class:     java_nio_MappedByteBuffer
+ * Method:    force0
+ * Signature: (Ljava/io/FileDescriptor;JJ)V
+ */
+JNIEXPORT void JNICALL Java_java_nio_MappedByteBuffer_force0
+  (JNIEnv *, jobject, jobject, jlong, jlong);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ojluni/src/main/native/openjdksub.mk b/ojluni/src/main/native/openjdksub.mk
index d412c23..5c50252 100644
--- a/ojluni/src/main/native/openjdksub.mk
+++ b/ojluni/src/main/native/openjdksub.mk
@@ -36,6 +36,7 @@
     net_util.c \
     net_util_md.c \
     Net.c \
+    MappedByteBuffer.c \
     Inet6Address.c \
     Inet4Address.c \
     linux_close.c \