Merge "Trigger boot animation on userspace reboot"
diff --git a/adb/Android.bp b/adb/Android.bp
index b39defe..7c5e3ea 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -114,6 +114,61 @@
     },
 }
 
+// libadbconnection
+// =========================================================
+// libadbconnection_client/server implement the socket handling for jdwp
+// forwarding and the track-jdwp service.
+cc_library {
+    name: "libadbconnection_server",
+    srcs: ["adbconnection/adbconnection_server.cpp"],
+
+    export_include_dirs: ["adbconnection/include"],
+
+    stl: "libc++_static",
+    shared_libs: ["liblog"],
+    static_libs: ["libbase"],
+
+    defaults: ["adbd_defaults", "host_adbd_supported"],
+
+    // Avoid getting duplicate symbol of android::build::getbuildnumber().
+    use_version_lib: false,
+
+    recovery_available: true,
+    compile_multilib: "both",
+}
+
+cc_library {
+    name: "libadbconnection_client",
+    srcs: ["adbconnection/adbconnection_client.cpp"],
+
+    export_include_dirs: ["adbconnection/include"],
+
+    stl: "libc++_static",
+    shared_libs: ["liblog"],
+    static_libs: ["libbase"],
+
+    defaults: ["adbd_defaults"],
+    visibility: [
+        "//art:__subpackages__",
+        "//system/core/adb/apex:__subpackages__",
+    ],
+    apex_available: [
+        "com.android.adbd",
+        "test_com.android.adbd",
+    ],
+
+    // libadbconnection_client doesn't need an embedded build number.
+    use_version_lib: false,
+
+    stubs: {
+        symbol_file: "adbconnection/libadbconnection_client.map.txt",
+        versions: ["1"],
+    },
+
+    host_supported: true,
+    compile_multilib: "both",
+}
+
 // libadb
 // =========================================================
 // These files are compiled for both the host and the device.
