1 /* 2 * Copyright (C) 2013, 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 #include "log_utils.h" 18 19 #include <cstdio> 20 #include <stdarg.h> 21 22 #include "defines.h" 23 24 namespace latinime { 25 /* static */ void LogUtils::logToJava(JNIEnv *const env, const char *const format, ...) { 26 static const char *TAG = "LatinIME:LogUtils"; 27 const jclass androidUtilLogClass = env->FindClass("android/util/Log"); 28 if (!androidUtilLogClass) { 29 // If we can't find the class, we are probably in off-device testing, and 30 // it's expected. Regardless, logging is not essential to functionality, so 31 // we should just return. However, FindClass has thrown an exception behind 32 // our back and there is no way to prevent it from doing that, so we clear 33 // the exception before we return. 34 env->ExceptionClear(); 35 return; 36 } 37 const jmethodID logDotIMethodId = env->GetStaticMethodID(androidUtilLogClass, "i", 38 "(Ljava/lang/String;Ljava/lang/String;)I"); 39 if (!logDotIMethodId) { 40 env->ExceptionClear(); 41 if (androidUtilLogClass) env->DeleteLocalRef(androidUtilLogClass); 42 return; 43 } 44 const jstring javaTag = env->NewStringUTF(TAG); 45 46 static const int DEFAULT_LINE_SIZE = 128; 47 char fixedSizeCString[DEFAULT_LINE_SIZE]; 48 va_list argList; 49 va_start(argList, format); 50 // Get the necessary size. Add 1 for the 0 terminator. 51 const int size = vsnprintf(fixedSizeCString, DEFAULT_LINE_SIZE, format, argList) + 1; 52 va_end(argList); 53 54 jstring javaString; 55 if (size <= DEFAULT_LINE_SIZE) { 56 // The buffer was large enough. 57 javaString = env->NewStringUTF(fixedSizeCString); 58 } else { 59 // The buffer was not large enough. 60 va_start(argList, format); 61 char variableSizeCString[size]; 62 vsnprintf(variableSizeCString, size, format, argList); 63 va_end(argList); 64 javaString = env->NewStringUTF(variableSizeCString); 65 } 66 67 env->CallStaticIntMethod(androidUtilLogClass, logDotIMethodId, javaTag, javaString); 68 if (javaString) env->DeleteLocalRef(javaString); 69 if (javaTag) env->DeleteLocalRef(javaTag); 70 if (androidUtilLogClass) env->DeleteLocalRef(androidUtilLogClass); 71 } 72 } 73