Merge "Revert "DO NOT MERGE Libnativebridge: Temporarily change back to late dlopen"" into lmp-dev
diff --git a/adb/commandline.c b/adb/commandline.c
index b268ca5..51c039e 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -1870,7 +1870,7 @@
     char buf[4096];
     char* quoted;
 
-    snprintf(buf, sizeof(buf), "shell:rm ");
+    snprintf(buf, sizeof(buf), "shell:rm -f ");
     quoted = escape_arg(filename);
     strncat(buf, quoted, sizeof(buf)-1);
     free(quoted);
diff --git a/adb/usb_osx.c b/adb/usb_osx.c
index 45ce444..ca4f2af 100644
--- a/adb/usb_osx.c
+++ b/adb/usb_osx.c
@@ -512,14 +512,18 @@
         return -1;
     }
 
-    result =
-      (*handle->interface)->ReadPipe(handle->interface,
-                                    handle->bulkIn, buf, &numBytes);
+    result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes);
 
-    if (0 == result)
+    if (kIOUSBPipeStalled == result) {
+        DBG(" Pipe stalled, clearing stall.\n");
+        (*handle->interface)->ClearPipeStall(handle->interface, handle->bulkIn);
+        result = (*handle->interface)->ReadPipe(handle->interface, handle->bulkIn, buf, &numBytes);
+    }
+
+    if (kIOReturnSuccess == result)
         return 0;
     else {
-        DBG("ERR: usb_read failed with status %d\n", result);
+        DBG("ERR: usb_read failed with status %x\n", result);
     }
 
     return -1;
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index c4a2143..e49ef9b 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -49,13 +49,13 @@
   struct tm tm;
   localtime_r(&t, &tm);
   char timestr[64];
-  _LOG(log, logtype::BACKTRACE, "\n\nABI: '%s'\n", ABI_STRING);
   strftime(timestr, sizeof(timestr), "%F %T", &tm);
-  _LOG(log, logtype::BACKTRACE, "\n----- pid %d at %s -----\n", pid, timestr);
+  _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr);
 
   if (procname) {
     _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname);
   }
+  _LOG(log, logtype::BACKTRACE, "ABI: '%s'\n", ABI_STRING);
 }
 
 static void dump_process_footer(log_t* log, pid_t pid) {
diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c
index 03b3177..43d05aa 100644
--- a/fastboot/fastboot.c
+++ b/fastboot/fastboot.c
@@ -104,7 +104,6 @@
     {"recovery.img", "recovery.sig", "recovery", true},
     {"system.img", "system.sig", "system", false},
     {"vendor.img", "vendor.sig", "vendor", true},
-    {"tos.img", "tos.sig", "tos", true},
 };
 
 void get_my_path(char *path);
