16235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski/* 26235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * Copyright (C) 2016 The Android Open Source Project 36235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * 46235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * Licensed under the Apache License, Version 2.0 (the "License"); 56235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * you may not use this file except in compliance with the License. 66235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * You may obtain a copy of the License at 76235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * 86235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * http://www.apache.org/licenses/LICENSE-2.0 96235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * 106235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * Unless required by applicable law or agreed to in writing, software 116235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * distributed under the License is distributed on an "AS IS" BASIS, 126235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * See the License for the specific language governing permissions and 146235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * limitations under the License. 156235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski */ 166235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 176235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski#include <fcntl.h> 186235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 196235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski#include "JNIHelp.h" 206235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski#include "core_jni_helpers.h" 216235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski#include "jni.h" 22834763b2ab872bf31a5d6ad9dcb0f76a6aad82fcMark Salyzyn#include <private/android_logger.h> 236235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 246235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski// The size of the tag number comes out of the payload size. 256235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t)) 266235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 276235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskinamespace android { 286235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 296235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gCollectionClass; 306235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jmethodID gCollectionAddID; 316235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 326235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gEventClass; 336235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jmethodID gEventInitID; 346235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 356235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gIntegerClass; 366235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jfieldID gIntegerValueID; 376235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 386235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gLongClass; 396235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jfieldID gLongValueID; 406235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 416235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gFloatClass; 426235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jfieldID gFloatValueID; 436235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 446235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jclass gStringClass; 456235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 466235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 476235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jboolean android_app_admin_SecurityLog_isLoggingEnabled(JNIEnv* env, 486235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject /* clazz */) { 496235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return (bool)__android_log_security(); 506235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 516235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 526235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jint android_app_admin_SecurityLog_writeEvent_String(JNIEnv* env, 536235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject /* clazz */, 546235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jint tag, jstring value) { 556235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski uint8_t buf[MAX_EVENT_PAYLOAD]; 566235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 576235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski // Don't throw NPE -- I feel like it's sort of mean for a logging function 586235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski // to be all crashy if you pass in NULL -- but make the NULL value explicit. 596235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL"; 606235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski uint32_t len = strlen(str); 616235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski size_t max = sizeof(buf) - sizeof(len) - 2; // Type byte, final newline 626235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (len > max) len = max; 636235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 646235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[0] = EVENT_TYPE_STRING; 656235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[1], &len, sizeof(len)); 666235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[1 + sizeof(len)], str, len); 676235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[1 + sizeof(len) + len] = '\n'; 686235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 696235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (value != NULL) env->ReleaseStringUTFChars(value, str); 706235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return __android_log_security_bwrite(tag, buf, 2 + sizeof(len) + len); 716235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 726235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 736235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic jint android_app_admin_SecurityLog_writeEvent_Array(JNIEnv* env, jobject clazz, 746235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jint tag, jobjectArray value) { 756235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (value == NULL) { 766235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return android_app_admin_SecurityLog_writeEvent_String(env, clazz, tag, NULL); 776235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 786235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 796235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski uint8_t buf[MAX_EVENT_PAYLOAD]; 806235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski const size_t max = sizeof(buf) - 1; // leave room for final newline 816235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski size_t pos = 2; // Save room for type tag & array count 826235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 836235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jsize copied = 0, num = env->GetArrayLength(value); 846235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski for (; copied < num && copied < 255; ++copied) { 856235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject item = env->GetObjectArrayElement(value, copied); 866235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (item == NULL || env->IsInstanceOf(item, gStringClass)) { 876235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (pos + 1 + sizeof(jint) > max) break; 886235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL"; 896235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jint len = strlen(str); 906235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len); 916235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[pos++] = EVENT_TYPE_STRING; 926235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[pos], &len, sizeof(len)); 936235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[pos + sizeof(len)], str, len); 946235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski pos += sizeof(len) + len; 956235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str); 966235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else if (env->IsInstanceOf(item, gIntegerClass)) { 976235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jint intVal = env->GetIntField(item, gIntegerValueID); 986235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (pos + 1 + sizeof(intVal) > max) break; 996235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[pos++] = EVENT_TYPE_INT; 1006235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[pos], &intVal, sizeof(intVal)); 1016235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski pos += sizeof(intVal); 1026235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else if (env->IsInstanceOf(item, gLongClass)) { 1036235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jlong longVal = env->GetLongField(item, gLongValueID); 1046235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (pos + 1 + sizeof(longVal) > max) break; 1056235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[pos++] = EVENT_TYPE_LONG; 1066235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[pos], &longVal, sizeof(longVal)); 1076235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski pos += sizeof(longVal); 1086235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else if (env->IsInstanceOf(item, gFloatClass)) { 1096235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jfloat floatVal = env->GetFloatField(item, gFloatValueID); 1106235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (pos + 1 + sizeof(floatVal) > max) break; 1116235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[pos++] = EVENT_TYPE_FLOAT; 1126235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(&buf[pos], &floatVal, sizeof(floatVal)); 1136235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski pos += sizeof(floatVal); 1146235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else { 1156235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowException(env, 1166235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "java/lang/IllegalArgumentException", 1176235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "Invalid payload item type"); 1186235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return -1; 1196235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1206235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env->DeleteLocalRef(item); 1216235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1226235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1236235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[0] = EVENT_TYPE_LIST; 1246235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[1] = copied; 1256235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski buf[pos++] = '\n'; 1266235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return __android_log_security_bwrite(tag, buf, pos); 1276235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 1286235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1296235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic void readEvents(JNIEnv* env, int loggerMode, jlong startTime, jobject out) { 1306235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski struct logger_list *logger_list; 1316235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (startTime) { 1326235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski logger_list = android_logger_list_alloc_time(loggerMode, 1336235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski log_time(startTime / NS_PER_SEC, startTime % NS_PER_SEC), 0); 1346235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else { 1356235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski logger_list = android_logger_list_alloc(loggerMode, 0, 0); 1366235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1376235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (!logger_list) { 1386235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowIOException(env, errno); 1396235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 1406235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1416235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1426235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (!android_logger_open(logger_list, LOG_ID_SECURITY)) { 1436235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowIOException(env, errno); 1446235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski android_logger_list_free(logger_list); 1456235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 1466235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1476235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1486235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski while (1) { 1496235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski log_msg log_msg; 1506235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski int ret = android_logger_list_read(logger_list, &log_msg); 1516235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1526235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (ret == 0) { 1536235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski break; 1546235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1556235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (ret < 0) { 1566235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (ret == -EINTR) { 1576235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski continue; 1586235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1596235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (ret == -EINVAL) { 1606235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowException(env, "java/io/IOException", "Event too short"); 1616235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } else if (ret != -EAGAIN) { 1626235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowIOException(env, -ret); // Will throw on return 1636235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1646235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski break; 1656235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1666235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1676235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (log_msg.id() != LOG_ID_SECURITY) { 1686235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski continue; 1696235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1706235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1716235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jsize len = ret; 1726235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jbyteArray array = env->NewByteArray(len); 1736235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (array == NULL) { 1746235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski break; 1756235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1766235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1776235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jbyte *bytes = env->GetByteArrayElements(array, NULL); 1786235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski memcpy(bytes, log_msg.buf, len); 1796235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env->ReleaseByteArrayElements(array, bytes, 0); 1806235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1816235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject event = env->NewObject(gEventClass, gEventInitID, array); 1826235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (event == NULL) { 1836235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski break; 1846235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1856235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1866235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env->CallBooleanMethod(out, gCollectionAddID, event); 1876235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env->DeleteLocalRef(event); 1886235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env->DeleteLocalRef(array); 1896235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 1906235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1916235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski android_logger_list_close(logger_list); 1926235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 1936235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1946235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic void android_app_admin_SecurityLog_readEvents(JNIEnv* env, jobject /* clazz */, 1956235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject out) { 1966235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 1976235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (out == NULL) { 1986235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowNullPointerException(env, NULL); 1996235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 2006235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 2016235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, out); 2026235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 2036235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2046235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic void android_app_admin_SecurityLog_readEventsSince(JNIEnv* env, jobject /* clazz */, 2056235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jlong timestamp, 2066235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject out) { 2076235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2086235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (out == NULL) { 2096235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowNullPointerException(env, NULL); 2106235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 2116235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 2126235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, timestamp, out); 2136235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 2146235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2156235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic void android_app_admin_SecurityLog_readPreviousEvents(JNIEnv* env, jobject /* clazz */, 2166235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject out) { 2176235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2186235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (out == NULL) { 2196235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowNullPointerException(env, NULL); 2206235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 2216235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 2226235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_PSTORE, 0, out); 2236235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 2246235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2256235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic void android_app_admin_SecurityLog_readEventsOnWrapping(JNIEnv* env, jobject /* clazz */, 2266235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jlong timestamp, 2276235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jobject out) { 2286235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski if (out == NULL) { 2296235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jniThrowNullPointerException(env, NULL); 2306235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return; 2316235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 2326235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski readEvents(env, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK | ANDROID_LOG_WRAP, timestamp, out); 2336235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 2346235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2356235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski/* 2366235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski * JNI registration. 2376235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski */ 2386235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic const JNINativeMethod gRegisterMethods[] = { 2396235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski /* name, signature, funcPtr */ 2406235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "isLoggingEnabled", 2416235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "()Z", 2426235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_isLoggingEnabled 2436235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2446235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "writeEvent", 2456235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(ILjava/lang/String;)I", 2466235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_writeEvent_String 2476235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2486235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "writeEvent", 2496235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(I[Ljava/lang/Object;)I", 2506235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_writeEvent_Array 2516235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2526235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "readEvents", 2536235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(Ljava/util/Collection;)V", 2546235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_readEvents 2556235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2566235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "readEventsSince", 2576235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(JLjava/util/Collection;)V", 2586235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_readEventsSince 2596235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2606235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "readPreviousEvents", 2616235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(Ljava/util/Collection;)V", 2626235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_readPreviousEvents 2636235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2646235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "readEventsOnWrapping", 2656235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "(JLjava/util/Collection;)V", 2666235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski (void*) android_app_admin_SecurityLog_readEventsOnWrapping 2676235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski }, 2686235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski}; 2696235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2706235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic struct { const char *name; jclass *clazz; } gClasses[] = { 2716235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "android/app/admin/SecurityLog$SecurityEvent", &gEventClass }, 2726235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "java/lang/Integer", &gIntegerClass }, 2736235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "java/lang/Long", &gLongClass }, 2746235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "java/lang/Float", &gFloatClass }, 2756235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "java/lang/String", &gStringClass }, 2766235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { "java/util/Collection", &gCollectionClass }, 2776235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski}; 2786235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2796235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic struct { jclass *c; const char *name, *ft; jfieldID *id; } gFields[] = { 2806235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { &gIntegerClass, "value", "I", &gIntegerValueID }, 2816235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { &gLongClass, "value", "J", &gLongValueID }, 2826235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { &gFloatClass, "value", "F", &gFloatValueID }, 2836235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski}; 2846235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2856235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskistatic struct { jclass *c; const char *name, *mt; jmethodID *id; } gMethods[] = { 2866235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { &gEventClass, "<init>", "([B)V", &gEventInitID }, 2876235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski { &gCollectionClass, "add", "(Ljava/lang/Object;)Z", &gCollectionAddID }, 2886235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski}; 2896235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2906235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinskiint register_android_app_admin_SecurityLog(JNIEnv* env) { 2916235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski for (int i = 0; i < NELEM(gClasses); ++i) { 2926235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski jclass clazz = FindClassOrDie(env, gClasses[i].name); 2936235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski *gClasses[i].clazz = MakeGlobalRefOrDie(env, clazz); 2946235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 2956235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 2966235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski for (int i = 0; i < NELEM(gFields); ++i) { 2976235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski *gFields[i].id = GetFieldIDOrDie(env, 2986235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski *gFields[i].c, gFields[i].name, gFields[i].ft); 2996235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 3006235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 3016235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski for (int i = 0; i < NELEM(gMethods); ++i) { 3026235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski *gMethods[i].id = GetMethodIDOrDie(env, 3036235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski *gMethods[i].c, gMethods[i].name, gMethods[i].mt); 3046235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski } 3056235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 3066235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski return RegisterMethodsOrDie( 3076235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski env, 3086235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski "android/app/admin/SecurityLog", 3096235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski gRegisterMethods, NELEM(gRegisterMethods)); 3106235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski} 3116235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski 3126235a94ffaed1d82cee2317481c18776f601da1bMichal Karpinski}; // namespace android 313