android_util_Log.cpp revision 3762c311729fe9f3af085c14c5c1fb471d994c03
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* //device/libs/android_runtime/android_util_Log.cpp
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2006, The Android Open Source Project
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** you may not use this file except in compliance with the License.
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** You may obtain a copy of the License at
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** See the License for the specific language governing permissions and
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License.
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_NAMESPACE "log.tag."
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "Log_println"
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <assert.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
2399ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten#include <utils/Log.h>
2499ed22412db547c59d3da08114d9d5a586442b30Glenn Kasten#include <utils/String8.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "jni.h"
2799b49840d309727678b77403d6cc9f920111623fMathias Agopian#include "JNIHelp.h"
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include "utils/misc.h"
2999b49840d309727678b77403d6cc9f920111623fMathias Agopian#include "android_runtime/AndroidRuntime.h"
3099b49840d309727678b77403d6cc9f920111623fMathias Agopian
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define MIN(a,b) ((a<b)?a:b)
32a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian
3399b49840d309727678b77403d6cc9f920111623fMathias Agopiannamespace android {
34375f56363a8737119ce2222dcfaacbe1cf733fc0Mathias Agopian
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct levels_t {
3699b49840d309727678b77403d6cc9f920111623fMathias Agopian    jint verbose;
379cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian    jint debug;
387e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    jint info;
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jint warn;
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jint error;
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jint assert;
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project};
43f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopianstatic levels_t levels;
44f1d8e87b09abf963cd5b6a026194c1940fadb7b4Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic int toLevel(const char* value)
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (value[0]) {
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'V': return levels.verbose;
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'D': return levels.debug;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'I': return levels.info;
51d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        case 'W': return levels.warn;
52d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        case 'E': return levels.error;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'A': return levels.assert;
54b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        case 'S': return -1; // SUPPRESS
55118d0245ee0a3b107055782aa8b555404b6f0280Mathias Agopian    }
56a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian    return levels.info;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
6096f0819f81293076e652792794a961543e6750d7Mathias Agopian{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int len;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char key[PROPERTY_KEY_MAX];
6396f0819f81293076e652792794a961543e6750d7Mathias Agopian    char buf[PROPERTY_VALUE_MAX];
6496f0819f81293076e652792794a961543e6750d7Mathias Agopian
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tag == NULL) {
6696f0819f81293076e652792794a961543e6750d7Mathias Agopian        return false;
6796f0819f81293076e652792794a961543e6750d7Mathias Agopian    }
6896f0819f81293076e652792794a961543e6750d7Mathias Agopian
694f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    jboolean result = false;
70b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian
7196f0819f81293076e652792794a961543e6750d7Mathias Agopian    const char* chars = env->GetStringUTFChars(tag, NULL);
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
7496f0819f81293076e652792794a961543e6750d7Mathias Agopian        char buf2[200];
7596f0819f81293076e652792794a961543e6750d7Mathias Agopian        snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %d characters\n",
760ef4e15a6c12778daf464a4953d7e15e651f49acMathias Agopian                chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
7796f0819f81293076e652792794a961543e6750d7Mathias Agopian
7896f0819f81293076e652792794a961543e6750d7Mathias Agopian        // release the chars!
7996f0819f81293076e652792794a961543e6750d7Mathias Agopian        env->ReleaseStringUTFChars(tag, chars);
80a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian
81a67932fe6864ac346e7f78b86df11cf6c5344137Mathias Agopian        jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
8296f0819f81293076e652792794a961543e6750d7Mathias Agopian        return false;
834f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    } else {
84b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian        strncpy(key, LOG_NAMESPACE, sizeof(LOG_NAMESPACE)-1);
854f113740180b6512b43723c4728f262882dc9b45Mathias Agopian        strcpy(key + sizeof(LOG_NAMESPACE) - 1, chars);
864f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    }
874f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
884f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    env->ReleaseStringUTFChars(tag, chars);
894f113740180b6512b43723c4728f262882dc9b45Mathias Agopian
904f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    len = property_get(key, buf, "");
914f113740180b6512b43723c4728f262882dc9b45Mathias Agopian    int logLevel = toLevel(buf);
92b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian    return (logLevel >= 0 && level >= logLevel) ? true : false;
93b7e930db175c192464cebdeb49eb56cf6dd60114Mathias Agopian}
949a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis
959a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis/*
969a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis * In class android.util.Log:
979a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis *  public static native int println_native(int buffer, int priority, String tag, String msg)
989a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis */
999a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennisstatic jint android_util_Log_println_native(JNIEnv* env, jobject clazz,
100d9e8c64c3dce1612eb948a5c16ba4ff62202b423Mathias Agopian        jint bufID, jint priority, jstring tagObj, jstring msgObj)
1019a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis{
1029a78c90cd46b2a3bd637b056873149d3b94384b4Jamie Gennis    const char* tag = NULL;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char* msg = NULL;
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (msgObj == NULL) {
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        jniThrowNullPointerException(env, "println needs a message");
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return -1;
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (bufID < 0 || bufID >= LOG_ID_MAX) {
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        jniThrowNullPointerException(env, "bad bufID");
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return -1;
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tagObj != NULL)
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        tag = env->GetStringUTFChars(tagObj, NULL);
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    msg = env->GetStringUTFChars(msgObj, NULL);
1180d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian
1192b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
1202b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tag != NULL)
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        env->ReleaseStringUTFChars(tagObj, tag);
12359119e658a12279e8fff508f8773843de2d90917Mathias Agopian    env->ReleaseStringUTFChars(msgObj, msg);
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
125076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return res;
126076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian}
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * JNI registration.
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic JNINativeMethod gMethods[] = {
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /* name, signature, funcPtr */
1332b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian    { "isLoggable",      "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
1340d1318b974feba2e6ff13e36a1781343c2fce045Mathias Agopian    { "println_native",  "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
1352b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian};
1362b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian
1372b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopianint register_android_util_Log(JNIEnv* env)
1382b92d89e23e1a2a07d0e0d01c00eed33ea580affMathias Agopian{
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jclass clazz = env->FindClass("android/util/Log");
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (clazz == NULL) {
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ALOGE("Can't find android/util/Log");
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return -1;
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
148a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian    levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
149a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian    levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
150a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian    levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
1511f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
152a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
155a1e6bc864fb821c1b470b7aad9b75c441f54eeb4Mathias Agopian
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project