@@ -123,8 +122,6 @@
         fn = "system.img";
     } else if(!strcmp(item,"vendor")) {
         fn = "vendor.img";
-    } else if(!strcmp(item,"tos")) {
-        fn = "tos.img";
     } else if(!strcmp(item,"userdata")) {
         fn = "userdata.img";
     } else if(!strcmp(item,"cache")) {
@@ -291,7 +288,7 @@
             "commands:\n"
             "  update <filename>                        reflash device from update.zip\n"
             "  flashall                                 flash boot, system, vendor and if found,\n"
-            "                                           recovery, tos\n"
+            "                                           recovery\n"
             "  flash <partition> [ <filename> ]         write a file to a flash partition\n"
             "  erase <partition>                        erase a flash partition\n"
             "  format[:[<fs type>][:[<size>]] <partition> format a flash partition.\n"
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 3f94af5..91e6c33 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -433,7 +433,7 @@
                     char *tmp_mount_point)
 {
     int i = 0;
-    int ret = -1;
+    int ret = FS_MGR_DOMNT_FAILED;
     int mount_errors = 0;
     int first_mount_errno = 0;
     char *m;
@@ -493,7 +493,11 @@
     if (mount_errors) {
         ERROR("Cannot mount filesystem on %s at %s. error: %s\n",
             n_blk_device, m, strerror(first_mount_errno));
-        ret = -1;
+        if (first_mount_errno == EBUSY) {
+            ret = FS_MGR_DOMNT_BUSY;
+        } else {
+            ret = FS_MGR_DOMNT_FAILED;
+        }
     } else {
         /* We didn't find a match, say so and return an error */
         ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index d9c58d4..0c7eb20 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -59,6 +59,9 @@
 #define FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED 1
 #define FS_MGR_MNTALL_DEV_NOT_ENCRYPTED 0
 int fs_mgr_mount_all(struct fstab *fstab);
+
+#define FS_MGR_DOMNT_FAILED -1
+#define FS_MGR_DOMNT_BUSY -2
 int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
                     char *tmp_mount_point);
 int fs_mgr_do_tmpfs_mount(char *n_name);
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 345f354..394feb8 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -68,7 +68,7 @@
 #define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
 
 #define BATTERY_FULL_THRESH     95
-#define SCREEN_ON_BATTERY_THRESH 1
+#define SCREEN_ON_BATTERY_THRESH 0
 
 #define LAST_KMSG_PATH          "/proc/last_kmsg"
 #define LAST_KMSG_PSTORE_PATH   "/sys/fs/pstore/console-ramoops"
diff --git a/include/cutils/debugger.h b/include/cutils/debugger.h
index ae6bfc4..4bcc8e6 100644
--- a/include/cutils/debugger.h
+++ b/include/cutils/debugger.h
@@ -23,10 +23,13 @@
 extern "C" {
 #endif
 
-#if __LP64__
-#define DEBUGGER_SOCKET_NAME "android:debuggerd64"
+#define DEBUGGER32_SOCKET_NAME "android:debuggerd"
+#define DEBUGGER64_SOCKET_NAME "android:debuggerd64"
+
+#if defined(__LP64__)
+#define DEBUGGER_SOCKET_NAME DEBUGGER64_SOCKET_NAME
 #else
-#define DEBUGGER_SOCKET_NAME "android:debuggerd"
+#define DEBUGGER_SOCKET_NAME DEBUGGER32_SOCKET_NAME
 #endif
 
 typedef enum {
@@ -45,6 +48,16 @@
     int32_t original_si_code;
 } debugger_msg_t;
 
+#if defined(__LP64__)
+// For a 64 bit process to contact the 32 bit debuggerd.
+typedef struct {
+    debugger_action_t action;
+    pid_t tid;
+    uint32_t abort_msg_address;
+    int32_t original_si_code;
+} debugger32_msg_t;
+#endif
+
 /* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
  * Stores the tombstone path in the provided buffer.
  * Returns 0 on success, -1 on error.
diff --git a/include/netutils/ifc.h b/include/netutils/ifc.h
index 9a8b282..3b27234 100644
--- a/include/netutils/ifc.h
+++ b/include/netutils/ifc.h
@@ -36,6 +36,7 @@
 
 #define RESET_IPV4_ADDRESSES 0x01
 #define RESET_IPV6_ADDRESSES 0x02
+#define RESET_IGNORE_INTERFACE_ADDRESS 0x04
 #define RESET_ALL_ADDRESSES  (RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES)
 extern int ifc_reset_connections(const char *ifname, const int reset_mask);
 
diff --git a/include/system/audio.h b/include/system/audio.h
index 1c70240..9a25cfb 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -111,7 +111,8 @@
     AUDIO_FLAG_SECURE              = 0x2,
     AUDIO_FLAG_SCO                 = 0x4,
     AUDIO_FLAG_BEACON              = 0x8,
-    AUDIO_FLAG_HW_AV_SYNC          = 0x10
+    AUDIO_FLAG_HW_AV_SYNC          = 0x10,
+    AUDIO_FLAG_HW_HOTWORD          = 0x20,
 };
 
 /* Do not change these values without updating their counterparts
@@ -585,6 +586,8 @@
     AUDIO_DEVICE_OUT_FM                        = 0x100000,
     /* Line out for av devices */
     AUDIO_DEVICE_OUT_AUX_LINE                  = 0x200000,
+    /* limited-output speaker device for acoustic safety */
+    AUDIO_DEVICE_OUT_SPEAKER_SAFE              = 0x400000,
     AUDIO_DEVICE_OUT_DEFAULT                   = AUDIO_DEVICE_BIT_DEFAULT,
     AUDIO_DEVICE_OUT_ALL      = (AUDIO_DEVICE_OUT_EARPIECE |
                                  AUDIO_DEVICE_OUT_SPEAKER |
@@ -608,6 +611,7 @@
                                  AUDIO_DEVICE_OUT_SPDIF |
                                  AUDIO_DEVICE_OUT_FM |
                                  AUDIO_DEVICE_OUT_AUX_LINE |
+                                 AUDIO_DEVICE_OUT_SPEAKER_SAFE |
                                  AUDIO_DEVICE_OUT_DEFAULT),
     AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
                                  AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
@@ -707,8 +711,9 @@
  * attributes corresponding to the specified flags.
  */
 typedef enum {
-    AUDIO_INPUT_FLAG_NONE = 0x0,        // no attributes
-    AUDIO_INPUT_FLAG_FAST = 0x1,        // prefer an input that supports "fast tracks"
+    AUDIO_INPUT_FLAG_NONE       = 0x0,  // no attributes
+    AUDIO_INPUT_FLAG_FAST       = 0x1,  // prefer an input that supports "fast tracks"
+    AUDIO_INPUT_FLAG_HW_HOTWORD = 0x2,  // prefer an input that captures from hw hotword source
 } audio_input_flags_t;
 
 /* Additional information about compressed streams offloaded to
diff --git a/init/builtins.c b/init/builtins.c
index de83c93..c192551 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -478,7 +478,8 @@
     mkdir("/cache/recovery", 0700);
     int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600);
     if (fd >= 0) {
-        write(fd, "--wipe_data", strlen("--wipe_data") + 1);
+        write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1);
+        write(fd, "--reason=wipe_data_via_recovery\n", strlen("--reason=wipe_data_via_recovery\n") + 1);
         close(fd);
     } else {
         ERROR("could not open /cache/recovery/command\n");
@@ -515,7 +516,12 @@
     pid = fork();
     if (pid > 0) {
         /* Parent.  Wait for the child to return */
-        waitpid(pid, &status, 0);
+        int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
+        if (wp_ret < 0) {
+            /* Unexpected error code. We will continue anyway. */
+            NOTICE("waitpid failed rc=%d, errno=%d\n", wp_ret, errno);
+        }
+
         if (WIFEXITED(status)) {
             ret = WEXITSTATUS(status);
         } else {
diff --git a/libcutils/debugger.c b/libcutils/debugger.c
index 056de5d..4035ee1 100644
--- a/libcutils/debugger.c
+++ b/libcutils/debugger.c
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <stdbool.h>
+#include <fcntl.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -21,70 +24,129 @@
 #include <cutils/debugger.h>
 #include <cutils/sockets.h>
 
-int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {
-    int s = socket_local_client(DEBUGGER_SOCKET_NAME,
-            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
-    if (s < 0) {
-        return -1;
-    }
+#if defined(__LP64__)
+#include <elf.h>
 
-    debugger_msg_t msg;
-    memset(&msg, 0, sizeof(msg));
+static bool is32bit(pid_t tid) {
+  char* exeline;
+  if (asprintf(&exeline, "/proc/%d/exe", tid) == -1) {
+    return false;
+  }
+  int fd = open(exeline, O_RDONLY | O_CLOEXEC);
+  free(exeline);
+  if (fd == -1) {
+    return false;
+  }
+
+  char ehdr[EI_NIDENT];
+  ssize_t bytes = read(fd, &ehdr, sizeof(ehdr));
+  close(fd);
+  if (bytes != (ssize_t) sizeof(ehdr) || memcmp(ELFMAG, ehdr, SELFMAG) != 0) {
+    return false;
+  }
+  if (ehdr[EI_CLASS] == ELFCLASS32) {
+    return true;
+  }
+  return false;
+}
+#endif
+
+static int send_request(int sock_fd, void* msg_ptr, size_t msg_len) {
+  int result = 0;
+  if (TEMP_FAILURE_RETRY(write(sock_fd, msg_ptr, msg_len)) != (ssize_t) msg_len) {
+    result = -1;
+  } else {
+    char ack;
+    if (TEMP_FAILURE_RETRY(read(sock_fd, &ack, 1)) != 1) {
+      result = -1;
+    }
+  }
+  return result;
+}
+
+static int make_dump_request(debugger_action_t action, pid_t tid) {
+  const char* socket_name;
+  debugger_msg_t msg;
+  size_t msg_len;
+  void* msg_ptr;
+
+#if defined(__LP64__)
+  debugger32_msg_t msg32;
+  if (is32bit(tid)) {
+    msg_len = sizeof(debugger32_msg_t);
+    memset(&msg32, 0, msg_len);
+    msg32.tid = tid;
+    msg32.action = action;
+    msg_ptr = &msg32;
+
+    socket_name = DEBUGGER32_SOCKET_NAME;
+  } else
+#endif
+  {
+    msg_len = sizeof(debugger_msg_t);
+    memset(&msg, 0, msg_len);
     msg.tid = tid;
-    msg.action = DEBUGGER_ACTION_DUMP_TOMBSTONE;
+    msg.action = action;
+    msg_ptr = &msg;
 
-    int result = 0;
-    if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) {
-        result = -1;
-    } else {
-        char ack;
-        if (TEMP_FAILURE_RETRY(read(s, &ack, 1)) != 1) {
-            result = -1;
-        } else {
-            if (pathbuf && pathlen) {
-                ssize_t n = TEMP_FAILURE_RETRY(read(s, pathbuf, pathlen - 1));
-                if (n <= 0) {
-                    result = -1;
-                } else {
-                    pathbuf[n] = '\0';
-                }
-            }
-        }
-    }
-    TEMP_FAILURE_RETRY(close(s));
-    return result;
+    socket_name = DEBUGGER_SOCKET_NAME;
+  }
+
+  int sock_fd = socket_local_client(socket_name, ANDROID_SOCKET_NAMESPACE_ABSTRACT,
+      SOCK_STREAM | SOCK_CLOEXEC);
+  if (sock_fd < 0) {
+    return -1;
+  }
+
+  if (send_request(sock_fd, msg_ptr, msg_len) < 0) {
+    TEMP_FAILURE_RETRY(close(sock_fd));
+    return -1;
+  }
+
+  return sock_fd;
 }
 
 int dump_backtrace_to_file(pid_t tid, int fd) {
-    int s = socket_local_client(DEBUGGER_SOCKET_NAME,
-            ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
-    if (s < 0) {
-        return -1;
-    }
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid);
+  if (sock_fd < 0) {
+    return -1;
+  }
 
-    debugger_msg_t msg;
-    memset(&msg, 0, sizeof(msg));
-    msg.tid = tid;
-    msg.action = DEBUGGER_ACTION_DUMP_BACKTRACE;
-
-    int result = 0;
-    if (TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))) != sizeof(msg)) {
-        result = -1;
-    } else {
-        char ack;
-        if (TEMP_FAILURE_RETRY(read(s, &ack, 1)) != 1) {
-            result = -1;
-        } else {
-            char buffer[4096];
-            ssize_t n;
-            while ((n = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)))) > 0) {
-                if (TEMP_FAILURE_RETRY(write(fd, buffer, n)) != n) {
-                    result = -1;
-                    break;
-                }
-            }
-        }
+  /* Write the data read from the socket to the fd. */
+  int result = 0;
+  char buffer[1024];
+  ssize_t n;
+  while ((n = TEMP_FAILURE_RETRY(read(sock_fd, buffer, sizeof(buffer)))) > 0) {
+    if (TEMP_FAILURE_RETRY(write(fd, buffer, n)) != n) {
+      result = -1;
+      break;
     }
-    TEMP_FAILURE_RETRY(close(s));
-    return result;
+  }
+  TEMP_FAILURE_RETRY(close(sock_fd));
+  return result;
+}
+
+int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {
+  int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid);
+  if (sock_fd < 0) {
+    return -1;
+  }
+
+  /* Read the tombstone file name. */
+  char buffer[100]; /* This is larger than the largest tombstone path. */
+  int result = 0;
+  ssize_t n = TEMP_FAILURE_RETRY(read(sock_fd, buffer, sizeof(buffer) - 1));
+  if (n <= 0) {
+    result = -1;
+  } else {
+    if (pathbuf && pathlen) {
+      if (n >= (ssize_t) pathlen) {
+        n = pathlen - 1;
+      }
+      buffer[n] = '\0';
+      memcpy(pathbuf, buffer, n + 1);
+    }
+  }
+  TEMP_FAILURE_RETRY(close(sock_fd));
+  return result;
 }
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 3f6c6b5..913f51e 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -599,14 +599,16 @@
 {
 #ifdef HAVE_ANDROID_OS
     int result, success;
-    in_addr_t myaddr;
+    in_addr_t myaddr = 0;
     struct ifreq ifr;
     struct in6_ifreq ifr6;
 
     if (reset_mask & RESET_IPV4_ADDRESSES) {
         /* IPv4. Clear connections on the IP address. */
         ifc_init();
-        ifc_get_info(ifname, &myaddr, NULL, NULL);
+        if (!(reset_mask & RESET_IGNORE_INTERFACE_ADDRESS)) {
+            ifc_get_info(ifname, &myaddr, NULL, NULL);
+        }
         ifc_init_ifr(ifname, &ifr);
         init_sockaddr_in(&ifr.ifr_addr, myaddr);
         result = ioctl(ifc_ctl_sock, SIOCKILLADDR,  &ifr);