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/liblog/log_read.c b/liblog/log_read.c
index 6f6fe5f..e4acac2 100644
--- a/liblog/log_read.c
+++ b/liblog/log_read.c
@@ -296,11 +296,8 @@
     return ret;
 }
 
-int android_logger_clear(struct logger *logger)
+static int check_log_success(char *buf, ssize_t ret)
 {
-    char buf[512];
-
-    ssize_t ret = send_log_msg(logger, "clear %d", buf, sizeof(buf));
     if (ret < 0) {
         return ret;
     }
@@ -312,8 +309,16 @@
     return 0;
 }
 
+int android_logger_clear(struct logger *logger)
+{
+    char buf[512];
+
+    return check_log_success(buf,
+        send_log_msg(logger, "clear %d", buf, sizeof(buf)));
+}
+
 /* returns the total size of the log's ring buffer */
-int android_logger_get_log_size(struct logger *logger)
+long android_logger_get_log_size(struct logger *logger)
 {
     char buf[512];
 
@@ -326,14 +331,28 @@
         return -1;
     }
 
-    return atoi(buf);
+    return atol(buf);
 }
 
+#ifdef USERDEBUG_BUILD
+
+int android_logger_set_log_size(struct logger *logger, unsigned long size)
+{
+    char buf[512];
+
+    snprintf(buf, sizeof(buf), "setLogSize %d %lu",
+        logger ? logger->id : (unsigned) -1, size);
+
+    return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));
+}
+
+#endif /* USERDEBUG_BUILD */
+
 /*
  * returns the readable size of the log's ring buffer (that is, amount of the
  * log consumed)
  */
-int android_logger_get_log_readable_size(struct logger *logger)
+long android_logger_get_log_readable_size(struct logger *logger)
 {
     char buf[512];
 
@@ -346,7 +365,7 @@
         return -1;
     }
 
-    return atoi(buf);
+    return atol(buf);
 }
 
 /*
@@ -383,6 +402,32 @@
     return send_log_msg(NULL, NULL, buf, len);
 }
 
+#ifdef USERDEBUG_BUILD
+
+ssize_t android_logger_get_prune_list(struct logger_list *logger_list UNUSED,
+                                      char *buf, size_t len)
+{
+    return send_log_msg(NULL, "getPruneList", buf, len);
+}
+
+int android_logger_set_prune_list(struct logger_list *logger_list UNUSED,
+                                  char *buf, size_t len)
+{
+    const char cmd[] = "setPruneList ";
+    const size_t cmdlen = sizeof(cmd) - 1;
+
+    if (strlen(buf) > (len - cmdlen)) {
+        return -ENOMEM; /* KISS */
+    }
+    memmove(buf + cmdlen, buf, len - cmdlen);
+    buf[len - 1] = '\0';
+    memcpy(buf, cmd, cmdlen);
+
+    return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));
+}
+
+#endif /* USERDEBUG_BUILD */
+
 struct logger_list *android_logger_list_alloc(int mode,
                                               unsigned int tail,
                                               pid_t pid)