core: updating from upstream

Followed instructions from go/nnapi-dep-instructions

BUG=b:211342927
TEST=FEATURES=test emerge-amd64-generic nnapi aosp-frameworks-ml-nn

Exempt-From-Owner-Approval: this is a fork / mirror of an Android repository and we don't want to modify OWNERS files
Change-Id: I8720939ad2818157e33b8f39096b99f494f8878f
NOKEYCHECK=True
GitOrigin-RevId: cb38e42b0b0301cfd309caae66755a724b04a5a2
diff --git a/Android.bp b/Android.bp
index 0d9f2c7..c8bfb01 100644
--- a/Android.bp
+++ b/Android.bp
@@ -156,7 +156,6 @@
     },
     srcs: [
         "config_utils.cpp",
-        "canned_fs_config.cpp",
         "iosched_policy.cpp",
         "load_file.cpp",
         "native_handle.cpp",
@@ -173,6 +172,7 @@
         not_windows: {
             srcs: libcutils_nonwindows_sources + [
                 "ashmem-host.cpp",
+                "canned_fs_config.cpp",
                 "fs_config.cpp",
                 "trace-host.cpp",
             ],
@@ -193,6 +193,7 @@
             srcs: libcutils_nonwindows_sources + [
                 "android_reboot.cpp",
                 "ashmem-dev.cpp",
+                "canned_fs_config.cpp",
                 "fs_config.cpp",
                 "klog.cpp",
                 "partition_utils.cpp",
diff --git a/canned_fs_config.cpp b/canned_fs_config.cpp
index 2772ef0..b677949 100644
--- a/canned_fs_config.cpp
+++ b/canned_fs_config.cpp
@@ -18,6 +18,8 @@
 #include <private/canned_fs_config.h>
 #include <private/fs_config.h>
 
+#include <android-base/strings.h>
+
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -25,104 +27,107 @@
 #include <stdlib.h>
 #include <string.h>
 
-typedef struct {
-    const char* path;
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+using android::base::ConsumePrefix;
+using android::base::StartsWith;
+using android::base::Tokenize;
+
+struct Entry {
+    std::string path;
     unsigned uid;
     unsigned gid;
     unsigned mode;
     uint64_t capabilities;
-} Path;
+};
 
-static Path* canned_data = NULL;
-static int canned_alloc = 0;
-static int canned_used = 0;
-
-static int path_compare(const void* a, const void* b) {
-    return strcmp(((Path*)a)->path, ((Path*)b)->path);
-}
+static std::vector<Entry> canned_data;
 
 int load_canned_fs_config(const char* fn) {
-    char buf[PATH_MAX + 200];
-    FILE* f;
-
-    f = fopen(fn, "r");
-    if (f == NULL) {
-        fprintf(stderr, "failed to open %s: %s\n", fn, strerror(errno));
-        return -1;
-    }
-
-    while (fgets(buf, sizeof(buf), f)) {
-        Path* p;
-        char* token;
-        char* line = buf;
-        bool rootdir;
-
-        while (canned_used >= canned_alloc) {
-            canned_alloc = (canned_alloc+1) * 2;
-            canned_data = (Path*) realloc(canned_data, canned_alloc * sizeof(Path));
+    std::ifstream input(fn);
+    for (std::string line; std::getline(input, line);) {
+        // Historical: the root dir can be represented as a space character.
+        // e.g. " 1000 1000 0755" is parsed as
+        // path = " ", uid = 1000, gid = 1000, mode = 0755.
+        // But at the same time, we also have accepted
+        // "/ 1000 1000 0755".
+        if (StartsWith(line, " ")) {
+            line.insert(line.begin(), '/');
         }
-        p = canned_data + canned_used;
-        if (line[0] == '/') line++;
-        rootdir = line[0] == ' ';
-        p->path = strdup(rootdir ? "" : strtok(line, " "));
-        p->uid = atoi(strtok(rootdir ? line : NULL, " "));
-        p->gid = atoi(strtok(NULL, " "));
-        p->mode = strtol(strtok(NULL, " "), NULL, 8);   // mode is in octal
-        p->capabilities = 0;
 
-        do {
-            token = strtok(NULL, " ");
-            if (token && strncmp(token, "capabilities=", 13) == 0) {
-                p->capabilities = strtoll(token+13, NULL, 0);
+        std::vector<std::string> tokens = Tokenize(line, " ");
+        if (tokens.size() < 4) {
+            std::cerr << "Ill-formed line: " << line << " in " << fn << std::endl;
+            return -1;
+        }
+
+        // Historical: remove the leading '/' if exists.
+        std::string path(tokens[0].front() == '/' ? std::string(tokens[0], 1) : tokens[0]);
+
+        Entry e{
+                .path = std::move(path),
+                .uid = static_cast<unsigned int>(atoi(tokens[1].c_str())),
+                .gid = static_cast<unsigned int>(atoi(tokens[2].c_str())),
+                // mode is in octal
+                .mode = static_cast<unsigned int>(strtol(tokens[3].c_str(), nullptr, 8)),
+                .capabilities = 0,
+        };
+
+        for (size_t i = 4; i < tokens.size(); i++) {
+            std::string_view sv = tokens[i];
+            if (ConsumePrefix(&sv, "capabilities=")) {
+                e.capabilities = strtoll(std::string(sv).c_str(), nullptr, 0);
                 break;
             }
-        } while (token);
+            // Historical: there can be tokens like "selabel=..." here. They have been ignored.
+            // It's not an error because selabels are applied separately in e2fsdroid using the
+            // file_contexts files set via -S option.
+            std::cerr << "info: ignored token \"" << sv << "\" in " << fn << std::endl;
+        }
 
-        canned_used++;
+        canned_data.emplace_back(std::move(e));
     }
 
-    fclose(f);
+    // Note: we used to sort the entries by path names. This was to improve the lookup performance
+    // by doing binary search. However, this is no longer the case. The lookup performance is not
+    // critical because this tool runs on the host, not on the device. Now, there can be multiple
+    // entries for the same path. Then the one that comes the last wins. This is to allow overriding
+    // platform provided fs_config with a user provided fs_config by appending the latter to the
+    // former.
+    //
+    // To implement the strategy, reverse the entries order, and search from the top.
+    std::reverse(canned_data.begin(), canned_data.end());
 
-    qsort(canned_data, canned_used, sizeof(Path), path_compare);
-    printf("loaded %d fs_config entries\n", canned_used);
-
+    std::cout << "loaded " << canned_data.size() << " fs_config entries" << std::endl;
     return 0;
 }
 
-static const int kDebugCannedFsConfig = 0;
+void canned_fs_config(const char* path, [[maybe_unused]] int dir,
+                      [[maybe_unused]] const char* target_out_path, unsigned* uid, unsigned* gid,
+                      unsigned* mode, uint64_t* capabilities) {
+    if (path != nullptr && path[0] == '/') path++;  // canned paths lack the leading '/'
 
-void canned_fs_config(const char* path, int dir, const char* target_out_path,
-                      unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) {
-    Path key, *p;
+    const Entry* found = nullptr;
+    // canned_data is already reversed. First match wins.
+    for (const auto& entry : canned_data) {
+        if (path == entry.path) {
+            found = &entry;
+            break;
+        }
+        continue;
+    }
 
-    key.path = path;
-    if (path[0] == '/') key.path++; // canned paths lack the leading '/'
-    p = (Path*) bsearch(&key, canned_data, canned_used, sizeof(Path), path_compare);
-    if (p == NULL) {
-        fprintf(stderr, "failed to find [%s] in canned fs_config\n", path);
+    if (found == nullptr) {
+        std::cerr << "failed to find " << path << " in canned fs_config" << std::endl;
         exit(1);
     }
-    *uid = p->uid;
-    *gid = p->gid;
-    *mode = p->mode;
-    *capabilities = p->capabilities;
 
-    if (kDebugCannedFsConfig) {
-        // for debugging, run the built-in fs_config and compare the results.
-
-        unsigned c_uid, c_gid, c_mode;
-        uint64_t c_capabilities;
-
-        fs_config(path, dir, target_out_path, &c_uid, &c_gid, &c_mode, &c_capabilities);
-
-        if (c_uid != *uid) printf("%s uid %d %d\n", path, *uid, c_uid);
-        if (c_gid != *gid) printf("%s gid %d %d\n", path, *gid, c_gid);
-        if (c_mode != *mode) printf("%s mode 0%o 0%o\n", path, *mode, c_mode);
-        if (c_capabilities != *capabilities) {
-            printf("%s capabilities %" PRIx64 " %" PRIx64 "\n",
-                path,
-                *capabilities,
-                c_capabilities);
-        }
-    }
+    *uid = found->uid;
+    *gid = found->gid;
+    *mode = found->mode;
+    *capabilities = found->capabilities;
 }
diff --git a/fs_config.cpp b/fs_config.cpp
index e9497a8..a6835fc 100644
--- a/fs_config.cpp
+++ b/fs_config.cpp
@@ -211,6 +211,7 @@
     { 00755, AID_ROOT,      AID_ROOT,      0, "first_stage_ramdisk/system/bin/resize2fs" },
     { 00755, AID_ROOT,      AID_ROOT,      0, "first_stage_ramdisk/system/bin/snapuserd" },
     { 00755, AID_ROOT,      AID_ROOT,      0, "first_stage_ramdisk/system/bin/tune2fs" },
+    { 00755, AID_ROOT,      AID_ROOT,      0, "first_stage_ramdisk/system/bin/fsck.f2fs" },
     // generic defaults
     { 00755, AID_ROOT,      AID_ROOT,      0, "bin/*" },
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
diff --git a/include/cutils/list.h b/include/cutils/list.h
index dfdc53b..7eb8725 100644
--- a/include/cutils/list.h
+++ b/include/cutils/list.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2013 The Android Open Source Project
+ * Copyright (C) 2008 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.
@@ -14,8 +14,7 @@
  * limitations under the License.
  */
 
-#ifndef _CUTILS_LIST_H_
-#define _CUTILS_LIST_H_
+#pragma once
 
 #include <stddef.h>
 
@@ -38,9 +37,6 @@
         .prev = &(name), \
     }
 
-#define list_for_each(node, list) \
-    for ((node) = (list)->next; (node) != (list); (node) = (node)->next)
-
 #define list_for_each_reverse(node, list) \
     for ((node) = (list)->prev; (node) != (list); (node) = (node)->prev)
 
@@ -49,6 +45,10 @@
          (node) != (list); \
          (node) = (n), (n) = (node)->next)
 
+#define list_for_each(node, list)                                                \
+    for (struct listnode* __n = ((node) = (list)->next)->next; (node) != (list); \
+         (node) = __n, __n = (node)->next)
+
 static inline void list_init(struct listnode *node)
 {
     node->next = node;
@@ -84,5 +84,3 @@
 #ifdef __cplusplus
 };
 #endif /* __cplusplus */
-
-#endif
diff --git a/include/cutils/multiuser.h b/include/cutils/multiuser.h
index 9a2305c..0575ccf 100644
--- a/include/cutils/multiuser.h
+++ b/include/cutils/multiuser.h
@@ -30,6 +30,8 @@
 extern appid_t multiuser_get_app_id(uid_t uid);
 
 extern uid_t multiuser_get_uid(userid_t user_id, appid_t app_id);
+extern uid_t multiuser_get_sdk_sandbox_uid(userid_t user_id, appid_t app_id);
+extern uid_t multiuser_convert_sdk_sandbox_to_app_uid(uid_t uid);
 
 extern gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id);
 extern gid_t multiuser_get_ext_gid(userid_t user_id, appid_t app_id);
diff --git a/include/cutils/qtaguid.h b/include/cutils/qtaguid.h
index 3f5e41f..a5ffb03 100644
--- a/include/cutils/qtaguid.h
+++ b/include/cutils/qtaguid.h
@@ -34,24 +34,6 @@
 extern int qtaguid_untagSocket(int sockfd);
 
 /*
- * For the given uid, switch counter sets.
- * The kernel only keeps a limited number of sets.
- * 2 for now.
- */
-extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid);
-
-/*
- * Delete all tag info that relates to the given tag an uid.
- * If the tag is 0, then ALL info about the uid is freed.
- * The delete data also affects active tagged sockets, which are
- * then untagged.
- * The calling process can only operate on its own tags.
- * Unless it is part of the happy AID_NET_BW_ACCT group.
- * In which case it can clobber everything.
- */
-extern int qtaguid_deleteTagData(int tag, uid_t uid);
-
-/*
  * Enable/disable qtaguid functionnality at a lower level.
  * When pacified, the kernel will accept commands but do nothing.
  */
diff --git a/include/cutils/trace.h b/include/cutils/trace.h
index 24c6ae6..17a0070 100644
--- a/include/cutils/trace.h
+++ b/include/cutils/trace.h
@@ -75,7 +75,8 @@
 #define ATRACE_TAG_AIDL             (1<<24)
 #define ATRACE_TAG_NNAPI            (1<<25)
 #define ATRACE_TAG_RRO              (1<<26)
-#define ATRACE_TAG_LAST             ATRACE_TAG_RRO
+#define ATRACE_TAG_THERMAL          (1 << 27)
+#define ATRACE_TAG_LAST             ATRACE_TAG_THERMAL
 
 // Reserved for initialization.
 #define ATRACE_TAG_NOT_READY        (1ULL<<63)
@@ -208,6 +209,39 @@
 }
 
 /**
+ * Trace an instantaneous context. name is used to identify the context.
+ *
+ * An "instant" is an event with no defined duration. Visually is displayed like a single marker
+ * in the timeline (rather than a span, in the case of begin/end events).
+ *
+ * By default, instant events are added into a dedicated track that has the same name of the event.
+ * Use atrace_instant_for_track to put different instant events into the same timeline track/row.
+ */
+#define ATRACE_INSTANT(name) atrace_instant(ATRACE_TAG, name)
+static inline void atrace_instant(uint64_t tag, const char* name) {
+    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
+        void atrace_instant_body(const char*);
+        atrace_instant_body(name);
+    }
+}
+
+/**
+ * Trace an instantaneous context. name is used to identify the context.
+ * trackName is the name of the row where the event should be recorded.
+ *
+ * An "instant" is an event with no defined duration. Visually is displayed like a single marker
+ * in the timeline (rather than a span, in the case of begin/end events).
+ */
+#define ATRACE_INSTANT_FOR_TRACK(trackName, name) \
+    atrace_instant_for_track(ATRACE_TAG, trackName, name)
+static inline void atrace_instant_for_track(uint64_t tag, const char* trackName, const char* name) {
+    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
+        void atrace_instant_for_track_body(const char*, const char*);
+        atrace_instant_for_track_body(trackName, name);
+    }
+}
+
+/**
  * Traces an integer counter value.  name is used to identify the counter.
  * This can be used to track how a value changes over time.
  */
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index c471fa0..8bb8652 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -130,6 +130,13 @@
 #define AID_VIRTUALIZATIONSERVICE 1081 /* VirtualizationService daemon */
 #define AID_ARTD 1082             /* ART Service daemon */
 #define AID_UWB 1083              /* UWB subsystem */
+#define AID_THREAD_NETWORK 1084   /* Thread Network subsystem */
+#define AID_DICED 1085            /* Android's DICE daemon */
+#define AID_DMESGD 1086           /* dmesg parsing daemon for kernel report collection */
+#define AID_JC_WEAVER 1087        /* Javacard Weaver HAL - to manage omapi ARA rules */
+#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 */
 /* Changes to this file must be made in AOSP, *not* in internal branches. */
 
 #define AID_SHELL 2000 /* adb and debug shell user */
@@ -157,6 +164,7 @@
 #define AID_READPROC 3009     /* Allow /proc read access */
 #define AID_WAKELOCK 3010     /* Allow system wakelock read/write access */
 #define AID_UHID 3011         /* Allow read/write to /dev/uhid node */
+#define AID_READTRACEFS 3012  /* Allow tracefs read */
 
 /* The range 5000-5999 is also reserved for vendor partition. */
 #define AID_OEM_RESERVED_2_START 5000
@@ -206,6 +214,10 @@
  */
 #define AID_OVERFLOWUID 65534 /* unmapped user in the user namespace */
 
+/* use the ranges below to determine whether a process is sdk sandbox */
+#define AID_SDK_SANDBOX_PROCESS_START 20000 /* start of uids allocated to sdk sandbox processes */
+#define AID_SDK_SANDBOX_PROCESS_END 29999   /* end of uids allocated to sdk sandbox processes */
+
 /* use the ranges below to determine whether a process is isolated */
 #define AID_ISOLATED_START 90000 /* start of uids for fully isolated sandboxed processes */
 #define AID_ISOLATED_END 99999   /* end of uids for fully isolated sandboxed processes */
diff --git a/include/private/android_projectid_config.h b/include/private/android_projectid_config.h
index 7ef3854..56a39a6 100644
--- a/include/private/android_projectid_config.h
+++ b/include/private/android_projectid_config.h
@@ -49,3 +49,13 @@
 #define PROJECT_ID_EXT_OBB_START 40000
 /* End of project IDs for apps to mark external OBB data. */
 #define PROJECT_ID_EXT_OBB_END 49999
+
+/* Start of project IDs for apps to mark internal app data. */
+#define PROJECT_ID_APP_START 50000
+/* End of project IDs for apps to mark internal app data. */
+#define PROJECT_ID_APP_END 59999
+
+/* Start of project IDs for apps to mark internal app cache data. */
+#define PROJECT_ID_APP_CACHE_START 60000
+/* End of project IDs for apps to mark internal app cache data. */
+#define PROJECT_ID_APP_CACHE_END 69999
diff --git a/multiuser.cpp b/multiuser.cpp
index 0fd3d0c..967f991 100644
--- a/multiuser.cpp
+++ b/multiuser.cpp
@@ -29,6 +29,25 @@
     return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET);
 }
 
