Merge "fastboot: Print OemCmdHandler return message on success"
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index f4ba347..e113308 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -1463,6 +1463,29 @@
   ASSERT_BACKTRACE_FRAME(result, "bar");
 }
 
+TEST_F(CrasherTest, seccomp_tombstone_thread_abort) {
+  int intercept_result;
+  unique_fd output_fd;
+
+  static const auto dump_type = kDebuggerdTombstone;
+  StartProcess(
+      []() {
+        std::thread abort_thread([] { abort(); });
+        abort_thread.join();
+      },
+      &seccomp_fork);
+
+  StartIntercept(&output_fd, dump_type);
+  FinishCrasher();
+  AssertDeath(SIGABRT);
+  FinishIntercept(&intercept_result);
+  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+  std::string result;
+  ConsumeFd(std::move(output_fd), &result);
+  ASSERT_BACKTRACE_FRAME(result, "abort");
+}
+
 TEST_F(CrasherTest, seccomp_backtrace) {
   int intercept_result;
   unique_fd output_fd;
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 396bcb8..7c7979b 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -849,8 +849,10 @@
     if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
         fs_mgr_set_blk_ro(source);
     }
-    android::base::SetProperty("ro.boottime.init.mount." + Basename(target),
-                               std::to_string(t.duration().count()));
+    if (ret == 0) {
+        android::base::SetProperty("ro.boottime.init.mount." + Basename(target),
+                                   std::to_string(t.duration().count()));
+    }
     errno = save_errno;
     return ret;
 }
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 8e6bbd9..f4d5c72 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -171,11 +171,11 @@
     std::optional<uint64_t> last_label_;
     std::shared_ptr<std::vector<CowOperation>> ops_;
     std::shared_ptr<std::vector<uint32_t>> merge_op_blocks_;
-    uint64_t merge_op_start_;
+    uint64_t merge_op_start_{};
     std::shared_ptr<std::unordered_map<uint32_t, int>> block_map_;
-    uint64_t num_total_data_ops_;
-    uint64_t num_ordered_ops_to_merge_;
-    bool has_seq_ops_;
+    uint64_t num_total_data_ops_{};
+    uint64_t num_ordered_ops_to_merge_{};
+    bool has_seq_ops_{};
     std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
     ReaderFlags reader_flag_;
 };
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index bc2bceb..fbc8c30 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -72,7 +72,7 @@
 
     cflags: [
         "-Wall",
-        "-Werror"
+        "-Werror",
     ],
 
     static_libs: [
@@ -89,14 +89,7 @@
         "liburing",
     ],
     include_dirs: ["bionic/libc/kernel"],
-}
-
-cc_binary {
-    name: "snapuserd",
-    defaults: ["snapuserd_defaults"],
-    init_rc: [
-        "snapuserd.rc",
-    ],
+    system_shared_libs: [],
 
     // snapuserd is started during early boot by first-stage init. At that
     // point, /system is mounted using the "dm-user" device-mapper kernel
@@ -105,16 +98,40 @@
     // faults for its code pages.
     static_executable: true,
 
-    system_shared_libs: [],
-    ramdisk_available: true,
-    vendor_ramdisk_available: true,
-    recovery_available: true,
-
     // Snapuserd segfaults with ThinLTO
     // http://b/208565717
     lto: {
          never: true,
-    }
+    },
+}
+
+cc_binary {
+    name: "snapuserd",
+    defaults: ["snapuserd_defaults"],
+    init_rc: [
+        "snapuserd.rc",
+    ],
+    ramdisk_available: false,
+    vendor_ramdisk_available: true,
+    recovery_available: true,
+}
+
+// This target will install to /system/bin/snapuserd_ramdisk 
+// It will also create a symblink on /system/bin/snapuserd that point to
+// /system/bin/snapuserd_ramdisk .
+// This way, init can check if generic ramdisk copy exists.
+cc_binary {
+    name: "snapuserd_ramdisk",
+    defaults: ["snapuserd_defaults"],
+    init_rc: [
+        "snapuserd.rc",
+    ],
+    // This target is specifically for generic ramdisk, therefore we set
+    // vendor_ramdisk_available to false.
+    ramdisk_available: true,
+    vendor_ramdisk_available: false,
+    ramdisk: true,
+    symlinks: ["snapuserd"],
 }
 
 cc_test {
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index b5fac53..8c49e4a 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -94,7 +94,13 @@
         }
 
         if (entry.flags & MS_RDONLY) {
-            EXPECT_EQ(entry.fs_type, "erofs") << entry.mount_point;
+            std::vector<std::string> allowed = {"erofs", "ext4"};
+            if (vsr_level == __ANDROID_API_T__) {
+                allowed.emplace_back("f2fs");
+            }
+
+            EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end())
+                    << entry.mount_point;
         } else {
             EXPECT_NE(entry.fs_type, "ext4") << entry.mount_point;
         }
