Merge "fastboot: add UDP protocol."
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 58ccd0a..cb54d04 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -883,8 +883,6 @@
             fprintf(stderr, "ADB server didn't ACK\n" );
             return -1;
         }
-
-        setsid();
     }
 #endif /* !defined(_WIN32) */
     return 0;
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 6397c52..27b7109 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -127,10 +127,12 @@
         setup_daemon_logging();
 
 #if !defined(_WIN32)
-        // Set the process group so that ctrl-c in the spawning process doesn't kill us.
-        // Do this here instead of after the fork so that a ctrl-c between the "starting server" and
-        // "done starting server" messages gets a chance to terminate the server.
-        setpgrp();
+        // Start a new session for the daemon. Do this here instead of after the fork so
+        // that a ctrl-c between the "starting server" and "done starting server" messages
+        // gets a chance to terminate the server.
+        if (setsid() == -1) {
+            fatal("setsid() failed: %s", strerror(errno));
+        }
 #endif
 
         // Any error output written to stderr now goes to adb.log. We could
diff --git a/bootstat/Android.mk b/bootstat/Android.mk
index bbb903d..c6349c1 100644
--- a/bootstat/Android.mk
+++ b/bootstat/Android.mk
@@ -32,6 +32,7 @@
 
 bootstat_shared_libs := \
         libbase \
+        libcutils \
         liblog
 
 bootstat_cflags := \
diff --git a/bootstat/README.md b/bootstat/README.md
index 1b4bf7f..b3964ce 100644
--- a/bootstat/README.md
+++ b/bootstat/README.md
@@ -7,10 +7,11 @@
 
     Usage: bootstat [options]
     options include:
-      -d              Dump the boot event records to the console.
-      -h              Show this help.
-      -l              Log all metrics to logstorage.
-      -r              Record the relative time of a named boot event.
+      -h, --help            Show this help
+      -l, --log             Log all metrics to logstorage
+      -p, --print           Dump the boot event records to the console
+      -r, --record          Record the timestamp of a named boot event
+      --record_boot_reason  Record the reason why the device booted
 
 ## Relative time ##
 
diff --git a/bootstat/boot_event_record_store.cpp b/bootstat/boot_event_record_store.cpp
index 1bdcf2b..22a67bb 100644
--- a/bootstat/boot_event_record_store.cpp
+++ b/bootstat/boot_event_record_store.cpp
@@ -56,19 +56,31 @@
     LOG(ERROR) << "Failed to read /proc/uptime";
   }
 
+  // Cast intentionally rounds down.
+  int32_t uptime = static_cast<int32_t>(strtod(uptime_str.c_str(), NULL));
+  AddBootEventWithValue(name, uptime);
+}
+
+// The implementation of AddBootEventValue makes use of the mtime file
+// attribute to store the value associated with a boot event in order to
+// optimize on-disk size requirements and small-file thrashing.
+void BootEventRecordStore::AddBootEventWithValue(
+    const std::string& name, int32_t value) {
   std::string record_path = GetBootEventPath(name);
   if (creat(record_path.c_str(), S_IRUSR | S_IWUSR) == -1) {
     PLOG(ERROR) << "Failed to create " << record_path;
   }
 
+  // Fill out the stat structure for |record_path| in order to get the atime to
+  // set in the utime() call.
   struct stat file_stat;
   if (stat(record_path.c_str(), &file_stat) == -1) {
     PLOG(ERROR) << "Failed to read " << record_path;
   }
 
-  // Cast intentionally rounds down.
-  time_t uptime = static_cast<time_t>(strtod(uptime_str.c_str(), NULL));
-  struct utimbuf times = {file_stat.st_atime, uptime};
+  // Set the |modtime| of the file to store the value of the boot event while
+  // preserving the |actime| (as read by stat).
+  struct utimbuf times = {/* actime */ file_stat.st_atime, /* modtime */ value};
   if (utime(record_path.c_str(), &times) == -1) {
     PLOG(ERROR) << "Failed to set mtime for " << record_path;
   }
diff --git a/bootstat/boot_event_record_store.h b/bootstat/boot_event_record_store.h
index 77978ef..d1b7835 100644
--- a/bootstat/boot_event_record_store.h
+++ b/bootstat/boot_event_record_store.h
@@ -37,6 +37,10 @@
   // Persists the boot event named |name| in the record store.
   void AddBootEvent(const std::string& name);
 
+  // Persists the boot event named |name| with the associated |value| in the
+  // record store.
+  void AddBootEventWithValue(const std::string& name, int32_t value);
+
   // Returns a list of all of the boot events persisted in the record store.
   std::vector<BootEventRecord> GetAllBootEvents() const;
 
@@ -45,6 +49,7 @@
   // more test-friendly path.
   FRIEND_TEST(BootEventRecordStoreTest, AddSingleBootEvent);
   FRIEND_TEST(BootEventRecordStoreTest, AddMultipleBootEvents);
+  FRIEND_TEST(BootEventRecordStoreTest, AddBootEventWithValue);
 
   // Sets the filesystem path of the record store.
   void SetStorePath(const std::string& path);
diff --git a/bootstat/boot_event_record_store_test.cpp b/bootstat/boot_event_record_store_test.cpp
index 384f84d..3e6d706 100644
--- a/bootstat/boot_event_record_store_test.cpp
+++ b/bootstat/boot_event_record_store_test.cpp
@@ -154,3 +154,15 @@
     EXPECT_TRUE(FuzzUptimeEquals(uptime, *i));
   }
 }
