19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
27933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn * Copyright (C) 2007-2014 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
197b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn#include <log/log_event_list.h>
207b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn
2196bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn#include <log/log.h>
2296bf5985d5a360568832fd26b6d5b44236c9343eMark Salyzyn
232279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h>
24ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include "core_jni_helpers.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
273ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzyn#define UNUSED  __attribute__((__unused__))
283ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzyn
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gCollectionClass;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gCollectionAddID;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gEventClass;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gEventInitID;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gIntegerClass;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gIntegerValueID;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gLongClass;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gLongValueID;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brownstatic jclass gFloatClass;
44e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brownstatic jfieldID gFloatValueID;
45e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gStringClass;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog:
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  static native int writeEvent(int tag, int value)
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
523ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzynstatic jint android_util_EventLog_writeEvent_Integer(JNIEnv* env UNUSED,
533ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzyn                                                     jobject clazz UNUSED,
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                     jint tag, jint value)
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
567b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    android_log_event_list ctx(tag);
577b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    ctx << (int32_t)value;
587b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    return ctx.write();
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog:
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  static native int writeEvent(long tag, long value)
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
653ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzynstatic jint android_util_EventLog_writeEvent_Long(JNIEnv* env UNUSED,
663ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzyn                                                  jobject clazz UNUSED,
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                                  jint tag, jlong value)
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
697b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    android_log_event_list ctx(tag);
707b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    ctx << (int64_t)value;
717b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    return ctx.write();
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog:
76e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown *  static native int writeEvent(long tag, float value)
77e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown */
78e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brownstatic jint android_util_EventLog_writeEvent_Float(JNIEnv* env UNUSED,
79e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown                                                  jobject clazz UNUSED,
80e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown                                                  jint tag, jfloat value)
81e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown{
827b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    android_log_event_list ctx(tag);
837b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    ctx << (float)value;
847b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    return ctx.write();
85e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown}
86e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown
87e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown/*
88e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown * In class android.util.EventLog:
8962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor *  static native int writeEvent(int tag, String value)
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
913ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzynstatic jint android_util_EventLog_writeEvent_String(JNIEnv* env,
923ed8e2e679668767dc90c35a3a8a24e9ebf0b940Mark Salyzyn                                                    jobject clazz UNUSED,
9362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor                                                    jint tag, jstring value) {
947b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    android_log_event_list ctx(tag);
9562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor    // Don't throw NPE -- I feel like it's sort of mean for a logging function
9662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor    // to be all crashy if you pass in NULL -- but make the NULL value explicit.
977b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    if (value != NULL) {
987b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        const char *str = env->GetStringUTFChars(value, NULL);
997b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        ctx << str;
1007b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        env->ReleaseStringUTFChars(value, str);
1017b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    } else {
1027b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        ctx << "NULL";
1037b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    }
1047b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    return ctx.write();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * In class android.util.EventLog:
10962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor *  static native int writeEvent(long tag, Object... value)
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
11162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnorstatic jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
11262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor                                                   jint tag, jobjectArray value) {
1137b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    android_log_event_list ctx(tag);
1147b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (value == NULL) {
1167b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        ctx << "[NULL]";
1177b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        return ctx.write();
11862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor    }
11962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor
12062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor    jsize copied = 0, num = env->GetArrayLength(value);
1216916089e838662b41d902cd9a0d2560b04633ef9Dan Egnor    for (; copied < num && copied < 255; ++copied) {
1227b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        if (ctx.status()) break;
12362136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        jobject item = env->GetObjectArrayElement(value, copied);
1247b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        if (item == NULL) {
1257b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            ctx << "NULL";
1267b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn        } else if (env->IsInstanceOf(item, gStringClass)) {
1277b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            const char *str = env->GetStringUTFChars((jstring) item, NULL);
1287b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            ctx << str;
1297b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            env->ReleaseStringUTFChars((jstring) item, str);
13062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        } else if (env->IsInstanceOf(item, gIntegerClass)) {
1317b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            ctx << (int32_t)env->GetIntField(item, gIntegerValueID);
13262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        } else if (env->IsInstanceOf(item, gLongClass)) {
1337b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            ctx << (int64_t)env->GetLongField(item, gLongValueID);
134e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown        } else if (env->IsInstanceOf(item, gFloatClass)) {
1357b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn            ctx << (float)env->GetFloatField(item, gFloatValueID);
13662136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        } else {
13762136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor            jniThrowException(env,
13862136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor                    "java/lang/IllegalArgumentException",
13962136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor                    "Invalid payload item type");
14062136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor            return -1;
14162136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        }
14262136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor        env->DeleteLocalRef(item);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1447b25bb8ec79e420e9655a00301cbca80a38cde2dMark Salyzyn    return ctx.write();
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
147d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wrenstatic void readEvents(JNIEnv* env, int loggerMode, jintArray tags, jlong startTime, jobject out) {
148d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    struct logger_list *logger_list;
149d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    if (startTime) {
150d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        logger_list = android_logger_list_alloc_time(loggerMode,
151d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0);
152d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    } else {
153d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        logger_list = android_logger_list_alloc(loggerMode, 0, 0);
154d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    }
155d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    if (!logger_list) {
156d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        jniThrowIOException(env, errno);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
160d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    if (!android_logger_open(logger_list, LOG_ID_EVENTS)) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        jniThrowIOException(env, errno);
162d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        android_logger_list_free(logger_list);
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jsize tagLength = env->GetArrayLength(tags);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    jint *tagValues = env->GetIntArrayElements(tags, NULL);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1697933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn    while (1) {
1707933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        log_msg log_msg;
1717933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        int ret = android_logger_list_read(logger_list, &log_msg);
17278158db51029e7dbe160e60af0deb7594bec051dDan Egnor
1737933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        if (ret == 0) {
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1757933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        }
1767933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        if (ret < 0) {
177b519aeca47a7b798926c00ce5c8cf730e26e75fdMark Salyzyn            if (ret == -EINTR) {
1787933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn                continue;
1797933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            }
180b519aeca47a7b798926c00ce5c8cf730e26e75fdMark Salyzyn            if (ret == -EINVAL) {
1817933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn                jniThrowException(env, "java/io/IOException", "Event too short");
182b519aeca47a7b798926c00ce5c8cf730e26e75fdMark Salyzyn            } else if (ret != -EAGAIN) {
183b519aeca47a7b798926c00ce5c8cf730e26e75fdMark Salyzyn                jniThrowIOException(env, -ret);  // Will throw on return
1847933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
188ca50cd2114f2c509ae2d1d06468e61f3cfc0b280Mark Salyzyn        if (log_msg.id() != LOG_ID_EVENTS) {
189ca50cd2114f2c509ae2d1d06468e61f3cfc0b280Mark Salyzyn            continue;
190ca50cd2114f2c509ae2d1d06468e61f3cfc0b280Mark Salyzyn        }
191ca50cd2114f2c509ae2d1d06468e61f3cfc0b280Mark Salyzyn
1927933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn        int32_t tag = * (int32_t *) log_msg.msg();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int found = 0;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; !found && i < tagLength; ++i) {
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            found = (tag == tagValues[i]);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (found) {
2007933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            jsize len = ret;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jbyteArray array = env->NewByteArray(len);
2027933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            if (array == NULL) {
2037933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn                break;
2047933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jbyte *bytes = env->GetByteArrayElements(array, NULL);
2077933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            memcpy(bytes, log_msg.buf, len);
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->ReleaseByteArrayElements(array, bytes, 0);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            jobject event = env->NewObject(gEventClass, gEventInitID, array);
2117933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            if (event == NULL) {
2127933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn                break;
2137933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn            }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->CallBooleanMethod(out, gCollectionAddID, event);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->DeleteLocalRef(event);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->DeleteLocalRef(array);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2217933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn    android_logger_list_close(logger_list);
2227933c2943f4a13b56944ad92e2194ed0020e5b04Mark Salyzyn
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->ReleaseIntArrayElements(tags, tagValues, 0);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22695ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller/*
227d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren * In class android.util.EventLog:
228d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *  static native void readEvents(int[] tags, Collection<Event> output)
229d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *
230d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *  Reads events from the event log
231d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren */
232d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wrenstatic void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED,
233d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                                             jintArray tags,
234d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                                             jobject out) {
235d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren
236d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    if (tags == NULL || out == NULL) {
237d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        jniThrowNullPointerException(env, NULL);
238d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        return;
239d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    }
240d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren
241d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, tags, 0, out);
242d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren }
243d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren/*
244d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren * In class android.util.EventLog:
245d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *  static native void readEventsOnWrapping(int[] tags, long timestamp, Collection<Event> output)
246d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *
247d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren *  Reads events from the event log, blocking until events after timestamp are to be overwritten.
248d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren */
249d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wrenstatic void android_util_EventLog_readEventsOnWrapping(JNIEnv* env, jobject clazz UNUSED,
250d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                                             jintArray tags,
251d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                                             jlong timestamp,
252d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren                                             jobject out) {
253d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    if (tags == NULL || out == NULL) {
254d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        jniThrowNullPointerException(env, NULL);
255d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren        return;
256d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    }
257d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP,
258d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren            tags, timestamp, out);
259d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren}
260d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren
261d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren/*
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration.
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
26476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gRegisterMethods[] = {
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* name, signature, funcPtr */
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "writeEvent", "(II)I", (void*) android_util_EventLog_writeEvent_Integer },
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "writeEvent", "(IJ)I", (void*) android_util_EventLog_writeEvent_Long },
268e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown    { "writeEvent", "(IF)I", (void*) android_util_EventLog_writeEvent_Float },
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "writeEvent",
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "(ILjava/lang/String;)I",
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      (void*) android_util_EventLog_writeEvent_String
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    },
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "writeEvent",
27462136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor      "(I[Ljava/lang/Object;)I",
27562136d3e1c1262fc31a1f77f6d6acbd75e5ea81dDan Egnor      (void*) android_util_EventLog_writeEvent_Array
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    },
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "readEvents",
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      "([ILjava/util/Collection;)V",
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      (void*) android_util_EventLog_readEvents
28095ff2401a9c6f0252aeedfa27ba0a9a5f0d7f55eJim Miller    },
281d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    { "readEventsOnWrapping",
282d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren      "([IJLjava/util/Collection;)V",
283d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren      (void*) android_util_EventLog_readEventsOnWrapping
284d09bf8271eea566ed064bd333f9564c4dd718c5bChris Wren    },
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { const char *name; jclass *clazz; } gClasses[] = {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "android/util/EventLog$Event", &gEventClass },
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "java/lang/Integer", &gIntegerClass },
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "java/lang/Long", &gLongClass },
291e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown    { "java/lang/Float", &gFloatClass },
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "java/lang/String", &gStringClass },
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "java/util/Collection", &gCollectionClass },
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { &gIntegerClass, "value", "I", &gIntegerValueID },
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { &gLongClass, "value", "J", &gLongValueID },
299e7e9ccea3246eec3607bfc77bc8500611989e84cJeff Brown    { &gFloatClass, "value", "F", &gFloatValueID },
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = {
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { &gEventClass, "<init>", "([B)V", &gEventInitID },
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID },
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_util_EventLog(JNIEnv* env) {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < NELEM(gClasses); ++i) {
309ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe        jclass clazz = FindClassOrDie(env, gClasses[i].name);
310ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe        *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz);
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < NELEM(gFields); ++i) {
314ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe        *gFields[i].id = GetFieldIDOrDie(env,
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *gFields[i].c, gFields[i].name, gFields[i].ft);
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (int i = 0; i < NELEM(gMethods); ++i) {
319ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe        *gMethods[i].id = GetMethodIDOrDie(env,
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *gMethods[i].c, gMethods[i].name, gMethods[i].mt);
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
323ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env,
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "android/util/EventLog",
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            gRegisterMethods, NELEM(gRegisterMethods));
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
330