Home | History | Annotate | Download | only in jni
      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 "core_jni_helpers.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 void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
    224 {
    225     report_sysprop_change();
    226 }
    227 
    228 static const JNINativeMethod method_table[] = {
    229     { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
    230       (void*) SystemProperties_getS },
    231     { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
    232       (void*) SystemProperties_getSS },
    233     { "native_get_int", "(Ljava/lang/String;I)I",
    234       (void*) SystemProperties_get_int },
    235     { "native_get_long", "(Ljava/lang/String;J)J",
    236       (void*) SystemProperties_get_long },
    237     { "native_get_boolean", "(Ljava/lang/String;Z)Z",
    238       (void*) SystemProperties_get_boolean },
    239     { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
    240       (void*) SystemProperties_set },
    241     { "native_add_change_callback", "()V",
    242       (void*) SystemProperties_add_change_callback },
    243     { "native_report_sysprop_change", "()V",
    244       (void*) SystemProperties_report_sysprop_change },
    245 };
    246 
    247 int register_android_os_SystemProperties(JNIEnv *env)
    248 {
    249     return RegisterMethodsOrDie(env, "android/os/SystemProperties", method_table,
    250                                 NELEM(method_table));
    251 }
    252 
    253 };
    254