+
+TEST_F(BootEventRecordStoreTest, AddBootEventWithValue) {
+  BootEventRecordStore store;
+  store.SetStorePath(GetStorePathForTesting());
+
+  store.AddBootEventWithValue("permian", 42);
+
+  auto events = store.GetAllBootEvents();
+  ASSERT_EQ(1U, events.size());
+  EXPECT_EQ("permian", events[0].first);
+  EXPECT_EQ(42, events[0].second);
+}
\ No newline at end of file
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a83f8ad..31c84c7 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -18,14 +18,15 @@
 // timestamp, dump the persisted events, and log all events to EventLog to be
 // uploaded to Android log storage via Tron.
 
-//#define LOG_TAG "bootstat"
-
+#include <getopt.h>
 #include <unistd.h>
 #include <cstddef>
 #include <cstdio>
+#include <map>
 #include <memory>
 #include <string>
 #include <android-base/logging.h>
+#include <cutils/properties.h>
 #include <log/log.h>
 #include "boot_event_record_store.h"
 #include "event_log_list_builder.h"
@@ -35,7 +36,7 @@
 // Builds an EventLog buffer named |event| containing |data| and writes
 // the log into the Tron histogram logs.
 void LogBootEvent(const std::string& event, int32_t data) {
-  LOG(INFO) << "Logging boot time: " << event << " " << data;
+  LOG(INFO) << "Logging boot metric: " << event << " " << data;
 
   EventLogListBuilder log_builder;
   log_builder.Append(event);
@@ -74,10 +75,11 @@
   fprintf(stderr, "Usage: %s [options]\n", cmd);
   fprintf(stderr,
           "options include:\n"
-          "  -d              Dump the boot event records to the console.\n"
-          "  -h              Show this help.\n"
-          "  -l              Log all metrics to logstorage.\n"
-          "  -r              Record the timestamp of a named boot event.\n");
+          "  -h, --help            Show this help\n"
+          "  -l, --log             Log all metrics to logstorage\n"
+          "  -p, --print           Dump the boot event records to the console\n"
+          "  -r, --record          Record the timestamp of a named boot event\n"
+          "  --record_boot_reason  Record the reason why the device booted\n");
 }
 
 // Constructs a readable, printable string from the givencommand line
@@ -92,6 +94,61 @@
   return cmd;
 }
 