+uid_t multiuser_get_sdk_sandbox_uid(userid_t user_id, appid_t app_id) {
+    int sdk_sandbox_offset = AID_SDK_SANDBOX_PROCESS_START - AID_APP_START;
+    if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
+        return (user_id * AID_USER_OFFSET) + (app_id % AID_USER_OFFSET) + sdk_sandbox_offset;
+    } else {
+        return -1;
+    }
+}
+
+uid_t multiuser_convert_sdk_sandbox_to_app_uid(uid_t uid) {
+    appid_t app_id = multiuser_get_app_id(uid);
+    int sdk_sandbox_offset = AID_SDK_SANDBOX_PROCESS_START - AID_APP_START;
+    if (app_id >= AID_SDK_SANDBOX_PROCESS_START && app_id <= AID_SDK_SANDBOX_PROCESS_END) {
+        return uid - sdk_sandbox_offset;
+    } else {
+        return -1;
+    }
+}
+
 gid_t multiuser_get_cache_gid(userid_t user_id, appid_t app_id) {
     if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
         return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_CACHE_GID_START);
diff --git a/multiuser_test.cpp b/multiuser_test.cpp
index 4b0fd13..b57223d 100644
--- a/multiuser_test.cpp
+++ b/multiuser_test.cpp
@@ -18,6 +18,7 @@
 #include <gtest/gtest.h>
 
 static constexpr auto ERR_GID = static_cast<gid_t>(-1);
