Merge "system/core: replace EVENT_TAG_MAP_FILE with NULL"
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index 11d8afb..9ac1d30 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <log/log_event_list.h>
 #include <private/android_logger.h>
 
 #include "log_portability.h"
@@ -319,7 +320,7 @@
     context->storage[1] = context->count[0];
     len = context->len = context->pos;
     msg = (const char *)context->storage;
-    /* it'snot a list */
+    /* it's not a list */
     if (context->count[0] <= 1) {
         len -= sizeof(uint8_t) + sizeof(uint8_t);
         if (len < 0) {
@@ -332,6 +333,38 @@
         __android_log_security_bwrite(context->tag, msg, len);
 }
 
+LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
+                                                     const char **buffer) {
+    android_log_context_internal *context;
+    const char *msg;
+    ssize_t len;
+
+    context = (android_log_context_internal *)ctx;
+    if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
+        return -EBADF;
+    }
+    if (context->list_nest_depth) {
+        return -EIO;
+    }
+    if (buffer == NULL) {
+        return -EFAULT;
+    }
+    /* NB: if there was overflow, then log is truncated. Nothing reported */
+    context->storage[1] = context->count[0];
+    len = context->len = context->pos;
+    msg = (const char *)context->storage;
+    /* it's not a list */
+    if (context->count[0] <= 1) {
+        len -= sizeof(uint8_t) + sizeof(uint8_t);
+        if (len < 0) {
+            len = 0;
+        }
+        msg += sizeof(uint8_t) + sizeof(uint8_t);
+    }
+    *buffer = msg;
+    return len;
+}
+
 /*
  * Extract a 4-byte value from a byte stream.
  */
diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c
index 7262fc5..14d6482 100644
--- a/liblog/log_event_write.c
+++ b/liblog/log_event_write.c
@@ -18,6 +18,7 @@
 #include <stdint.h>
 
 #include <log/log.h>
+#include <log/log_event_list.h>
 
 #include "log_portability.h"
 
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 70c7a48..02a572d 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -33,6 +33,7 @@
 #include <cutils/properties.h>
 #include <gtest/gtest.h>
 #include <log/logprint.h>
+#include <log/log_event_list.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
 
@@ -2650,6 +2651,19 @@
     ASSERT_TRUE(NULL == ctx);
 }
 
+TEST(liblog, android_log_write_list_buffer) {
+    __android_log_event_list ctx(1005);
+    ctx << 1005 << "tag_def" << "(tag|1),(name|3),(format|3)";
+    std::string buffer(ctx);
+    ctx.close();
+
+    char msgBuf[1024];
+    memset(msgBuf, 0, sizeof(msgBuf));
+    EXPECT_EQ(android_log_buffer_to_string(buffer.data(), buffer.length(),
+                                           msgBuf, sizeof(msgBuf)), 0);
+    EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]");
+}
+
 static const char __pmsg_file[] =
         "/data/william-shakespeare/MuchAdoAboutNothing.txt";
 
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 8d7c04e..11cffe6 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -29,6 +29,7 @@
 
 #include <gtest/gtest.h>
 #include <log/log.h>
+#include <log/log_event_list.h>
 
 #define BIG_BUFFER (5 * 1024)
 
@@ -1091,7 +1092,7 @@
     while (fgets(buffer, sizeof(buffer), fp)) {
         char *hold = *list;
         char *buf = buffer;
-	while (isspace(*buf)) {
+        while (isspace(*buf)) {
             ++buf;
         }
         char *end = buf + strlen(buf);
@@ -1126,7 +1127,7 @@
 
     while (fgets(buffer, sizeof(buffer), fp)) {
         char *buf = buffer;
-	while (isspace(*buf)) {
+        while (isspace(*buf)) {
             ++buf;
         }
         char *end = buf + strlen(buf);
@@ -1295,7 +1296,7 @@
 
     {
         static const struct tag hhgtg = { 42, "answer" };
-        android_log_event_context ctx(hhgtg.tagNo);
+        android_log_event_list ctx(hhgtg.tagNo);
         static const char theAnswer[] = "what is five by seven";
         ctx << theAnswer;
         ctx.write();
@@ -1307,7 +1308,7 @@
         static const struct tag sync = { 2720, "sync" };
         static const char id[] = "logcat.decriptive";
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << id << (int32_t)42 << (int32_t)-1 << (int32_t)0;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1317,7 +1318,7 @@
 
         // Partial match to description
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << id << (int32_t)43 << (int64_t)-1 << (int32_t)0;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1327,7 +1328,7 @@
 
         // Negative Test of End_to_End, ensure it is working
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << id << (int32_t)44 << (int32_t)-1 << (int64_t)0;
             ctx.write();
             fprintf(stderr, "Expect a \"Closest match\" message\n");
@@ -1340,7 +1341,7 @@
     {
         static const struct tag sync = { 2747, "contacts_aggregation" };
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint64_t)30 << (int32_t)2;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1348,7 +1349,7 @@
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint64_t)31570 << (int32_t)911;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr,
@@ -1359,42 +1360,42 @@
     {
         static const struct tag sync = { 75000, "sqlite_mem_alarm_current" };
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)512;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=512B"));
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)3072;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=3KB"));
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)2097152;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=2MB"));
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)2097153;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=2097153B"));
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)1073741824;
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=1GB"));
         }
 
         {
-            android_log_event_context ctx(sync.tagNo);
+            android_log_event_list ctx(sync.tagNo);
             ctx << (uint32_t)3221225472; // 3MB, but on purpose overflowed
             ctx.write();
             EXPECT_TRUE(End_to_End(sync.tagStr, "current=-1GB"));
@@ -1403,7 +1404,7 @@
 
     {
         static const struct tag sync = { 27501, "notification_panel_hidden" };
-        android_log_event_context ctx(sync.tagNo);
+        android_log_event_list ctx(sync.tagNo);
         ctx.write();
         EXPECT_TRUE(End_to_End(sync.tagStr, ""));
     }