Add unique IDs to log entry

Bug: 36366838
Test: add hash entry to logs and display it in dump
Change-Id: I7fb9b8997e46456331a946e03bfe040c47fa20b8
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index de38e7f..94ae11e 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -72,6 +72,8 @@
     ++it;
     // skip timestamp
     ++it;
+    // skip hash
+    ++it;
     // Skip author if present
     if (it->type == EVENT_AUTHOR) {
         ++it;
@@ -86,12 +88,26 @@
     return it.payload<timespec>();
 }
 
+NBLog::log_hash_t NBLog::FormatEntry::hash() const {
+    auto it = begin();
+    // skip start fmt
+    ++it;
+    // skip timestamp
+    ++it;
+    // unaligned 64-bit read not supported
+    log_hash_t hash;
+    memcpy(&hash, it->data, sizeof(hash));
+    return hash;
+}
+
 pid_t NBLog::FormatEntry::author() const {
     auto it = begin();
     // skip start fmt
     ++it;
     // skip timestamp
     ++it;
+    // skip hash
+    ++it;
     // if there is an author entry, return it, return -1 otherwise
     if (it->type == EVENT_AUTHOR) {
         return it.payload<int>();
@@ -106,6 +122,8 @@
     it.copyTo(dst);
     // copy timestamp
     (++it).copyTo(dst);
+    // copy hash
+    (++it).copyTo(dst);
     // insert author entry
     size_t authorEntrySize = NBLog::Entry::kOverhead + sizeof(author);
     uint8_t authorEntry[authorEntrySize];
@@ -360,19 +378,27 @@
     log(&entry, true);
 }
 
-void NBLog::Writer::logFormat(const char *fmt, ...)
+void NBLog::Writer::logHash(log_hash_t hash)
+{
+    if (!mEnabled) {
+        return;
+    }
+    log(EVENT_HASH, &hash, sizeof(hash));
+}
+
+void NBLog::Writer::logFormat(const char *fmt, log_hash_t hash, ...)
 {
     if (!mEnabled) {
         return;
     }
 
     va_list ap;
-    va_start(ap, fmt);
-    Writer::logVFormat(fmt, ap);
+    va_start(ap, hash);
+    Writer::logVFormat(fmt, hash, ap);
     va_end(ap);
 }
 
-void NBLog::Writer::logVFormat(const char *fmt, va_list argp)
+void NBLog::Writer::logVFormat(const char *fmt, log_hash_t hash, va_list argp)
 {
     if (!mEnabled) {
         return;
@@ -383,6 +409,7 @@
     char* s;
     struct timespec t;
     Writer::logTimestamp();
+    Writer::logHash(hash);
     for (const char *p = fmt; *p != '\0'; p++) {
         // TODO: implement more complex formatting such as %.3f
         if (*p != '%') {
@@ -446,6 +473,7 @@
     case EVENT_INTEGER:
     case EVENT_FLOAT:
     case EVENT_PID:
+    case EVENT_HASH:
     case EVENT_START_FMT:
         break;
     case EVENT_RESERVED:
@@ -568,6 +596,12 @@
     Writer::logEnd();
 }
 
+void NBLog::LockedWriter::logHash(log_hash_t hash)
+{
+    Mutex::Autolock _l(mLock);
+    Writer::logHash(hash);
+}
+
 bool NBLog::LockedWriter::isEnabled() const
 {
     Mutex::Autolock _l(mLock);
@@ -877,6 +911,11 @@
     timestamp->appendFormat("[%d.%03d]", (int) ts.tv_sec,
                     (int) (ts.tv_nsec / 1000000));
 
+    // log unique hash
+    log_hash_t hash = fmtEntry.hash();
+    // print only lower 16bit of hash as hex and line as int to reduce spam in the log
+    body->appendFormat("%.4X-%d ", (int)(hash >> 16) & 0xFFFF, (int) hash & 0xFFFF);
+
     // log author (if present)
     handleAuthor(fmtEntry, body);
 
diff --git a/media/libnbaio/include/NBLog.h b/media/libnbaio/include/NBLog.h
index 59b77bd..6ea33bd 100644
--- a/media/libnbaio/include/NBLog.h
+++ b/media/libnbaio/include/NBLog.h
@@ -34,6 +34,8 @@
 
 public:
 
+typedef uint64_t log_hash_t;
+
 class Writer;
 class Reader;
 
@@ -50,6 +52,8 @@
     EVENT_AUTHOR,               // author index (present in merged logs) tracks entry's original log
     EVENT_START_FMT,            // logFormat start event: entry includes format string, following
                                 // entries contain format arguments
+    EVENT_HASH,                 // unique HASH of log origin, originates from hash of file name
+                                // and line number
     EVENT_END_FMT,              // end of logFormat argument list
 };
 
@@ -60,6 +64,7 @@
 // a formatted entry has the following structure:
 //    * START_FMT entry, containing the format string
 //    * TIMESTAMP entry
+//    * HASH entry
 //    * author entry of the thread that generated it (optional, present in merged log)
 //    * format arg1
 //    * format arg2
@@ -131,6 +136,9 @@
     // get format entry timestamp
     timespec    timestamp() const;
 
+    // get format entry's unique id
+    log_hash_t  hash() const;
+
     // entry's author index (-1 if none present)
     // a Merger has a vector of Readers, author simply points to the index of the
     // Reader that originated the entry
@@ -252,10 +260,11 @@
     virtual void    logInteger(const int x);
     virtual void    logFloat(const float x);
     virtual void    logPID();
-    virtual void    logFormat(const char *fmt, ...);
-    virtual void    logVFormat(const char *fmt, va_list ap);
+    virtual void    logFormat(const char *fmt, log_hash_t hash, ...);
+    virtual void    logVFormat(const char *fmt, log_hash_t hash, va_list ap);
     virtual void    logStart(const char *fmt);
     virtual void    logEnd();
+    virtual void    logHash(log_hash_t hash);
 
 
     virtual bool    isEnabled() const;
@@ -304,6 +313,7 @@
     virtual void    logPID();
     virtual void    logStart(const char *fmt);
     virtual void    logEnd();
+    virtual void    logHash(log_hash_t hash);
 
     virtual bool    isEnabled() const;
     virtual bool    setEnabled(bool enabled);