blob: 5dace6b7e536667c33d3446e9de563bd9704e6b8 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_os_SystemProperties.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughes69a017b2011-04-08 14:10:28 -07005** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughes69a017b2011-04-08 14:10:28 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughes69a017b2011-04-08 14:10:28 -070011** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
Dianne Hackborna53de062012-05-08 18:53:51 -070018#define LOG_TAG "SysPropJNI"
19
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020#include "cutils/properties.h"
Dianne Hackborna53de062012-05-08 18:53:51 -070021#include "utils/misc.h"
22#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include "jni.h"
Andreas Gampeed6b9df2014-11-20 22:02:20 -080024#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include <nativehelper/JNIHelp.h>
26
27namespace android
28{
29
30static 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) {
Elliott Hughes69a017b2011-04-08 14:10:28 -070039 jniThrowNullPointerException(env, "key must not be null.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 goto error;
41 }
Mike Lockwoodd1945952009-08-12 17:15:51 -040042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 key = env->GetStringUTFChars(keyJ, NULL);
Mike Lockwoodd1945952009-08-12 17:15:51 -040044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 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 }
Mike Lockwoodd1945952009-08-12 17:15:51 -040053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 env->ReleaseStringUTFChars(keyJ, key);
Mike Lockwoodd1945952009-08-12 17:15:51 -040055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056error:
57 return rvJ;
58}
59
60static jstring SystemProperties_getS(JNIEnv *env, jobject clazz,
61 jstring keyJ)
62{
63 return SystemProperties_getSS(env, clazz, keyJ, NULL);
64}
65
Mike Lockwoodd1945952009-08-12 17:15:51 -040066static 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];
Dianne Hackborn83e6eb12012-05-08 14:53:24 -070072 char* end;
Mike Lockwoodd1945952009-08-12 17:15:51 -040073 jint result = defJ;
74
75 if (keyJ == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -070076 jniThrowNullPointerException(env, "key must not be null.");
Mike Lockwoodd1945952009-08-12 17:15:51 -040077 goto error;
78 }
79
80 key = env->GetStringUTFChars(keyJ, NULL);
81
82 len = property_get(key, buf, "");
83 if (len > 0) {
Dianne Hackborn83e6eb12012-05-08 14:53:24 -070084 result = strtol(buf, &end, 0);
85 if (end == buf) {
86 result = defJ;
87 }
Mike Lockwoodd1945952009-08-12 17:15:51 -040088 }
89
90 env->ReleaseStringUTFChars(keyJ, key);
91
92error:
93 return result;
94}
95
96static 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];
Dianne Hackborn83e6eb12012-05-08 14:53:24 -0700102 char* end;
Mike Lockwoodd1945952009-08-12 17:15:51 -0400103 jlong result = defJ;
104
105 if (keyJ == NULL) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700106 jniThrowNullPointerException(env, "key must not be null.");
Mike Lockwoodd1945952009-08-12 17:15:51 -0400107 goto error;
108 }
109
110 key = env->GetStringUTFChars(keyJ, NULL);
111
112 len = property_get(key, buf, "");
113 if (len > 0) {
Dianne Hackborn83e6eb12012-05-08 14:53:24 -0700114 result = strtoll(buf, &end, 0);
115 if (end == buf) {
116 result = defJ;
117 }
Mike Lockwoodd1945952009-08-12 17:15:51 -0400118 }
119
120 env->ReleaseStringUTFChars(keyJ, key);
121
122error:
123 return result;
124}
125
126static 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) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700135 jniThrowNullPointerException(env, "key must not be null.");
Mike Lockwoodd1945952009-08-12 17:15:51 -0400136 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
158error:
159 return result;
160}
161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162static 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) {
Elliott Hughes69a017b2011-04-08 14:10:28 -0700170 jniThrowNullPointerException(env, "key must not be null.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 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 }
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 err = property_set(key, val);
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 env->ReleaseStringUTFChars(keyJ, key);
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800184
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 if (valJ != NULL) {
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800186 env->ReleaseStringUTFChars(valJ, val);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 }
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800188
189 if (err < 0) {
190 jniThrowException(env, "java/lang/RuntimeException",
191 "failed to set system property");
192 }
193}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194
Dianne Hackborna53de062012-05-08 18:53:51 -0700195static JavaVM* sVM = NULL;
196static jclass sClazz = NULL;
197static jmethodID sCallChangeCallbacks;
198
199static 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
210static 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
Daniel Micay76f6a862015-09-19 17:31:01 -0400223static const JNINativeMethod method_table[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 { "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 },
Mike Lockwoodd1945952009-08-12 17:15:51 -0400228 { "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 },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
235 (void*) SystemProperties_set },
Dianne Hackborna53de062012-05-08 18:53:51 -0700236 { "native_add_change_callback", "()V",
237 (void*) SystemProperties_add_change_callback },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238};
239
240int register_android_os_SystemProperties(JNIEnv *env)
241{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800242 return RegisterMethodsOrDie(env, "android/os/SystemProperties", method_table,
243 NELEM(method_table));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244}
245
246};