diff --git a/init/action_parser.cpp b/init/action_parser.cpp
index 52f6a1f..49fe24a 100644
--- a/init/action_parser.cpp
+++ b/init/action_parser.cpp
@@ -142,6 +142,14 @@
         action_subcontext = subcontext_;
     }
 
+    // We support 'on' for only Vendor APEXes from /{vendor, odm}.
+    // It is to prevent mainline modules from using 'on' triggers because events/properties are
+    // not stable for mainline modules.
+    // Note that this relies on Subcontext::PathMatchesSubcontext() to identify Vendor APEXes.
+    if (StartsWith(filename, "/apex/") && !action_subcontext) {
+        return Error() << "ParseSection() failed: 'on' is supported for only Vendor APEXes.";
+    }
+
     std::string event_trigger;
     std::map<std::string, std::string> property_triggers;
 
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index d050ed7..202a86a 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -119,19 +119,14 @@
 // Move snapuserd before switching root, so that it is available at the same path
 // after switching root.
 void PrepareSwitchRoot() {
-    constexpr const char* src = "/system/bin/snapuserd";
-    constexpr const char* dst = "/first_stage_ramdisk/system/bin/snapuserd";
+    static constexpr const auto& snapuserd = "/system/bin/snapuserd";
+    static constexpr const auto& snapuserd_ramdisk = "/system/bin/snapuserd_ramdisk";
+    static constexpr const auto& dst = "/first_stage_ramdisk/system/bin/snapuserd";
 
     if (access(dst, X_OK) == 0) {
         LOG(INFO) << dst << " already exists and it can be executed";
         return;
     }
-
-    if (access(src, F_OK) != 0) {
-        PLOG(INFO) << "Not moving " << src << " because it cannot be accessed";
-        return;
-    }
-
     auto dst_dir = android::base::Dirname(dst);
     std::error_code ec;
     if (access(dst_dir.c_str(), F_OK) != 0) {
@@ -139,7 +134,18 @@
             LOG(FATAL) << "Cannot create " << dst_dir << ": " << ec.message();
         }
     }
-    Copy(src, dst);
+
+    // prefer the generic ramdisk copy of snapuserd, because that's on system side of treble
+    // boundary, and therefore is more likely to be updated along with the Android platform.
+    // The vendor ramdisk copy might be under vendor freeze, or vendor might choose not to update
+    // it.
+    if (access(snapuserd_ramdisk, F_OK) == 0) {
+        LOG(INFO) << "Using generic ramdisk copy of snapuserd " << snapuserd_ramdisk;
+        Copy(snapuserd_ramdisk, dst);
+    } else if (access(snapuserd, F_OK) == 0) {
+        LOG(INFO) << "Using vendor ramdisk copy of snapuserd " << snapuserd;
+        Copy(snapuserd, dst);
+    }
 }
 }  // namespace
 
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 9f7c215..a1f6e04 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -54,6 +54,7 @@
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
+#include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <property_info_parser/property_info_parser.h>
@@ -76,9 +77,12 @@
 
 using namespace std::literals;
 
+using android::base::ErrnoError;
+using android::base::Error;
 using android::base::GetProperty;
 using android::base::ParseInt;
 using android::base::ReadFileToString;
+using android::base::Result;
 using android::base::Split;
 using android::base::StartsWith;
 using android::base::StringPrintf;
@@ -629,8 +633,8 @@
     return result;
 }
 