+// Convenience wrapper over the property API that returns an
+// std::string.
+std::string GetProperty(const char* key) {
+  std::vector<char> temp(PROPERTY_VALUE_MAX);
+  const int len = property_get(key, &temp[0], nullptr);
+  if (len < 0) {
+    return "";
+  }
+  return std::string(&temp[0], len);
+}
+
+// A mapping from boot reason string, as read from the ro.boot.bootreason
+// system property, to a unique integer ID. Viewers of log data dashboards for
+// the boot_reason metric may refer to this mapping to discern the histogram
+// values.
+const std::map<std::string, int> kBootReasonMap = {
+  {"normal", 0},
+  {"recovery", 1},
+  {"reboot", 2},
+  {"PowerKey", 3},
+  {"hard_reset", 4},
+  {"kernel_panic", 5},
+  {"rpm_err", 6},
+  {"hw_reset", 7},
+  {"tz_err", 8},
+  {"adsp_err", 9},
+  {"modem_err", 10},
+  {"mba_err", 11},
+  {"Watchdog", 12},
+  {"Panic", 13},
+};
+
+// Converts a string value representing the reason the system booted to an
+// integer representation. This is necessary for logging the boot_reason metric
+// via Tron, which does not accept non-integer buckets in histograms.
+int32_t BootReasonStrToEnum(const std::string& boot_reason) {
+  static const int32_t kUnknownBootReason = -1;
+
+  auto mapping = kBootReasonMap.find(boot_reason);
+  if (mapping != kBootReasonMap.end()) {
+    return mapping->second;
+  }
+
+  LOG(INFO) << "Unknown boot reason: " << boot_reason;
+  return kUnknownBootReason;
+}
+
+// Records the boot_reason metric by querying the ro.boot.bootreason system
+// property.
+void RecordBootReason() {
+  int32_t boot_reason = BootReasonStrToEnum(GetProperty("ro.boot.bootreason"));
+  BootEventRecordStore boot_event_store;
+  boot_event_store.AddBootEventWithValue("boot_reason", boot_reason);
+}
+
 }  // namespace
 
 int main(int argc, char **argv) {
@@ -100,9 +157,31 @@
   const std::string cmd_line = GetCommandLine(argc, argv);
   LOG(INFO) << "Service started: " << cmd_line;
 
+  int option_index = 0;
+  static const char boot_reason_str[] = "record_boot_reason";
+  static const struct option long_options[] = {
+    { "help",            no_argument,       NULL,   'h' },
+    { "log",             no_argument,       NULL,   'l' },
+    { "print",           no_argument,       NULL,   'p' },
+    { "record",          required_argument, NULL,   'r' },
+    { boot_reason_str,   no_argument,       NULL,   0 },
+    { NULL,              0,                 NULL,   0 }
+  };
+
   int opt = 0;
-  while ((opt = getopt(argc, argv, "hlpr:")) != -1) {
+  while ((opt = getopt_long(argc, argv, "hlpr:", long_options, &option_index)) != -1) {
     switch (opt) {
+      // This case handles long options which have no single-character mapping.
+      case 0: {
+        const std::string option_name = long_options[option_index].name;
+        if (option_name == boot_reason_str) {
+          RecordBootReason();
+        } else {
+          LOG(ERROR) << "Invalid option: " << option_name;
+        }
+        break;
+      }
+
       case 'h': {
         ShowHelp(argv[0]);
         break;
diff --git a/bootstat/bootstat.rc b/bootstat/bootstat.rc
index 2c37dd2..218b9f8 100644
--- a/bootstat/bootstat.rc
+++ b/bootstat/bootstat.rc
@@ -10,5 +10,8 @@
     # Record boot_complete timing event.
     exec - root root -- /system/bin/bootstat -r boot_complete
 
+    # Record the boot reason.
+    exec - root root -- /system/bin/bootstat --record_boot_reason
+
     # Log all boot events.
     exec - root root -- /system/bin/bootstat -l
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 8517c9f..8d9c5a3 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -224,7 +224,8 @@
                                                             msgBuf,
                                                             sizeof(msgBuf)));
             fflush(stderr);
-            EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
+            EXPECT_EQ((int)(19 + sizeof(buffer)),
+                      android_log_printLogLine(logformat, fileno(stderr), &entry));
             android_log_format_free(logformat);
         }
     }
@@ -272,7 +273,7 @@
         }
 
         int len = get4LE(eventData + 4 + 1);
-        if (len == 0) {
+        if (len == (sizeof(buffer) - 1)) {
             ++count;
 
             AndroidLogFormat *logformat = android_log_format_new();
@@ -285,7 +286,8 @@
                                                             msgBuf,
                                                             sizeof(msgBuf)));
             fflush(stderr);
-            EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
+            EXPECT_EQ((int)(19 + sizeof(buffer)),
+                      android_log_printLogLine(logformat, fileno(stderr), &entry));
             android_log_format_free(logformat);
         }
     }
@@ -295,6 +297,119 @@
     android_logger_list_close(logger_list);
 }
 
+TEST(liblog, __android_log_bswrite__newline_prefix) {
+    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[] = "\nHello World\n";
+    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((int)(19 + 19 - 1 + sizeof(buffer)),
+                      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_buf_write__newline_prefix) {
+    struct logger_list *logger_list;
+
+    pid_t pid = getpid();
+
+    ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+        LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
+
+    static const char tag[] = "TEST__android_log_buf_write";
+    static const char buffer[] = "\nHello World\n";
+    log_time ts(android_log_clockid());
+
+    EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
+                                         tag, 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 != (sizeof(tag) + sizeof(buffer) + 1))
+         || (log_msg.id() != LOG_ID_MAIN)) {
+            continue;
+        }
+
+        ++count;
+
+        AndroidLogFormat *logformat = android_log_format_new();
+        EXPECT_TRUE(NULL != logformat);
+        AndroidLogEntry entry;
+        EXPECT_EQ(0, android_log_processLogBuffer(&log_msg.entry_v1,
+                                                  &entry));
+        fflush(stderr);
+        EXPECT_EQ((int)(11 + 11 + sizeof(tag) + sizeof(tag) + sizeof(buffer) - 3),
+                  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";
@@ -609,7 +724,7 @@
     EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
 }
 