@@ -358,11 +413,11 @@
     generated_headers: ["platform_tools_version"],
 
     static_libs: [
+        "libadbconnection_server",
         "libdiagnose_usb",
     ],
 
     shared_libs: [
-        "libadbconnection_server",
         "libadbd_auth",
         "libasyncio",
         "libbase",
@@ -411,12 +466,12 @@
     ],
 
     static_libs: [
+        "libadbconnection_server",
         "libadbd_core",
         "libdiagnose_usb",
     ],
 
     shared_libs: [
-        "libadbconnection_server",
         "libadbd_auth",
         "libasyncio",
         "libbase",
@@ -452,7 +507,7 @@
     defaults: ["adbd_defaults", "host_adbd_supported"],
     recovery_available: true,
 
-    // Avoid getting duplicate symbol of android::build::GetBuildNumber().
+    // avoid getting duplicate symbol of android::build::getbuildnumber().
     use_version_lib: false,
 
     // libminadbd wants both, as it's used to build native tests.
@@ -460,11 +515,11 @@
 
     // libadbd doesn't build any additional source, but to expose libadbd_core as a shared library.
     whole_static_libs: [
+        "libadbconnection_server",
         "libadbd_core",
     ],
 
     shared_libs: [
-        "libadbconnection_server",
         "libadbd_auth",
         "libadbd_services",
         "libasyncio",
@@ -500,6 +555,7 @@
 
     stl: "libc++_static",
     static_libs: [
+        "libadbconnection_server",
         "libadbd",
         "libadbd_auth",
         "libadbd_services",
@@ -516,7 +572,6 @@
     ],
 
     shared_libs: [
-        "libadbconnection_server",
         "libcrypto",
     ],
 }
diff --git a/adb/adbconnection/.clang-format b/adb/adbconnection/.clang-format
new file mode 120000
index 0000000..e545823
--- /dev/null
+++ b/adb/adbconnection/.clang-format
@@ -0,0 +1 @@
+../../.clang-format-2
\ No newline at end of file
diff --git a/adb/adbconnection/adbconnection_client.cpp b/adb/adbconnection/adbconnection_client.cpp
new file mode 100644
index 0000000..ee48abb
--- /dev/null
+++ b/adb/adbconnection/adbconnection_client.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2020 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 "adbconnection/client.h"
+
+#include <pwd.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <memory>
+#include <optional>
+
+#include <android-base/cmsg.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
+using android::base::unique_fd;
+
+static constexpr char kJdwpControlName[] = "\0jdwp-control";
+
+struct AdbConnectionClientContext {
+  unique_fd control_socket_;
+};
+
+bool SocketPeerIsTrusted(int fd) {
+  ucred cr;
+  socklen_t cr_length = sizeof(cr);
+  if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_length) != 0) {
+    PLOG(ERROR) << "couldn't get socket credentials";
+    return false;
+  }
+
+  passwd* shell = getpwnam("shell");
+  if (cr.uid != 0 && cr.uid != shell->pw_uid) {
+    LOG(ERROR) << "untrusted uid " << cr.uid << " on other end of socket";
+    return false;
+  }
+
+  return true;
+}
+
+AdbConnectionClientContext* adbconnection_client_new(
+    const AdbConnectionClientInfo* const* info_elems, size_t info_count) {
+  auto ctx = std::make_unique<AdbConnectionClientContext>();
+
+  std::optional<uint64_t> pid;
+  std::optional<bool> debuggable;
+
+  for (size_t i = 0; i < info_count; ++i) {
+    auto info = info_elems[i];
+    switch (info->type) {
+      case AdbConnectionClientInfoType::pid:
+        if (pid) {
+          LOG(ERROR) << "multiple pid entries in AdbConnectionClientInfo, ignoring";
+          continue;
+        }
+        pid = info->data.pid;
+        break;
+
+      case AdbConnectionClientInfoType::debuggable:
+        if (debuggable) {
+          LOG(ERROR) << "multiple debuggable entries in AdbConnectionClientInfo, ignoring";
+          continue;
+        }
+        debuggable = info->data.pid;
+        break;
+    }
+  }
+
+  if (!pid) {
+    LOG(ERROR) << "AdbConnectionClientInfo missing required field pid";
+    return nullptr;
+  }
+
+  if (!debuggable) {
+    LOG(ERROR) << "AdbConnectionClientInfo missing required field debuggable";
+    return nullptr;
+  }
+
+  ctx->control_socket_.reset(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0));
+  if (ctx->control_socket_ < 0) {
+    PLOG(ERROR) << "failed to create Unix domain socket";
+    return nullptr;
+  }
+
+  struct timeval timeout;
+  timeout.tv_sec = 1;
+  timeout.tv_usec = 0;
+  setsockopt(ctx->control_socket_.get(), SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
+
+  sockaddr_un addr = {};
+  addr.sun_family = AF_UNIX;
+  memcpy(addr.sun_path, kJdwpControlName, sizeof(kJdwpControlName));
+  size_t addr_len = offsetof(sockaddr_un, sun_path) + sizeof(kJdwpControlName) - 1;
+
+  int rc = connect(ctx->control_socket_.get(), reinterpret_cast<sockaddr*>(&addr), addr_len);
+  if (rc != 0) {
+    PLOG(ERROR) << "failed to connect to jdwp control socket";
+    return nullptr;
+  }
+
+  bool trusted = SocketPeerIsTrusted(ctx->control_socket_.get());
+  if (!trusted) {
+    LOG(ERROR) << "adb socket is not trusted, aborting connection";
+    return nullptr;
+  }
+
+  uint32_t pid_u32 = static_cast<uint32_t>(*pid);
+  rc = TEMP_FAILURE_RETRY(write(ctx->control_socket_.get(), &pid_u32, sizeof(pid_u32)));
+  if (rc != sizeof(pid_u32)) {
+    PLOG(ERROR) << "failed to send JDWP process pid to adbd";
+  }
+
+  return ctx.release();
+}
+
+void adbconnection_client_destroy(AdbConnectionClientContext* ctx) {
+  delete ctx;
+}
+
+int adbconnection_client_pollfd(AdbConnectionClientContext* ctx) {
+  return ctx->control_socket_.get();
+}
+
+int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx) {
+  char dummy;
+  unique_fd jdwp_fd;
+  ssize_t rc = android::base::ReceiveFileDescriptors(ctx->control_socket_, &dummy, 1, &jdwp_fd);
+  if (rc != 1) {
+    return rc;
+  }
+  return jdwp_fd.release();
+}
diff --git a/adb/adbconnection/adbconnection_server.cpp b/adb/adbconnection/adbconnection_server.cpp
new file mode 100644
index 0000000..939da2f
--- /dev/null
+++ b/adb/adbconnection/adbconnection_server.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 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 "adbconnection/server.h"
+
+#include <sys/epoll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <array>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+
+using android::base::unique_fd;
+
+#define JDWP_CONTROL_NAME "\0jdwp-control"
+#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME) - 1)
+
+static_assert(JDWP_CONTROL_NAME_LEN <= sizeof(reinterpret_cast<sockaddr_un*>(0)->sun_path));
+
+// Listen for incoming jdwp clients forever.
+void adbconnection_listen(void (*callback)(int fd, pid_t pid)) {
+  sockaddr_un addr = {};
+  socklen_t addrlen = JDWP_CONTROL_NAME_LEN + sizeof(addr.sun_family);
+
+  addr.sun_family = AF_UNIX;
+  memcpy(addr.sun_path, JDWP_CONTROL_NAME, JDWP_CONTROL_NAME_LEN);
+
+  unique_fd s(socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
+  if (s < 0) {
+    PLOG(ERROR) << "failed to create JDWP control socket";
+    return;
+  }
+
+  if (bind(s.get(), reinterpret_cast<sockaddr*>(&addr), addrlen) < 0) {
+    PLOG(ERROR) << "failed to bind JDWP control socket";
+    return;
+  }
+
+  if (listen(s.get(), 4) < 0) {
+    PLOG(ERROR) << "failed to listen on JDWP control socket";
+    return;
+  }
+
+  std::vector<unique_fd> pending_connections;
+
+  unique_fd epfd(epoll_create1(EPOLL_CLOEXEC));
+  std::array<epoll_event, 16> events;
+
+  events[0].events = EPOLLIN;
+  events[0].data.fd = -1;
+  if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, s.get(), &events[0]) != 0) {
+    LOG(FATAL) << "failed to register event with epoll fd";
+  }
+
+  while (true) {
+    int epoll_rc = TEMP_FAILURE_RETRY(epoll_wait(epfd.get(), events.data(), events.size(), -1));
+    if (epoll_rc == -1) {
+      PLOG(FATAL) << "epoll_wait failed";
+    }
+
+    for (int i = 0; i < epoll_rc; ++i) {
+      const epoll_event& event = events[i];
+      if (event.data.fd == -1) {
+        unique_fd client(
+            TEMP_FAILURE_RETRY(accept4(s.get(), nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC)));
+
+        if (client == -1) {
+          PLOG(WARNING) << "failed to accept client on JDWP control socket";
+          continue;
+        }
+
+        epoll_event register_event;
+        register_event.events = EPOLLIN;
+        register_event.data.fd = client.get();
+
+        if (epoll_ctl(epfd.get(), EPOLL_CTL_ADD, client.get(), &register_event) != 0) {
+          PLOG(FATAL) << "failed to register JDWP client with epoll";
+        }
+
+        pending_connections.emplace_back(std::move(client));
+      } else {
+        // n^2, but the backlog should be short.
+        auto it = std::find_if(pending_connections.begin(), pending_connections.end(),
+                               [&](const unique_fd& fd) { return fd.get() == event.data.fd; });
+
+        if (it == pending_connections.end()) {
+          LOG(FATAL) << "failed to find JDWP client (" << event.data.fd
+                     << ") in pending connections";
+        }
+
+        // Massively oversized buffer: we're expecting an int32_t from the other end.
+        char buf[32];
+        int rc = TEMP_FAILURE_RETRY(recv(it->get(), buf, sizeof(buf), MSG_DONTWAIT));
+        if (rc != 4) {
+          LOG(ERROR) << "received data of incorrect size from JDWP client: read " << rc
+                     << ", expected 4";
+        } else {
+          int32_t pid;
+          memcpy(&pid, buf, sizeof(pid));
+          callback(it->release(), static_cast<pid_t>(pid));
+        }
+
+        if (epoll_ctl(epfd.get(), EPOLL_CTL_DEL, event.data.fd, nullptr) != 0) {
+          LOG(FATAL) << "failed to delete fd from JDWP epoll fd";
+        }
+
+        pending_connections.erase(it);
+      }
+    }
+  }
+}
diff --git a/adb/adbconnection/include/adbconnection/client.h b/adb/adbconnection/include/adbconnection/client.h
new file mode 100644
index 0000000..692fea0
--- /dev/null
+++ b/adb/adbconnection/include/adbconnection/client.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <android-base/unique_fd.h>
+
+extern "C" {
+
+struct AdbConnectionClientContext;
+
+enum AdbConnectionClientInfoType {
+  pid,
+  debuggable,
+};
+
+struct AdbConnectionClientInfo {
+  AdbConnectionClientInfoType type;
+  union {
+    uint64_t pid;
+    bool debuggable;
+  } data;
+};
+
+// Construct a context and connect to adbd.
+// Returns null if we fail to connect to adbd.
+AdbConnectionClientContext* adbconnection_client_new(
+    const AdbConnectionClientInfo* const* info_elems, size_t info_count);
+
+void adbconnection_client_destroy(AdbConnectionClientContext* ctx);
+
+// Get an fd which can be polled upon to detect when a jdwp socket is available.
+// You do not own this fd. Do not close it.
+int adbconnection_client_pollfd(AdbConnectionClientContext* ctx);
+
+// Receive a jdwp client fd.
+// Ownership is transferred to the caller of this function.
+int adbconnection_client_receive_jdwp_fd(AdbConnectionClientContext* ctx);
+}
diff --git a/adb/adbconnection/include/adbconnection/server.h b/adb/adbconnection/include/adbconnection/server.h
new file mode 100644
index 0000000..57ca6cd
--- /dev/null
+++ b/adb/adbconnection/include/adbconnection/server.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+
+#include <android-base/unique_fd.h>
+
+extern "C" {
+
+void adbconnection_listen(void (*callback)(int fd, pid_t pid));
+}
diff --git a/adb/adbconnection/libadbconnection_client.map.txt b/adb/adbconnection/libadbconnection_client.map.txt
new file mode 100644
index 0000000..153a0e4
--- /dev/null
+++ b/adb/adbconnection/libadbconnection_client.map.txt
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2019 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.
+#
+
+LIBADBCONNECTION_CLIENT_1 {
+  global:
+    adbconnection_client_new;
+    adbconnection_client_destroy;
+    adbconnection_client_pollfd;
+    adbconnection_client_receive_jdwp_fd;
+  local:
+    *;
+};
diff --git a/adb/apex/Android.bp b/adb/apex/Android.bp
index 40ea448..75c4ed9 100644
--- a/adb/apex/Android.bp
+++ b/adb/apex/Android.bp
@@ -2,6 +2,12 @@
     name: "com.android.adbd-defaults",
 
     binaries: ["adbd"],
