Use libcore Posix class for StatFs implementation

Remove some JNI and duplicated functionality and use libcore's Posix
class for the statfs function instead.

Change-Id: Ic1e161dc10c18c2c6ee81d895a0efd8910086dbf
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 912bfdf..ca7fdba 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -16,59 +16,77 @@
 
 package android.os;
 
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStatFs;
+
 /**
- * Retrieve overall information about the space on a filesystem.  This is a
- * Wrapper for Unix statfs().
+ * Retrieve overall information about the space on a filesystem. This is a
+ * wrapper for Unix statfs().
  */
 public class StatFs {
-    /**
-     * Construct a new StatFs for looking at the stats of the
-     * filesystem at <var>path</var>.  Upon construction, the stat of
-     * the file system will be performed, and the values retrieved available
-     * from the methods on this class.
-     * 
-     * @param path A path in the desired file system to state.
-     */
-    public StatFs(String path) { native_setup(path); }
-    
-    /**
-     * Perform a restat of the file system referenced by this object.  This
-     * is the same as re-constructing the object with the same file system
-     * path, and the new stat values are available upon return.
-     */
-    public void restat(String path) { native_restat(path); }
-
-    @Override
-    protected void finalize() { native_finalize(); }
+    private StructStatFs mStat;
 
     /**
-     * The size, in bytes, of a block on the file system.  This corresponds
-     * to the Unix statfs.f_bsize field.
+     * Construct a new StatFs for looking at the stats of the filesystem at
+     * {@code path}. Upon construction, the stat of the file system will be
+     * performed, and the values retrieved available from the methods on this
+     * class.
+     *
+     * @param path path in the desired file system to stat.
      */
-    public native int getBlockSize();
+    public StatFs(String path) {
+        mStat = doStat(path);
+    }
+
+    private static StructStatFs doStat(String path) {
+        try {
+            return Libcore.os.statfs(path);
+        } catch (ErrnoException e) {
+            throw new IllegalArgumentException("Invalid path: " + path, e);
+        }
+    }
 
     /**
-     * The total number of blocks on the file system.  This corresponds
-     * to the Unix statfs.f_blocks field.
+     * Perform a restat of the file system referenced by this object. This is
+     * the same as re-constructing the object with the same file system path,
+     * and the new stat values are available upon return.
      */
-    public native int getBlockCount();
+    public void restat(String path) {
+        mStat = doStat(path);
+    }
+
+    /**
+     * The size, in bytes, of a block on the file system. This corresponds to
+     * the Unix {@code statfs.f_bsize} field.
+     */
+    public int getBlockSize() {
+        return (int) mStat.f_bsize;
+    }
+
+    /**
+     * The total number of blocks on the file system. This corresponds to the
+     * Unix {@code statfs.f_blocks} field.
+     */
+    public int getBlockCount() {
+        return (int) mStat.f_blocks;
+    }
 
     /**
      * The total number of blocks that are free on the file system, including
-     * reserved blocks (that are not available to normal applications).  This
-     * corresponds to the Unix statfs.f_bfree field.  Most applications will
-     * want to use {@link #getAvailableBlocks()} instead.
+     * reserved blocks (that are not available to normal applications). This
+     * corresponds to the Unix {@code statfs.f_bfree} field. Most applications
+     * will want to use {@link #getAvailableBlocks()} instead.
      */
-    public native int getFreeBlocks();
+    public int getFreeBlocks() {
+        return (int) mStat.f_bfree;
+    }
 
     /**
      * The number of blocks that are free on the file system and available to
-     * applications.  This corresponds to the Unix statfs.f_bavail field.
+     * applications. This corresponds to the Unix {@code statfs.f_bavail} field.
      */
-    public native int getAvailableBlocks();    
-    
-    private int mNativeContext;
-    private native void native_restat(String path);
-    private native void native_setup(String path);
-    private native void native_finalize();
+    public int getAvailableBlocks() {
+        return (int) mStat.f_bavail;
+    }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index b5a2f98..6f3653d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -67,7 +67,6 @@
 	android_os_ParcelFileDescriptor.cpp \
 	android_os_Parcel.cpp \
 	android_os_SELinux.cpp \
-	android_os_StatFs.cpp \
 	android_os_SystemClock.cpp \
 	android_os_SystemProperties.cpp \
 	android_os_Trace.cpp \
diff --git a/core/jni/android_os_StatFs.cpp b/core/jni/android_os_StatFs.cpp
deleted file mode 100644
index 79d8fef..0000000
--- a/core/jni/android_os_StatFs.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2007, 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.
- */
-
-#if INCLUDE_SYS_MOUNT_FOR_STATFS
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
-
-#include <errno.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-
-
-namespace android
-{
-
-// ----------------------------------------------------------------------------
-
-struct fields_t {
-    jfieldID    context;
-};
-static fields_t fields;
-
-// ----------------------------------------------------------------------------
-
-static jint
-android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bsize;
-}
-
-static jint
-android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_blocks;
-}
-
-static jint
-android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bfree;
-}
-
-static jint
-android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    return stat->f_bavail;
-}
-
-static void
-android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
-{
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    // get the object handle
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    if (stat == NULL) {
-        jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
-        return;
-    }
-
-    const char* pathstr = env->GetStringUTFChars(path, NULL);
-    if (pathstr == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
-        return;
-    }
-
-    // note that stat will contain the new file data corresponding to
-    // pathstr
-    if (statfs(pathstr, stat) != 0) {
-        ALOGE("statfs %s failed, errno: %d", pathstr, errno);
-        delete stat;
-        env->SetIntField(thiz, fields.context, 0);
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-    }
-    // Release pathstr
-    env->ReleaseStringUTFChars(path, pathstr);
-}
-
-static void
-android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
-{
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    struct statfs* stat = new struct statfs;
-    if (stat == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
-        return;
-    }
-    env->SetIntField(thiz, fields.context, (int)stat);
-    android_os_StatFs_native_restat(env, thiz, path);
-}
-
-static void
-android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
-{
-    struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
-    if (stat != NULL) {
-        delete stat;
-        env->SetIntField(thiz, fields.context, 0);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static JNINativeMethod gMethods[] = {
-    {"getBlockSize",       "()I",                       (void *)android_os_StatFs_getBlockSize},
-    {"getBlockCount",      "()I",                       (void *)android_os_StatFs_getBlockCount},
-    {"getFreeBlocks",      "()I",                       (void *)android_os_StatFs_getFreeBlocks},
-    {"getAvailableBlocks", "()I",                       (void *)android_os_StatFs_getAvailableBlocks},
-    {"native_setup",       "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_setup},
-    {"native_finalize",    "()V",                       (void *)android_os_StatFs_native_finalize},
-    {"native_restat",      "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_restat},
-};
-
-
-int register_android_os_StatFs(JNIEnv *env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/os/StatFs");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/os/StatFs");
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        ALOGE("Can't find StatFs.mNativeContext");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env,
-            "android/os/StatFs", gMethods, NELEM(gMethods));
-}
-
-}   // namespace android