Loading core/jni/android_util_EventLog.cpp +32 −39 Original line number Diff line number Diff line /* * Copyright (C) 2007 The Android Open Source Project * Copyright (C) 2007-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -142,18 +142,21 @@ static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz, * In class android.util.EventLog: * static native void readEvents(int[] tags, Collection<Event> output) * * Reads events from the event log, typically /dev/log/events * Reads events from the event log */ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, jintArray tags, jobject out) { if (tags == NULL || out == NULL) { jniThrowNullPointerException(env, NULL); return; } int fd = open("/dev/" LOGGER_LOG_EVENTS, O_RDONLY | O_NONBLOCK); if (fd < 0) { struct logger_list *logger_list = android_logger_list_open( LOG_ID_EVENTS, O_RDONLY | O_NONBLOCK, 0, 0); if (!logger_list) { jniThrowIOException(env, errno); return; } Loading @@ -161,41 +164,26 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, jsize tagLength = env->GetArrayLength(tags); jint *tagValues = env->GetIntArrayElements(tags, NULL); uint8_t buf[LOGGER_ENTRY_MAX_LEN]; struct timeval timeout = {0, 0}; fd_set readset; FD_ZERO(&readset); for (;;) { // Use a short select() to try to avoid problems hanging on read(). // This means we block for 5ms at the end of the log -- oh well. timeout.tv_usec = 5000; FD_SET(fd, &readset); int r = select(fd + 1, &readset, NULL, NULL, &timeout); if (r == 0) { break; // no more events } else if (r < 0 && errno == EINTR) { continue; // interrupted by signal, try again } else if (r < 0) { jniThrowIOException(env, errno); // Will throw on return break; } while (1) { log_msg log_msg; int ret = android_logger_list_read(logger_list, &log_msg); int len = read(fd, buf, sizeof(buf)); if (len == 0 || (len < 0 && errno == EAGAIN)) { break; // no more events } else if (len < 0 && errno == EINTR) { continue; // interrupted by signal, try again } else if (len < 0) { jniThrowIOException(env, errno); // Will throw on return if (ret == 0) { break; } else if ((size_t) len < sizeof(logger_entry) + sizeof(int32_t)) { } if (ret < 0) { if (errno == EINTR) { continue; } if (errno == EINVAL) { jniThrowException(env, "java/io/IOException", "Event too short"); } else if (errno != EAGAIN) { jniThrowIOException(env, errno); // Will throw on return } break; } logger_entry* entry = (logger_entry*) buf; int32_t tag = * (int32_t*) (buf + sizeof(*entry)); int32_t tag = * (int32_t *) log_msg.msg(); int found = 0; for (int i = 0; !found && i < tagLength; ++i) { Loading @@ -203,16 +191,20 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, } if (found) { jsize len = sizeof(*entry) + entry->len; jsize len = ret; jbyteArray array = env->NewByteArray(len); if (array == NULL) break; if (array == NULL) { break; } jbyte *bytes = env->GetByteArrayElements(array, NULL); memcpy(bytes, buf, len); memcpy(bytes, log_msg.buf, len); env->ReleaseByteArrayElements(array, bytes, 0); jobject event = env->NewObject(gEventClass, gEventInitID, array); if (event == NULL) break; if (event == NULL) { break; } env->CallBooleanMethod(out, gCollectionAddID, event); env->DeleteLocalRef(event); Loading @@ -220,7 +212,8 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, } } close(fd); android_logger_list_close(logger_list); env->ReleaseIntArrayElements(tags, tagValues, 0); } Loading Loading
core/jni/android_util_EventLog.cpp +32 −39 Original line number Diff line number Diff line /* * Copyright (C) 2007 The Android Open Source Project * Copyright (C) 2007-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -142,18 +142,21 @@ static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz, * In class android.util.EventLog: * static native void readEvents(int[] tags, Collection<Event> output) * * Reads events from the event log, typically /dev/log/events * Reads events from the event log */ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, jintArray tags, jobject out) { if (tags == NULL || out == NULL) { jniThrowNullPointerException(env, NULL); return; } int fd = open("/dev/" LOGGER_LOG_EVENTS, O_RDONLY | O_NONBLOCK); if (fd < 0) { struct logger_list *logger_list = android_logger_list_open( LOG_ID_EVENTS, O_RDONLY | O_NONBLOCK, 0, 0); if (!logger_list) { jniThrowIOException(env, errno); return; } Loading @@ -161,41 +164,26 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, jsize tagLength = env->GetArrayLength(tags); jint *tagValues = env->GetIntArrayElements(tags, NULL); uint8_t buf[LOGGER_ENTRY_MAX_LEN]; struct timeval timeout = {0, 0}; fd_set readset; FD_ZERO(&readset); for (;;) { // Use a short select() to try to avoid problems hanging on read(). // This means we block for 5ms at the end of the log -- oh well. timeout.tv_usec = 5000; FD_SET(fd, &readset); int r = select(fd + 1, &readset, NULL, NULL, &timeout); if (r == 0) { break; // no more events } else if (r < 0 && errno == EINTR) { continue; // interrupted by signal, try again } else if (r < 0) { jniThrowIOException(env, errno); // Will throw on return break; } while (1) { log_msg log_msg; int ret = android_logger_list_read(logger_list, &log_msg); int len = read(fd, buf, sizeof(buf)); if (len == 0 || (len < 0 && errno == EAGAIN)) { break; // no more events } else if (len < 0 && errno == EINTR) { continue; // interrupted by signal, try again } else if (len < 0) { jniThrowIOException(env, errno); // Will throw on return if (ret == 0) { break; } else if ((size_t) len < sizeof(logger_entry) + sizeof(int32_t)) { } if (ret < 0) { if (errno == EINTR) { continue; } if (errno == EINVAL) { jniThrowException(env, "java/io/IOException", "Event too short"); } else if (errno != EAGAIN) { jniThrowIOException(env, errno); // Will throw on return } break; } logger_entry* entry = (logger_entry*) buf; int32_t tag = * (int32_t*) (buf + sizeof(*entry)); int32_t tag = * (int32_t *) log_msg.msg(); int found = 0; for (int i = 0; !found && i < tagLength; ++i) { Loading @@ -203,16 +191,20 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, } if (found) { jsize len = sizeof(*entry) + entry->len; jsize len = ret; jbyteArray array = env->NewByteArray(len); if (array == NULL) break; if (array == NULL) { break; } jbyte *bytes = env->GetByteArrayElements(array, NULL); memcpy(bytes, buf, len); memcpy(bytes, log_msg.buf, len); env->ReleaseByteArrayElements(array, bytes, 0); jobject event = env->NewObject(gEventClass, gEventInitID, array); if (event == NULL) break; if (event == NULL) { break; } env->CallBooleanMethod(out, gCollectionAddID, event); env->DeleteLocalRef(event); Loading @@ -220,7 +212,8 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz, } } close(fd); android_logger_list_close(logger_list); env->ReleaseIntArrayElements(tags, tagValues, 0); } Loading