+    compile_multilib: "both",
+    multilib: {
+        both: {
+            native_shared_libs: ["libadbconnection_client"],
+        },
+    },
     prebuilts: ["com.android.adbd.init.rc", "com.android.adbd.ld.config.txt"],
 
     key: "com.android.adbd.key",
diff --git a/base/include/android-base/errno_restorer.h b/base/include/android-base/errno_restorer.h
new file mode 100644
index 0000000..1c8597c
--- /dev/null
+++ b/base/include/android-base/errno_restorer.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include "errno.h"
+
+#include "android-base/macros.h"
+
+namespace android {
+namespace base {
+
+class ErrnoRestorer {
+ public:
+  ErrnoRestorer() : saved_errno_(errno) {}
+
+  ~ErrnoRestorer() { errno = saved_errno_; }
+
+  // Allow this object to be used as part of && operation.
+  operator bool() const { return true; }
+
+ private:
+  const int saved_errno_;
+
+  DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
+};
+
+}  // namespace base
+}  // namespace android
diff --git a/base/include/android-base/expected.h b/base/include/android-base/expected.h
index 030ef35e..b3f5adb 100644
--- a/base/include/android-base/expected.h
+++ b/base/include/android-base/expected.h
@@ -111,6 +111,7 @@
     !(!std::is_convertible_v<const U&, T> ||
      !std::is_convertible_v<const G&, E>) /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const expected<U, G>& rhs) {
     if (rhs.has_value()) var_ = rhs.value();
     else var_ = unexpected(rhs.error());
@@ -149,6 +150,7 @@
     !(!std::is_convertible_v<const U&, T> ||
      !std::is_convertible_v<const G&, E>) /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(expected<U, G>&& rhs) {
     if (rhs.has_value()) var_ = std::move(rhs.value());
     else var_ = unexpected(std::move(rhs.error()));
@@ -180,6 +182,7 @@
                 !std::is_same_v<unexpected<E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
                 std::is_convertible_v<U&&, T> /* non-explicit */
                 )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(U&& v) : var_(std::in_place_index<0>, std::forward<U>(v)) {}
 
   template <class U = T _ENABLE_IF(
@@ -195,6 +198,7 @@
     std::is_constructible_v<E, const G&> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const unexpected<G>& e)
   : var_(std::in_place_index<1>, e.value()) {}
 
@@ -209,6 +213,7 @@
     std::is_constructible_v<E, G&&> &&
     std::is_convertible_v<G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(unexpected<G>&& e)
   : var_(std::in_place_index<1>, std::move(e.value())) {}
 
@@ -457,6 +462,7 @@
     std::is_void_v<U> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const expected<U, G>& rhs) {
     if (!rhs.has_value()) var_ = unexpected(rhs.error());
   }
@@ -473,6 +479,7 @@
     std::is_void_v<U> &&
     std::is_convertible_v<const G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(expected<U, G>&& rhs) {
     if (!rhs.has_value()) var_ = unexpected(std::move(rhs.error()));
   }
@@ -489,6 +496,7 @@
     std::is_constructible_v<E, const G&> &&
     std::is_convertible_v<const G&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(const unexpected<G>& e)
   : var_(std::in_place_index<1>, e.value()) {}
 
@@ -503,6 +511,7 @@
     std::is_constructible_v<E, G&&> &&
     std::is_convertible_v<G&&, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr expected(unexpected<G>&& e)
   : var_(std::in_place_index<1>, std::move(e.value())) {}
 
@@ -640,6 +649,7 @@
                 std::is_constructible_v<E, Err> &&
                 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, std::in_place_t> &&
                 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<E>>, unexpected>)>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(Err&& e) : val_(std::forward<Err>(e)) {}
 
   template<class U, class... Args _ENABLE_IF(
@@ -660,6 +670,7 @@
     !std::is_convertible_v<const unexpected<Err>, E> &&
     std::is_convertible_v<Err, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(const unexpected<Err>& rhs)
   : val_(rhs.value()) {}
 
@@ -690,6 +701,7 @@
     !std::is_convertible_v<const unexpected<Err>, E> &&
     std::is_convertible_v<Err, E> /* non-explicit */
   )>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   constexpr unexpected(unexpected<Err>&& rhs)
   : val_(std::move(rhs.value())) {}
 
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index cc162cd..accc225 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -64,6 +64,7 @@
 #include <memory>
 #include <ostream>
 
+#include "android-base/errno_restorer.h"
 #include "android-base/macros.h"
 
 // Note: DO NOT USE DIRECTLY. Use LOG_TAG instead.
@@ -154,27 +155,6 @@
 // Replace the current aborter.
 void SetAborter(AbortFunction&& aborter);
 
-class ErrnoRestorer {
- public:
-  ErrnoRestorer()
-      : saved_errno_(errno) {
-  }
-
-  ~ErrnoRestorer() {
-    errno = saved_errno_;
-  }
-
-  // Allow this object to be used as part of && operation.
-  operator bool() const {
-    return true;
-  }
-
- private:
-  const int saved_errno_;
-
-  DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
-};
-
 // A helper macro that produces an expression that accepts both a qualified name and an
 // unqualified name for a LogSeverity, and returns a LogSeverity value.
 // Note: DO NOT USE DIRECTLY. This is an implementation detail.
diff --git a/base/include/android-base/result.h b/base/include/android-base/result.h
index 1b763af..b6d26e7 100644
--- a/base/include/android-base/result.h
+++ b/base/include/android-base/result.h
@@ -90,6 +90,7 @@
   ResultError(T&& message, int code) : message_(std::forward<T>(message)), code_(code) {}
 
   template <typename T>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator android::base::expected<T, ResultError>() {
     return android::base::unexpected(ResultError(message_, code_));
   }
@@ -118,9 +119,11 @@
 class Error {
  public:
   Error() : errno_(0), append_errno_(false) {}
+  // NOLINTNEXTLINE(google-explicit-constructor)
   Error(int errno_to_append) : errno_(errno_to_append), append_errno_(true) {}
 
   template <typename T>
+  // NOLINTNEXTLINE(google-explicit-constructor)
   operator android::base::expected<T, ResultError>() {
     return android::base::unexpected(ResultError(str(), errno_));
   }
diff --git a/base/logging.cpp b/base/logging.cpp
index 1d8ef57..a868706 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -608,7 +608,6 @@
   // we need to fall back to using gMinimumLogSeverity, since __android_log_is_loggable() will not
   // take into consideration the value from SetMinimumLogSeverity().
   if (liblog_functions) {
-    // TODO: It is safe to pass nullptr for tag, but it will be better to use the default log tag.
     int priority = LogSeverityToPriority(severity);
     return __android_log_is_loggable(priority, tag, ANDROID_LOG_INFO);
   } else {
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 3463a68..9180a06 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -101,6 +101,7 @@
 using android::base::unique_fd;
 using android::dm::DeviceMapper;
 using android::dm::DmDeviceState;
+using android::dm::DmTargetLinear;
 
 // Realistically, this file should be part of the android::fs_mgr namespace;
 using namespace android::fs_mgr;
@@ -1114,6 +1115,83 @@
     }
 }
 
+static constexpr const char* kUserdataWrapperName = "userdata-wrapper";
+
+static void WrapUserdata(FstabEntry* entry, dev_t dev, const std::string& block_device) {
+    DeviceMapper& dm = DeviceMapper::Instance();
+    if (dm.GetState(kUserdataWrapperName) != DmDeviceState::INVALID) {
+        // This will report failure for us. If we do fail to get the path,
+        // we leave the device unwrapped.
+        dm.GetDmDevicePathByName(kUserdataWrapperName, &entry->blk_device);
+        return;
+    }
+
+    unique_fd fd(open(block_device.c_str(), O_RDONLY | O_CLOEXEC));
+    if (fd < 0) {
+        PLOG(ERROR) << "open failed: " << entry->blk_device;
+        return;
+    }
+
+    auto dev_str = android::base::StringPrintf("%u:%u", major(dev), minor(dev));
+    uint64_t sectors = get_block_device_size(fd) / 512;
+
+    android::dm::DmTable table;
+    table.Emplace<DmTargetLinear>(0, sectors, dev_str, 0);
+
+    std::string dm_path;
+    if (!dm.CreateDevice(kUserdataWrapperName, table, &dm_path, 20s)) {
+        LOG(ERROR) << "Failed to create userdata wrapper device";
+        return;
+    }
+    entry->blk_device = dm_path;
+}
+
+// When using Virtual A/B, partitions can be backed by /data and mapped with
+// device-mapper in first-stage init. This can happen when merging an OTA or
+// when using adb remount to house "scratch". In this case, /data cannot be
+// mounted directly off the userdata block device, and e2fsck will refuse to
+// scan it, because the kernel reports the block device as in-use.
+//
+// As a workaround, when mounting /data, we create a trivial dm-linear wrapper
+// if the underlying block device already has dependencies. Note that we make
+// an exception for metadata-encrypted devices, since dm-default-key is already
+// a wrapper.
+static void WrapUserdataIfNeeded(FstabEntry* entry, const std::string& actual_block_device = {}) {
+    const auto& block_device =
+            actual_block_device.empty() ? entry->blk_device : actual_block_device;
+    if (entry->mount_point != "/data" || !entry->key_dir.empty() ||
+        android::base::StartsWith(block_device, "/dev/block/dm-")) {
+        return;
+    }
+
+    struct stat st;
+    if (stat(block_device.c_str(), &st) < 0) {
+        PLOG(ERROR) << "stat failed: " << block_device;
+        return;
+    }
+
+    std::string path = android::base::StringPrintf("/sys/dev/block/%u:%u/holders",
+                                                   major(st.st_rdev), minor(st.st_rdev));
+    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
+    if (!dir) {
+        PLOG(ERROR) << "opendir failed: " << path;
+        return;
+    }
+
+    struct dirent* d;
+    bool has_holders = false;
+    while ((d = readdir(dir.get())) != nullptr) {
+        if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) {
+            has_holders = true;
+            break;
+        }
+    }
+
+    if (has_holders) {
+        WrapUserdata(entry, st.st_rdev, block_device);
+    }
+}
+
 static bool IsMountPointMounted(const std::string& mount_point) {
     // Check if this is already mounted.
     Fstab fstab;
@@ -1193,6 +1271,8 @@
             }
         }
 
+        WrapUserdataIfNeeded(&current_entry);
+
         if (!checkpoint_manager.Update(&current_entry)) {
             continue;
         }
@@ -1463,6 +1543,9 @@
     }
     std::string block_device;
     if (auto entry = GetEntryForMountPoint(&proc_mounts, "/data"); entry != nullptr) {
+        // Note: we don't care about a userdata wrapper here, since it's safe
+        // to remount on top of the bow device instead, there will be no
+        // conflicts.
         block_device = entry->blk_device;
     } else {
         LERROR << "/data is not mounted";
@@ -1581,6 +1664,8 @@
             }
         }
 
+        WrapUserdataIfNeeded(&fstab_entry, n_blk_device);
+
         if (!checkpoint_manager.Update(&fstab_entry, n_blk_device)) {
             LERROR << "Could not set up checkpoint partition, skipping!";
             continue;
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index f9a3df9..ff6b036 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -130,6 +130,7 @@
 #define AID_GSID 1074            /* GSI service daemon */
 #define AID_FSVERITY_CERT 1075   /* fs-verity key ownership in keystore */
 #define AID_CREDSTORE 1076       /* identity credential manager service */
+#define AID_EXTERNAL_STORAGE 1077 /* Full external storage access including USB OTG volumes */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index e86d9ec..ca68296 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include "logger_write.h"
+
 #include <errno.h>
 #include <inttypes.h>
 #include <libgen.h>
@@ -27,6 +29,7 @@
 
 #include <shared_mutex>
 
+#include <android-base/errno_restorer.h>
 #include <android-base/macros.h>
 #include <private/android_filesystem_config.h>
 #include <private/android_logger.h>
@@ -52,6 +55,8 @@
 #include <windows.h>
 #endif
 
+using android::base::ErrnoRestorer;
+
 #define LOG_BUF_SIZE 1024
 
 #if defined(__ANDROID__)
@@ -136,11 +141,11 @@
 // It's possible for logging to happen during static initialization before our globals are
 // initialized, so we place this std::string in a function such that it is initialized on the first
 // call.
-static std::string& GetDefaultTag() {
+std::string& GetDefaultTag() {
   static std::string default_tag = getprogname();
   return default_tag;
 }
-static RwLock default_tag_lock;
+RwLock default_tag_lock;
 
 void __android_log_set_default_tag(const char* tag) {
   auto lock = std::unique_lock{default_tag_lock};
@@ -194,11 +199,9 @@
 
 #ifdef __ANDROID__
 static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) {
-  int ret, save_errno;
+  int ret;
   struct timespec ts;
 
-  save_errno = errno;
-
   if (log_id == LOG_ID_KERNEL) {
     return -EINVAL;
   }
@@ -207,23 +210,19 @@
 
   if (log_id == LOG_ID_SECURITY) {
     if (vec[0].iov_len < 4) {
-      errno = save_errno;
       return -EINVAL;
     }
 
     ret = check_log_uid_permissions();
     if (ret < 0) {
-      errno = save_errno;
       return ret;
     }
     if (!__android_log_security()) {
       /* If only we could reset downstream logd counter */
-      errno = save_errno;
       return -EPERM;
     }
   } else if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS) {
     if (vec[0].iov_len < 4) {
-      errno = save_errno;
       return -EINVAL;
     }
   }
@@ -231,7 +230,6 @@
   ret = LogdWrite(log_id, &ts, vec, nr);
   PmsgWrite(log_id, &ts, vec, nr);
 
-  errno = save_errno;
   return ret;
 }
 #else
@@ -311,6 +309,8 @@
 }
 
 void __android_log_write_logger_data(__android_logger_data* logger_data, const char* msg) {
+  ErrnoRestorer errno_restorer;
+
   auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
   if (logger_data->tag == nullptr) {
     tag_lock.lock();
@@ -328,6 +328,8 @@
 }
 
 int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) {
+  ErrnoRestorer errno_restorer;
+
   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
     return 0;
   }
@@ -338,6 +340,8 @@
 }
 
 int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) {
+  ErrnoRestorer errno_restorer;
+
   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
     return 0;
   }
@@ -353,6 +357,8 @@
 }
 
 int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
+  ErrnoRestorer errno_restorer;
+
   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
     return 0;
   }
@@ -371,6 +377,8 @@
 }
 
 int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) {
+  ErrnoRestorer errno_restorer;
+
   if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) {
     return 0;
   }
@@ -417,6 +425,8 @@
 }
 
 int __android_log_bwrite(int32_t tag, const void* payload, size_t len) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[2];
 
   vec[0].iov_base = &tag;
@@ -428,6 +438,8 @@
 }
 
 int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[2];
 
   vec[0].iov_base = &tag;
@@ -439,6 +451,8 @@
 }
 
 int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[2];
 
   vec[0].iov_base = &tag;
@@ -455,6 +469,8 @@
  * handy if we just want to dump an integer into the log.
  */
 int __android_log_btwrite(int32_t tag, char type, const void* payload, size_t len) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[3];
 
   vec[0].iov_base = &tag;
@@ -472,6 +488,8 @@
  * event log.
  */
 int __android_log_bswrite(int32_t tag, const char* payload) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[4];
   char type = EVENT_TYPE_STRING;
   uint32_t len = strlen(payload);
@@ -493,6 +511,8 @@
  * security log.
  */
 int __android_log_security_bswrite(int32_t tag, const char* payload) {
+  ErrnoRestorer errno_restorer;
+
   struct iovec vec[4];
   char type = EVENT_TYPE_STRING;
   uint32_t len = strlen(payload);
diff --git a/liblog/logger_write.h b/liblog/logger_write.h
new file mode 100644
index 0000000..065fd55
--- /dev/null
+++ b/liblog/logger_write.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "rwlock.h"
+
+std::string& GetDefaultTag();  // Must read lock default_tag_lock
+extern RwLock default_tag_lock;
\ No newline at end of file
diff --git a/liblog/properties.cpp b/liblog/properties.cpp
index a53c92b..b13662f 100644
--- a/liblog/properties.cpp
+++ b/liblog/properties.cpp
@@ -25,9 +25,12 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <shared_mutex>
 
 #include <private/android_logger.h>
 
+#include "logger_write.h"
+
 static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER;
 
 static int lock() {
@@ -93,10 +96,17 @@
   /* sizeof() is used on this array below */
   static const char log_namespace[] = "persist.log.tag.";
   static const size_t base_offset = 8; /* skip "persist." */
-  /* calculate the size of our key temporary buffer */
-  const size_t taglen = tag ? len : 0;
+
+  auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
+  if (tag == nullptr || len == 0) {
+    tag_lock.lock();
+    auto& tag_string = GetDefaultTag();
+    tag = tag_string.c_str();
+    len = tag_string.size();
+  }
+
   /* sizeof(log_namespace) = strlen(log_namespace) + 1 */
-  char key[sizeof(log_namespace) + taglen];
+  char key[sizeof(log_namespace) + len];
   char* kp;
   size_t i;
   char c = 0;
@@ -146,7 +156,7 @@
     }
   }
 
