Merge "init.rc: Add cpuacct to cgroup mount for cpu statistic"
diff --git a/adb/commandline.c b/adb/commandline.c
index cd84c3a..857cee3 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -105,8 +105,8 @@
         "                                 environment variable is used, which must\n"
         "                                 be an absolute path.\n"
         " devices                       - list all connected devices\n"
-        " connect <host>:<port>         - connect to a device via TCP/IP"
-        " disconnect <host>:<port>      - disconnect from a TCP/IP device"
+        " connect <host>:<port>         - connect to a device via TCP/IP\n"
+        " disconnect <host>:<port>      - disconnect from a TCP/IP device\n"
         "\n"
         "device commands:\n"
         "  adb push <local> <remote>    - copy file/dir to device\n"
diff --git a/include/cutils/log.h b/include/cutils/log.h
index ec3cac8..dd47c35 100644
--- a/include/cutils/log.h
+++ b/include/cutils/log.h
@@ -196,6 +196,91 @@
 #define IF_LOGE() IF_LOG(LOG_ERROR, LOG_TAG)
 #endif
 
+
+// ---------------------------------------------------------------------
+
+/*
+ * Simplified macro to send a verbose system log message using the current LOG_TAG.
+ */
+#ifndef SLOGV
+#if LOG_NDEBUG
+#define SLOGV(...)   ((void)0)
+#else
+#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
+#endif
+#endif
+
+#define CONDITION(cond)     (__builtin_expect((cond)!=0, 0))
+
+#ifndef SLOGV_IF
+#if LOG_NDEBUG
+#define SLOGV_IF(cond, ...)   ((void)0)
+#else
+#define SLOGV_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+#endif
+
+/*
+ * Simplified macro to send a debug system log message using the current LOG_TAG.
+ */
+#ifndef SLOGD
+#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGD_IF
+#define SLOGD_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an info system log message using the current LOG_TAG.
+ */
+#ifndef SLOGI
+#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGI_IF
+#define SLOGI_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send a warning system log message using the current LOG_TAG.
+ */
+#ifndef SLOGW
+#define SLOGW(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGW_IF
+#define SLOGW_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+/*
+ * Simplified macro to send an error system log message using the current LOG_TAG.
+ */
+#ifndef SLOGE
+#define SLOGE(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGE_IF
+#define SLOGE_IF(cond, ...) \
+    ( (CONDITION(cond)) \
+    ? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
+    : (void)0 )
+#endif
+
+    
+
 // ---------------------------------------------------------------------
 
 /*
@@ -338,6 +423,21 @@
 #define android_logToFile(tag, file) (0)
 #define android_logToFd(tag, fd) (0)
 
+typedef enum {
+    LOG_ID_MAIN = 0,
+    LOG_ID_RADIO = 1,
+    LOG_ID_EVENTS = 2,
+    LOG_ID_SYSTEM = 3,
+
+    LOG_ID_MAX
+} log_id_t;
+
+/*
+ * Send a simple string to the log.
+ */
+int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text);
+int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...);
+
 
 #ifdef __cplusplus
 }
diff --git a/include/cutils/logger.h b/include/cutils/logger.h
index 3a08019..b60f7ad 100644
--- a/include/cutils/logger.h
+++ b/include/cutils/logger.h
@@ -25,6 +25,7 @@
 #define LOGGER_LOG_MAIN		"log/main"
 #define LOGGER_LOG_RADIO	"log/radio"
 #define LOGGER_LOG_EVENTS	"log/events"
+#define LOGGER_LOG_SYSTEM	"log/system"
 
 #define LOGGER_ENTRY_MAX_LEN		(4*1024)
 #define LOGGER_ENTRY_MAX_PAYLOAD	\
diff --git a/include/cutils/logprint.h b/include/cutils/logprint.h
index d6ec480..769c8a7 100644
--- a/include/cutils/logprint.h
+++ b/include/cutils/logprint.h
@@ -142,7 +142,7 @@
  * Assumes single threaded execution
  *
  */
-int android_log_filterAndPrintLogLine(
+int android_log_printLogLine(
     AndroidLogFormat *p_format,
     int fd,
     const AndroidLogEntry *entry);
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 241dbf0..49ceb92 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -27,6 +27,7 @@
 
 #include <cutils/logger.h>
 #include <cutils/logd.h>
+#include <cutils/log.h>
 
 #define LOG_BUF_SIZE	1024
 
@@ -41,21 +42,13 @@
 #define log_close(filedes) close(filedes)
 #endif
 
-typedef enum {
-    LOG_ID_MAIN = 0,
-    LOG_ID_RADIO,
-    LOG_ID_EVENTS,
-    LOG_ID_MAX
-} log_id_t;
-
 static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
-static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) =
-    __write_to_log_init;
+static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
 #ifdef HAVE_PTHREADS
 static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1 };
