blob: a94cac0f18f537b92ba675e67f542b252e37c48d [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
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070020#include "android-base/logging.h"
21#include "android-base/properties.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include "cutils/properties.h"
Dianne Hackborna53de062012-05-08 18:53:51 -070023#include "utils/misc.h"
24#include <utils/Log.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#include "jni.h"
Andreas Gampeed6b9df2014-11-20 22:02:20 -080026#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027#include <nativehelper/JNIHelp.h>
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070028#include <nativehelper/ScopedPrimitiveArray.h>
29#include <nativehelper/ScopedUtfChars.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31namespace android
32{
33
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070034namespace {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070036template <typename T, typename Handler>
37T ConvertKeyAndForward(JNIEnv *env, jstring keyJ, T defJ, Handler handler) {
38 std::string key;
39 {
40 // Scope the String access. If the handler can throw an exception,
41 // releasing the string characters late would trigger an abort.
42 ScopedUtfChars key_utf(env, keyJ);
43 if (key_utf.c_str() == nullptr) {
44 return defJ;
Dianne Hackborn83e6eb12012-05-08 14:53:24 -070045 }
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070046 key = key_utf.c_str(); // This will make a copy, but we can't avoid
47 // with the existing interface in
48 // android::base.
Mike Lockwoodd1945952009-08-12 17:15:51 -040049 }
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070050 return handler(key, defJ);
Mike Lockwoodd1945952009-08-12 17:15:51 -040051}
52
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070053jstring SystemProperties_getSS(JNIEnv *env, jclass clazz, jstring keyJ,
54 jstring defJ)
Mike Lockwoodd1945952009-08-12 17:15:51 -040055{
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070056 // Using ConvertKeyAndForward is sub-optimal for copying the key string,
57 // but improves reuse and reasoning over code.
58 auto handler = [&](const std::string& key, jstring defJ) {
59 std::string prop_val = android::base::GetProperty(key, "");
60 if (!prop_val.empty()) {
61 return env->NewStringUTF(prop_val.c_str());
62 };
63 if (defJ != nullptr) {
64 return defJ;
Dianne Hackborn83e6eb12012-05-08 14:53:24 -070065 }
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070066 // This function is specified to never return null (or have an
67 // exception pending).
68 return env->NewStringUTF("");
69 };
70 return ConvertKeyAndForward(env, keyJ, defJ, handler);
Mike Lockwoodd1945952009-08-12 17:15:51 -040071}
72
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070073jstring SystemProperties_getS(JNIEnv *env, jclass clazz, jstring keyJ)
Mike Lockwoodd1945952009-08-12 17:15:51 -040074{
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070075 return SystemProperties_getSS(env, clazz, keyJ, nullptr);
76}
Mike Lockwoodd1945952009-08-12 17:15:51 -040077
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070078template <typename T>
79T SystemProperties_get_integral(JNIEnv *env, jclass, jstring keyJ,
80 T defJ)
81{
82 auto handler = [](const std::string& key, T defV) {
83 return android::base::GetIntProperty<T>(key, defV);
84 };
85 return ConvertKeyAndForward(env, keyJ, defJ, handler);
86}
Mike Lockwoodd1945952009-08-12 17:15:51 -040087
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070088jboolean SystemProperties_get_boolean(JNIEnv *env, jclass, jstring keyJ,
89 jboolean defJ)
90{
91 auto handler = [](const std::string& key, jboolean defV) -> jboolean {
92 bool result = android::base::GetBoolProperty(key, defV);
93 return result ? JNI_TRUE : JNI_FALSE;
94 };
95 return ConvertKeyAndForward(env, keyJ, defJ, handler);
96}
Mike Lockwoodd1945952009-08-12 17:15:51 -040097
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -070098void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ,
99 jstring valJ)
100{
101 auto handler = [&](const std::string& key, bool) {
102 std::string val;
103 if (valJ != nullptr) {
104 ScopedUtfChars key_utf(env, valJ);
105 val = key_utf.c_str();
Mike Lockwoodd1945952009-08-12 17:15:51 -0400106 }
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700107 return android::base::SetProperty(key, val);
108 };
109 if (!ConvertKeyAndForward(env, keyJ, true, handler)) {
110 // Must have been a failure in SetProperty.
Brad Fitzpatrick06f36742011-03-10 16:04:59 -0800111 jniThrowException(env, "java/lang/RuntimeException",
112 "failed to set system property");
113 }
114}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700116JavaVM* sVM = nullptr;
117jclass sClazz = nullptr;
118jmethodID sCallChangeCallbacks;
Dianne Hackborna53de062012-05-08 18:53:51 -0700119
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700120void do_report_sysprop_change() {
Dianne Hackborna53de062012-05-08 18:53:51 -0700121 //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700122 if (sVM != nullptr && sClazz != nullptr) {
Dianne Hackborna53de062012-05-08 18:53:51 -0700123 JNIEnv* env;
124 if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
125 //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
126 env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
127 }
128 }
129}
130
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700131void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
Dianne Hackborna53de062012-05-08 18:53:51 -0700132{
133 // This is called with the Java lock held.
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700134 if (sVM == nullptr) {
Dianne Hackborna53de062012-05-08 18:53:51 -0700135 env->GetJavaVM(&sVM);
136 }
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700137 if (sClazz == nullptr) {
Dianne Hackborna53de062012-05-08 18:53:51 -0700138 sClazz = (jclass) env->NewGlobalRef(clazz);
139 sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
140 add_sysprop_change_callback(do_report_sysprop_change, -10000);
141 }
142}
143
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700144void SystemProperties_report_sysprop_change(JNIEnv /**env*/, jobject /*clazz*/)
Martijn Coenen0754b272016-11-17 14:06:38 +0100145{
146 report_sysprop_change();
147}
148
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700149} // namespace
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
151int register_android_os_SystemProperties(JNIEnv *env)
152{
Andreas Gampe2e6b9cb2017-07-29 14:14:39 -0700153 const JNINativeMethod method_table[] = {
154 { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
155 (void*) SystemProperties_getS },
156 { "native_get",
157 "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
158 (void*) SystemProperties_getSS },
159 { "native_get_int", "(Ljava/lang/String;I)I",
160 (void*) SystemProperties_get_integral<jint> },
161 { "native_get_long", "(Ljava/lang/String;J)J",
162 (void*) SystemProperties_get_integral<jlong> },
163 { "native_get_boolean", "(Ljava/lang/String;Z)Z",
164 (void*) SystemProperties_get_boolean },
165 { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
166 (void*) SystemProperties_set },
167 { "native_add_change_callback", "()V",
168 (void*) SystemProperties_add_change_callback },
169 { "native_report_sysprop_change", "()V",
170 (void*) SystemProperties_report_sysprop_change },
171 };
172 return RegisterMethodsOrDie(env, "android/os/SystemProperties",
173 method_table, NELEM(method_table));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174}
175
176};