-  if (taglen) {
+  if (len) {
     int local_change_detected = change_detected;
     if (!not_locked) {
       if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) ||
diff --git a/liblog/tests/liblog_default_tag.cpp b/liblog/tests/liblog_default_tag.cpp
index a5baa9f..5643f63 100644
--- a/liblog/tests/liblog_default_tag.cpp
+++ b/liblog/tests/liblog_default_tag.cpp
@@ -96,4 +96,48 @@
 
   LOG(WARNING) << "message";
   EXPECT_TRUE(message_seen);
+}
+
+TEST(liblog_default_tag, default_tag_plus_log_severity) {
+  using namespace android::base;
+  bool message_seen = false;
+  std::string expected_tag = "liblog_test_tag";
+  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
+    message_seen = true;
+    EXPECT_EQ(expected_tag, tag);
+  });
+  __android_log_set_default_tag(expected_tag.c_str());
+
+  auto log_tag_property = "log.tag." + expected_tag;
+  SetProperty(log_tag_property, "V");
+
+  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
+  EXPECT_TRUE(message_seen);
+  message_seen = false;
+
+  LOG(VERBOSE) << "message";
+  EXPECT_TRUE(message_seen);
+}
+
+TEST(liblog_default_tag, generated_default_tag_plus_log_severity) {
+  using namespace android::base;
+  bool message_seen = false;
+  std::string expected_tag = getprogname();
+  SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
+    message_seen = true;
+    EXPECT_EQ(expected_tag, tag);
+  });
+
+  // Even without any calls to SetDefaultTag(), the first message that attempts to log, will
+  // generate a default tag from getprogname() and check log.tag.<default tag> for loggability. This
+  // case checks that we can log a Verbose message when log.tag.<getprogname()> is set to 'V'.
+  auto log_tag_property = "log.tag." + expected_tag;
+  SetProperty(log_tag_property, "V");
+
+  __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, nullptr, "message");
+  EXPECT_TRUE(message_seen);
+  message_seen = false;
+
+  LOG(VERBOSE) << "message";
+  EXPECT_TRUE(message_seen);
 }
\ No newline at end of file
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c
index 8212eba..5999e39 100644
--- a/libnetutils/ifc_utils.c
+++ b/libnetutils/ifc_utils.c
@@ -257,8 +257,8 @@
  *
  * Returns zero on success and negative errno on failure.
  */
