logd: liblog: logcat: Add LogWhiteBlackList

- liblog android_logger_get_log_size and android_logger_get_readable_size
  adjusted to return long instead of int because of -G flag extending range

NB: ifdef'd only for userdebug and eng builds

- liblog Add android_logger_[sg]et_prune_list and android_logger_set_log_size
- logcat Add -P, -p and -G flags
- logd Add LogWhiteBlackList and configurable log size

(cherry picked from commit 18a5432158ad43b8faefe4950b30e760200ce0b4)

Change-Id: I1572338c1b34bd968ad7867857ef708156ec3b6a
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 812e2e0..00b5ba9 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -229,8 +229,19 @@
                     "                  'events' or 'all'. Multiple -b parameters are allowed and\n"
                     "                  results are interleaved. The default is -b main -b system.\n"
                     "  -B              output the log in binary.\n"
-                    "  -S              output statistics");
+                    "  -S              output statistics.\n");
 
+#ifdef USERDEBUG_BUILD
+
+    fprintf(stderr, "--------------------- eng & userdebug builds only ---------------------------\n"
+                    "  -G <count>      set size of log's ring buffer and exit\n"
+                    "  -p              output prune white and ~black list\n"
+                    "  -P '<list> ...' set prune white and ~black list; UID, /PID or !(worst UID)\n"
+                    "                  default is ~!, prune worst UID.\n"
+                    "-----------------------------------------------------------------------------\n"
+    );
+
+#endif
 
     fprintf(stderr,"\nfilterspecs are a series of \n"
                    "  <tag>[:priority]\n\n"
@@ -279,6 +290,11 @@
     int hasSetLogFormat = 0;
     int clearLog = 0;
     int getLogSize = 0;
+#ifdef USERDEBUG_BUILD
+    unsigned long setLogSize = 0;
+    int getPruneList = 0;
+    char *setPruneList = NULL;
+#endif
     int printStatistics = 0;
     int mode = O_RDONLY;
     const char *forceFilters = NULL;
@@ -305,7 +321,13 @@
     for (;;) {
         int ret;
 
-        ret = getopt(argc, argv, "cdt:T:gsQf:r::n:v:b:BS");
+        ret = getopt(argc, argv,
+#ifdef USERDEBUG_BUILD
+            "cdt:T:gG:sQf:r::n:v:b:BSpP:"
+#else
+            "cdt:T:gsQf:r::n:v:b:BS"
+#endif
+        );
 
         if (ret < 0) {
             break;
@@ -337,6 +359,55 @@
                 getLogSize = 1;
             break;
 
+#ifdef USERDEBUG_BUILD
+
+            case 'G': {
+                // would use atol if not for the multiplier
+                char *cp = optarg;
+                setLogSize = 0;
+                while (('0' <= *cp) && (*cp <= '9')) {
+                    setLogSize *= 10;
+                    setLogSize += *cp - '0';
+                    ++cp;
+                }
+
+                switch(*cp) {
+                case 'g':
+                case 'G':
+                    setLogSize *= 1024;
+                /* FALLTHRU */
+                case 'm':
+                case 'M':
+                    setLogSize *= 1024;
+                /* FALLTHRU */
+                case 'k':
+                case 'K':
+                    setLogSize *= 1024;
+                /* FALLTHRU */
+                case '\0':
+                break;
+
+                default:
+                    setLogSize = 0;
+                }
+
+                if (!setLogSize) {
+                    fprintf(stderr, "ERROR: -G <num><multiplier>\n");
+                    exit(1);
+                }
+            }
+            break;
+
+            case 'p':
+                getPruneList = 1;
+            break;
+
+            case 'P':
+                setPruneList = optarg;
+            break;
+
+#endif
+
             case 'b': {
                 if (strcmp(optarg, "all") == 0) {
                     while (devices) {
@@ -602,8 +673,17 @@
             }
         }
 
+#ifdef USERDEBUG_BUILD
+
+        if (setLogSize && android_logger_set_log_size(dev->logger, setLogSize)) {
+            perror("setLogSize");
+            exit(EXIT_FAILURE);
+        }
+
+#endif
+
         if (getLogSize) {
-            int size, readable;
+            long size, readable;
 
             size = android_logger_get_log_size(dev->logger);
             if (size < 0) {
@@ -617,7 +697,7 @@
                 exit(EXIT_FAILURE);
             }
 
-            printf("%s: ring buffer is %dKb (%dKb consumed), "
+            printf("%s: ring buffer is %ldKb (%ldKb consumed), "
                    "max entry is %db, max payload is %db\n", dev->device,
                    size / 1024, readable / 1024,
                    (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD);
@@ -626,15 +706,46 @@
         dev = dev->next;
     }
 
-    if (printStatistics) {
+#ifdef USERDEBUG_BUILD
+
+    if (setPruneList) {
+        size_t len = strlen(setPruneList) + 32; // margin to allow rc
+        char *buf = (char *) malloc(len);
+
+        strcpy(buf, setPruneList);
+        int ret = android_logger_set_prune_list(logger_list, buf, len);
+        free(buf);
+
+        if (ret) {
+            perror("setPruneList");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+#endif
+
+    if (
+#ifdef USERDEBUG_BUILD
+        printStatistics || getPruneList
+#else
+        printStatistics
+#endif
+    ) {
         size_t len = 8192;
         char *buf;
 
         for(int retry = 32;
                 (retry >= 0) && ((buf = new char [len]));
                 delete [] buf, --retry) {
+#ifdef USERDEBUG_BUILD
+            if (getPruneList) {
+                android_logger_get_prune_list(logger_list, buf, len);
+            } else {
+                android_logger_get_statistics(logger_list, buf, len);
+            }
+#else
             android_logger_get_statistics(logger_list, buf, len);
-
+#endif
             buf[len-1] = '\0';
             size_t ret = atol(buf) + 1;
             if (ret < 4) {
@@ -650,7 +761,7 @@
         }
 
         if (!buf) {
-            perror("statistics read");
+            perror("response read");
             exit(EXIT_FAILURE);
         }
 
@@ -679,6 +790,11 @@
     if (getLogSize) {
         exit(0);
     }
+#ifdef USERDEBUG_BUILD
+    if (setLogSize || setPruneList) {
+        exit(0);
+    }
+#endif
     if (clearLog) {
         exit(0);
     }