1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License.
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17abf945fb9ce99d8c2769ac5b2691b2732fa59887Elliott Hughes#define LOG_TAG "System"
18abf945fb9ce99d8c2769ac5b2691b2732fa59887Elliott Hughes
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include "JNIHelp.h"
20e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes#include "JniConstants.h"
2105960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes#include "ScopedUtfChars.h"
228545b837c61c3eaea2b8433b6791aa401f37e5f7Elliott Hughes#include "cutils/log.h"
232ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include "openssl/opensslv.h"
24ddafeb1d73cfe504720d10a2634b5858fc4cc413Elliott Hughes#include "toStringArray.h"
252ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include "zlib.h"
262ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
272ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include <string>
282ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include <vector>
292ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
302ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include <limits.h>
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <stdlib.h>
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project#include <string.h>
3322ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes#include <sys/time.h>
3422ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes#include <time.h>
352ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes#include <unistd.h>
362ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
37a7ef55258ac71153487357b861c7639d627df82fElliott Hughesstatic void System_log(JNIEnv* env, jclass, jchar type, jstring javaMessage, jthrowable exception) {
38a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    ScopedUtfChars message(env, javaMessage);
39a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    if (message.c_str() == NULL) {
40a7ef55258ac71153487357b861c7639d627df82fElliott Hughes        // Since this function is used for last-gasp debugging output, be noisy on failure.
41679cf68b607e9b4a3beb8bcdee06868ae583386fSteve Block        ALOGE("message.c_str() == NULL");
42a7ef55258ac71153487357b861c7639d627df82fElliott Hughes        return;
43a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    }
44a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    int priority;
45a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    switch (type) {
46a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'D': case 'd': priority = ANDROID_LOG_DEBUG;   break;
47a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'E': case 'e': priority = ANDROID_LOG_ERROR;   break;
48a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'F': case 'f': priority = ANDROID_LOG_FATAL;   break;
49a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'I': case 'i': priority = ANDROID_LOG_INFO;    break;
50a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'S': case 's': priority = ANDROID_LOG_SILENT;  break;
51a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'V': case 'v': priority = ANDROID_LOG_VERBOSE; break;
52a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    case 'W': case 'w': priority = ANDROID_LOG_WARN;    break;
53a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    default:            priority = ANDROID_LOG_DEFAULT; break;
54a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    }
55a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    LOG_PRI(priority, LOG_TAG, "%s", message.c_str());
56a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    if (exception != NULL) {
57a7ef55258ac71153487357b861c7639d627df82fElliott Hughes        jniLogException(env, priority, LOG_TAG, exception);
58a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    }
59a7ef55258ac71153487357b861c7639d627df82fElliott Hughes}
60a7ef55258ac71153487357b861c7639d627df82fElliott Hughes
6105960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes// Sets a field via JNI. Used for the standard streams, which are read-only otherwise.
6205960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughesstatic void System_setFieldImpl(JNIEnv* env, jclass clazz,
6305960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes        jstring javaName, jstring javaSignature, jobject object) {
6405960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    ScopedUtfChars name(env, javaName);
6505960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    if (name.c_str() == NULL) {
6605960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes        return;
6705960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    }
6805960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    ScopedUtfChars signature(env, javaSignature);
6905960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    if (signature.c_str() == NULL) {
7005960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes        return;
7105960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    }
7205960876dff6a5b686821eed8f7ae7cef5af4f50Elliott Hughes    jfieldID fieldID = env->GetStaticFieldID(clazz, name.c_str(), signature.c_str());
7394367e0ead84fc2228799a78ec207ea52e203f1aElliott Hughes    env->SetStaticObjectField(clazz, fieldID, object);
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
762ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughesstatic jobjectArray System_specialProperties(JNIEnv* env, jclass) {
772ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    std::vector<std::string> properties;
782ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
792ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    char path[PATH_MAX];
802ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    properties.push_back(std::string("user.dir=") + getcwd(path, sizeof(path)));
812ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
822ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    properties.push_back("android.zlib.version=" ZLIB_VERSION);
832ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    properties.push_back("android.openssl.version=" OPENSSL_VERSION_TEXT);
842ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
852ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    return toStringArray(env, properties);
862ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes}
872ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes
8822ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughesstatic jlong System_currentTimeMillis(JNIEnv*, jclass) {
8922ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    timeval now;
9022ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    gettimeofday(&now, NULL);
9122ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    jlong when = now.tv_sec * 1000LL + now.tv_usec / 1000;
9222ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    return when;
9322ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes}
9422ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes
9522ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughesstatic jlong System_nanoTime(JNIEnv*, jclass) {
9622ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    timespec now;
97508bf13ba75610c75c4f40811dde0ec7e401f4c1Elliott Hughes    clock_gettime(CLOCK_MONOTONIC, &now);
9822ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    return now.tv_sec * 1000000000LL + now.tv_nsec;
9922ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes}
10022ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes
10122ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughesstatic jstring System_mapLibraryName(JNIEnv* env, jclass, jstring javaName) {
10222ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    ScopedUtfChars name(env, javaName);
10322ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    if (name.c_str() == NULL) {
10422ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes        return NULL;
10522ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    }
10622ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    char* mappedName = NULL;
10722ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    asprintf(&mappedName, OS_SHARED_LIB_FORMAT_STR, name.c_str());
10822ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    jstring result = env->NewStringUTF(mappedName);
10922ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    free(mappedName);
11022ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    return result;
11122ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes}
11222ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectstatic JNINativeMethod gMethods[] = {
11422ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    NATIVE_METHOD(System, currentTimeMillis, "()J"),
115a7ef55258ac71153487357b861c7639d627df82fElliott Hughes    NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
11622ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
11722ccdd01e2fabc37d858be32291a854ff72f1840Elliott Hughes    NATIVE_METHOD(System, nanoTime, "()J"),
118e22935d3c7040c22b48d53bd18878844f381287cElliott Hughes    NATIVE_METHOD(System, setFieldImpl, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"),
1192ef68714ff84d43705f57f724fbcb1a28ebd954dElliott Hughes    NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project};
1217cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughesvoid register_java_lang_System(JNIEnv* env) {
1227cd6760f7045d771faae8080a8c6150bf678f679Elliott Hughes    jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods));
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
124