mediaresourcemanager: change resource manager service log to use ring buffer.

move the ring buffer implementation from libcameraservice to media include.

also add line prefix support to the service log.

Bug: 20637674
Change-Id: Ib6b32f31abe92c42644ef7012f1e3d46220ccfbd
diff --git a/services/camera/libcameraservice/utils/RingBuffer.h b/include/media/RingBuffer.h
similarity index 100%
rename from services/camera/libcameraservice/utils/RingBuffer.h
rename to include/media/RingBuffer.h
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 502fcfa..31edf44 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -38,9 +38,9 @@
 #include "CameraFlashlight.h"
 
 #include "common/CameraModule.h"
+#include "media/RingBuffer.h"
 #include "utils/AutoConditionLock.h"
 #include "utils/ClientManager.h"
-#include "utils/RingBuffer.h"
 
 #include <set>
 #include <string>
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index 3c093f9..e2b6695 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -126,8 +126,8 @@
             }
         }
     }
-    result.append("  Logs:\n");
-    result.append(mServiceLog->toString());
+    result.append("  Events logs (most recent at top):\n");
+    result.append(mServiceLog->toString("    " /* linePrefix */));
 
     write(fd, result.string(), result.size());
     return OK;
diff --git a/services/mediaresourcemanager/ServiceLog.cpp b/services/mediaresourcemanager/ServiceLog.cpp
index be7b308..791e797 100644
--- a/services/mediaresourcemanager/ServiceLog.cpp
+++ b/services/mediaresourcemanager/ServiceLog.cpp
@@ -27,28 +27,37 @@
 
 namespace android {
 
-ServiceLog::ServiceLog() : mMaxNum(kDefaultMaxNum) {}
-ServiceLog::ServiceLog(size_t maxNum) : mMaxNum(maxNum) {}
+ServiceLog::ServiceLog() : mMaxNum(kDefaultMaxNum), mLogs(mMaxNum) {}
+ServiceLog::ServiceLog(size_t maxNum) : mMaxNum(maxNum), mLogs(mMaxNum) {}
 
 void ServiceLog::add(const String8 &log) {
     Mutex::Autolock lock(mLock);
     time_t now = time(0);
     char buf[64];
     strftime(buf, sizeof(buf), "%m-%d %T", localtime(&now));
-    String8 formattedLog = String8::format("%s %s", buf, log.string());
-    if (mLogs.add(formattedLog) == mMaxNum) {
-        mLogs.removeAt(0);
-    }
+    mLogs.add(String8::format("%s %s", buf, log.string()));
 }
 
-String8 ServiceLog::toString() const {
+String8 ServiceLog::toString(const char *linePrefix) const {
     Mutex::Autolock lock(mLock);
     String8 result;
-    for (size_t i = 0; i < mLogs.size(); ++i) {
-        result.append(mLogs[i]);
-        result.append("\n");
+    for (const auto& log : mLogs) {
+        addLine(log.string(), linePrefix, &result);
+    }
+    if (mLogs.size() == mMaxNum) {
+        addLine("...", linePrefix, &result);
+    } else if (mLogs.size() == 0) {
+        addLine("[no events yet]", linePrefix, &result);
     }
     return result;
 }
 
+void ServiceLog::addLine(const char *log, const char *prefix, String8 *result) const {
+    if (prefix != NULL) {
+        result->append(prefix);
+    }
+    result->append(log);
+    result->append("\n");
+}
+
 } // namespace android
diff --git a/services/mediaresourcemanager/ServiceLog.h b/services/mediaresourcemanager/ServiceLog.h
index 14814ff..a6f16eb 100644
--- a/services/mediaresourcemanager/ServiceLog.h
+++ b/services/mediaresourcemanager/ServiceLog.h
@@ -23,6 +23,8 @@
 #include <utils/threads.h>
 #include <utils/Vector.h>
 
+#include "media/RingBuffer.h"
+
 namespace android {
 
 class ServiceLog : public RefBase {
@@ -31,12 +33,14 @@
     ServiceLog(size_t maxNum);
 
     void add(const String8 &log);
-    String8 toString() const;
+    String8 toString(const char *linePrefix = NULL) const;
 
 private:
-    int mMaxNum;
+    size_t mMaxNum;
     mutable Mutex mLock;
-    Vector<String8> mLogs;
+    RingBuffer<String8> mLogs;
+
+    void addLine(const char *log, const char *prefix, String8 *result) const;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/mediaresourcemanager/test/ServiceLog_test.cpp b/services/mediaresourcemanager/test/ServiceLog_test.cpp
index 6ddcb87..9172499 100644
--- a/services/mediaresourcemanager/test/ServiceLog_test.cpp
+++ b/services/mediaresourcemanager/test/ServiceLog_test.cpp
@@ -34,35 +34,48 @@
 };
 
 TEST_F(ServiceLogTest, addThenToString) {
+    String8 logString;
+
     mServiceLog->add(String8("log1"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log1"));
-    ALOGV("toString:\n%s", mServiceLog->toString().string());
+    logString = mServiceLog->toString();
+    EXPECT_TRUE(logString.contains("log1"));
+    ALOGV("toString:\n%s", logString.string());
+
+    static const char kTestLogPrefix[] = "testlogprefix: ";
+    logString = mServiceLog->toString(kTestLogPrefix);
+    EXPECT_TRUE(logString.contains(kTestLogPrefix));
+    EXPECT_TRUE(logString.contains("log1"));
+    ALOGV("toString:\n%s", logString.string());
 
     mServiceLog->add(String8("log2"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log1"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log2"));
-    ALOGV("toString:\n%s", mServiceLog->toString().string());
+    logString = mServiceLog->toString();
+    EXPECT_TRUE(logString.contains("log1"));
+    EXPECT_TRUE(logString.contains("log2"));
+    ALOGV("toString:\n%s", logString.string());
 
     mServiceLog->add(String8("log3"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log1"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log2"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log3"));
-    ALOGV("toString:\n%s", mServiceLog->toString().string());
+    logString = mServiceLog->toString();
+    EXPECT_TRUE(logString.contains("log1"));
+    EXPECT_TRUE(logString.contains("log2"));
+    EXPECT_TRUE(logString.contains("log3"));
+    ALOGV("toString:\n%s", logString.string());
 
     mServiceLog->add(String8("log4"));
-    EXPECT_FALSE(mServiceLog->toString().contains("log1"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log2"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log3"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log4"));
-    ALOGV("toString:\n%s", mServiceLog->toString().string());
+    logString = mServiceLog->toString();
+    EXPECT_FALSE(logString.contains("log1"));
+    EXPECT_TRUE(logString.contains("log2"));
+    EXPECT_TRUE(logString.contains("log3"));
+    EXPECT_TRUE(logString.contains("log4"));
+    ALOGV("toString:\n%s", logString.string());
 
     mServiceLog->add(String8("log5"));
-    EXPECT_FALSE(mServiceLog->toString().contains("log1"));
-    EXPECT_FALSE(mServiceLog->toString().contains("log2"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log3"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log4"));
-    EXPECT_TRUE(mServiceLog->toString().contains("log5"));
-    ALOGV("toString:\n%s", mServiceLog->toString().string());
+    logString = mServiceLog->toString();
+    EXPECT_FALSE(logString.contains("log1"));
+    EXPECT_FALSE(logString.contains("log2"));
+    EXPECT_TRUE(logString.contains("log3"));
+    EXPECT_TRUE(logString.contains("log4"));
+    EXPECT_TRUE(logString.contains("log5"));
+    ALOGV("toString:\n%s", logString.string());
 }
 
 } // namespace android