Merge "Build pixelflinger tests as native tests, not executables."
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index fc13977..61805c9 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -53,10 +53,10 @@
   int32_t original_si_code;
 };
 
-static void wait_for_user_action(pid_t pid) {
+static void wait_for_user_action(const debugger_request_t &request) {
   // Find out the name of the process that crashed.
   char path[64];
-  snprintf(path, sizeof(path), "/proc/%d/exe", pid);
+  snprintf(path, sizeof(path), "/proc/%d/exe", request.pid);
 
   char exe[PATH_MAX];
   int count;
@@ -78,7 +78,7 @@
         "* Wait for gdb to start, then press the VOLUME DOWN key\n"
         "* to let the process continue crashing.\n"
         "********************************************************\n",
-        pid, exe, pid);
+        request.pid, exe, request.tid);
 
   // Wait for VOLUME DOWN.
   if (init_getevent() == 0) {
@@ -93,7 +93,7 @@
     uninit_getevent();
   }
 
-  ALOGI("debuggerd resuming process %d", pid);
+  ALOGI("debuggerd resuming process %d", request.pid);
 }
 
 static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) {
@@ -323,7 +323,7 @@
         // for user action for the crashing process.
         // in this case, we log a message and turn the debug LED on
         // waiting for a gdb connection (for instance)
-        wait_for_user_action(request.pid);
+        wait_for_user_action(request);
       } else {
         // just detach
         if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index a58d9e5..dea016d 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -438,16 +438,16 @@
 // Reads the contents of the specified log device, filters out the entries
 // that don't match the specified pid, and writes them to the tombstone file.
 //
-// If "tail" is set, we only print the last few lines.
+// If "tail" is non-zero, log the last "tail" number of lines.
 static EventTagMap* g_eventTagMap = NULL;
 
-static void dump_log_file(log_t* log, pid_t pid, const char* filename,
-  unsigned int tail) {
+static void dump_log_file(
+    log_t* log, pid_t pid, const char* filename, unsigned int tail) {
   bool first = true;
-  struct logger_list *logger_list;
+  struct logger_list* logger_list;
 
   logger_list = android_logger_list_open(
-    android_name_to_log_id(filename), O_RDONLY | O_NONBLOCK, tail, pid);
+      android_name_to_log_id(filename), O_RDONLY | O_NONBLOCK, tail, pid);
 
   if (!logger_list) {
     ALOGE("Unable to open %s: %s\n", filename, strerror(errno));
@@ -458,6 +458,7 @@
 
   while (true) {
     ssize_t actual = android_logger_list_read(logger_list, &log_entry);
+    struct logger_entry* entry;
 
     if (actual < 0) {
       if (actual == -EINTR) {
@@ -481,15 +482,11 @@
     // because you will be writing as fast as you're reading.  Any
     // high-frequency debug diagnostics should just be written to
     // the tombstone file.
-    struct logger_entry* entry = &log_entry.entry_v1;
 
-    if (entry->pid != static_cast<int32_t>(pid)) {
-      // wrong pid, ignore
-      continue;
-    }
+    entry = &log_entry.entry_v1;
 
     if (first) {
-      _LOG(log, logtype::HEADER, "--------- %slog %s\n",
+      _LOG(log, logtype::LOGS, "--------- %slog %s\n",
         tail ? "tail end of " : "", filename);
       first = false;
     }
@@ -532,7 +529,7 @@
     // consume any trailing newlines
     char* nl = msg + strlen(msg) - 1;
     while (nl >= msg && *nl == '\n') {
-        *nl-- = '\0';
+      *nl-- = '\0';
     }
 
     char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?');
@@ -549,7 +546,6 @@
       _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8s: %s\n",
          timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
          prioChar, tag, msg);
-
     } while ((msg = nl));
   }
 
@@ -558,7 +554,7 @@
 
 // Dumps the logs generated by the specified pid to the tombstone, from both
 // "system" and "main" log devices.  Ideally we'd interleave the output.
-static void dump_logs(log_t* log, pid_t pid, unsigned tail) {
+static void dump_logs(log_t* log, pid_t pid, unsigned int tail) {
   dump_log_file(log, pid, "system", tail);
   dump_log_file(log, pid, "main", tail);
 }
diff --git a/include/system/window.h b/include/system/window.h
index 16b7b67..31f202f 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -26,8 +26,8 @@
 #include <system/graphics.h>
 #include <unistd.h>
 
-#ifndef __unused
-#define __unused __attribute__((__unused__))
+#ifndef __UNUSED
+#define __UNUSED __attribute__((__unused__))
 #endif
 #ifndef __deprecated
 #define __deprecated __attribute__((__deprecated__))
@@ -610,19 +610,19 @@
 
 /* deprecated. Always returns 0. Don't call. */
 static inline int native_window_connect(
-        struct ANativeWindow* window __unused, int api __unused) __deprecated;
+        struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
 
 static inline int native_window_connect(
-        struct ANativeWindow* window __unused, int api __unused) {
+        struct ANativeWindow* window __UNUSED, int api __UNUSED) {
     return 0;
 }
 
 /* deprecated. Always returns 0. Don't call. */
 static inline int native_window_disconnect(
-        struct ANativeWindow* window __unused, int api __unused) __deprecated;
+        struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
 
 static inline int native_window_disconnect(
-        struct ANativeWindow* window __unused, int api __unused) {
+        struct ANativeWindow* window __UNUSED, int api __UNUSED) {
     return 0;
 }
 
diff --git a/init/builtins.c b/init/builtins.c
index 0c32b2a..b32981e 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -862,11 +862,24 @@
 }
 
 int do_loglevel(int nargs, char **args) {
-    if (nargs == 2) {
-        klog_set_level(atoi(args[1]));
-        return 0;
+    int log_level;
+    char log_level_str[PROP_VALUE_MAX] = "";
+    if (nargs != 2) {
+        ERROR("loglevel: missing argument\n");
+        return -EINVAL;
     }
-    return -1;
+
+    if (expand_props(log_level_str, args[1], sizeof(log_level_str))) {
+        ERROR("loglevel: cannot expand '%s'\n", args[1]);
+        return -EINVAL;
+    }
+    log_level = atoi(log_level_str);
+    if (log_level < KLOG_ERROR_LEVEL || log_level > KLOG_DEBUG_LEVEL) {
+        ERROR("loglevel: invalid log level'%d'\n", log_level);
+        return -EINVAL;
+    }
+    klog_set_level(log_level);
+    return 0;
 }
 
 int do_load_persist_props(int nargs, char **args) {
diff --git a/init/init.c b/init/init.c
index f001071..e4ac1cf 100644
--- a/init/init.c
+++ b/init/init.c
@@ -528,7 +528,8 @@
 
 void execute_one_command(void)
 {
-    int ret;
+    int ret, i;
+    char cmd_str[256] = "";
 
     if (!cur_action || !cur_command || is_last_command(cur_action, cur_command)) {
         cur_action = action_remove_queue_head();
@@ -545,7 +546,17 @@
         return;
 
     ret = cur_command->func(cur_command->nargs, cur_command->args);
-    INFO("command '%s' r=%d\n", cur_command->args[0], ret);
+    if (klog_get_level() >= KLOG_INFO_LEVEL) {
+        for (i = 0; i < cur_command->nargs; i++) {
+            strlcat(cmd_str, cur_command->args[i], sizeof(cmd_str));
+            if (i < cur_command->nargs - 1) {
+                strlcat(cmd_str, " ", sizeof(cmd_str));
+            }
+        }
+        INFO("command '%s' action=%s status=%d (%s:%d)\n",
+             cmd_str, cur_action ? cur_action->name : "", ret, cur_command->filename,
+             cur_command->line);
+    }
 }
 
 static int wait_for_coldboot_done_action(int nargs, char **args)
diff --git a/init/init.h b/init/init.h
index c241912..a7615a3 100644
--- a/init/init.h
+++ b/init/init.h
@@ -29,10 +29,14 @@
     struct listnode clist;
 
     int (*func)(int nargs, char **args);
+
+    int line;
+    const char *filename;
+
     int nargs;
     char *args[1];
 };
-    
+
 struct action {
         /* node in list of all actions */
     struct listnode alist;
@@ -43,7 +47,7 @@
 
     unsigned hash;
     const char *name;
-    
+
     struct listnode commands;
     struct command *current;
 };
diff --git a/init/init_parser.c b/init/init_parser.c
index 289e759..f412de7 100644
--- a/init/init_parser.c
+++ b/init/init_parser.c
@@ -584,6 +584,7 @@
     cmd = calloc(1, sizeof(*cmd));
     cmd->func = func;
     cmd->args[0] = name;
+    cmd->nargs = 1;
     list_add_tail(&act->commands, &cmd->clist);
 
     list_add_tail(&action_list, &act->alist);
@@ -870,6 +871,8 @@
     }
     cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs);
     cmd->func = kw_func(kw);
+    cmd->line = state->line;
+    cmd->filename = state->filename;
     cmd->nargs = nargs;
     memcpy(cmd->args, args, sizeof(char*) * nargs);
     list_add_tail(&act->commands, &cmd->clist);
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 08b08fe..a2c9c0f 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -428,6 +428,9 @@
 on nonencrypted
     class_start late_start
 
+on property:sys.init_log_level=*
+    loglevel ${sys.init_log_level}
+
 on charger
     class_start charger