From be0482b421a44521ea3e9300f3a2ef972c663100 Mon Sep 17 00:00:00 2001 From: Tej Singh Date: Tue, 19 Mar 2019 22:01:57 -0700 Subject: [PATCH] Public StatsLog API for generic mainline logging. Sets up a public api for logging atoms to statsd. The API excepts a buffer which is already encoded in the proper format for the socket, as well as the number of bytes of the buffer to write. It performs a JNI call to perform the socket write. Autogenerated app code will be built for each mainline module that needs to use this API to log. Test: builds Test: existing logs flow properly Bug: 126134616 Change-Id: I8a9a91e638d730e3ff69cb9345692e49e0db3c96 --- api/system-current.txt | 4 ++ core/java/android/util/StatsLog.java | 11 +++++ core/jni/Android.bp | 9 ++-- core/jni/AndroidRuntime.cpp | 2 + core/jni/android_util_StatsLog.cpp | 69 ++++++++++++++++++++++++++++ tools/stats_log_api_gen/main.cpp | 4 +- 6 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 core/jni/android_util_StatsLog.cpp diff --git a/api/system-current.txt b/api/system-current.txt index 9548a27fc33ae..b8469d2a22653 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -9471,6 +9471,10 @@ package android.util { method public int getUid(); } + public final class StatsLog { + method public static void writeRaw(@NonNull byte[], int); + } + public class StatsLogAtoms { field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8 diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index bf46e95c7b091..30d3d7d069b5d 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.PACKAGE_USAGE_STATS; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.app.IActivityManager; import android.content.Context; import android.os.IStatsManager; @@ -199,6 +200,16 @@ public final class StatsLog extends StatsLogInternal { } } + /** + * Write an event to stats log using the raw format. + * + * @param buffer The encoded buffer of data to write.. + * @param size The number of bytes from the buffer to write. + * @hide + */ + @SystemApi + public static native void writeRaw(@NonNull byte[] buffer, int size); + private static void enforceDumpCallingPermission(Context context) { context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission."); } diff --git a/core/jni/Android.bp b/core/jni/Android.bp index cd34d2e1b441d..664f7f47cf181 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,10 +1,10 @@ genrule { - name: "android_util_StatsLog.cpp", + name: "android_util_StatsLogInternal.cpp", tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp", + cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp", out: [ - "android_util_StatsLog.cpp", + "android_util_StatsLogInternal.cpp", ], } @@ -111,6 +111,7 @@ cc_library_shared { "android_util_Binder.cpp", "android_util_EventLog.cpp", "android_util_Log.cpp", + "android_util_StatsLog.cpp", "android_util_MemoryIntArray.cpp", "android_util_PathParser.cpp", "android_util_Process.cpp", @@ -306,7 +307,7 @@ cc_library_shared { "server_configurable_flags", ], - generated_sources: ["android_util_StatsLog.cpp"], + generated_sources: ["android_util_StatsLogInternal.cpp"], local_include_dirs: ["android/graphics"], export_include_dirs: [ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index da27852a3a350..7d9fe095121fb 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -127,6 +127,7 @@ extern int register_android_app_admin_SecurityLog(JNIEnv* env); extern int register_android_content_AssetManager(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_StatsLog(JNIEnv* env); +extern int register_android_util_StatsLogInternal(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_MemoryIntArray(JNIEnv* env); extern int register_android_util_PathParser(JNIEnv* env); @@ -1394,6 +1395,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_util_MemoryIntArray), REG_JNI(register_android_util_PathParser), REG_JNI(register_android_util_StatsLog), + REG_JNI(register_android_util_StatsLogInternal), REG_JNI(register_android_app_admin_SecurityLog), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp new file mode 100644 index 0000000000000..e749d34035dd4 --- /dev/null +++ b/core/jni/android_util_StatsLog.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_NAMESPACE "StatsLog.tag." +#define LOG_TAG "StatsLog_println" + +#include +#include + +#include "jni.h" +#include +#include "utils/misc.h" +#include "core_jni_helpers.h" +#include "stats_event_list.h" + +namespace android { + +static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size) +{ + if (buf == NULL) { + return; + } + jint actualSize = env->GetArrayLength(buf); + if (actualSize < size) { + return; + } + + jbyte* bufferArray = env->GetByteArrayElements(buf, NULL); + if (bufferArray == NULL) { + return; + } + const uint32_t statsEventTag = 1937006964; + struct iovec vec[2]; + vec[0].iov_base = (void*) &statsEventTag; + vec[0].iov_len = sizeof(statsEventTag); + vec[1].iov_base = (void*) bufferArray; + vec[1].iov_len = size; + write_to_statsd(vec, 2); + + env->ReleaseByteArrayElements(buf, bufferArray, 0); +} + +/* + * JNI registration. + */ +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw }, +}; + +int register_android_util_StatsLog(JNIEnv* env) +{ + return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index 0270c72ff240e..021692037e0a4 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -1403,10 +1403,10 @@ write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDe fprintf(out, "\n"); // Print registration function - fprintf(out, "int register_android_util_StatsLog(JNIEnv* env) {\n"); + fprintf(out, "int register_android_util_StatsLogInternal(JNIEnv* env) {\n"); fprintf(out, " return RegisterMethodsOrDie(\n"); fprintf(out, " env,\n"); - fprintf(out, " \"android/util/StatsLog\",\n"); + fprintf(out, " \"android/util/StatsLogInternal\",\n"); fprintf(out, " gRegisterMethods, NELEM(gRegisterMethods));\n"); fprintf(out, "}\n");