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
SystemProperties_getSS(JNIEnv * env,jobject clazz,jstring keyJ,jstring defJ)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
SystemProperties_getS(JNIEnv * env,jobject clazz,jstring keyJ)60 static jstring SystemProperties_getS(JNIEnv *env, jobject clazz,
61 jstring keyJ)
62 {
63 return SystemProperties_getSS(env, clazz, keyJ, NULL);
64 }
65
SystemProperties_get_int(JNIEnv * env,jobject clazz,jstring keyJ,jint defJ)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
SystemProperties_get_long(JNIEnv * env,jobject clazz,jstring keyJ,jlong defJ)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
SystemProperties_get_boolean(JNIEnv * env,jobject clazz,jstring keyJ,jboolean defJ)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
SystemProperties_set(JNIEnv * env,jobject clazz,jstring keyJ,jstring valJ)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
do_report_sysprop_change()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
SystemProperties_add_change_callback(JNIEnv * env,jobject clazz)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
SystemProperties_report_sysprop_change(JNIEnv,jobject)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
register_android_os_SystemProperties(JNIEnv * env)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