Merge "fs_mgr: code clean up"
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 7e46b02..d3b2f3d 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -64,7 +64,7 @@
 
 #define FUNCTIONFS_ENDPOINT_ALLOC       _IOR('g', 231, __u32)
 
-static constexpr size_t ENDPOINT_ALLOC_RETRIES = 2;
+static constexpr size_t ENDPOINT_ALLOC_RETRIES = 10;
 
 static int dummy_fd = -1;
 
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index b705e27..568879e 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -78,6 +78,14 @@
     }                                                                           \
   } while (0)
 
+#define ASSERT_NOT_MATCH(str, pattern)                                                      \
+  do {                                                                                      \
+    std::regex r((pattern));                                                                \
+    if (std::regex_search((str), r)) {                                                      \
+      FAIL() << "regex mismatch: expected to not find " << (pattern) << " in: \n" << (str); \
+    }                                                                                       \
+  } while (0)
+
 static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd) {
   intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
                                           ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
@@ -226,12 +234,14 @@
     FAIL() << "failed to wait for crasher: " << strerror(errno);
   }
 
-  if (WIFEXITED(status)) {
-    FAIL() << "crasher failed to exec: " << strerror(WEXITSTATUS(status));
-  } else if (!WIFSIGNALED(status)) {
-    FAIL() << "crasher didn't terminate via a signal";
+  if (signo == 0) {
+    ASSERT_TRUE(WIFEXITED(status));
+    ASSERT_EQ(0, WEXITSTATUS(signo));
+  } else {
+    ASSERT_FALSE(WIFEXITED(status));
+    ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
+    ASSERT_EQ(signo, WTERMSIG(status));
   }
-  ASSERT_EQ(signo, WTERMSIG(status));
   crasher_pid = -1;
 }
 
@@ -336,6 +346,26 @@
   ASSERT_MATCH(result, R"(Abort message: 'abort message goes here')");
 }
 
