android_util_Log.cpp revision c1b9bbb21c8ad5109978a4e9e770cd18b0257434
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
21c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <assert.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "jni.h"
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "JNIHelp.h"
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "utils/misc.h"
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "android_runtime/AndroidRuntime.h"
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define MIN(a,b) ((a<b)?a:b)
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstruct levels_t {
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jint verbose;
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    jint debug;
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    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};
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic levels_t levels;
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
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;
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'W': return levels.warn;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'E': return levels.error;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'A': return levels.assert;
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        case 'S': return -1; // SUPPRESS
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return levels.info;
57}
58
59static jboolean android_util_Log_isLoggable(JNIEnv* env, jobject clazz, jstring tag, jint level)
60{
61    int len;
62    char key[PROPERTY_KEY_MAX];
63    char buf[PROPERTY_VALUE_MAX];
64
65    if (tag == NULL) {
66        return false;
67    }
68
69    jboolean result = false;
70
71    const char* chars = env->GetStringUTFChars(tag, NULL);
72
73    if ((strlen(chars)+sizeof(LOG_NAMESPACE)) > PROPERTY_KEY_MAX) {
74        char buf2[200];
75        snprintf(buf2, sizeof(buf2), "Log tag \"%s\" exceeds limit of %d characters\n",
76                chars, PROPERTY_KEY_MAX - sizeof(LOG_NAMESPACE));
77
78        // release the chars!
79        env->ReleaseStringUTFChars(tag, chars);
80
81        jniThrowException(env, "java/lang/IllegalArgumentException", buf2);
82        return false;
83    } else {
84        strncpy(key, LOG_NAMESPACE, sizeof(LOG_NAMESPACE)-1);
85        strcpy(key + sizeof(LOG_NAMESPACE) - 1, chars);
86    }
87
88    env->ReleaseStringUTFChars(tag, chars);
89
90    len = property_get(key, buf, "");
91    int logLevel = toLevel(buf);
92    return (logLevel >= 0 && level >= logLevel) ? true : false;
93}
94
95/*
96 * In class android.util.Log:
97 *  public static native int println_native(int buffer, int priority, String tag, String msg)
98 */
99static jint android_util_Log_println_native(JNIEnv* env, jobject clazz,
100        jint bufID, jint priority, jstring tagObj, jstring msgObj)
101{
102    const char* tag = NULL;
103    const char* msg = NULL;
104
105    if (msgObj == NULL) {
106        jniThrowNullPointerException(env, "println needs a message");
107        return -1;
108    }
109
110    if (bufID < 0 || bufID >= LOG_ID_MAX) {
111        jniThrowNullPointerException(env, "bad bufID");
112        return -1;
113    }
114
115    if (tagObj != NULL)
116        tag = env->GetStringUTFChars(tagObj, NULL);
117    msg = env->GetStringUTFChars(msgObj, NULL);
118
119    int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
120
121    if (tag != NULL)
122        env->ReleaseStringUTFChars(tagObj, tag);
123    env->ReleaseStringUTFChars(msgObj, msg);
124
125    return res;
126}
127
128/*
129 * JNI registration.
130 */
131static JNINativeMethod gMethods[] = {
132    /* name, signature, funcPtr */
133    { "isLoggable",      "(Ljava/lang/String;I)Z", (void*) android_util_Log_isLoggable },
134    { "println_native",  "(IILjava/lang/String;Ljava/lang/String;)I", (void*) android_util_Log_println_native },
135};
136
137int register_android_util_Log(JNIEnv* env)
138{
139    jclass clazz = env->FindClass("android/util/Log");
140
141    if (clazz == NULL) {
142        LOGE("Can't find android/util/Log");
143        return -1;
144    }
145
146    levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
147    levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
148    levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
149    levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
150    levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
151    levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
152
153    return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
154}
155
156}; // namespace android
157