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