1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "System" 18 19 #include "JNIHelp.h" 20 #include "JniConstants.h" 21 #include "ScopedUtfChars.h" 22 #include "cutils/log.h" 23 #include "openssl/opensslv.h" 24 #include "toStringArray.h" 25 #include "zlib.h" 26 27 #include <string> 28 #include <vector> 29 30 #include <limits.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <sys/time.h> 34 #include <time.h> 35 #include <unistd.h> 36 37 #if defined(HAVE_ANDROID_OS) 38 extern "C" void android_get_LD_LIBRARY_PATH(char*, size_t); 39 #endif 40 41 static void System_log(JNIEnv* env, jclass, jchar type, jstring javaMessage, jthrowable exception) { 42 ScopedUtfChars message(env, javaMessage); 43 if (message.c_str() == NULL) { 44 // Since this function is used for last-gasp debugging output, be noisy on failure. 45 ALOGE("message.c_str() == NULL"); 46 return; 47 } 48 int priority; 49 switch (type) { 50 case 'D': case 'd': priority = ANDROID_LOG_DEBUG; break; 51 case 'E': case 'e': priority = ANDROID_LOG_ERROR; break; 52 case 'F': case 'f': priority = ANDROID_LOG_FATAL; break; 53 case 'I': case 'i': priority = ANDROID_LOG_INFO; break; 54 case 'S': case 's': priority = ANDROID_LOG_SILENT; break; 55 case 'V': case 'v': priority = ANDROID_LOG_VERBOSE; break; 56 case 'W': case 'w': priority = ANDROID_LOG_WARN; break; 57 default: priority = ANDROID_LOG_DEFAULT; break; 58 } 59 LOG_PRI(priority, LOG_TAG, "%s", message.c_str()); 60 if (exception != NULL) { 61 jniLogException(env, priority, LOG_TAG, exception); 62 } 63 } 64 65 // Sets a field via JNI. Used for the standard streams, which are read-only otherwise. 66 static void System_setFieldImpl(JNIEnv* env, jclass clazz, 67 jstring javaName, jstring javaSignature, jobject object) { 68 ScopedUtfChars name(env, javaName); 69 if (name.c_str() == NULL) { 70 return; 71 } 72 ScopedUtfChars signature(env, javaSignature); 73 if (signature.c_str() == NULL) { 74 return; 75 } 76 jfieldID fieldID = env->GetStaticFieldID(clazz, name.c_str(), signature.c_str()); 77 env->SetStaticObjectField(clazz, fieldID, object); 78 } 79 80 static jobjectArray System_specialProperties(JNIEnv* env, jclass) { 81 std::vector<std::string> properties; 82 83 char path[PATH_MAX]; 84 properties.push_back(std::string("user.dir=") + getcwd(path, sizeof(path))); 85 86 properties.push_back("android.zlib.version=" ZLIB_VERSION); 87 #if defined(OPENSSL_IS_BORINGSSL) 88 properties.push_back("android.openssl.version=BoringSSL"); 89 #else 90 properties.push_back("android.openssl.version=" OPENSSL_VERSION_TEXT); 91 #endif 92 93 const char* library_path = getenv("LD_LIBRARY_PATH"); 94 #if defined(HAVE_ANDROID_OS) 95 if (library_path == NULL) { 96 android_get_LD_LIBRARY_PATH(path, sizeof(path)); 97 library_path = path; 98 } 99 #endif 100 if (library_path == NULL) { 101 library_path = ""; 102 } 103 properties.push_back(std::string("java.library.path=") + library_path); 104 105 return toStringArray(env, properties); 106 } 107 108 static jlong System_currentTimeMillis(JNIEnv*, jclass) { 109 timeval now; 110 gettimeofday(&now, NULL); 111 jlong when = now.tv_sec * 1000LL + now.tv_usec / 1000; 112 return when; 113 } 114 115 static jlong System_nanoTime(JNIEnv*, jclass) { 116 #if defined(__linux__) 117 timespec now; 118 clock_gettime(CLOCK_MONOTONIC, &now); 119 return now.tv_sec * 1000000000LL + now.tv_nsec; 120 #else // __APPLE__ 121 timeval now; 122 gettimeofday(&now, NULL); 123 return static_cast<jlong>(now.tv_sec) * 1000000000LL + now.tv_usec * 1000LL; 124 #endif 125 } 126 127 static JNINativeMethod gMethods[] = { 128 NATIVE_METHOD(System, currentTimeMillis, "!()J"), 129 NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"), 130 NATIVE_METHOD(System, nanoTime, "!()J"), 131 NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"), 132 NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"), 133 }; 134 void register_java_lang_System(JNIEnv* env) { 135 jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods)); 136 } 137