+static constexpr auto ERR_UID = static_cast<uid_t>(-1);
 
 TEST(MultiuserTest, TestMerge) {
     EXPECT_EQ(0U, multiuser_get_uid(0, 0));
@@ -30,6 +31,40 @@
     EXPECT_EQ(1050000U, multiuser_get_uid(10, 50000));
 }
 
+TEST(MultiuserTest, TestSdkSandboxUid) {
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 0));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 1000));
+    EXPECT_EQ(20000U, multiuser_get_sdk_sandbox_uid(0, 10000));
+    EXPECT_EQ(25000U, multiuser_get_sdk_sandbox_uid(0, 15000));
+    EXPECT_EQ(29999U, multiuser_get_sdk_sandbox_uid(0, 19999));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(0, 50000));
+
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 0));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 1000));
+    EXPECT_EQ(1020000U, multiuser_get_sdk_sandbox_uid(10, 10000));
+    EXPECT_EQ(1025000U, multiuser_get_sdk_sandbox_uid(10, 15000));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 20000));
+    EXPECT_EQ(ERR_UID, multiuser_get_sdk_sandbox_uid(10, 50000));
+}
+
+TEST(MultiuserTest, TestSdkSandboxUidConvertation) {
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(0));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(10000));
+    EXPECT_EQ(10000U, multiuser_convert_sdk_sandbox_to_app_uid(20000));
+    EXPECT_EQ(15000U, multiuser_convert_sdk_sandbox_to_app_uid(25000));
+    EXPECT_EQ(19999U, multiuser_convert_sdk_sandbox_to_app_uid(29999));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(50000));
+
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1000000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1001000));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1010000));
+    EXPECT_EQ(1010000U, multiuser_convert_sdk_sandbox_to_app_uid(1020000));
+    EXPECT_EQ(1015000U, multiuser_convert_sdk_sandbox_to_app_uid(1025000));
+    EXPECT_EQ(1019999U, multiuser_convert_sdk_sandbox_to_app_uid(1029999));
+    EXPECT_EQ(ERR_UID, multiuser_convert_sdk_sandbox_to_app_uid(1050000));
+}
+
 TEST(MultiuserTest, TestSplitUser) {
     EXPECT_EQ(0U, multiuser_get_user_id(0));
     EXPECT_EQ(0U, multiuser_get_user_id(1000));
diff --git a/qtaguid.cpp b/qtaguid.cpp
index 2fe877c..a987b85 100644
--- a/qtaguid.cpp
+++ b/qtaguid.cpp
@@ -34,8 +34,6 @@
   public:
     int (*netdTagSocket)(int, uint32_t, uid_t);
     int (*netdUntagSocket)(int);
-    int (*netdSetCounterSet)(uint32_t, uid_t);
-    int (*netdDeleteTagData)(uint32_t, uid_t);
 };
 
 int stubTagSocket(int, uint32_t, uid_t) {
@@ -46,16 +44,8 @@
     return -EREMOTEIO;
 }
 