+static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };
 
 /*
  * This is used by the C++ code to decide if it should write logs through
@@ -110,6 +103,7 @@
         log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
         log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
         log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);
+        log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);
 
         write_to_log = __write_to_log_kernel;
 
@@ -123,6 +117,12 @@
             log_fds[LOG_ID_EVENTS] = -1;
             write_to_log = __write_to_log_null;
         }
+
+        printf("LOG_ID_SYSTEM=%d\n", log_fds[LOG_ID_SYSTEM]);
+        printf("LOG_ID_MAIN=%d\n", log_fds[LOG_ID_MAIN]);
+        if (log_fds[LOG_ID_SYSTEM] < 0) {
+            log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
+        }
     }
 
 #ifdef HAVE_PTHREADS
@@ -161,6 +161,34 @@
     return write_to_log(log_id, vec, 3);
 }
 
+int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
+{
+    struct iovec vec[3];
+
+    if (!tag)
+        tag = "";
+
+    /* XXX: This needs to go! */
+    if (!strcmp(tag, "HTC_RIL") ||
+        !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
+        !strcmp(tag, "AT") ||
+        !strcmp(tag, "GSM") ||
+        !strcmp(tag, "STK") ||
+        !strcmp(tag, "CDMA") ||
+        !strcmp(tag, "PHONE") ||
+        !strcmp(tag, "SMS"))
+            bufID = LOG_ID_RADIO;
+
+    vec[0].iov_base   = (unsigned char *) &prio;
+    vec[0].iov_len    = 1;
+    vec[1].iov_base   = (void *) tag;
+    vec[1].iov_len    = strlen(tag) + 1;
+    vec[2].iov_base   = (void *) msg;
+    vec[2].iov_len    = strlen(msg) + 1;
+
+    return write_to_log(bufID, vec, 3);
+}
+
 int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)
 {
     char buf[LOG_BUF_SIZE];    
@@ -173,7 +201,7 @@
 int __android_log_print(int prio, const char *tag, const char *fmt, ...)
 {
     va_list ap;
-    char buf[LOG_BUF_SIZE];    
+    char buf[LOG_BUF_SIZE];
 
     va_start(ap, fmt);
     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
@@ -182,6 +210,18 @@
     return __android_log_write(prio, tag, buf);
 }
 
+int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)
+{
+    va_list ap;
+    char buf[LOG_BUF_SIZE];
+
+    va_start(ap, fmt);
+    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+    va_end(ap);
+
+    return __android_log_buf_write(bufID, prio, tag, buf);
+}
+
 void __android_log_assert(const char *cond, const char *tag,
 			  const char *fmt, ...)
 {
diff --git a/liblog/logprint.c b/liblog/logprint.c
index 080f9e3..5ddda36 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -840,7 +840,7 @@
  * Returns count bytes written
  */
 
-int android_log_filterAndPrintLogLine(
+int android_log_printLogLine(
     AndroidLogFormat *p_format,
     int fd,
     const AndroidLogEntry *entry)
@@ -850,11 +850,6 @@
     char *outBuffer = NULL;
     size_t totalLen;
 
-    if (0 == android_log_shouldPrintLine(p_format, entry->tag,
-            entry->priority)) {
-        return 0;
-    }
-
     outBuffer = android_log_formatLogLine(p_format, defaultBuffer,
             sizeof(defaultBuffer), entry, &totalLen);
 
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 43c9ccd..670408c 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -24,6 +24,7 @@
 #define DEFAULT_MAX_ROTATED_LOGS 4
 
 static AndroidLogFormat * g_logformat;
+static bool g_nonblock = false;
 
 /* logd prefixes records with a length field */
 #define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t)
@@ -174,16 +175,6 @@
         }
     }
 
-    if (g_devCount > 1) {
-        binaryMsgBuf[0] = dev->label;
-        binaryMsgBuf[1] = ' ';
-        bytesWritten = write(g_outFD, binaryMsgBuf, 2);
-        if (bytesWritten < 0) {
-            perror("output error");
-            exit(-1);
-        }
-    }
-
     if (dev->binary) {
         err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap,
                 binaryMsgBuf, sizeof(binaryMsgBuf));
@@ -192,15 +183,27 @@
     } else {
         err = android_log_processLogBuffer(buf, &entry);
     }
-    if (err < 0)
+    if (err < 0) {
         goto error;
+    }
 
-    bytesWritten = android_log_filterAndPrintLogLine(
-                        g_logformat, g_outFD, &entry);
+    if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) {
+        if (false && g_devCount > 1) {
+            binaryMsgBuf[0] = dev->label;
+            binaryMsgBuf[1] = ' ';
+            bytesWritten = write(g_outFD, binaryMsgBuf, 2);
+            if (bytesWritten < 0) {
+                perror("output error");
+                exit(-1);
+            }
+        }
 
-    if (bytesWritten < 0) {
-        perror("output error");
-        exit(-1);
+        bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry);
+
+        if (bytesWritten < 0) {
+            perror("output error");
+            exit(-1);
+        }
     }
 
     g_outByteCount += bytesWritten;
@@ -318,6 +321,10 @@
                     }
                     eatEntry(dev, entry);
                 }
+                // They requested to just dump the log
+                if (g_nonblock) {
+                    exit(0);
+                }
             } else {
                 // print all that aren't the last in their list
                 while (true) {
@@ -483,7 +490,7 @@
             break;
 
             case 'd':
-                mode |= O_NONBLOCK;
+                g_nonblock = true;
             break;
 
             case 'g':
@@ -638,8 +645,16 @@
     }
 
     if (!devices) {
-        devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, LOGGER_LOG_MAIN[0]);
+        devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, 'm');
         android::g_devCount = 1;
+        int accessmode =
+                  (mode & O_RDONLY) ? R_OK : 0
+                | (mode & O_WRONLY) ? W_OK : 0;
+        // only add this if it's available
+        if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) {
+            devices->next = new log_device_t(strdup("/dev/"LOGGER_LOG_SYSTEM), false, 's');
+            android::g_devCount++;
+        }
     }
 
     if (android::g_logRotateSizeKBytes != 0 
@@ -714,7 +729,6 @@
                 perror("ioctl");
                 exit(EXIT_FAILURE);
             }
-            return 0;
         }
 
         if (getLogSize) {
@@ -744,6 +758,9 @@
     if (getLogSize) {
         return 0;
     }
+    if (clearLog) {
+        return 0;
+    }
 
     //LOG_EVENT_INT(10, 12345);
     //LOG_EVENT_LONG(11, 0x1122334455667788LL);