Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2007, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #if INCLUDE_SYS_MOUNT_FOR_STATFS
     18 #include <sys/mount.h>
     19 #else
     20 #include <sys/statfs.h>
     21 #endif
     22 
     23 #include <errno.h>
     24 
     25 #include "jni.h"
     26 #include "JNIHelp.h"
     27 #include "android_runtime/AndroidRuntime.h"
     28 
     29 
     30 namespace android
     31 {
     32 
     33 // ----------------------------------------------------------------------------
     34 
     35 struct fields_t {
     36     jfieldID    context;
     37 };
     38 static fields_t fields;
     39 
     40 // ----------------------------------------------------------------------------
     41 
     42 static jint
     43 android_os_StatFs_getBlockSize(JNIEnv *env, jobject thiz)
     44 {
     45     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
     46     return stat->f_bsize;
     47 }
     48 
     49 static jint
     50 android_os_StatFs_getBlockCount(JNIEnv *env, jobject thiz)
     51 {
     52     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
     53     return stat->f_blocks;
     54 }
     55 
     56 static jint
     57 android_os_StatFs_getFreeBlocks(JNIEnv *env, jobject thiz)
     58 {
     59     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
     60     return stat->f_bfree;
     61 }
     62 
     63 static jint
     64 android_os_StatFs_getAvailableBlocks(JNIEnv *env, jobject thiz)
     65 {
     66     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
     67     return stat->f_bavail;
     68 }
     69 
     70 static void
     71 android_os_StatFs_native_restat(JNIEnv *env, jobject thiz, jstring path)
     72 {
     73     if (path == NULL) {
     74         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
     75         return;
     76     }
     77 
     78     // get the object handle
     79     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
     80     if (stat == NULL) {
     81         jniThrowException(env, "java/lang/NoSuchFieldException", NULL);
     82         return;
     83     }
     84 
     85     const char* pathstr = env->GetStringUTFChars(path, NULL);
     86     if (pathstr == NULL) {
     87         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
     88         return;
     89     }
     90 
     91     // note that stat will contain the new file data corresponding to
     92     // pathstr
     93     if (statfs(pathstr, stat) != 0) {
     94         LOGE("statfs %s failed, errno: %d", pathstr, errno);
     95         delete stat;
     96         env->SetIntField(thiz, fields.context, 0);
     97         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
     98     }
     99     // Release pathstr
    100     env->ReleaseStringUTFChars(path, pathstr);
    101 }
    102 
    103 static void
    104 android_os_StatFs_native_setup(JNIEnv *env, jobject thiz, jstring path)
    105 {
    106     if (path == NULL) {
    107         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
    108         return;
    109     }
    110 
    111     struct statfs* stat = new struct statfs;
    112     if (stat == NULL) {
    113         jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
    114         return;
    115     }
    116     env->SetIntField(thiz, fields.context, (int)stat);
    117     android_os_StatFs_native_restat(env, thiz, path);
    118 }
    119 
    120 static void
    121 android_os_StatFs_native_finalize(JNIEnv *env, jobject thiz)
    122 {
    123     struct statfs *stat = (struct statfs *)env->GetIntField(thiz, fields.context);
    124     if (stat != NULL) {
    125         delete stat;
    126         env->SetIntField(thiz, fields.context, 0);
    127     }
    128 }
    129 
    130 // ----------------------------------------------------------------------------
    131 
    132 static JNINativeMethod gMethods[] = {
    133     {"getBlockSize",       "()I",                       (void *)android_os_StatFs_getBlockSize},
    134     {"getBlockCount",      "()I",                       (void *)android_os_StatFs_getBlockCount},
    135     {"getFreeBlocks",      "()I",                       (void *)android_os_StatFs_getFreeBlocks},
    136     {"getAvailableBlocks", "()I",                       (void *)android_os_StatFs_getAvailableBlocks},
    137     {"native_setup",       "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_setup},
    138     {"native_finalize",    "()V",                       (void *)android_os_StatFs_native_finalize},
    139     {"native_restat",      "(Ljava/lang/String;)V",     (void *)android_os_StatFs_native_restat},
    140 };
    141 
    142 
    143 int register_android_os_StatFs(JNIEnv *env)
    144 {
    145     jclass clazz;
    146 
    147     clazz = env->FindClass("android/os/StatFs");
    148     if (clazz == NULL) {
    149         LOGE("Can't find android/os/StatFs");
    150         return -1;
    151     }
    152 
    153     fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
    154     if (fields.context == NULL) {
    155         LOGE("Can't find StatFs.mNativeContext");
    156         return -1;
    157     }
    158 
    159     return AndroidRuntime::registerNativeMethods(env,
    160             "android/os/StatFs", gMethods, NELEM(gMethods));
    161 }
    162 
    163 }   // namespace android
    164