+TEST_F(CrasherTest, abort_message_backtrace) {
+  int intercept_result;
+  unique_fd output_fd;
+  StartProcess([]() {
+    android_set_abort_message("not actually aborting");
+    raise(DEBUGGER_SIGNAL);
+    exit(0);
+  });
+  StartIntercept(&output_fd);
+  FinishCrasher();
+  AssertDeath(0);
+  FinishIntercept(&intercept_result);
+
+  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+  std::string result;
+  ConsumeFd(std::move(output_fd), &result);
+  ASSERT_NOT_MATCH(result, R"(Abort message:)");
+}
+
 TEST_F(CrasherTest, intercept_timeout) {
   int intercept_result;
   unique_fd output_fd;
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index cd00dc5..b70554f 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -389,8 +389,9 @@
 
   log_signal_summary(signal_number, info);
 
-  // Populate si_value with the abort message address, if found.
-  if (abort_message) {
+  // If this was a fatal crash, populate si_value with the abort message address if possible.
+  // Note that applications can set an abort message without aborting.
+  if (abort_message && signal_number != DEBUGGER_SIGNAL) {
     info->si_value.sival_ptr = abort_message;
   }
 
diff --git a/fastboot/README.md b/fastboot/README.md
index 022d34b..ec7dcb4 100644
--- a/fastboot/README.md
+++ b/fastboot/README.md
@@ -126,6 +126,16 @@
                        space in RAM or "FAIL" if not.  The size of
                        the download is remembered.
 
+    upload             Read data from memory which was staged by the last
+                       command, e.g. an oem command.  The client will reply
+                       with "DATA%08x" if it is ready to send %08x bytes of
+                       data.  If no data was staged in the last command,
+                       the client must reply with "FAIL".  After the client
+                       successfully sends %08x bytes, the client shall send
+                       a single packet starting with "OKAY".  Clients
+                       should not support "upload" unless it supports an
+                       oem command that requires "upload" capabilities.
+
     verify:%08x        Send a digital signature to verify the downloaded
                        data.  Required if the bootloader is "secure"
                        otherwise "flash" and "boot" will be ignored.
diff --git a/fastboot/engine.cpp b/fastboot/engine.cpp
index bf887c9..56ee816 100644
--- a/fastboot/engine.cpp
+++ b/fastboot/engine.cpp
@@ -45,6 +45,7 @@
 #define OP_DOWNLOAD_SPARSE 5
 #define OP_WAIT_FOR_DISCONNECT 6
 #define OP_DOWNLOAD_FD 7
+#define OP_UPLOAD 8
 
 typedef struct Action Action;
 
@@ -332,6 +333,22 @@
     a->msg = mkmsg("downloading '%s'", name);
 }
 
+void fb_queue_download_fd(const char *name, int fd, uint32_t sz)
+{
+    Action *a;
+    a = queue_action(OP_DOWNLOAD_FD, "");
+    a->fd = fd;
+    a->size = sz;
+    a->msg = mkmsg("sending '%s' (%d KB)", name, sz / 1024);
+}
+
+void fb_queue_upload(char *outfile)
+{
+    Action *a = queue_action(OP_UPLOAD, "");
+    a->data = outfile;
+    a->msg = mkmsg("uploading '%s'", outfile);
+}
+
 void fb_queue_notice(const char *notice)
 {
     Action *a = queue_action(OP_NOTICE, "");
@@ -386,6 +403,9 @@
             if (status) break;
         } else if (a->op == OP_WAIT_FOR_DISCONNECT) {
             transport->WaitForDisconnect();
+        } else if (a->op == OP_UPLOAD) {
+            status = fb_upload_data(transport, reinterpret_cast<char*>(a->data));
+            status = a->func(a, status, status ? fb_get_error().c_str() : "");
         } else {
             die("bogus action");
         }
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3b524ac..982545c 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -371,6 +371,13 @@
             "  continue                                 Continue with autoboot.\n"
             "  reboot [bootloader|emergency]            Reboot device [into bootloader or emergency mode].\n"
             "  reboot-bootloader                        Reboot device into bootloader.\n"
+            "  oem <parameter1> ... <parameterN>        Executes oem specific command.\n"
+            "  stage <infile>                           Sends contents of <infile> to stage for\n"
+            "                                           the next command. Supported only on\n"
+            "                                           Android Things devices.\n"
+            "  get_staged <outfile>                     Receives data to <outfile> staged by the\n"
+            "                                           last command. Supported only on Android\n"
+            "                                           Things devices.\n"
             "  help                                     Show this help message.\n"
             "\n"
             "options:\n"
@@ -494,8 +501,7 @@
     return bdata;
 }
 
-static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz)
-{
+static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz) {
     ZipString zip_entry_name(entry_name);
     ZipEntry zip_entry;
     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
@@ -505,6 +511,7 @@
 
     *sz = zip_entry.uncompressed_length;
 
+    fprintf(stderr, "extracting %s (%" PRId64 " MB)...\n", entry_name, *sz / 1024 / 1024);
     uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length));
     if (data == nullptr) {
         fprintf(stderr, "failed to allocate %" PRId64 " bytes for '%s'\n", *sz, entry_name);
@@ -553,22 +560,39 @@
     return "";
 }
 
+static int make_temporary_fd() {
+    // TODO: reimplement to avoid leaking a FILE*.
+    return fileno(tmpfile());
+}
+
 #else
 
