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