Merge "libmetrics: Update BASE_VERS to 369476"
diff --git a/adb/shell_service.cpp b/adb/shell_service.cpp
index 95dff11..e092dc4 100644
--- a/adb/shell_service.cpp
+++ b/adb/shell_service.cpp
@@ -183,7 +183,6 @@
     ~Subprocess();
 
     const std::string& command() const { return command_; }
-    bool is_interactive() const { return command_.empty(); }
 
     int local_socket_fd() const { return local_socket_sfd_.fd(); }
 
@@ -332,7 +331,7 @@
         parent_error_sfd.Reset();
         close_on_exec(child_error_sfd.fd());
 
-        if (is_interactive()) {
+        if (command_.empty()) {
             execle(_PATH_BSHELL, _PATH_BSHELL, "-", nullptr, cenv.data());
         } else {
             execle(_PATH_BSHELL, _PATH_BSHELL, "-c", command_.c_str(), nullptr, cenv.data());
@@ -409,20 +408,6 @@
         exit(-1);
     }
 
-    if (!is_interactive()) {
-        termios tattr;
-        if (tcgetattr(child_fd, &tattr) == -1) {
-            WriteFdExactly(error_sfd->fd(), "tcgetattr failed");
-            exit(-1);
-        }
-
-        cfmakeraw(&tattr);
-        if (tcsetattr(child_fd, TCSADRAIN, &tattr) == -1) {
-            WriteFdExactly(error_sfd->fd(), "tcsetattr failed");
-            exit(-1);
-        }
-    }
-
     return child_fd;
 }
 
diff --git a/bootstat/README.md b/bootstat/README.md
index b494951..1b4bf7f 100644
--- a/bootstat/README.md
+++ b/bootstat/README.md
@@ -34,8 +34,9 @@
     $ bootstat -l
 
 bootstat logs all boot events recorded using the `-r` option to the EventLog
-using the Tron histogram. On GMS devices these logs are uploaded via Clearcut
-for aggregation and analysis.
+using the Tron histogram. These logs may be uploaded by interested parties
+for aggregation and analysis of boot time across different devices and
+versions.
 
 ## Printing boot events ##
 
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 90874f5..384f84d 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -65,7 +65,7 @@
     const std::string entry_path = path + "/" + entry_name;
     if (entry->d_type == DT_DIR) {
       DeleteDirectory(entry_path);
-    }  else {
+    } else {
       unlink(entry_path.c_str());
     }
   }
diff --git a/liblog/logprint.c b/liblog/logprint.c
index bd36cdd..4ef62a1 100644
--- a/liblog/logprint.c
+++ b/liblog/logprint.c
@@ -1488,7 +1488,7 @@
         strcat(p, suffixBuf);
         p += suffixLen;
     } else {
-        while(pm < (entry->message + entry->messageLen)) {
+        do {
             const char *lineStart;
             size_t lineLen;
             lineStart = pm;
@@ -1510,7 +1510,7 @@
             p += suffixLen;
 
             if (*pm == '\n') pm++;
-        }
+        } while (pm < (entry->message + entry->messageLen));
     }
 
     if (p_outLength != NULL) {
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 50afc5f..a936455 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -165,6 +165,133 @@
     android_logger_list_close(logger_list);
 }
 
+static inline int32_t get4LE(const char* src)
+{
+    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+}
+
+TEST(liblog, __android_log_bswrite) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+    static const char buffer[] = "Hello World";
+    log_time ts(android_log_clockid());
+
+    ASSERT_LT(0, __android_log_bswrite(0, buffer));
+    usleep(1000000);
+
+    int count = 0;
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+            break;
+        }
+
+        ASSERT_EQ(log_msg.entry.pid, pid);
+
+        if ((log_msg.entry.sec < (ts.tv_sec - 1))
+         || ((ts.tv_sec + 1) < log_msg.entry.sec)
+         || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
+         || (log_msg.id() != LOG_ID_EVENTS)) {
+            continue;
+        }
+
+        char *eventData = log_msg.msg();
+
+        if (eventData[4] != EVENT_TYPE_STRING) {
+            continue;
+        }
+
+        int len = get4LE(eventData + 4 + 1);
+        if (len == (sizeof(buffer) - 1)) {
+            ++count;
+
+            AndroidLogFormat *logformat = android_log_format_new();
+            EXPECT_TRUE(NULL != logformat);
+            AndroidLogEntry entry;
+            char msgBuf[1024];
+            EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
+                                                            &entry,
+                                                            NULL,
+                                                            msgBuf,
+                                                            sizeof(msgBuf)));
+            fflush(stderr);
+            EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
+            android_log_format_free(logformat);
+        }
+    }
+
+    EXPECT_EQ(1, count);
+
+    android_logger_list_close(logger_list);
+}
+
+TEST(liblog, __android_log_bswrite__empty_string) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+    static const char buffer[] = "";
+    log_time ts(android_log_clockid());
+
+    ASSERT_LT(0, __android_log_bswrite(0, buffer));
+    usleep(1000000);
+
+    int count = 0;
+
+    for (;;) {
+        log_msg log_msg;
+        if (android_logger_list_read(logger_list, &log_msg) <= 0) {
+            break;
+        }
+
+        ASSERT_EQ(log_msg.entry.pid, pid);
+
+        if ((log_msg.entry.sec < (ts.tv_sec - 1))
+         || ((ts.tv_sec + 1) < log_msg.entry.sec)
+         || (log_msg.entry.len != (4 + 1 + 4))
+         || (log_msg.id() != LOG_ID_EVENTS)) {
+            continue;
+        }
+
+        char *eventData = log_msg.msg();
+
+        if (eventData[4] != EVENT_TYPE_STRING) {
+            continue;
+        }
+
+        int len = get4LE(eventData + 4 + 1);
+        if (len == 0) {
+            ++count;
+
+            AndroidLogFormat *logformat = android_log_format_new();
+            EXPECT_TRUE(NULL != logformat);
+            AndroidLogEntry entry;
+            char msgBuf[1024];
+            EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
+                                                            &entry,
+                                                            NULL,
+                                                            msgBuf,
+                                                            sizeof(msgBuf)));
+            fflush(stderr);
+            EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
+            android_log_format_free(logformat);
+        }
+    }
+
+    EXPECT_EQ(1, count);
+
+    android_logger_list_close(logger_list);
+}
+
 TEST(liblog, __security) {
     static const char persist_key[] = "persist.logd.security";
     static const char readonly_key[] = "ro.device_owner";
@@ -1106,11 +1233,6 @@
     property_set(key + base_offset, hold[3]);
 }
 
-static inline int32_t get4LE(const char* src)
-{
-    return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
-}
-
 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
     const int TAG = 123456781;
     const char SUBTAG[] = "test-subtag";