+static std::string make_temporary_template() {
+    const char* tmpdir = getenv("TMPDIR");
+    if (tmpdir == nullptr) tmpdir = P_tmpdir;
+    return std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
+}
+
 static std::string make_temporary_directory() {
-    const char *tmpdir = getenv("TMPDIR");
-    if (tmpdir == nullptr) {
-        tmpdir = P_tmpdir;
-    }
-    std::string result = std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
-    if (mkdtemp(&result[0]) == NULL) {
-        fprintf(stderr, "Unable to create temporary directory: %s\n",
-            strerror(errno));
+    std::string result(make_temporary_template());
+    if (mkdtemp(&result[0]) == nullptr) {
+        fprintf(stderr, "Unable to create temporary directory: %s\n", strerror(errno));
         return "";
     }
     return result;
 }
 
+static int make_temporary_fd() {
+    std::string path_template(make_temporary_template());
+    int fd = mkstemp(&path_template[0]);
+    if (fd == -1) {
+        fprintf(stderr, "Unable to create temporary file: %s\n", strerror(errno));
+        return -1;
+    }
+    unlink(path_template.c_str());
+    return fd;
+}
+
 #endif
 
 static std::string create_fbemarker_tmpdir() {
@@ -603,8 +627,8 @@
 }
 
 static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) {
-    FILE* fp = tmpfile();
-    if (fp == nullptr) {
+    unique_fd fd(make_temporary_fd());
+    if (fd == -1) {
         fprintf(stderr, "failed to create temporary file for '%s': %s\n",
                 entry_name, strerror(errno));
         return -1;
@@ -614,21 +638,20 @@
     ZipEntry zip_entry;
     if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
         fprintf(stderr, "archive does not contain '%s'\n", entry_name);
-        fclose(fp);
         return -1;
     }
 
-    int fd = fileno(fp);
+    fprintf(stderr, "extracting %s (%" PRIu32 " MB)...\n", entry_name,
+            zip_entry.uncompressed_length / 1024 / 1024);
     int error = ExtractEntryToFile(zip, &zip_entry, fd);
     if (error != 0) {
         fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error));
-        fclose(fp);
         return -1;
     }
 
     lseek(fd, 0, SEEK_SET);
     // TODO: We're leaking 'fp' here.
-    return fd;
+    return fd.release();
 }
 
 static char *strip(char *s)
@@ -1151,7 +1174,7 @@
             }
             flash_buf(partition.c_str(), &buf);
             /* not closing the fd here since the sparse code keeps the fd around
-             * but hasn't mmaped data yet. The tmpfile will get cleaned up when the
+             * but hasn't mmaped data yet. The temporary file will get cleaned up when the
              * program exits.
              */
         };
@@ -1412,7 +1435,8 @@
         return;
     }
 
-    fd = fileno(tmpfile());
+    fd = make_temporary_fd();
+    if (fd == -1) return;
 
     unsigned eraseBlkSize, logicalBlkSize;
     eraseBlkSize = fb_get_flash_block_size(transport, "erase-block-size");
@@ -1806,6 +1830,20 @@
             }
             fb_set_active(slot.c_str());
             skip(2);
+        } else if(!strcmp(*argv, "stage")) {
+            require(2);
+            std::string infile(argv[1]);
+            skip(2);
+            struct fastboot_buffer buf;
+            if (!load_buf(transport, infile.c_str(), &buf) || buf.type != FB_BUFFER_FD) {
+                die("cannot load '%s'", infile.c_str());
+            }
+            fb_queue_download_fd(infile.c_str(), buf.fd, buf.sz);
+        } else if(!strcmp(*argv, "get_staged")) {
+            require(2);
+            char *outfile = argv[1];
+            skip(2);
+            fb_queue_upload(outfile);
         } else if(!strcmp(*argv, "oem")) {
             argc = do_oem_command(argc, argv);
         } else if(!strcmp(*argv, "flashing")) {
diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h
index 3f95270..e30c6de 100644
--- a/fastboot/fastboot.h
+++ b/fastboot/fastboot.h
@@ -44,6 +44,7 @@
 int64_t fb_download_data(Transport* transport, const void* data, uint32_t size);
 int64_t fb_download_data_fd(Transport* transport, int fd, uint32_t size);
 int fb_download_data_sparse(Transport* transport, struct sparse_file* s);
+int64_t fb_upload_data(Transport* transport, const char* outfile);
 const std::string fb_get_error();
 
 #define FB_COMMAND_SZ 64
@@ -64,6 +65,8 @@
 void fb_queue_reboot(void);
 void fb_queue_command(const char *cmd, const char *msg);
 void fb_queue_download(const char *name, void *data, uint32_t size);
+void fb_queue_download_fd(const char *name, int fd, uint32_t sz);
+void fb_queue_upload(char *outfile);
 void fb_queue_notice(const char *notice);
 void fb_queue_wait_for_disconnect(void);
 int64_t fb_execute_queue(Transport* transport);
diff --git a/fastboot/protocol.cpp b/fastboot/protocol.cpp
index 334f81f..dcdf8f0 100644
--- a/fastboot/protocol.cpp
+++ b/fastboot/protocol.cpp
@@ -29,14 +29,18 @@
 #define round_down(a, b) \
     ({ typeof(a) _a = (a); typeof(b) _b = (b); _a - (_a % _b); })
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 
 #include <algorithm>
+#include <vector>
 
+#include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
 #include <sparse/sparse.h>
 #include <utils/FileMap.h>
 
@@ -45,6 +49,9 @@
 
 static std::string g_error;
 
+using android::base::unique_fd;
+using android::base::WriteStringToFile;
+
 const std::string fb_get_error() {
     return g_error;
 }
@@ -126,15 +133,30 @@
     return check_response(transport, size, response);
 }
 
