Create libstats_jni

This cl creates libstats_jni, puts the android_util_StatsLog class in it
to implement the jni StatsLog.writeImpl() call, and puts the library in
the statsd apex.

Right now, it does NOT load the library properly and therefore the
library is still in the platform. It needs to be removed from the
platform.

Test: boots
Test: adb shell cmd stats print-logs shows logs still flow
Bug: 147315667
Change-Id: I0a06b66d4640d00ee75bc273423b33dafc944b05
diff --git a/apex/Android.bp b/apex/Android.bp
index 09ca1d2..1f9f18c 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -19,8 +19,9 @@
 }
 
 apex_defaults {
-    // libc.so and libcutils.so are included in the apex
-    // native_shared_libs: ["libc", "libcutils"],
+    native_shared_libs: [
+        "libstats_jni",
+    ],
     // binaries: ["vold"],
     java_libs: [
         "framework-statsd",
@@ -44,3 +45,33 @@
     // com.android.os.statsd.pk8 (the private key)
     certificate: "com.android.os.statsd",
 }
+
+
+// JNI library for StatsLog.write
+cc_library_shared {
+    name: "libstats_jni",
+    srcs: ["jni/**/*.cpp"],
+    shared_libs: [
+        "libnativehelper", // Has stable abi - should not be copied into apex.
+        "liblog",  // Has a stable abi - should not be copied into apex.
+    ],
+    static_libs: [
+        //TODO: make shared - need libstatssocket to also live in the apex.
+        "libstatssocket",
+        "libcutils", // TODO: remove - needed by libstatssocket
+    ],
+    //TODO: is libc++_static correct?
+    stl: "libc++_static",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-Wno-unused-parameter",
+    ],
+    apex_available: [
+        "com.android.os.statsd",
+        "test_com.android.os.statsd",
+        //TODO (b/148620413): remove platform.
+         "//apex_available:platform",
+    ],
+}
\ No newline at end of file
diff --git a/apex/jni/android_util_StatsLog.cpp b/apex/jni/android_util_StatsLog.cpp
new file mode 100644
index 0000000..9d410eb
--- /dev/null
+++ b/apex/jni/android_util_StatsLog.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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 "jni.h"
+#include <log/log.h>
+#include <nativehelper/JNIHelp.h>
+#include "stats_buffer_writer.h"
+
+namespace android {
+
+static void android_util_StatsLog_write(JNIEnv* env, jobject clazz, jbyteArray buf, jint size,
+        jint atomId) {
+    if (buf == NULL) {
+        return;
+    }
+    jint actualSize = env->GetArrayLength(buf);
+    if (actualSize < size) {
+        return;
+    }
+
+    jbyte* bufferArray = env->GetByteArrayElements(buf, NULL);
+    if (bufferArray == NULL) {
+        return;
+    }
+
+    write_buffer_to_statsd((void*) bufferArray, size, atomId);
+
+    env->ReleaseByteArrayElements(buf, bufferArray, 0);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "writeImpl", "([BII)V", (void*) android_util_StatsLog_write },
+};
+
+int register_android_util_StatsLog(JNIEnv* env)
+{
+    return jniRegisterNativeMethods(env, "android/util/StatsLog", gMethods, NELEM(gMethods));
+}
+}; // namespace android
+
+/*
+ * JNI Initialization
+ */
+jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
+    JNIEnv* e;
+    int status;
+
+    ALOGV("statsd : loading JNI\n");
+    // Check JNI version
+    if (jvm->GetEnv((void**)&e, JNI_VERSION_1_4)) {
+        ALOGE("JNI version mismatch error");
+        return JNI_ERR;
+    }
+    status = android::register_android_util_StatsLog(e);
+    if (status < 0) {
+        ALOGE("jni statsd registration failure, status: %d", status);
+        return JNI_ERR;
+    }
+    return JNI_VERSION_1_4;
+}