android_util_EventLog.cpp revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_runtime/AndroidRuntime.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "cutils/logger.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define END_DELIMITER '\n' 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INT_BUFFER_SIZE (sizeof(jbyte)+sizeof(jint)+sizeof(END_DELIMITER)) 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LONG_BUFFER_SIZE (sizeof(jbyte)+sizeof(jlong)+sizeof(END_DELIMITER)) 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INITAL_BUFFER_CAPACITY 256 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define MAX(a,b) ((a>b)?a:b) 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gCollectionClass; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gCollectionAddID; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gEventClass; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gEventInitID; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gIntegerClass; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gIntegerValueID; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gListClass; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gListItemsID; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gLongClass; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gLongValueID; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gStringClass; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ByteBuf { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t len; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t capacity; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t* buf; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteBuf(size_t initSize) { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = (uint8_t*)malloc(initSize); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = 0; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project capacity = initSize; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~ByteBuf() { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free(buf); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool ensureExtraCapacity(size_t extra) { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t spaceNeeded = len + extra; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (spaceNeeded > capacity) { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t newCapacity = MAX(spaceNeeded, 2 * capacity); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* newBuf = realloc(buf, newCapacity); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newBuf == NULL) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project capacity = newCapacity; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf = (uint8_t*)newBuf; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void putIntEvent(jint value) { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool succeeded = ensureExtraCapacity(INT_BUFFER_SIZE); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[len++] = EVENT_TYPE_INT; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf+len, &value, sizeof(jint)); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len += sizeof(jint); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void putByte(uint8_t value) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool succeeded = ensureExtraCapacity(sizeof(uint8_t)); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[len++] = value; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void putLongEvent(jlong value) { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool succeeded = ensureExtraCapacity(LONG_BUFFER_SIZE); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[len++] = EVENT_TYPE_LONG; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf+len, &value, sizeof(jlong)); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len += sizeof(jlong); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void putStringEvent(JNIEnv* env, jstring value) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char* strValue = env->GetStringUTFChars(value, NULL); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t strLen = strlen(strValue); //env->GetStringUTFLength(value); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool succeeded = ensureExtraCapacity(1 + sizeof(uint32_t) + strLen); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[len++] = EVENT_TYPE_STRING; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf+len, &strLen, sizeof(uint32_t)); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len += sizeof(uint32_t); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(buf+len, strValue, strLen); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseStringUTFChars(value, strValue); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len += strLen; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void putList(JNIEnv* env, jobject list) { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobjectArray items = (jobjectArray) env->GetObjectField(list, gListItemsID); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (items == NULL) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/NullPointerException", NULL); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize numItems = env->GetArrayLength(items); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putByte(EVENT_TYPE_LIST); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putByte(numItems); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We'd like to call GetPrimitveArrayCritical() but that might 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // not be safe since we're going to be doing some I/O 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < numItems; i++) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject item = env->GetObjectArrayElement(items, i); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->IsInstanceOf(item, gIntegerClass)) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint intVal = env->GetIntField(item, gIntegerValueID); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putIntEvent(intVal); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (env->IsInstanceOf(item, gLongClass)) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong longVal = env->GetLongField(item, gLongValueID); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putLongEvent(longVal); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (env->IsInstanceOf(item, gStringClass)) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putStringEvent(env, (jstring)item); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (env->IsInstanceOf(item, gListClass)) { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project putList(env, item); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException( 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env, 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "java/lang/IllegalArgumentException", 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Attempt to log an illegal item type."); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(item); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(items); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog: 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * static native int writeEvent(int tag, int value) 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_util_EventLog_writeEvent_Integer(JNIEnv* env, jobject clazz, 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint tag, jint value) 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return android_btWriteLog(tag, EVENT_TYPE_INT, &value, sizeof(value)); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog: 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * static native int writeEvent(long tag, long value) 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_util_EventLog_writeEvent_Long(JNIEnv* env, jobject clazz, 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint tag, jlong value) 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return android_btWriteLog(tag, EVENT_TYPE_LONG, &value, sizeof(value)); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog: 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * static native int writeEvent(long tag, List value) 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_util_EventLog_writeEvent_List(JNIEnv* env, jobject clazz, 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint tag, jobject value) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == NULL) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("java/lang/IllegalArgumentException"); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ThrowNew(clazz, "writeEvent needs a value."); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteBuf byteBuf(INITAL_BUFFER_CAPACITY); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuf.putList(env, value); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuf.putByte((uint8_t)END_DELIMITER); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numBytesPut = byteBuf.len; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bytesWritten = android_bWriteLog(tag, byteBuf.buf, numBytesPut); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bytesWritten; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog: 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * static native int writeEvent(int tag, String value) 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_util_EventLog_writeEvent_String(JNIEnv* env, jobject clazz, 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint tag, jstring value) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == NULL) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("java/lang/IllegalArgumentException"); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ThrowNew(clazz, "logEvent needs a value."); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteBuf byteBuf(INITAL_BUFFER_CAPACITY); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuf.putStringEvent(env, value); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byteBuf.putByte((uint8_t)END_DELIMITER); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numBytesPut = byteBuf.len; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bytesWritten = android_bWriteLog(tag, byteBuf.buf, numBytesPut); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bytesWritten; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog: 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * static native void readEvents(int[] tags, Collection<Event> output) 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray tags, 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject out) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (tags == NULL || out == NULL) { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/lang/NullPointerException", NULL); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = open("/dev/" LOGGER_LOG_EVENTS, O_RDONLY | O_NONBLOCK); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize tagLength = env->GetArrayLength(tags); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint *tagValues = env->GetIntArrayElements(tags, NULL); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t buf[LOGGER_ENTRY_MAX_LEN]; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = read(fd, buf, sizeof(buf)); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 0 || (len < 0 && errno == EAGAIN)) { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len < 0) { 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This calls env->ThrowNew(), which doesn't throw an exception 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now, but sets a flag to trigger an exception after we return. 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowIOException(env, errno); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((size_t) len < sizeof(logger_entry) + sizeof(int32_t)) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowException(env, "java/io/IOException", "Event too short"); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project logger_entry* entry = (logger_entry*) buf; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t tag = * (int32_t*) (buf + sizeof(*entry)); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int found = 0; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; !found && i < tagLength; ++i) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project found = (tag == tagValues[i]); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (found) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jsize len = sizeof(*entry) + entry->len; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray array = env->NewByteArray(len); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (array == NULL) break; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyte *bytes = env->GetByteArrayElements(array, NULL); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(bytes, buf, len); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseByteArrayElements(array, bytes, 0); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject event = env->NewObject(gEventClass, gEventInitID, array); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == NULL) break; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallBooleanMethod(out, gCollectionAddID, event); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(event); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(array); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(tags, tagValues, 0); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gRegisterMethods[] = { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer }, 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long }, 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "writeEvent", 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(ILjava/lang/String;)I", 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_util_EventLog_writeEvent_String 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "writeEvent", 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "(ILandroid/util/EventLog$List;)I", 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_util_EventLog_writeEvent_List 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }, 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "readEvents", 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "([ILjava/util/Collection;)V", 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_util_EventLog_readEvents 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { const char *name; jclass *clazz; } gClasses[] = { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "android/util/EventLog$Event", &gEventClass }, 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "android/util/EventLog$List", &gListClass }, 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "java/lang/Integer", &gIntegerClass }, 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "java/lang/Long", &gLongClass }, 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "java/lang/String", &gStringClass }, 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "java/util/Collection", &gCollectionClass }, 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { &gIntegerClass, "value", "I", &gIntegerValueID }, 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { &gListClass, "mItems", "[Ljava/lang/Object;", &gListItemsID }, 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { &gLongClass, "value", "J", &gLongValueID }, 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { &gEventClass, "<init>", "([B)V", &gEventInitID }, 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_util_EventLog(JNIEnv* env) { 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NELEM(gClasses); ++i) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass(gClasses[i].name); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (clazz == NULL) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Can't find class: %s\n", gClasses[i].name); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *gClasses[i].clazz = (jclass) env->NewGlobalRef(clazz); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NELEM(gFields); ++i) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *gFields[i].id = env->GetFieldID( 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *gFields[i].c, gFields[i].name, gFields[i].ft); 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*gFields[i].id == NULL) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Can't find field: %s\n", gFields[i].name); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < NELEM(gMethods); ++i) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *gMethods[i].id = env->GetMethodID( 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *gMethods[i].c, gMethods[i].name, gMethods[i].mt); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (*gMethods[i].id == NULL) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Can't find method: %s\n", gMethods[i].name); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AndroidRuntime::registerNativeMethods( 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env, 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android/util/EventLog", 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gRegisterMethods, NELEM(gRegisterMethods)); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 354