-static int64_t _command_data(Transport* transport, const void* data, uint32_t size) {
+static int64_t _command_write_data(Transport* transport, const void* data, uint32_t size) {
     int64_t r = transport->Write(data, size);
     if (r < 0) {
-        g_error = android::base::StringPrintf("data transfer failure (%s)", strerror(errno));
+        g_error = android::base::StringPrintf("data write failure (%s)", strerror(errno));
         transport->Close();
         return -1;
     }
     if (r != static_cast<int64_t>(size)) {
-        g_error = "data transfer failure (short transfer)";
+        g_error = "data write failure (short transfer)";
+        transport->Close();
+        return -1;
+    }
+    return r;
+}
+
+static int64_t _command_read_data(Transport* transport, void* data, uint32_t size) {
+    int64_t r = transport->Read(data, size);
+    if (r < 0) {
+        g_error = android::base::StringPrintf("data read failure (%s)", strerror(errno));
+        transport->Close();
+        return -1;
+    }
+    if (r != (static_cast<int64_t>(size))) {
+        g_error = "data read failure (short transfer)";
         transport->Close();
         return -1;
     }
@@ -155,8 +177,7 @@
     if (r < 0) {
         return -1;
     }
-
-    r = _command_data(transport, data, size);
+    r = _command_write_data(transport, data, size);
     if (r < 0) {
         return -1;
     }
@@ -187,7 +208,7 @@
             return -1;
         }
 
-        if (_command_data(transport, filemap.getDataPtr(), len) < 0) {
+        if (_command_write_data(transport, filemap.getDataPtr(), len) < 0) {
             return -1;
         }
 
@@ -224,6 +245,28 @@
     return _command_send_fd(transport, cmd.c_str(), fd, size, 0) < 0 ? -1 : 0;
 }
 
+int64_t fb_upload_data(Transport* transport, const char* outfile) {
+    // positive return value is the upload size sent by the device
+    int64_t r = _command_start(transport, "upload", std::numeric_limits<int32_t>::max(), nullptr);
+    if (r <= 0) {
+        g_error = android::base::StringPrintf("command start failed (%s)", strerror(errno));
+        return r;
+    }
+
+    std::string data;
+    data.resize(r);
+    if ((r = _command_read_data(transport, &data[0], data.size())) == -1) {
+        return r;
+    }
+
+    if (!WriteStringToFile(data, outfile, true)) {
+        g_error = android::base::StringPrintf("write to '%s' failed", outfile);
+        return -1;
+    }
+
+    return _command_end(transport);
+}
+
 #define TRANSPORT_BUF_SIZE 1024
 static char transport_buf[TRANSPORT_BUF_SIZE];
 static int transport_buf_len;
@@ -245,7 +288,7 @@
     }
 
     if (transport_buf_len == TRANSPORT_BUF_SIZE) {
-        r = _command_data(transport, transport_buf, TRANSPORT_BUF_SIZE);
+        r = _command_write_data(transport, transport_buf, TRANSPORT_BUF_SIZE);
         if (r != TRANSPORT_BUF_SIZE) {
             return -1;
         }
@@ -258,7 +301,7 @@
             return -1;
         }
         to_write = round_down(len, TRANSPORT_BUF_SIZE);
-        r = _command_data(transport, ptr, to_write);
+        r = _command_write_data(transport, ptr, to_write);
         if (r != to_write) {
             return -1;
         }
@@ -280,7 +323,7 @@
 
 static int fb_download_data_sparse_flush(Transport* transport) {
     if (transport_buf_len > 0) {
-        int64_t r = _command_data(transport, transport_buf, transport_buf_len);
+        int64_t r = _command_write_data(transport, transport_buf, transport_buf_len);
         if (r != static_cast<int64_t>(transport_buf_len)) {
             return -1;
         }
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index a83d263..6e9069e 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -1359,7 +1359,8 @@
 
         std::string mount_point;
         if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
-            mount_point = "system";
+            // In AVB, the dm device name is vroot instead of system.
+            mount_point = fs_mgr_is_avb(&fstab->recs[i]) ? "vroot" : "system";
         } else {
             mount_point = basename(fstab->recs[i].mount_point);
         }
@@ -1378,6 +1379,10 @@
 
         status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
 
+        // To be consistent in vboot 1.0 and vboot 2.0 (AVB), change the mount_point
+        // back to 'system' for the callback. So it has property [partition.system.verified]
+        // instead of [partition.vroot.verified].
+        if (mount_point == "vroot") mount_point = "system";
         if (*status == 'C' || *status == 'V') {
             callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
         }
diff --git a/init/reboot.cpp b/init/reboot.cpp
index 470b875..838406d 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -423,7 +423,6 @@
 bool HandlePowerctlMessage(const std::string& command) {
     unsigned int cmd = 0;
     std::vector<std::string> cmd_params = android::base::Split(command, ",");
-    std::string reason_string = cmd_params[0];
     std::string reboot_target = "";
     bool run_fsck = false;
     bool command_invalid = false;
@@ -436,7 +435,6 @@
             // The shutdown reason is PowerManager.SHUTDOWN_USER_REQUESTED.
             // Run fsck once the file system is remounted in read-only mode.
             run_fsck = true;
-            reason_string = cmd_params[1];
         }
     } else if (cmd_params[0] == "reboot") {
         cmd = ANDROID_RB_RESTART2;
@@ -467,6 +465,6 @@
         return false;
     }
 
-    DoReboot(cmd, reason_string, reboot_target, run_fsck);
+    DoReboot(cmd, command, reboot_target, run_fsck);
     return true;
 }
diff --git a/init/service.cpp b/init/service.cpp
index 2284a21..39f6709 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -274,10 +274,6 @@
     std::for_each(descriptors_.begin(), descriptors_.end(),
                   std::bind(&DescriptorInfo::Clean, std::placeholders::_1));
 
-    if (flags_ & SVC_EXEC) {
-        LOG(INFO) << "SVC_EXEC pid " << pid_ << " finished...";
-    }
-
     if (flags_ & SVC_TEMPORARY) {
         return;
     }
@@ -1047,21 +1043,26 @@
     Service* svc = FindServiceByPid(pid);
 
     std::string name;
+    std::string wait_string;
     if (svc) {
         name = android::base::StringPrintf("Service '%s' (pid %d)",
                                            svc->name().c_str(), pid);
+        if (svc->flags() & SVC_EXEC) {
+            wait_string =
+                android::base::StringPrintf(" waiting took %f seconds", exec_waiter_->duration_s());
+        }
     } else {
         name = android::base::StringPrintf("Untracked pid %d", pid);
     }
 
     if (WIFEXITED(status)) {
-        LOG(INFO) << name << " exited with status " << WEXITSTATUS(status);
+        LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
     } else if (WIFSIGNALED(status)) {
-        LOG(INFO) << name << " killed by signal " << WTERMSIG(status);
+        LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
     } else if (WIFSTOPPED(status)) {
-        LOG(INFO) << name << " stopped by signal " << WSTOPSIG(status);
+        LOG(INFO) << name << " stopped by signal " << WSTOPSIG(status) << wait_string;
     } else {
-        LOG(INFO) << name << " state changed";
+        LOG(INFO) << name << " state changed" << wait_string;
     }
 
     if (!svc) {
@@ -1071,7 +1072,6 @@
     svc->Reap();
 
     if (svc->flags() & SVC_EXEC) {
-        LOG(INFO) << "Wait for exec took " << *exec_waiter_;
         exec_waiter_.reset();
     }
     if (svc->flags() & SVC_TEMPORARY) {
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 4a525be..285aa6e 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -57,6 +57,7 @@
 
 cc_library_headers {
     name: "libbacktrace_headers",
+    vendor_available: true,
     export_include_dirs: ["include"],
 }
 
diff --git a/libsystem/Android.bp b/libsystem/Android.bp
index 4d076d5..846a585 100644
--- a/libsystem/Android.bp
+++ b/libsystem/Android.bp
@@ -1,4 +1,15 @@
 cc_library_headers {
     name: "libsystem_headers",
+    vendor_available: true,
+    host_supported: true,
     export_include_dirs: ["include"],
+
+    target: {
+        linux_bionic: {
+            enabled: true,
+        },
+        windows: {
+            enabled: true,
+        },
+    }
 }
diff --git a/libutils/Android.bp b/libutils/Android.bp
index b46ad62..33770ba 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -16,8 +16,22 @@
     name: "libutils_headers",
     vendor_available: true,
     host_supported: true,
+
+    header_libs: [
+        "libsystem_headers",
+        "libcutils_headers"
+    ],
+    export_header_lib_headers: [
+        "libsystem_headers",
+        "libcutils_headers"
+    ],
     export_include_dirs: ["include"],
+
     target: {
+        android: {
+            header_libs: ["libbacktrace_headers"],
+            export_header_lib_headers: ["libbacktrace_headers"],
+        },
         linux_bionic: {
             enabled: true,
         },
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index 73ed4eb..983847c 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -21,6 +21,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 #include <memory>
 
 #include <utils/Log.h>
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2dd5771..540e976 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -384,6 +384,7 @@
     mkdir /data/misc/radio 0770 system radio
     mkdir /data/misc/sms 0770 system radio
     mkdir /data/misc/zoneinfo 0775 system system
+    mkdir /data/misc/textclassifier 0771 system system
     mkdir /data/misc/vpn 0770 system vpn
     mkdir /data/misc/shared_relro 0771 shared_relro shared_relro
     mkdir /data/misc/systemkeys 0700 system system
diff --git a/rootdir/init.usb.configfs.rc b/rootdir/init.usb.configfs.rc
index 32f0198..de1aab3 100644
--- a/rootdir/init.usb.configfs.rc
+++ b/rootdir/init.usb.configfs.rc
@@ -2,6 +2,7 @@
     write /config/usb_gadget/g1/UDC "none"
     stop adbd
     setprop sys.usb.ffs.ready 0
+    setprop sys.usb.ffs.mtp.ready 0
     write /config/usb_gadget/g1/bDeviceClass 0
     write /config/usb_gadget/g1/bDeviceSubClass 0
     write /config/usb_gadget/g1/bDeviceProtocol 0
@@ -11,6 +12,9 @@
     rmdir /config/usb_gadget/g1/functions/rndis.gs4
     setprop sys.usb.state ${sys.usb.config}
 
+on property:init.svc.adbd=stopped
+    setprop sys.usb.ffs.ready 0
+
 on property:sys.usb.config=adb && property:sys.usb.configfs=1
     start adbd
 
@@ -20,7 +24,7 @@
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
     setprop sys.usb.state ${sys.usb.config}
 
-on property:sys.usb.config=mtp && property:sys.usb.configfs=1
+on property:sys.usb.ffs.mtp.ready=1 && property:sys.usb.config=mtp && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp"
     symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -29,14 +33,15 @@
 on property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
     start adbd
 
-on property:sys.usb.ffs.ready=1 && property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
+on property:sys.usb.ffs.ready=1 && property:sys.usb.ffs.mtp.ready=1 && \
+property:sys.usb.config=mtp,adb && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "mtp_adb"
     symlink /config/usb_gadget/g1/functions/mtp.gs0 /config/usb_gadget/g1/configs/b.1/f1
     symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
     setprop sys.usb.state ${sys.usb.config}
 
-on property:sys.usb.config=ptp && property:sys.usb.configfs=1
+on property:sys.usb.ffs.mtp.ready=1 && property:sys.usb.config=ptp && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp"
     symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
     write /config/usb_gadget/g1/UDC ${sys.usb.controller}
@@ -45,7 +50,8 @@
 on property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
     start adbd
 
-on property:sys.usb.ffs.ready=1 && property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
+on property:sys.usb.ffs.ready=1 && property:sys.usb.ffs.mtp.ready=1 && \
+property:sys.usb.config=ptp,adb && property:sys.usb.configfs=1
     write /config/usb_gadget/g1/configs/b.1/strings/0x409/configuration "ptp_adb"
     symlink /config/usb_gadget/g1/functions/ptp.gs1 /config/usb_gadget/g1/configs/b.1/f1
     symlink /config/usb_gadget/g1/functions/ffs.adb /config/usb_gadget/g1/configs/b.1/f2
diff --git a/trusty/Android.bp b/trusty/Android.bp
new file mode 100644
index 0000000..1b2e2c7
--- /dev/null
+++ b/trusty/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+    "libtrusty",
+]
diff --git a/trusty/libtrusty/Android.bp b/trusty/libtrusty/Android.bp
new file mode 100644
index 0000000..f316da2
--- /dev/null
+++ b/trusty/libtrusty/Android.bp
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+subdirs = [
+    "tipc-test",
+]
+
+cc_library {
+    name: "libtrusty",
+
+    srcs: ["trusty.c"],
+    export_include_dirs: ["include"],
+
+    shared_libs: ["liblog"],
+}
diff --git a/trusty/libtrusty/Android.mk b/trusty/libtrusty/Android.mk
deleted file mode 100644
index 45fc079..0000000
--- a/trusty/libtrusty/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# == libtrusty Static library ==
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libtrusty
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := trusty.c
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-include $(BUILD_STATIC_LIBRARY)
-
-# ==  libtrusty shared library ==
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libtrusty
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := trusty.c
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_SHARED_LIBRARIES := liblog
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/trusty/libtrusty/tipc-test/Android.bp b/trusty/libtrusty/tipc-test/Android.bp
new file mode 100644
index 0000000..cb00fe7
--- /dev/null
+++ b/trusty/libtrusty/tipc-test/Android.bp
@@ -0,0 +1,26 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "tipc-test",
+    static_executable: true,
+
+    srcs: ["tipc_test.c"],
+    static_libs: [
+        "libc",
+        "libtrusty",
+        "liblog",
+    ],
+    gtest: false,
+}
diff --git a/trusty/libtrusty/tipc-test/Android.mk b/trusty/libtrusty/tipc-test/Android.mk
deleted file mode 100644
index 80030fe..0000000
--- a/trusty/libtrusty/tipc-test/Android.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := tipc-test
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := tipc_test.c
-LOCAL_STATIC_LIBRARIES := libc libtrusty liblog
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
-LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-
-include $(BUILD_EXECUTABLE)