-int stubSetCounterSet(uint32_t, uid_t) {
-    return -EREMOTEIO;
-}
-
-int stubDeleteTagData(uint32_t, uid_t) {
-    return -EREMOTEIO;
-}
-
 netdHandler initHandler(void) {
-    netdHandler handler = {stubTagSocket, stubUntagSocket, stubSetCounterSet, stubDeleteTagData};
+    netdHandler handler = {stubTagSocket, stubUntagSocket};
 
     void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
     if (!netdClientHandle) {
@@ -73,15 +63,6 @@
         ALOGE("load netdUntagSocket handler failed: %s", dlerror());
     }
 
-    handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet");
-    if (!handler.netdSetCounterSet) {
-        ALOGE("load netdSetCounterSet handler failed: %s", dlerror());
-    }
-
-    handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData");
-    if (!handler.netdDeleteTagData) {
-        ALOGE("load netdDeleteTagData handler failed: %s", dlerror());
-    }
     return handler;
 }
 
@@ -114,13 +95,3 @@
     ALOGV("Untagging socket %d", sockfd);
     return getHandler().netdUntagSocket(sockfd);
 }
-
-int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
-    ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid);
-    return getHandler().netdSetCounterSet(counterSetNum, uid);
-}
-
-int qtaguid_deleteTagData(int tag, uid_t uid) {
-    ALOGV("Deleting tag data with tag %u for uid %d", tag, uid);
-    return getHandler().netdDeleteTagData(tag, uid);
-}
diff --git a/trace-container.cpp b/trace-container.cpp
index f7eed48..ef7c72d 100644
--- a/trace-container.cpp
+++ b/trace-container.cpp
@@ -217,6 +217,28 @@
     WRITE_MSG("F|%d|", "|%" PRId32, name, cookie);
 }
 
+void atrace_instant_body(const char* name) {
+    if (CC_LIKELY(atrace_use_container_sock)) {
+        WRITE_MSG_IN_CONTAINER("I", "|", "%s", name, "");
+        return;
+    }
+
+    if (atrace_marker_fd < 0) return;
+
+    WRITE_MSG("I|%d|", "%s", name, "");
+}
+
+void atrace_instant_for_track_body(const char* trackName, const char* name) {
+    if (CC_LIKELY(atrace_use_container_sock)) {
+        WRITE_MSG_IN_CONTAINER("N", "|", "|%s", trackName, name);
+        return;
+    }
+
+    if (atrace_marker_fd < 0) return;
+
+    WRITE_MSG("N|%d|", "|%s", name, trackName);
+}
+
 void atrace_int_body(const char* name, int32_t value)
 {
     if (CC_LIKELY(atrace_use_container_sock)) {
diff --git a/trace-dev.cpp b/trace-dev.cpp
index 1ab63dc..25c86f4 100644
--- a/trace-dev.cpp
+++ b/trace-dev.cpp
@@ -89,6 +89,14 @@
     WRITE_MSG("F|%d|", "|%" PRId32, name, cookie);
 }
 
+void atrace_instant_body(const char* name) {
+    WRITE_MSG("I|%d|", "%s", name, "");
+}
+
+void atrace_instant_for_track_body(const char* trackName, const char* name) {
+    WRITE_MSG("N|%d|", "|%s", trackName, name);
+}
+
 void atrace_int_body(const char* name, int32_t value)
 {
     WRITE_MSG("C|%d|", "|%" PRId32, name, value);
diff --git a/trace-dev_test.cpp b/trace-dev_test.cpp
index 832b36a..ff6d202 100644
--- a/trace-dev_test.cpp
+++ b/trace-dev_test.cpp
@@ -195,6 +195,106 @@
   ASSERT_STREQ(expected.c_str(), actual.c_str());
 }
 
+TEST_F(TraceDevTest, atrace_instant_body_normal) {
+    atrace_instant_body("fake_name");
+
+    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("I|%d|fake_name", getpid());
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_instant_body_exact) {
+    std::string expected = android::base::StringPrintf("I|%d|", getpid());
+    std::string name = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1);
+    atrace_instant_body(name.c_str());
+
+    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 += name;
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+    // Add a single character and verify we get the exact same value as before.
+    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+    name += '*';
+    atrace_instant_body(name.c_str());
+    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_instant_body_truncated) {
+    std::string expected = android::base::StringPrintf("I|%d|", getpid());
+    std::string name = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+    atrace_instant_body(name.c_str());
+
+    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;
+    expected += android::base::StringPrintf("%.*s", expected_len, name.c_str());
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_instant_for_track_body_normal) {
+    atrace_instant_for_track_body("fake_track", "fake_name");
+
+    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("N|%d|fake_track|fake_name", getpid());
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
+TEST_F(TraceDevTest, atrace_instant_for_track_body_exact) {
+    const int nameSize = 5;
+    std::string expected = android::base::StringPrintf("N|%d|", getpid());
+    std::string trackName = MakeName(ATRACE_MESSAGE_LENGTH - expected.length() - 1 - nameSize);
+    atrace_instant_for_track_body(trackName.c_str(), "name");
+
+    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 += trackName + "|name";
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+
+    // Add a single character and verify we get the exact same value as before.
+    ASSERT_EQ(0, lseek(atrace_marker_fd, 0, SEEK_SET));
+    trackName += '*';
+    atrace_instant_for_track_body(trackName.c_str(), "name");
+    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_instant_for_track_body_truncated) {
+    const int nameSize = 5;
+    std::string expected = android::base::StringPrintf("N|%d|", getpid());
+    std::string trackName = MakeName(2 * ATRACE_MESSAGE_LENGTH);
+    atrace_instant_for_track_body(trackName.c_str(), "name");
+
+    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 - nameSize;
+    expected += android::base::StringPrintf("%.*s|name", expected_len, trackName.c_str());
+    ASSERT_STREQ(expected.c_str(), actual.c_str());
+}
+
 TEST_F(TraceDevTest, atrace_int_body_normal) {
   atrace_int_body("fake_name", 12345);
 
diff --git a/trace-host.cpp b/trace-host.cpp
index 9781ad3..b01a0ec 100644
--- a/trace-host.cpp
+++ b/trace-host.cpp
@@ -28,6 +28,9 @@
 void atrace_end_body() { }
 void atrace_async_begin_body(const char* /*name*/, int32_t /*cookie*/) {}
 void atrace_async_end_body(const char* /*name*/, int32_t /*cookie*/) {}
+void atrace_instant_body(const char* /*name*/) {}
+void atrace_instant_for_track_body(const char* /*trackName*/,
+                                   const char* /*name*/) {}
 void atrace_int_body(const char* /*name*/, int32_t /*value*/) {}
 void atrace_int64_body(const char* /*name*/, int64_t /*value*/) {}
 void atrace_init() {}