-static const char max_payload_tag[] = "TEST_max_payload_XXXX";
+static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
 #define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
                                 sizeof(max_payload_tag) - 1)
 static const char max_payload_buf[] = "LEONATO\n\
diff --git a/logcat/logpersist b/logcat/logpersist
index dab466d..8762ff1 100755
--- a/logcat/logpersist
+++ b/logcat/logpersist
@@ -1,8 +1,8 @@
 #! /system/bin/sh
 # logpersist cat start and stop handlers
 progname="${0##*/}"
-case `getprop ro.build.type` in
-userdebug|eng) ;;
+case `getprop ro.debuggable` in
+1) ;;
 *) echo "${progname} - Permission denied"
    exit 1
    ;;
diff --git a/logd/README.property b/logd/README.property
index 22f86b9..6200d3e 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -8,7 +8,7 @@
 ro.device_owner            bool   false  Override persist.logd.security to false
 ro.logd.kernel             bool+ svelte+ Enable klogd daemon
 ro.logd.statistics         bool+ svelte+ Enable logcat -S statistics.
-ro.build.type              string        if user, logd.statistics &
+ro.debuggable              number        if not "1", logd.statistics &
                                          ro.logd.kernel default false.
 persist.logd.logpersistd   string        Enable logpersist daemon, "logcatd"
                                          turns on logcat -f in logd context
@@ -46,10 +46,10 @@
 
 NB:
 - bool+ - "true", "false" and comma separated list of "eng" (forced false if
-  ro.build.type is "user") or "svelte" (forced false if ro.config.low_ram is
+  ro.debuggable is not "1") or "svelte" (forced false if ro.config.low_ram is
   true).
 - svelte - see ro.config.low_ram for details.
-- svelte+ - see ro.config.low_ram and ro.build.type for details.
+- svelte+ - see ro.config.low_ram and ro.debuggable for details.
 - ro - <base property> temporary override, ro.<base property> platform default.
 - persist - <base property> override, persist.<base property> platform default.
 - build - VERBOSE for native, DEBUG for jvm isLoggable, or developer option.
diff --git a/logd/main.cpp b/logd/main.cpp
index 9cec313..bef40c7 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -202,8 +202,8 @@
         return false;
     }
     if (flag & BOOL_DEFAULT_FLAG_ENG) {
-        property_get("ro.build.type", property, "");
-        if (!strcmp(property, "user")) {
+        property_get("ro.debuggable", property, "");
+        if (strcmp(property, "1")) {
             return false;
         }
     }
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index 52716e9..9ade759 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -80,10 +80,16 @@
 
 $(LOCAL_PATH)/getevent.c: $(intermediates)/input.h-labels.h
 
+UAPI_INPUT_EVENT_CODES_H := bionic/libc/kernel/uapi/linux/input-event-codes.h
 INPUT_H_LABELS_H := $(intermediates)/input.h-labels.h
 $(INPUT_H_LABELS_H): PRIVATE_LOCAL_PATH := $(LOCAL_PATH)
-$(INPUT_H_LABELS_H): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/generate-input.h-labels.py > $@
-$(INPUT_H_LABELS_H): $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/generate-input.h-labels.py
+# The PRIVATE_CUSTOM_TOOL line uses = to evaluate the output path late.
+# We copy the input path so it can't be accidentally modified later.
+$(INPUT_H_LABELS_H): PRIVATE_UAPI_INPUT_EVENT_CODES_H := $(UAPI_INPUT_EVENT_CODES_H)
+$(INPUT_H_LABELS_H): PRIVATE_CUSTOM_TOOL = $(PRIVATE_LOCAL_PATH)/generate-input.h-labels.py $(PRIVATE_UAPI_INPUT_EVENT_CODES_H) > $@
+# The dependency line though gets evaluated now, so the PRIVATE_ copy doesn't exist yet,
+# and the original can't yet have been modified, so this is both sufficient and necessary.
+$(INPUT_H_LABELS_H): $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/generate-input.h-labels.py $(UAPI_INPUT_EVENT_CODES_H)
 $(INPUT_H_LABELS_H):
 	$(transform-generated-source)
 
diff --git a/toolbox/generate-input.h-labels.py b/toolbox/generate-input.h-labels.py
index ebb9588..30485a0 100755
--- a/toolbox/generate-input.h-labels.py
+++ b/toolbox/generate-input.h-labels.py
@@ -18,6 +18,7 @@
 
 import os
 import re
+import sys
 
 input_prop_list = []
 ev_list = []
@@ -36,7 +37,7 @@
 
 r = re.compile(r'#define\s+(\S+)\s+((?:0x)?\d+)')
 
-with open('bionic/libc/kernel/uapi/linux/input.h', 'r') as f:
+with open(sys.argv[1], 'r') as f:
   for line in f:
     m = r.match(line)
     if m: