Merge "liblp: Refactor the partition table update API."
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index b236fb3..0c3327f 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -79,22 +79,24 @@
 }
 
 std::string escape_arg(const std::string& s) {
-  std::string result = s;
-
   // Escape any ' in the string (before we single-quote the whole thing).
   // The correct way to do this for the shell is to replace ' with '\'' --- that is,
   // close the existing single-quoted string, escape a single single-quote, and start
   // a new single-quoted string. Like the C preprocessor, the shell will concatenate
   // these pieces into one string.
-  for (size_t i = 0; i < s.size(); ++i) {
-    if (s[i] == '\'') {
-      result.insert(i, "'\\'");
-      i += 2;
-    }
+
+  std::string result;
+  result.push_back('\'');
+
+  size_t base = 0;
+  while (true) {
+    size_t found = s.find('\'', base);
+    result.append(s, base, found - base);
+    if (found == s.npos) break;
+    result.append("'\\''");
+    base = found + 1;
   }
 
-  // Prefix and suffix the whole string with '.
-  result.insert(result.begin(), '\'');
   result.push_back('\'');
   return result;
 }
diff --git a/adb/adb_utils_test.cpp b/adb/adb_utils_test.cpp
index e1b6287..341323f 100644
--- a/adb/adb_utils_test.cpp
+++ b/adb/adb_utils_test.cpp
@@ -82,30 +82,38 @@
 #endif
 
 TEST(adb_utils, escape_arg) {
-  ASSERT_EQ(R"('')", escape_arg(""));
+  EXPECT_EQ(R"('')", escape_arg(""));
 
-  ASSERT_EQ(R"('abc')", escape_arg("abc"));
+  EXPECT_EQ(R"('abc')", escape_arg("abc"));
 
-  ASSERT_EQ(R"(' abc')", escape_arg(" abc"));
-  ASSERT_EQ(R"(''\''abc')", escape_arg("'abc"));
-  ASSERT_EQ(R"('"abc')", escape_arg("\"abc"));
-  ASSERT_EQ(R"('\abc')", escape_arg("\\abc"));
-  ASSERT_EQ(R"('(abc')", escape_arg("(abc"));
-  ASSERT_EQ(R"(')abc')", escape_arg(")abc"));
+  auto wrap = [](const std::string& x) { return '\'' + x + '\''; };
+  const std::string q = R"('\'')";
+  EXPECT_EQ(wrap(q), escape_arg("'"));
+  EXPECT_EQ(wrap(q + q), escape_arg("''"));
+  EXPECT_EQ(wrap(q + "abc" + q), escape_arg("'abc'"));
+  EXPECT_EQ(wrap(q + "abc"), escape_arg("'abc"));
+  EXPECT_EQ(wrap("abc" + q), escape_arg("abc'"));
+  EXPECT_EQ(wrap("abc" + q + "def"), escape_arg("abc'def"));
+  EXPECT_EQ(wrap("a" + q + "b" + q + "c"), escape_arg("a'b'c"));
+  EXPECT_EQ(wrap("a" + q + "bcde" + q + "f"), escape_arg("a'bcde'f"));
 
-  ASSERT_EQ(R"('abc abc')", escape_arg("abc abc"));
-  ASSERT_EQ(R"('abc'\''abc')", escape_arg("abc'abc"));
-  ASSERT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
-  ASSERT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
-  ASSERT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
-  ASSERT_EQ(R"('abc)abc')", escape_arg("abc)abc"));
+  EXPECT_EQ(R"(' abc')", escape_arg(" abc"));
+  EXPECT_EQ(R"('"abc')", escape_arg("\"abc"));
+  EXPECT_EQ(R"('\abc')", escape_arg("\\abc"));
+  EXPECT_EQ(R"('(abc')", escape_arg("(abc"));
+  EXPECT_EQ(R"(')abc')", escape_arg(")abc"));
 
-  ASSERT_EQ(R"('abc ')", escape_arg("abc "));
-  ASSERT_EQ(R"('abc'\''')", escape_arg("abc'"));
-  ASSERT_EQ(R"('abc"')", escape_arg("abc\""));
-  ASSERT_EQ(R"('abc\')", escape_arg("abc\\"));
-  ASSERT_EQ(R"('abc(')", escape_arg("abc("));
-  ASSERT_EQ(R"('abc)')", escape_arg("abc)"));
+  EXPECT_EQ(R"('abc abc')", escape_arg("abc abc"));
+  EXPECT_EQ(R"('abc"abc')", escape_arg("abc\"abc"));
+  EXPECT_EQ(R"('abc\abc')", escape_arg("abc\\abc"));
+  EXPECT_EQ(R"('abc(abc')", escape_arg("abc(abc"));
+  EXPECT_EQ(R"('abc)abc')", escape_arg("abc)abc"));
+
+  EXPECT_EQ(R"('abc ')", escape_arg("abc "));
+  EXPECT_EQ(R"('abc"')", escape_arg("abc\""));
+  EXPECT_EQ(R"('abc\')", escape_arg("abc\\"));
+  EXPECT_EQ(R"('abc(')", escape_arg("abc("));
+  EXPECT_EQ(R"('abc)')", escape_arg("abc)"));
 }
 
 void test_mkdirs(const std::string& basepath) {
diff --git a/adb/client/commandline.h b/adb/client/commandline.h
index 3d10030..3aa03a7 100644
--- a/adb/client/commandline.h
+++ b/adb/client/commandline.h
@@ -83,6 +83,14 @@
     DISALLOW_COPY_AND_ASSIGN(DefaultStandardStreamsCallback);
 };
 
+class SilentStandardStreamsCallbackInterface : public StandardStreamsCallbackInterface {
+  public:
+    SilentStandardStreamsCallbackInterface() = default;
+    void OnStdout(const char*, int) override final {}
+    void OnStderr(const char*, int) override final {}
+    int Done(int status) override final { return status; }
+};
+
 // Singleton.
 extern DefaultStandardStreamsCallback DEFAULT_STANDARD_STREAMS_CALLBACK;
 
diff --git a/adb/client/file_sync_client.cpp b/adb/client/file_sync_client.cpp
index 1275641..a438dbb 100644
--- a/adb/client/file_sync_client.cpp
+++ b/adb/client/file_sync_client.cpp
@@ -44,6 +44,8 @@
 #include "sysdeps/errno.h"
 #include "sysdeps/stat.h"
 
+#include "client/commandline.h"
+
 #include <android-base/file.h>
 #include <android-base/strings.h>
 #include <android-base/stringprintf.h>
@@ -202,12 +204,11 @@
         max = SYNC_DATA_MAX; // TODO: decide at runtime.
 
         std::string error;
-        FeatureSet features;
-        if (!adb_get_feature_set(&features, &error)) {
+        if (!adb_get_feature_set(&features_, &error)) {
             fd = -1;
             Error("failed to get feature set: %s", error.c_str());
         } else {
-            have_stat_v2_ = CanUseFeature(features, kFeatureStat2);
+            have_stat_v2_ = CanUseFeature(features_, kFeatureStat2);
             fd = adb_connect("sync:", &error);
             if (fd < 0) {
                 Error("connect failed: %s", error.c_str());
@@ -232,6 +233,8 @@
         line_printer_.KeepInfoLine();
     }
 
+    const FeatureSet& Features() const { return features_; }
+
     bool IsValid() { return fd >= 0; }
 
     bool ReceivedError(const char* from, const char* to) {
@@ -576,6 +579,7 @@
 
   private:
     bool expect_done_;
+    FeatureSet features_;
     bool have_stat_v2_;
 
     TransferLedger global_ledger_;
@@ -805,7 +809,7 @@
 }
 
 static bool local_build_list(SyncConnection& sc, std::vector<copyinfo>* file_list,
-                             const std::string& lpath,
+                             std::vector<std::string>* directory_list, const std::string& lpath,
                              const std::string& rpath) {
     std::vector<copyinfo> dirlist;
     std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(lpath.c_str()), closedir);
@@ -848,21 +852,9 @@
     // Close this directory and recurse.
     dir.reset();
 
-    // Add the current directory to the list if it was empty, to ensure that
-    // it gets created.
-    if (empty_dir) {
-        // TODO(b/25566053): Make pushing empty directories work.
-        // TODO(b/25457350): We don't preserve permissions on directories.
-        sc.Warning("skipping empty directory '%s'", lpath.c_str());
-        copyinfo ci(android::base::Dirname(lpath), android::base::Dirname(rpath),
-                    android::base::Basename(lpath), S_IFDIR);
-        ci.skip = true;
-        file_list->push_back(ci);
-        return true;
-    }
-
     for (const copyinfo& ci : dirlist) {
-        local_build_list(sc, file_list, ci.lpath, ci.rpath);
+        directory_list->push_back(ci.rpath);
+        local_build_list(sc, file_list, directory_list, ci.lpath, ci.rpath);
     }
 
     return true;
@@ -879,11 +871,54 @@
 
     // Recursively build the list of files to copy.
     std::vector<copyinfo> file_list;
+    std::vector<std::string> directory_list;
+
+    for (std::string dirpath = rpath; dirpath != "/"; dirpath = android::base::Dirname(dirpath)) {
+        directory_list.push_back(dirpath);
+    }
+    std::reverse(directory_list.begin(), directory_list.end());
+
     int skipped = 0;
-    if (!local_build_list(sc, &file_list, lpath, rpath)) {
+    if (!local_build_list(sc, &file_list, &directory_list, lpath, rpath)) {
         return false;
     }
 
+    // b/110953234:
+    // P shipped with a bug that causes directory creation as a side-effect of a push to fail.
+    // Work around this by explicitly doing a mkdir via shell.
+    //
+    // Devices that don't support shell_v2 are unhappy if we try to send a too-long packet to them,
+    // but they're not affected by this bug, so only apply the workaround if we have shell_v2.
+    //
+    // TODO(b/25457350): We don't preserve permissions on directories.
+    // TODO: Find all of the leaves and `mkdir -p` them instead?
+    if (CanUseFeature(sc.Features(), kFeatureShell2)) {
+        SilentStandardStreamsCallbackInterface cb;
+        std::string cmd = "mkdir";
+        for (const auto& dir : directory_list) {
+            std::string escaped_path = escape_arg(dir);
+            if (escaped_path.size() > 16384) {
+                // Somewhat arbitrarily limit that probably won't ever happen.
+                sc.Error("path too long: %s", escaped_path.c_str());
+                return false;
+            }
+
+            // The maximum should be 64kiB, but that's not including other stuff that gets tacked
+            // onto the command line, so let's be a bit conservative.
+            if (cmd.size() + escaped_path.size() > 32768) {
+                // Dispatch the command, ignoring failure (since the directory might already exist).
+                send_shell_command(cmd, false, &cb);
+                cmd = "mkdir";
+            }
+            cmd += " ";
+            cmd += escaped_path;
+        }
+
+        if (cmd != "mkdir") {
+            send_shell_command(cmd, false, &cb);
+        }
+    }
+
     if (check_timestamps) {
         for (const copyinfo& ci : file_list) {
             if (!sc.SendLstat(ci.rpath.c_str())) {
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index f1197d7..f2911e0 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -314,7 +314,6 @@
 #else /* !_WIN32 a.k.a. Unix */
 
 #include <cutils/sockets.h>
-#include <cutils/threads.h>
 #include <fcntl.h>
 #include <poll.h>
 #include <signal.h>
diff --git a/adb/test_device.py b/adb/test_device.py
index 5aa2684..4abe7a7 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -750,7 +750,6 @@
             if host_dir is not None:
                 shutil.rmtree(host_dir)
 
-    @unittest.expectedFailure # b/25566053
     def test_push_empty(self):
         """Push a directory containing an empty directory to the device."""
         self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])
diff --git a/base/include/android-base/threads.h b/base/include/android-base/threads.h
index f4ba809..dba1fc6 100644
--- a/base/include/android-base/threads.h
+++ b/base/include/android-base/threads.h
@@ -23,3 +23,8 @@
 uint64_t GetThreadId();
 }
 }  // namespace android
+
+#if defined(__GLIBC__)
+// bionic has this Linux-specifix call, but glibc doesn't.
+extern "C" int tgkill(int tgid, int tid, int sig);
+#endif
diff --git a/base/threads.cpp b/base/threads.cpp
index a71382b..48f6197 100644
--- a/base/threads.cpp
+++ b/base/threads.cpp
@@ -46,3 +46,9 @@
 
 }  // namespace base
 }  // namespace android
+
+#if defined(__GLIBC__)
+int tgkill(int tgid, int tid, int sig) {
+  return syscall(__NR_tgkill, tgid, tid, sig);
+}
+#endif
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 421f4e6..720590d 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -54,6 +54,8 @@
     }
     return true;
 #else
+    (void)block_device;
+    (void)device_info;
     LERROR << __PRETTY_FUNCTION__ << ": Not supported on this operating system.";
     return false;
 #endif
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index b4bf35f..a10e636 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -42,7 +42,6 @@
     "Backtrace.cpp",
     "BacktraceCurrent.cpp",
     "BacktracePtrace.cpp",
-    "thread_utils.c",
     "ThreadEntry.cpp",
     "UnwindStack.cpp",
     "UnwindStackMap.cpp",
@@ -94,7 +93,6 @@
             ],
 
             static_libs: [
-                "libcutils",
                 "libprocinfo",
             ],
 
@@ -145,7 +143,6 @@
         "backtrace_offline_test.cpp",
         "backtrace_test.cpp",
         "GetPss.cpp",
-        "thread_utils.c",
     ],
 
     cflags: [
@@ -159,7 +156,6 @@
         "libbacktrace",
         "libdexfile",
         "libbase",
-        "libcutils",
         "liblog",
         "libunwindstack",
     ],
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index 6445a7c..6bec63c 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -23,6 +23,7 @@
 #include <string>
 
 #include <android-base/stringprintf.h>
+#include <android-base/threads.h>
 
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
@@ -31,7 +32,6 @@
 
 #include "BacktraceLog.h"
 #include "UnwindStack.h"
-#include "thread_utils.h"
 
 using android::base::StringPrintf;
 
@@ -124,7 +124,7 @@
   if (pid == BACKTRACE_CURRENT_PROCESS) {
     pid = getpid();
     if (tid == BACKTRACE_CURRENT_THREAD) {
-      tid = gettid();
+      tid = android::base::GetThreadId();
     }
   } else if (tid == BACKTRACE_CURRENT_THREAD) {
     tid = pid;
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index f6f4423..39cb995 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -28,13 +28,13 @@
 
 #include <string>
 
+#include <android-base/threads.h>
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
 
 #include "BacktraceAsyncSafeLog.h"
 #include "BacktraceCurrent.h"
 #include "ThreadEntry.h"
-#include "thread_utils.h"
 
 bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
   if (!VerifyReadWordArgs(ptr, out_value)) {
@@ -76,7 +76,7 @@
     return UnwindFromContext(num_ignore_frames, ucontext);
   }
 
-  if (Tid() != gettid()) {
+  if (Tid() != android::base::GetThreadId()) {
     return UnwindThread(num_ignore_frames);
   }
 
@@ -114,16 +114,17 @@
 static void SignalLogOnly(int, siginfo_t*, void*) {
   ErrnoRestorer restore;
 
-  BACK_ASYNC_SAFE_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(), gettid(),
-                       THREAD_SIGNAL);
+  BACK_ASYNC_SAFE_LOGE("pid %d, tid %d: Received a spurious signal %d\n", getpid(),
+                       static_cast<int>(android::base::GetThreadId()), THREAD_SIGNAL);
 }
 
 static void SignalHandler(int, siginfo_t*, void* sigcontext) {
   ErrnoRestorer restore;
 
-  ThreadEntry* entry = ThreadEntry::Get(getpid(), gettid(), false);
+  ThreadEntry* entry = ThreadEntry::Get(getpid(), android::base::GetThreadId(), false);
   if (!entry) {
-    BACK_ASYNC_SAFE_LOGE("pid %d, tid %d entry not found", getpid(), gettid());
+    BACK_ASYNC_SAFE_LOGE("pid %d, tid %d entry not found", getpid(),
+                         static_cast<int>(android::base::GetThreadId()));
     return;
   }
 
diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp
index 399721d..6a967f7 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -32,8 +32,6 @@
 #include <procinfo/process_map.h>
 #endif
 
-#include "thread_utils.h"
-
 using android::base::StringPrintf;
 
 std::string backtrace_map_t::Name() const {
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp
index bf6b16f..9da457d 100644
--- a/libbacktrace/BacktracePtrace.cpp
+++ b/libbacktrace/BacktracePtrace.cpp
@@ -28,7 +28,6 @@
 
 #include "BacktraceLog.h"
 #include "BacktracePtrace.h"
-#include "thread_utils.h"
 
 #if !defined(__APPLE__)
 static bool PtraceRead(pid_t tid, uint64_t addr, word_t* out_value) {
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index e087b2e..4e7f761 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -23,10 +23,6 @@
 #include <set>
 #include <string>
 
-#if !defined(__ANDROID__)
-#include <cutils/threads.h>
-#endif
-
 #include <backtrace/Backtrace.h>
 #include <demangle.h>
 #include <unwindstack/Elf.h>
diff --git a/libbacktrace/backtrace_benchmarks.cpp b/libbacktrace/backtrace_benchmarks.cpp
index a23e3b4..099ac60 100644
--- a/libbacktrace/backtrace_benchmarks.cpp
+++ b/libbacktrace/backtrace_benchmarks.cpp
@@ -27,6 +27,7 @@
 #include <string>
 
 #include <android-base/file.h>
+#include <android-base/threads.h>
 
 #include <benchmark/benchmark.h>
 
@@ -154,7 +155,7 @@
 
 static void CreateBacktrace(benchmark::State& state, BacktraceMap* map, BacktraceCreateFn fn) {
   while (state.KeepRunning()) {
-    std::unique_ptr<Backtrace> backtrace(fn(getpid(), gettid(), map));
+    std::unique_ptr<Backtrace> backtrace(fn(getpid(), android::base::GetThreadId(), map));
     backtrace->Unwind(0);
   }
 }
diff --git a/libbacktrace/backtrace_offline_test.cpp b/libbacktrace/backtrace_offline_test.cpp
index 9877f29..7d1027e 100644
--- a/libbacktrace/backtrace_offline_test.cpp
+++ b/libbacktrace/backtrace_offline_test.cpp
@@ -31,9 +31,9 @@
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/threads.h>
 #include <backtrace/Backtrace.h>
 #include <backtrace/BacktraceMap.h>
-#include <cutils/threads.h>
 
 #include <gtest/gtest.h>
 
@@ -99,7 +99,7 @@
 
 static void* OfflineThreadFunc(void* arg) {
   OfflineThreadArg* fn_arg = reinterpret_cast<OfflineThreadArg*>(arg);
-  fn_arg->tid = gettid();
+  fn_arg->tid = android::base::GetThreadId();
   test_get_context_and_wait(&fn_arg->ucontext, &fn_arg->exit_flag);
   return nullptr;
 }
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index f78a31f..06a32c7 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -47,16 +47,15 @@
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
 #include <android-base/test_utils.h>
+#include <android-base/threads.h>
 #include <android-base/unique_fd.h>
 #include <cutils/atomic.h>
-#include <cutils/threads.h>
 
 #include <gtest/gtest.h>
 
 // For the THREAD_SIGNAL definition.
 #include "BacktraceCurrent.h"
 #include "backtrace_testlib.h"
-#include "thread_utils.h"
 
 // Number of microseconds per milliseconds.
 #define US_PER_MSEC             1000
@@ -525,7 +524,7 @@
 }
 
 void VerifyLevelThread(void*) {
-  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), android::base::GetThreadId()));
   ASSERT_TRUE(backtrace.get() != nullptr);
   ASSERT_TRUE(backtrace->Unwind(0));
   VERIFY_NO_ERROR(backtrace->GetError().error_code);
@@ -538,7 +537,7 @@
 }
 
 static void VerifyMaxThread(void*) {
-  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), gettid()));
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(getpid(), android::base::GetThreadId()));
   ASSERT_TRUE(backtrace.get() != nullptr);
   ASSERT_TRUE(backtrace->Unwind(0));
   ASSERT_EQ(BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT, backtrace->GetError().error_code);
@@ -553,7 +552,7 @@
 static void* ThreadLevelRun(void* data) {
   thread_t* thread = reinterpret_cast<thread_t*>(data);
 
-  thread->tid = gettid();
+  thread->tid = android::base::GetThreadId();
   EXPECT_NE(test_level_one(1, 2, 3, 4, ThreadSetState, data), 0);
   return nullptr;
 }
@@ -644,7 +643,7 @@
 static void* ThreadMaxRun(void* data) {
   thread_t* thread = reinterpret_cast<thread_t*>(data);
 
-  thread->tid = gettid();
+  thread->tid = android::base::GetThreadId();
   EXPECT_NE(test_recursive_call(MAX_BACKTRACE_FRAMES+10, ThreadSetState, data), 0);
   return nullptr;
 }
@@ -994,7 +993,7 @@
 static void* ThreadReadTest(void* data) {
   thread_t* thread_data = reinterpret_cast<thread_t*>(data);
 
-  thread_data->tid = gettid();
+  thread_data->tid = android::base::GetThreadId();
 
   // Create two map pages.
   // Mark the second page as not-readable.
@@ -1816,7 +1815,8 @@
 
 static void TestFrameSkipNumbering(create_func_t create_func, map_create_func_t map_create_func) {
   std::unique_ptr<BacktraceMap> map(map_create_func(getpid(), false));
-  std::unique_ptr<Backtrace> backtrace(create_func(getpid(), gettid(), map.get()));
+  std::unique_ptr<Backtrace> backtrace(
+      create_func(getpid(), android::base::GetThreadId(), map.get()));
   backtrace->Unwind(1);
   ASSERT_NE(0U, backtrace->NumFrames());
   ASSERT_EQ(0U, backtrace->GetFrame(0)->num);
diff --git a/libbacktrace/thread_utils.c b/libbacktrace/thread_utils.c
deleted file mode 100644
index e75f56e..0000000
--- a/libbacktrace/thread_utils.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#include "thread_utils.h"
-
-#if !defined(__BIONIC__)
-
-// glibc doesn't implement or export tgkill.
-#include <unistd.h>
-#include <sys/syscall.h>
-
-int tgkill(int tgid, int tid, int sig) {
-  return syscall(__NR_tgkill, tgid, tid, sig);
-}
-
-#endif
diff --git a/libbacktrace/thread_utils.h b/libbacktrace/thread_utils.h
deleted file mode 100644
index 9590657..0000000
--- a/libbacktrace/thread_utils.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#ifndef _LIBBACKTRACE_THREAD_UTILS_H
-#define _LIBBACKTRACE_THREAD_UTILS_H
-
-#include <unistd.h>
-
-#if !defined(__ANDROID__)
-#include <cutils/threads.h>
-#endif
-
-__BEGIN_DECLS
-
-int tgkill(int tgid, int tid, int sig);
-
-__END_DECLS
-
-#endif /* _LIBBACKTRACE_THREAD_UTILS_H */
diff --git a/libmemunreachable/tests/ThreadCapture_test.cpp b/libmemunreachable/tests/ThreadCapture_test.cpp
index 4fbf729..933d65a 100644
--- a/libmemunreachable/tests/ThreadCapture_test.cpp
+++ b/libmemunreachable/tests/ThreadCapture_test.cpp
@@ -32,6 +32,8 @@
 #include "ScopedDisableMalloc.h"
 #include "ScopedPipe.h"
 
+#include <android-base/threads.h>
+
 using namespace std::chrono_literals;
 
 namespace android {
@@ -260,7 +262,7 @@
 
       ThreadCapture thread_capture(ret, heap);
       thread_capture.InjectTestFunc([&](pid_t tid) {
-        syscall(SYS_tgkill, ret, tid, SIGKILL);
+        tgkill(ret, tid, SIGKILL);
         usleep(10000);
       });
       auto list_tids = allocator::vector<pid_t>(heap);
@@ -319,7 +321,7 @@
 
           ThreadCapture thread_capture(child, heap);
           thread_capture.InjectTestFunc([&](pid_t tid) {
-            syscall(SYS_tgkill, child, tid, sig);
+            tgkill(child, tid, sig);
             usleep(10000);
           });
           auto list_tids = allocator::vector<pid_t>(heap);
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index 83695bb..ea992c7 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -32,6 +32,7 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
+#include <android-base/threads.h>
 
 #include <unwindstack/Maps.h>
 #include <unwindstack/Memory.h>
@@ -231,8 +232,7 @@
     usleep(1000);
   }
   ASSERT_NE(0, tid.load());
-  // Portable tgkill method.
-  ASSERT_EQ(0, syscall(__NR_tgkill, getpid(), tid.load(), SIGUSR1)) << "Error: " << strerror(errno);
+  ASSERT_EQ(0, tgkill(getpid(), tid.load(), SIGUSR1)) << "Error: " << strerror(errno);
 
   // Wait for context data.
   void* ucontext;
diff --git a/logcat/event.logtags b/logcat/event.logtags
index 750761f..da8d2d4 100644
--- a/logcat/event.logtags
+++ b/logcat/event.logtags
@@ -113,6 +113,9 @@
 # graphics timestamp
 # 60100 - 60199 reserved for surfaceflinger
 
+# audio
+# 61000 - 61199 reserved for audioserver
+
 # 0 for screen off, 1 for screen on, 2 for key-guard done
 70000 screen_toggled (screen_state|1|5)
 
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 625ffba..d3f038e 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -318,8 +318,8 @@
     start vndservicemanager
 
     # Once everything is setup, no need to modify /.
-    # The bind+ro combination avoids modifying any other mount flags.
-    mount rootfs rootfs / remount bind ro
+    # The bind+remount combination allows this to work in containers.
+    mount rootfs rootfs / remount bind ro nodev
     # Mount shared so changes propagate into child namespaces
     mount rootfs rootfs / shared rec
     # Mount default storage into root namespace
@@ -718,6 +718,9 @@
 
 on property:security.perf_harden=0
     write /proc/sys/kernel/perf_event_paranoid 1
+    write /proc/sys/kernel/perf_event_max_sample_rate ${debug.perf_event_max_sample_rate:-100000}
+    write /proc/sys/kernel/perf_cpu_time_max_percent ${debug.perf_cpu_time_max_percent:-25}
+    write /proc/sys/kernel/perf_event_mlock_kb ${debug.perf_event_mlock_kb:-516}
 
 on property:security.perf_harden=1
     write /proc/sys/kernel/perf_event_paranoid 3