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