-int ifc_act_on_address(int action, const char *name, const char *address,
-                       int prefixlen) {
+int ifc_act_on_address(int action, const char* name, const char* address, int prefixlen,
+                       bool nodad) {
     int ifindex, s, len, ret;
     struct sockaddr_storage ss;
     int saved_errno;
@@ -311,6 +311,7 @@
 
     // Interface address message header.
     req.r.ifa_family = ss.ss_family;
+    req.r.ifa_flags = nodad ? IFA_F_NODAD : 0;
     req.r.ifa_prefixlen = prefixlen;
     req.r.ifa_index = ifindex;
 
@@ -363,12 +364,12 @@
 
 // Returns zero on success and negative errno on failure.
 int ifc_add_address(const char *name, const char *address, int prefixlen) {
-    return ifc_act_on_address(RTM_NEWADDR, name, address, prefixlen);
+    return ifc_act_on_address(RTM_NEWADDR, name, address, prefixlen, /*nodad*/ false);
 }
 
 // Returns zero on success and negative errno on failure.
 int ifc_del_address(const char *name, const char * address, int prefixlen) {
-    return ifc_act_on_address(RTM_DELADDR, name, address, prefixlen);
+    return ifc_act_on_address(RTM_DELADDR, name, address, prefixlen, /*nodad*/ false);
 }
 
 /*
diff --git a/libnetutils/include/netutils/ifc.h b/libnetutils/include/netutils/ifc.h
index 3b27234..ee896ac 100644
--- a/libnetutils/include/netutils/ifc.h
+++ b/libnetutils/include/netutils/ifc.h
@@ -17,8 +17,9 @@
 #ifndef _NETUTILS_IFC_H_
 #define _NETUTILS_IFC_H_
 
-#include <sys/cdefs.h>
 #include <arpa/inet.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
 
 __BEGIN_DECLS
 
@@ -42,6 +43,8 @@
 
 extern int ifc_get_addr(const char *name, in_addr_t *addr);
 extern int ifc_set_addr(const char *name, in_addr_t addr);
+extern int ifc_act_on_address(int action, const char* name, const char* address, int prefixlen,
+                              bool nodad);
 extern int ifc_add_address(const char *name, const char *address,
                            int prefixlen);
 extern int ifc_del_address(const char *name, const char *address,
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index 16339d3..698e74d 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -138,8 +138,17 @@
     return enabled;
 }
 
+static bool schedtune_enabled() {
+    return (CgroupMap::GetInstance().FindController("schedtune").IsUsable());
+}
+
+static bool cpuctl_enabled() {
+    return (CgroupMap::GetInstance().FindController("cpu").IsUsable());
+}
+
 bool schedboost_enabled() {
-    static bool enabled = (CgroupMap::GetInstance().FindController("schedtune").IsUsable());
+    static bool enabled = schedtune_enabled() || cpuctl_enabled();
+
     return enabled;
 }
 
@@ -162,7 +171,9 @@
 
     std::string group;
     if (schedboost_enabled()) {
-        if (getCGroupSubsys(tid, "schedtune", group) < 0) return -1;
+        if ((getCGroupSubsys(tid, "schedtune", group) < 0) &&
+            (getCGroupSubsys(tid, "cpu", group) < 0))
+		return -1;
     }
     if (group.empty() && cpusets_enabled()) {
         if (getCGroupSubsys(tid, "cpuset", group) < 0) return -1;
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 9447f86..72f01af 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -288,6 +288,11 @@
     return true;
 }
 
+void TaskProfile::MoveTo(TaskProfile* profile) {
+    profile->elements_ = std::move(elements_);
+    profile->res_cached_ = res_cached_;
+}
+
 bool TaskProfile::ExecuteForProcess(uid_t uid, pid_t pid) const {
     for (const auto& element : elements_) {
         if (!element->ExecuteForProcess(uid, pid)) {
@@ -458,7 +463,15 @@
                 LOG(WARNING) << "Unknown profile action: " << action_name;
             }
         }
-        profiles_[profile_name] = profile;
+        auto iter = profiles_.find(profile_name);
+        if (iter == profiles_.end()) {
+            profiles_[profile_name] = profile;
+        } else {
+            // Move the content rather that replace the profile because old profile might be
+            // referenced from an aggregate profile if vendor overrides task profiles
+            profile->MoveTo(iter->second.get());
+            profile.reset();
+        }
     }
 
     const Json::Value& aggregateprofiles_val = root["AggregateProfiles"];
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index 9f2308c..a64ca50 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -143,6 +143,7 @@
     TaskProfile() : res_cached_(false) {}
 
     void Add(std::unique_ptr<ProfileAction> e) { elements_.push_back(std::move(e)); }
+    void MoveTo(TaskProfile* profile);
 
     bool ExecuteForProcess(uid_t uid, pid_t pid) const;
     bool ExecuteForTask(int tid) const;
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp
index 1df1dff..00b3367 100644
--- a/libunwindstack/RegsArm64.cpp
+++ b/libunwindstack/RegsArm64.cpp
@@ -100,8 +100,8 @@
   fn("x27", regs_[ARM64_REG_R27]);
   fn("x28", regs_[ARM64_REG_R28]);
   fn("x29", regs_[ARM64_REG_R29]);
-  fn("sp", regs_[ARM64_REG_SP]);
   fn("lr", regs_[ARM64_REG_LR]);
+  fn("sp", regs_[ARM64_REG_SP]);
   fn("pc", regs_[ARM64_REG_PC]);
   fn("pst", regs_[ARM64_REG_PSTATE]);
 }
@@ -110,10 +110,10 @@
   arm64_user_regs* user = reinterpret_cast<arm64_user_regs*>(remote_data);
 
   RegsArm64* regs = new RegsArm64();
-  memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R31 + 1) * sizeof(uint64_t));
+  memcpy(regs->RawData(), &user->regs[0], (ARM64_REG_R30 + 1) * sizeof(uint64_t));
   uint64_t* reg_data = reinterpret_cast<uint64_t*>(regs->RawData());
-  reg_data[ARM64_REG_PC] = user->pc;
   reg_data[ARM64_REG_SP] = user->sp;
+  reg_data[ARM64_REG_PC] = user->pc;
   reg_data[ARM64_REG_PSTATE] = user->pstate;
   return regs;
 }
diff --git a/libunwindstack/TEST_MAPPING b/libunwindstack/TEST_MAPPING
index 55771c0..909f897 100644
--- a/libunwindstack/TEST_MAPPING
+++ b/libunwindstack/TEST_MAPPING
@@ -2,6 +2,9 @@
   "presubmit": [
     {
       "name": "libunwindstack_unit_test"
+    },
+    {
+      "name": "CtsSimpleperfTestCases"
     }
   ]
 }
diff --git a/libunwindstack/tests/RegsIterateTest.cpp b/libunwindstack/tests/RegsIterateTest.cpp
index bc95851..47e605a 100644
--- a/libunwindstack/tests/RegsIterateTest.cpp
+++ b/libunwindstack/tests/RegsIterateTest.cpp
@@ -111,8 +111,8 @@
   result.push_back({"x27", ARM64_REG_R27});
   result.push_back({"x28", ARM64_REG_R28});
   result.push_back({"x29", ARM64_REG_R29});
-  result.push_back({"sp", ARM64_REG_SP});
   result.push_back({"lr", ARM64_REG_LR});
+  result.push_back({"sp", ARM64_REG_SP});
   result.push_back({"pc", ARM64_REG_PC});
   result.push_back({"pst", ARM64_REG_PSTATE});
   return result;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index c4f3e15..7f4f025 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -165,7 +165,7 @@
     mkdir /mnt/secure/asec 0700 root root
     mkdir /mnt/asec 0755 root system
     mkdir /mnt/obb 0755 root system
-    mkdir /mnt/media_rw 0750 root media_rw
+    mkdir /mnt/media_rw 0750 root external_storage
     mkdir /mnt/user 0755 root root
     mkdir /mnt/user/0 0755 root root
     mkdir /mnt/user/0/self 0755 root root