1 /* //device/libs/android_runtime/android_os_SystemProperties.cpp 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #define LOG_TAG "SysPropJNI" 19 20 #include "cutils/properties.h" 21 #include "utils/misc.h" 22 #include <utils/Log.h> 23 #include "jni.h" 24 #include "android_runtime/AndroidRuntime.h" 25 #include <nativehelper/JNIHelp.h> 26 27 namespace android 28 { 29 30 static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz, 31 jstring keyJ, jstring defJ) 32 { 33 int len; 34 const char* key; 35 char buf[PROPERTY_VALUE_MAX]; 36 jstring rvJ = NULL; 37 38 if (keyJ == NULL) { 39 jniThrowNullPointerException(env, "key must not be null."); 40 goto error; 41 } 42 43 key = env->GetStringUTFChars(keyJ, NULL); 44 45 len = property_get(key, buf, ""); 46 if ((len <= 0) && (defJ != NULL)) { 47 rvJ = defJ; 48 } else if (len >= 0) { 49 rvJ = env->NewStringUTF(buf); 50 } else { 51 rvJ = env->NewStringUTF(""); 52 } 53 54 env->ReleaseStringUTFChars(keyJ, key); 55 56 error: 57 return rvJ; 58 } 59 60 static jstring SystemProperties_getS(JNIEnv *env, jobject clazz, 61 jstring keyJ) 62 { 63 return SystemProperties_getSS(env, clazz, keyJ, NULL); 64 } 65 66 static jint SystemProperties_get_int(JNIEnv *env, jobject clazz, 67 jstring keyJ, jint defJ) 68 { 69 int len; 70 const char* key; 71 char buf[PROPERTY_VALUE_MAX]; 72 char* end; 73 jint result = defJ; 74 75 if (keyJ == NULL) { 76 jniThrowNullPointerException(env, "key must not be null."); 77 goto error; 78 } 79 80 key = env->GetStringUTFChars(keyJ, NULL); 81 82 len = property_get(key, buf, ""); 83 if (len > 0) { 84 result = strtol(buf, &end, 0); 85 if (end == buf) { 86 result = defJ; 87 } 88 } 89 90 env->ReleaseStringUTFChars(keyJ, key); 91 92 error: 93 return result; 94 } 95 96 static jlong SystemProperties_get_long(JNIEnv *env, jobject clazz, 97 jstring keyJ, jlong defJ) 98 { 99 int len; 100 const char* key; 101 char buf[PROPERTY_VALUE_MAX]; 102 char* end; 103 jlong result = defJ; 104 105 if (keyJ == NULL) { 106 jniThrowNullPointerException(env, "key must not be null."); 107 goto error; 108 } 109 110 key = env->GetStringUTFChars(keyJ, NULL); 111 112 len = property_get(key, buf, ""); 113 if (len > 0) { 114 result = strtoll(buf, &end, 0); 115 if (end == buf) { 116 result = defJ; 117 } 118 } 119 120 env->ReleaseStringUTFChars(keyJ, key); 121 122 error: 123 return result; 124 } 125 126 static jboolean SystemProperties_get_boolean(JNIEnv *env, jobject clazz, 127 jstring keyJ, jboolean defJ) 128 { 129 int len; 130 const char* key; 131 char buf[PROPERTY_VALUE_MAX]; 132 jboolean result = defJ; 133 134 if (keyJ == NULL) { 135 jniThrowNullPointerException(env, "key must not be null."); 136 goto error; 137 } 138 139 key = env->GetStringUTFChars(keyJ, NULL); 140 141 len = property_get(key, buf, ""); 142 if (len == 1) { 143 char ch = buf[0]; 144 if (ch == '0' || ch == 'n') 145 result = false; 146 else if (ch == '1' || ch == 'y') 147 result = true; 148 } else if (len > 1) { 149 if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) { 150 result = false; 151 } else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) { 152 result = true; 153 } 154 } 155 156 env->ReleaseStringUTFChars(keyJ, key); 157 158 error: 159 return result; 160 } 161 162 static void SystemProperties_set(JNIEnv *env, jobject clazz, 163 jstring keyJ, jstring valJ) 164 { 165 int err; 166 const char* key; 167 const char* val; 168 169 if (keyJ == NULL) { 170 jniThrowNullPointerException(env, "key must not be null."); 171 return ; 172 } 173 key = env->GetStringUTFChars(keyJ, NULL); 174 175 if (valJ == NULL) { 176 val = ""; /* NULL pointer not allowed here */ 177 } else { 178 val = env->GetStringUTFChars(valJ, NULL); 179 } 180 181 err = property_set(key, val); 182 183 env->ReleaseStringUTFChars(keyJ, key); 184 185 if (valJ != NULL) { 186 env->ReleaseStringUTFChars(valJ, val); 187 } 188 189 if (err < 0) { 190 jniThrowException(env, "java/lang/RuntimeException", 191 "failed to set system property"); 192 } 193 } 194 195 static JavaVM* sVM = NULL; 196 static jclass sClazz = NULL; 197 static jmethodID sCallChangeCallbacks; 198 199 static void do_report_sysprop_change() { 200 //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz); 201 if (sVM != NULL && sClazz != NULL) { 202 JNIEnv* env; 203 if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) { 204 //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks); 205 env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks); 206 } 207 } 208 } 209 210 static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz) 211 { 212 // This is called with the Java lock held. 213 if (sVM == NULL) { 214 env->GetJavaVM(&sVM); 215 } 216 if (sClazz == NULL) { 217 sClazz = (jclass) env->NewGlobalRef(clazz); 218 sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V"); 219 add_sysprop_change_callback(do_report_sysprop_change, -10000); 220 } 221 } 222 223 static JNINativeMethod method_table[] = { 224 { "native_get", "(Ljava/lang/String;)Ljava/lang/String;", 225 (void*) SystemProperties_getS }, 226 { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;", 227 (void*) SystemProperties_getSS }, 228 { "native_get_int", "(Ljava/lang/String;I)I", 229 (void*) SystemProperties_get_int }, 230 { "native_get_long", "(Ljava/lang/String;J)J", 231 (void*) SystemProperties_get_long }, 232 { "native_get_boolean", "(Ljava/lang/String;Z)Z", 233 (void*) SystemProperties_get_boolean }, 234 { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V", 235 (void*) SystemProperties_set }, 236 { "native_add_change_callback", "()V", 237 (void*) SystemProperties_add_change_callback }, 238 }; 239 240 int register_android_os_SystemProperties(JNIEnv *env) 241 { 242 return AndroidRuntime::registerNativeMethods( 243 env, "android/os/SystemProperties", 244 method_table, NELEM(method_table)); 245 } 246 247 }; 248