-static bool load_properties_from_file(const char*, const char*,
-                                      std::map<std::string, std::string>*);
+static Result<void> load_properties_from_file(const char*, const char*,
+                                              std::map<std::string, std::string>*);
 
 /*
  * Filter is used to decide which properties to load: NULL loads all keys,
@@ -691,7 +695,10 @@
                 continue;
             }
 
-            load_properties_from_file(expanded_filename->c_str(), key, properties);
+            if (auto res = load_properties_from_file(expanded_filename->c_str(), key, properties);
+                !res.ok()) {
+                LOG(WARNING) << res.error();
+            }
         } else {
             value = strchr(key, '=');
             if (!value) continue;
@@ -738,20 +745,19 @@
 
 // Filter is used to decide which properties to load: NULL loads all keys,
 // "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
-static bool load_properties_from_file(const char* filename, const char* filter,
-                                      std::map<std::string, std::string>* properties) {
+static Result<void> load_properties_from_file(const char* filename, const char* filter,
+                                              std::map<std::string, std::string>* properties) {
     Timer t;
     auto file_contents = ReadFile(filename);
     if (!file_contents.ok()) {
-        PLOG(WARNING) << "Couldn't load property file '" << filename
-                      << "': " << file_contents.error();
-        return false;
+        return Error() << "Couldn't load property file '" << filename
+                       << "': " << file_contents.error();
     }
     file_contents->push_back('\n');
 
     LoadProperties(file_contents->data(), filter, filename, properties);
     LOG(VERBOSE) << "(Loading properties from " << filename << " took " << t << ".)";
-    return true;
+    return {};
 }
 
 static void LoadPropertiesFromSecondStageRes(std::map<std::string, std::string>* properties) {
@@ -760,7 +766,9 @@
         CHECK(errno == ENOENT) << "Cannot access " << prop << ": " << strerror(errno);
         return;
     }
-    load_properties_from_file(prop.c_str(), nullptr, properties);
+    if (auto res = load_properties_from_file(prop.c_str(), nullptr, properties); !res.ok()) {
+        LOG(WARNING) << res.error();
+    }
 }
 
 // persist.sys.usb.config values can't be combined on build-time when property
@@ -1058,7 +1066,10 @@
     std::map<std::string, std::string> properties;
 
     if (IsRecoveryMode()) {
-        load_properties_from_file("/prop.default", nullptr, &properties);
+        if (auto res = load_properties_from_file("/prop.default", nullptr, &properties);
+            !res.ok()) {
+            LOG(ERROR) << res.error();
+        }
     }
 
     // /<part>/etc/build.prop is the canonical location of the build-time properties since S.
@@ -1067,7 +1078,7 @@
     const auto load_properties_from_partition = [&properties](const std::string& partition,
                                                               int support_legacy_path_until) {
         auto path = "/" + partition + "/etc/build.prop";
-        if (load_properties_from_file(path.c_str(), nullptr, &properties)) {
+        if (load_properties_from_file(path.c_str(), nullptr, &properties).ok()) {
             return;
         }
         // To read ro.<partition>.build.version.sdk, temporarily load the legacy paths into a
@@ -1105,7 +1116,13 @@
     // Order matters here. The more the partition is specific to a product, the higher its
     // precedence is.
     LoadPropertiesFromSecondStageRes(&properties);
-    load_properties_from_file("/system/build.prop", nullptr, &properties);
+
+    // system should have build.prop, unlike the other partitions
+    if (auto res = load_properties_from_file("/system/build.prop", nullptr, &properties);
+        !res.ok()) {
+        LOG(WARNING) << res.error();
+    }
+
     load_properties_from_partition("system_ext", /* support_legacy_path_until */ 30);
     load_properties_from_file("/system_dlkm/etc/build.prop", nullptr, &properties);
     // TODO(b/117892318): uncomment the following condition when vendor.imgs for aosp_* targets are
@@ -1121,7 +1138,10 @@
 
     if (access(kDebugRamdiskProp, R_OK) == 0) {
         LOG(INFO) << "Loading " << kDebugRamdiskProp;
-        load_properties_from_file(kDebugRamdiskProp, nullptr, &properties);
+        if (auto res = load_properties_from_file(kDebugRamdiskProp, nullptr, &properties);
+            !res.ok()) {
+            LOG(WARNING) << res.error();
+        }
     }
 
     for (const auto& [name, value] : properties) {
diff --git a/init/service.cpp b/init/service.cpp
index 95a5328..01dd685 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -545,6 +545,10 @@
         if ((flags_ & SVC_ONESHOT) && disabled) {
             flags_ |= SVC_RESTART;
         }
+
+        LOG(INFO) << "service '" << name_
+                  << "' requested start, but it is already running (flags: " << flags_ << ")";
+
         // It is not an error to try to start a service that is already running.
         reboot_on_failure.Disable();
         return {};
diff --git a/init/util.cpp b/init/util.cpp
index af6cf50..1801d17 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -61,6 +61,8 @@
 
 const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
 
+const std::string kDataDirPrefix("/data/");
+
 void (*trigger_shutdown)(const std::string& command) = nullptr;
 
 // DecodeUid() - decodes and returns the given string, which can be either the
@@ -458,52 +460,34 @@
     return {};
 }
 
-static FscryptAction FscryptInferAction(const std::string& dir) {
-    const std::string prefix = "/data/";
-
-    if (!android::base::StartsWith(dir, prefix)) {
-        return FscryptAction::kNone;
-    }
-
-    // Only set policy on first level /data directories
-    // To make this less restrictive, consider using a policy file.
-    // However this is overkill for as long as the policy is simply
-    // to apply a global policy to all /data folders created via makedir
-    if (dir.find_first_of('/', prefix.size()) != std::string::npos) {
-        return FscryptAction::kNone;
-    }
-
-    // Special case various directories that must not be encrypted,
-    // often because their subdirectories must be encrypted.
-    // This isn't a nice way to do this, see b/26641735
-    std::vector<std::string> directories_to_exclude = {
-            "lost+found", "system_ce", "system_de", "misc_ce",     "misc_de",
-            "vendor_ce",  "vendor_de", "media",     "data",        "user",
-            "user_de",    "apex",      "preloads",  "app-staging", "gsi",
-    };
-    for (const auto& d : directories_to_exclude) {
-        if ((prefix + d) == dir) {
-            return FscryptAction::kNone;
+// Remove unnecessary slashes so that any later checks (e.g., the check for
+// whether the path is a top-level directory in /data) don't get confused.
+std::string CleanDirPath(const std::string& path) {
+    std::string result;
+    result.reserve(path.length());
+    // Collapse duplicate slashes, e.g. //data//foo// => /data/foo/
+    for (char c : path) {
+        if (c != '/' || result.empty() || result.back() != '/') {
+            result += c;
         }
     }
-    // Empty these directories if policy setting fails.
-    std::vector<std::string> wipe_on_failure = {
-            "rollback", "rollback-observer",  // b/139193659
-    };
-    for (const auto& d : wipe_on_failure) {
-        if ((prefix + d) == dir) {
-            return FscryptAction::kDeleteIfNecessary;
-        }
+    // Remove trailing slash, e.g. /data/foo/ => /data/foo
+    if (result.length() > 1 && result.back() == '/') {
+        result.pop_back();
     }
-    return FscryptAction::kRequire;
+    return result;
 }
 
 Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args) {
+    std::string path = CleanDirPath(args[1]);
+    const bool is_toplevel_data_dir =
+            StartsWith(path, kDataDirPrefix) &&
+            path.find_first_of('/', kDataDirPrefix.size()) == std::string::npos;
+    FscryptAction fscrypt_action =
+            is_toplevel_data_dir ? FscryptAction::kRequire : FscryptAction::kNone;
     mode_t mode = 0755;
     Result<uid_t> uid = -1;
     Result<gid_t> gid = -1;
-    FscryptAction fscrypt_inferred_action = FscryptInferAction(args[1]);
-    FscryptAction fscrypt_action = fscrypt_inferred_action;
     std::string ref_option = "ref";
     bool set_option_encryption = false;
     bool set_option_key = false;
@@ -568,24 +552,17 @@
     if (set_option_key && fscrypt_action == FscryptAction::kNone) {
         return Error() << "Key option set but encryption action is none";
     }
-    const std::string prefix = "/data/";
-    if (StartsWith(args[1], prefix) &&
-        args[1].find_first_of('/', prefix.size()) == std::string::npos) {
+    if (is_toplevel_data_dir) {
         if (!set_option_encryption) {
-            LOG(WARNING) << "Top-level directory needs encryption action, eg mkdir " << args[1]
+            LOG(WARNING) << "Top-level directory needs encryption action, eg mkdir " << path
                          << " <mode> <uid> <gid> encryption=Require";
         }
         if (fscrypt_action == FscryptAction::kNone) {
-            LOG(INFO) << "Not setting encryption policy on: " << args[1];
+            LOG(INFO) << "Not setting encryption policy on: " << path;
         }
     }
-    if (fscrypt_action != fscrypt_inferred_action) {
-        LOG(WARNING) << "Inferred action different from explicit one, expected "
-                     << static_cast<int>(fscrypt_inferred_action) << " but got "
-                     << static_cast<int>(fscrypt_action);
-    }
 
-    return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
+    return MkdirOptions{path, mode, *uid, *gid, fscrypt_action, ref_option};
 }
 
 Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
diff --git a/init/util.h b/init/util.h
index bf53675..47d4ff5 100644
--- a/init/util.h
+++ b/init/util.h
@@ -69,6 +69,7 @@
 
 bool IsLegalPropertyName(const std::string& name);
 Result<void> IsLegalPropertyValue(const std::string& name, const std::string& value);
+std::string CleanDirPath(const std::string& path);
 
 struct MkdirOptions {
     std::string target;
diff --git a/init/util_test.cpp b/init/util_test.cpp
index 565e7d4..e8144c3 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -170,5 +170,18 @@
     EXPECT_TRUE(is_dir(path1.c_str()));
 }
 
+TEST(util, CleanDirPath) {
+    EXPECT_EQ("", CleanDirPath(""));
+    EXPECT_EQ("/", CleanDirPath("/"));
+    EXPECT_EQ("/", CleanDirPath("//"));
+    EXPECT_EQ("/foo", CleanDirPath("/foo"));
+    EXPECT_EQ("/foo", CleanDirPath("//foo"));
+    EXPECT_EQ("/foo", CleanDirPath("/foo/"));
+    EXPECT_EQ("/foo/bar", CleanDirPath("/foo/bar"));
+    EXPECT_EQ("/foo/bar", CleanDirPath("/foo/bar/"));
+    EXPECT_EQ("/foo/bar", CleanDirPath("/foo/bar////"));
+    EXPECT_EQ("/foo/bar", CleanDirPath("//foo//bar"));
+}
+
 }  // namespace init
 }  // namespace android
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index 98ae0d4..3867f34 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -214,6 +214,7 @@
  * provided, which is the name of the row where this async event should be
  * recorded. The track name, name, and cookie used to begin an event must be
  * used to end it.
+ * The cookie here must be unique on the track_name level, not the name level.
  */
 #define ATRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie) \
     atrace_async_for_track_begin(ATRACE_TAG, track_name, name, cookie)
@@ -229,13 +230,13 @@
  * Trace the end of an asynchronous event.
  * This should correspond to a previous ATRACE_ASYNC_FOR_TRACK_BEGIN.
  */
-#define ATRACE_ASYNC_FOR_TRACK_END(track_name, name, cookie) \
-    atrace_async_for_track_end(ATRACE_TAG, track_name, name, cookie)
+#define ATRACE_ASYNC_FOR_TRACK_END(track_name, cookie) \
+    atrace_async_for_track_end(ATRACE_TAG, track_name, cookie)
 static inline void atrace_async_for_track_end(uint64_t tag, const char* track_name,
-                                              const char* name, int32_t cookie) {
+                                              int32_t cookie) {
     if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
-        void atrace_async_for_track_end_body(const char*, const char*, int32_t);
-        atrace_async_for_track_end_body(track_name, name, cookie);
+        void atrace_async_for_track_end_body(const char*, int32_t);
+        atrace_async_for_track_end_body(track_name, cookie);
     }
 }
 
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 8bb8652..bdb8075 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -137,6 +137,7 @@
 #define AID_JC_STRONGBOX 1088     /* Javacard Strongbox HAL - to manage omapi ARA rules */
 #define AID_JC_IDENTITYCRED 1089  /* Javacard Identity Cred HAL - to manage omapi ARA rules */
 #define AID_SDK_SANDBOX 1090      /* SDK sandbox virtual UID */
+#define AID_SECURITY_LOG_WRITER 1091 /* write to security log */
 /* 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/libcutils/trace-container.cpp b/libcutils/trace-container.cpp
index 8901e4a..eae6155 100644
--- a/libcutils/trace-container.cpp
+++ b/libcutils/trace-container.cpp
@@ -231,24 +231,24 @@
 
 void atrace_async_for_track_begin_body(const char* track_name, const char* name, int32_t cookie) {
     if (CC_LIKELY(atrace_use_container_sock)) {
-        WRITE_MSG_IN_CONTAINER("T", "|", "|%d", track_name, name, cookie);
+        WRITE_MSG_IN_CONTAINER("G", "|", "|%d", track_name, name, cookie);
         return;
     }
 
     if (atrace_marker_fd < 0) return;
 
-    WRITE_MSG("T|%d|", "|%" PRId32, track_name, name, cookie);
+    WRITE_MSG("G|%d|", "|%" PRId32, track_name, name, cookie);
 }
 
-void atrace_async_for_track_end_body(const char* track_name, const char* name, int32_t cookie) {
+void atrace_async_for_track_end_body(const char* track_name, int32_t cookie) {
     if (CC_LIKELY(atrace_use_container_sock)) {
-        WRITE_MSG_IN_CONTAINER("U", "|", "|%d", track_name, name, cookie);
+        WRITE_MSG_IN_CONTAINER("H", "|", "|%d", "", track_name, cookie);
         return;
     }
 
     if (atrace_marker_fd < 0) return;
 
-    WRITE_MSG("U|%d|", "|%" PRId32, track_name, name, cookie);
+    WRITE_MSG("H|%d|", "|%" PRId32, "", track_name, cookie);
 }
 
 void atrace_instant_body(const char* name) {
diff --git a/libcutils/trace-dev.cpp b/libcutils/trace-dev.cpp
index eacc8ee..1827e32 100644
--- a/libcutils/trace-dev.cpp
+++ b/libcutils/trace-dev.cpp
@@ -90,11 +90,11 @@
 }
 
 void atrace_async_for_track_begin_body(const char* track_name, const char* name, int32_t cookie) {
-    WRITE_MSG("T|%d|", "|%" PRId32, track_name, name, cookie);
+    WRITE_MSG("G|%d|", "|%" PRId32, track_name, name, cookie);
 }
 
-void atrace_async_for_track_end_body(const char* track_name, const char* name, int32_t cookie) {
-    WRITE_MSG("U|%d|", "|%" PRId32, track_name, name, cookie);
+void atrace_async_for_track_end_body(const char* track_name, int32_t cookie) {
+    WRITE_MSG("H|%d|", "|%" PRId32, "", track_name, cookie);
 }
 
 void atrace_instant_body(const char* name) {
diff --git a/libcutils/trace-dev_test.cpp b/libcutils/trace-dev_test.cpp
index 841674a..3dea5ff 100644
--- a/libcutils/trace-dev_test.cpp
+++ b/libcutils/trace-dev_test.cpp
@@ -202,13 +202,13 @@
 
     std::string actual;
     ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    std::string expected = android::base::StringPrintf("T|%d|fake_track|fake_name|12345", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|fake_track|fake_name|12345", getpid());
     ASSERT_STREQ(expected.c_str(), actual.c_str());
 }
 
 TEST_F(TraceDevTest, atrace_async_for_track_begin_body_exact_track_name) {
     const int name_size = 5;
-    std::string expected = android::base::StringPrintf("T|%d|", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|", getpid());
     std::string track_name =
             MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - name_size - 6);
     atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
@@ -224,7 +224,7 @@
     // Add a single character and verify name truncation
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
     track_name += '*';
-    expected = android::base::StringPrintf("T|%d|", getpid());
+    expected = android::base::StringPrintf("G|%d|", getpid());
     expected += track_name + "|nam|12345";
     atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
     EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
@@ -234,7 +234,7 @@
 }
 
 TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_track_name) {
-    std::string expected = android::base::StringPrintf("T|%d|", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|", getpid());
     std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
     atrace_async_for_track_begin_body(track_name.c_str(), "name", 12345);
 
@@ -250,7 +250,7 @@
 
 TEST_F(TraceDevTest, atrace_async_for_track_begin_body_exact_name) {
     const int track_name_size = 11;
-    std::string expected = android::base::StringPrintf("T|%d|", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|", getpid());
     std::string name =
             MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - track_name_size - 6);
     atrace_async_for_track_begin_body("track_name", name.c_str(), 12345);
@@ -274,7 +274,7 @@
 }
 
 TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_name) {
-    std::string expected = android::base::StringPrintf("T|%d|track_name|", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|track_name|", getpid());
     std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
     atrace_async_for_track_begin_body("track_name", name.c_str(), 12345);
 
@@ -289,7 +289,7 @@
 }
 
 TEST_F(TraceDevTest, atrace_async_for_track_begin_body_truncated_both) {
-    std::string expected = android::base::StringPrintf("T|%d|", getpid());
+    std::string expected = android::base::StringPrintf("G|%d|", getpid());
     std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
     std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
     atrace_async_for_track_begin_body(track_name.c_str(), name.c_str(), 12345);
@@ -306,112 +306,52 @@
 }
 
 TEST_F(TraceDevTest, atrace_async_for_track_end_body_normal) {
-    atrace_async_for_track_end_body("fake_track", "fake_name", 12345);
+    atrace_async_for_track_end_body("fake_track", 12345);
 
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
 
     std::string actual;
     ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    std::string expected = android::base::StringPrintf("U|%d|fake_track|fake_name|12345", getpid());
+    std::string expected = android::base::StringPrintf("H|%d|fake_track|12345", getpid());
     ASSERT_STREQ(expected.c_str(), actual.c_str());
 }
 
-TEST_F(TraceDevTest, atrace_async_for_track_end_body_exact_track_name) {
-    const int name_size = 5;
-    std::string expected = android::base::StringPrintf("U|%d|", getpid());
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_exact) {
+    std::string expected = android::base::StringPrintf("H|%d|", getpid());
     std::string track_name =
-            MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - name_size - 6);
-    atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+            MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 7);
+    atrace_async_for_track_end_body(track_name.c_str(), 12345);
 
     ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
 
     std::string actual;
     ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    expected += track_name + "|name|12345";
+    expected += track_name + "|12345";
     ASSERT_STREQ(expected.c_str(), actual.c_str());
 
-    // Add a single character and verify name truncation
+    // Add a single character and verify we get the exact same value as before.
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
     track_name += '*';
-    expected = android::base::StringPrintf("U|%d|", getpid());
-    expected += track_name + "|nam|12345";
-    atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+    atrace_async_for_track_end_body(track_name.c_str(), 12345);
     EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
     ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
     ASSERT_STREQ(expected.c_str(), actual.c_str());
 }
 
-TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_track_name) {
-    std::string expected = android::base::StringPrintf("U|%d|", getpid());
+TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated) {
+    std::string expected = android::base::StringPrintf("H|%d|", getpid());
     std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
-    atrace_async_for_track_end_body(track_name.c_str(), "name", 12345);
+    atrace_async_for_track_end_body(track_name.c_str(), 12345);
 
     ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
     ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
 
     std::string actual;
     ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 9;
-    expected += android::base::StringPrintf("%.*s|n|12345", expected_len, track_name.c_str());
-    ASSERT_STREQ(expected.c_str(), actual.c_str());
-}
-
-TEST_F(TraceDevTest, atrace_async_for_track_end_body_exact_name) {
-    const int track_name_size = 11;
-    std::string expected = android::base::StringPrintf("U|%d|", getpid());
-    std::string name =
-            MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - track_name_size - 6);
-    atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
-
-    ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
-    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
-
-    std::string actual;
-    ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    expected += "track_name|" + name + "|12345";
-    ASSERT_STREQ(expected.c_str(), actual.c_str());
-
-    // Add a single character and verify we get the same value as before.
-    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
-    name += '*';
-    atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
-    EXPECT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
-    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
-    ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    ASSERT_STREQ(expected.c_str(), actual.c_str());
-}
-
-TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_name) {
-    std::string expected = android::base::StringPrintf("U|%d|track_name|", getpid());
-    std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
-    atrace_async_for_track_end_body("track_name", name.c_str(), 12345);
-
-    ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
-    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
-
-    std::string actual;
-    ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 1 - 6;
-    expected += android::base::StringPrintf("%.*s|12345", expected_len, name.c_str());
-    ASSERT_STREQ(expected.c_str(), actual.c_str());
-}
-
-TEST_F(TraceDevTest, atrace_async_for_track_end_body_truncated_both) {
-    std::string expected = android::base::StringPrintf("U|%d|", getpid());
-    std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
-    std::string track_name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
-    atrace_async_for_track_end_body(track_name.c_str(), name.c_str(), 12345);
-
-    ASSERT_EQ(ATRACE_MESSAGE_LENGTH - 1, lseek(atrace_marker_fd, 0, SEEK_CUR));
-    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
-
-    std::string actual;
-    ASSERT_TRUE(android::base::ReadFdToString(atrace_marker_fd, &actual));
-    int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 3 - 6;
-    expected += android::base::StringPrintf("%.*s|%.1s|12345", expected_len, track_name.c_str(),
-                                            name.c_str());
+    int expected_len = ATRACE_MESSAGE_LENGTH - expected.length() - 7;
+    expected += android::base::StringPrintf("%.*s|12345", expected_len, track_name.c_str());
     ASSERT_STREQ(expected.c_str(), actual.c_str());
 }
 
diff --git a/libcutils/trace-host.cpp b/libcutils/trace-host.cpp
index c2a379b..e9f58c3 100644
--- a/libcutils/trace-host.cpp
+++ b/libcutils/trace-host.cpp
@@ -30,8 +30,7 @@
 void atrace_async_end_body(const char* /*name*/, int32_t /*cookie*/) {}
 void atrace_async_for_track_begin_body(const char* /*track_name*/, const char* /*name*/,
                                        int32_t /*cookie*/) {}
-void atrace_async_for_track_end_body(const char* /*track_name*/, const char* /*name*/,
-                                     int32_t /*cookie*/) {}
+void atrace_async_for_track_end_body(const char* /*track_name*/, int32_t /*cookie*/) {}
 void atrace_instant_body(const char* /*name*/) {}
 void atrace_instant_for_track_body(const char* /*track_name*/, const char* /*name*/) {}
 void atrace_int_body(const char* /*name*/, int32_t /*value*/) {}
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index f5533c2..8589a8d 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -224,19 +224,6 @@
       ]
     },
     {
-      "Name": "VMCompilationPerformance",
-      "Actions": [
-        {
-          "Name": "JoinCgroup",
-          "Params":
-          {
-            "Controller": "cpu",
-            "Path": "system"
-          }
-        }
-      ]
-    },
-    {
       "Name": "CpuPolicySpread",
       "Actions": [
         {
@@ -660,6 +647,10 @@
       "Profiles": [ "ServicePerformance", "LowIoPriority", "TimerSlackNormal" ]
     },
     {
+      "Name": "SCHED_SP_COMPUTE",
+      "Profiles": [ "HighPerformance", "ProcessCapacityHigh", "LowIoPriority", "TimerSlackNormal" ]
+    },
+    {
       "Name": "SCHED_SP_RT_APP",
       "Profiles": [ "RealtimePerformance", "MaxIoPriority", "TimerSlackNormal" ]
     },
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2746314..70a3736 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -922,7 +922,6 @@
     # contain any subdirectories other than the per-user ones.  /data/media/obb
     # is an exception that exists for legacy reasons.
     mkdir /data/media 0770 media_rw media_rw encryption=None
-    exec - media_rw media_rw -- /system/bin/chattr +F /data/media
     mkdir /data/misc_ce 01771 system misc encryption=None
     mkdir /data/misc_de 01771 system misc encryption=None
     mkdir /data/system_ce 0770 system system encryption=None
@@ -932,6 +931,11 @@
     mkdir /data/vendor_ce 0771 root root encryption=None
     mkdir /data/vendor_de 0771 root root encryption=None
 
+    # Set the casefold flag on /data/media.  For upgrades, a restorecon can be
+    # needed first to relabel the directory from media_rw_data_file.
+    restorecon /data/media
+    exec - media_rw media_rw -- /system/bin/chattr +F /data/media
+
     # A tmpfs directory, which will contain all apps CE DE data directory that
     # bind mount from the original source.
     mount tmpfs tmpfs /data_mirror nodev noexec nosuid mode=0700,uid=0,gid=1000
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 8cc8b59..cefef6e 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -333,7 +333,7 @@
             first_write = false;
         }
 
-        if (benchmark_size) {
+        if (benchmark_size && benchmark_time_ns) {
             int perf = benchmark_size * 1000000LLU / benchmark_time_ns;
             storage_info->update_perf_history(perf, system_clock::now());
         }
diff --git a/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp b/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp
index 9440724..78e765e 100644
--- a/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp
+++ b/trusty/keymaster/keymint/TrustyKeyMintOperation.cpp
@@ -52,11 +52,15 @@
 }
 
 ScopedAStatus TrustyKeyMintOperation::updateAad(
-        const vector<uint8_t>& input, const optional<HardwareAuthToken>& /* authToken */,
+        const vector<uint8_t>& input, const optional<HardwareAuthToken>& authToken,
         const optional<TimeStampToken>& /* timestampToken */) {
     UpdateOperationRequest request(impl_->message_version());
     request.op_handle = opHandle_;
     request.additional_params.push_back(TAG_ASSOCIATED_DATA, input.data(), input.size());
+    if (authToken) {
+        auto tokenAsVec(authToken2AidlVec(*authToken));
+        request.additional_params.push_back(TAG_AUTH_TOKEN, tokenAsVec.data(), tokenAsVec.size());
+    }
 
     UpdateOperationResponse response(impl_->message_version());
     impl_->UpdateOperation(request, &response);