Merge changes from topic "reapply_no_cgroup.rc" into main

* changes:
  Reapply "libprocessgroup: Combine all 3 ActivateControllers imple..."
  Reapply "libprocessgroup: Remove ACgroupController_getMaxActivati..."
  Reapply "libprocessgroup: Remove dependency on libcgrouprc"
  Reapply "libprocessgroup: Remove cgroup.rc file"
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..c77a803
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,5 @@
+dirgroup {
+    name: "trusty_dirgroup_system_core",
+    dirs: ["."],
+    visibility: ["//trusty/vendor/google/aosp/scripts"],
+}
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index c9235ee..15e8319 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -470,14 +470,12 @@
   }
 
   NativeBridgeGuestStateHeader header;
-  if (!process_memory->ReadFully(header_ptr, &header, sizeof(NativeBridgeGuestStateHeader))) {
-    PLOG(ERROR) << "failed to get the guest state header for thread " << tid;
-    return false;
-  }
-  if (header.signature != NATIVE_BRIDGE_GUEST_STATE_SIGNATURE) {
+  if (!process_memory->ReadFully(header_ptr, &header, sizeof(NativeBridgeGuestStateHeader)) ||
+      header.signature != NATIVE_BRIDGE_GUEST_STATE_SIGNATURE) {
     // Return when ptr points to unmapped memory or no valid guest state.
     return false;
   }
+
   auto guest_state_data_copy = std::make_unique<unsigned char[]>(header.guest_state_data_size);
   if (!process_memory->ReadFully(reinterpret_cast<uintptr_t>(header.guest_state_data),
                                  guest_state_data_copy.get(), header.guest_state_data_size)) {
diff --git a/fs_mgr/libdm/Android.bp b/fs_mgr/libdm/Android.bp
index c3ca758..1efd7de 100644
--- a/fs_mgr/libdm/Android.bp
+++ b/fs_mgr/libdm/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/fs_mgr/libfiemap/Android.bp b/fs_mgr/libfiemap/Android.bp
index c8d5756..a6be585 100644
--- a/fs_mgr/libfiemap/Android.bp
+++ b/fs_mgr/libfiemap/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 24eebdf..b211e83 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/fs_mgr/liblp/super_layout_builder.cpp b/fs_mgr/liblp/super_layout_builder.cpp
index fd7416b..bff26ea 100644
--- a/fs_mgr/liblp/super_layout_builder.cpp
+++ b/fs_mgr/liblp/super_layout_builder.cpp
@@ -184,7 +184,7 @@
                 return {};
             }
 
-            size_t size = e.num_sectors * LP_SECTOR_SIZE;
+            uint64_t size = e.num_sectors * LP_SECTOR_SIZE;
             uint64_t super_offset = e.target_data * LP_SECTOR_SIZE;
             extents.emplace_back(super_offset, size, image_name, image_offset);
 
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 50efb03..966696b 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 8ff41db..de20526 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -442,6 +442,7 @@
     FRIEND_TEST(SnapshotUpdateTest, QueryStatusError);
     FRIEND_TEST(SnapshotUpdateTest, SnapshotStatusFileWithoutCow);
     FRIEND_TEST(SnapshotUpdateTest, SpaceSwapUpdate);
+    FRIEND_TEST(SnapshotUpdateTest, InterruptMergeDuringPhaseUpdate);
     FRIEND_TEST(SnapshotUpdateTest, MapAllSnapshotsWithoutSlotSwitch);
     friend class SnapshotTest;
     friend class SnapshotUpdateTest;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index 05dec68..acabd67 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -1343,10 +1343,25 @@
         }
 
         if (merge_status == "snapshot" &&
-            DecideMergePhase(snapshot_status) == MergePhase::SECOND_PHASE &&
-            update_status.merge_phase() == MergePhase::FIRST_PHASE) {
-            // The snapshot is not being merged because it's in the wrong phase.
-            return MergeResult(UpdateState::None);
+            DecideMergePhase(snapshot_status) == MergePhase::SECOND_PHASE) {
+            if (update_status.merge_phase() == MergePhase::FIRST_PHASE) {
+                // The snapshot is not being merged because it's in the wrong phase.
+                return MergeResult(UpdateState::None);
+            } else {
+                // update_status is already in second phase but the
+                // snapshot_status is still not set to SnapshotState::MERGING.
+                //
+                // Resume the merge at this point. see b/374225913
+                LOG(INFO) << "SwitchSnapshotToMerge: " << name << " after resuming merge";
+                auto code = SwitchSnapshotToMerge(lock, name);
+                if (code != MergeFailureCode::Ok) {
+                    LOG(ERROR) << "Failed to switch snapshot: " << name
+                               << " to merge during second phase";
+                    return MergeResult(UpdateState::MergeFailed,
+                                       MergeFailureCode::UnknownTargetType);
+                }
+                return MergeResult(UpdateState::Merging);
+            }
         }
 
         if (merge_status == "snapshot-merge") {
@@ -1442,8 +1457,14 @@
         return MergeFailureCode::WriteStatus;
     }
 
+    auto current_slot_suffix = device_->GetSlotSuffix();
     MergeFailureCode result = MergeFailureCode::Ok;
     for (const auto& snapshot : snapshots) {
+        if (!android::base::EndsWith(snapshot, current_slot_suffix)) {
+            LOG(ERROR) << "Skipping invalid snapshot: " << snapshot
+                       << " during MergeSecondPhaseSnapshots";
+            continue;
+        }
         SnapshotStatus snapshot_status;
         if (!ReadSnapshotStatus(lock, snapshot, &snapshot_status)) {
             return MergeFailureCode::ReadStatus;
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 46c3a35..3e5ae2a 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -1607,6 +1607,146 @@
     }
 }
 
+// Test that shrinking and growing partitions at the same time is handled
+// correctly in VABC.
+TEST_F(SnapshotUpdateTest, InterruptMergeDuringPhaseUpdate) {
+    if (!snapuserd_required_) {
+        // b/179111359
+        GTEST_SKIP() << "Skipping snapuserd test";
+    }
+
+    auto old_sys_size = GetSize(sys_);
+    auto old_prd_size = GetSize(prd_);
+
+    // Grow |sys| but shrink |prd|.
+    SetSize(sys_, old_sys_size * 2);
+    sys_->set_estimate_cow_size(8_MiB);
+    SetSize(prd_, old_prd_size / 2);
+    prd_->set_estimate_cow_size(1_MiB);
+
+    AddOperationForPartitions();
+
+    ASSERT_TRUE(sm->BeginUpdate());
+    ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_));
+
+    // Check that the old partition sizes were saved correctly.
+    {
+        ASSERT_TRUE(AcquireLock());
+        auto local_lock = std::move(lock_);
+
+        SnapshotStatus status;
+        ASSERT_TRUE(sm->ReadSnapshotStatus(local_lock.get(), "prd_b", &status));
+        ASSERT_EQ(status.old_partition_size(), 3145728);
+        ASSERT_TRUE(sm->ReadSnapshotStatus(local_lock.get(), "sys_b", &status));
+        ASSERT_EQ(status.old_partition_size(), 3145728);
+    }
+
+    ASSERT_TRUE(WriteSnapshotAndHash(sys_));
+    ASSERT_TRUE(WriteSnapshotAndHash(vnd_));
+    ASSERT_TRUE(ShiftAllSnapshotBlocks("prd_b", old_prd_size));
+
+    sync();
+
+    // Assert that source partitions aren't affected.
+    for (const auto& name : {"sys_a", "vnd_a", "prd_a"}) {
+        ASSERT_TRUE(IsPartitionUnchanged(name));
+    }
+
+    ASSERT_TRUE(sm->FinishedSnapshotWrites(false));
+
+    // Simulate shutting down the device.
+    ASSERT_TRUE(UnmapAll());
+
+    // After reboot, init does first stage mount.
+    auto init = NewManagerForFirstStageMount("_b");
+    ASSERT_NE(init, nullptr);
+    ASSERT_TRUE(init->NeedSnapshotsInFirstStageMount());
+    ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
+
+    // Check that the target partitions have the same content.
+    for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
+        ASSERT_TRUE(IsPartitionUnchanged(name));
+    }
+
+    // Initiate the merge and wait for it to be completed.
+    if (ShouldSkipLegacyMerging()) {
+        LOG(INFO) << "Skipping legacy merge in test";
+        return;
+    }
+    ASSERT_TRUE(init->InitiateMerge());
+    ASSERT_EQ(init->IsSnapuserdRequired(), snapuserd_required_);
+    {
+        // Check that the merge phase is FIRST_PHASE until at least one call
+        // to ProcessUpdateState() occurs.
+        ASSERT_TRUE(AcquireLock());
+        auto local_lock = std::move(lock_);
+        auto status = init->ReadSnapshotUpdateStatus(local_lock.get());
+        ASSERT_EQ(status.merge_phase(), MergePhase::FIRST_PHASE);
+    }
+
+    // Wait until prd_b merge is completed which is part of first phase
+    std::chrono::milliseconds timeout(6000);
+    auto start = std::chrono::steady_clock::now();
+    // Keep polling until the merge is complete or timeout is reached
+    while (true) {
+        // Query the merge status
+        const auto merge_status = init->snapuserd_client()->QuerySnapshotStatus("prd_b");
+        if (merge_status == "snapshot-merge-complete") {
+            break;
+        }
+
+        auto now = std::chrono::steady_clock::now();
+        auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
+
+        ASSERT_TRUE(elapsed < timeout);
+        // sleep for a second and allow merge to complete
+        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+    }
+
+    // Now, forcefully update the snapshot-update status to SECOND PHASE
+    // This will not update the snapshot status of sys_b to MERGING
+    if (init->UpdateUsesUserSnapshots()) {
+        ASSERT_TRUE(AcquireLock());
+        auto local_lock = std::move(lock_);
+        auto status = init->ReadSnapshotUpdateStatus(local_lock.get());
+        status.set_merge_phase(MergePhase::SECOND_PHASE);
+        ASSERT_TRUE(init->WriteSnapshotUpdateStatus(local_lock.get(), status));
+    }
+
+    // Simulate shutting down the device and creating partitions again.
+    ASSERT_TRUE(UnmapAll());
+    ASSERT_TRUE(init->CreateLogicalAndSnapshotPartitions("super", snapshot_timeout_));
+
+    DeviceMapper::TargetInfo target;
+    ASSERT_TRUE(init->IsSnapshotDevice("prd_b", &target));
+
+    ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
+    ASSERT_TRUE(init->IsSnapshotDevice("sys_b", &target));
+    ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
+    ASSERT_TRUE(init->IsSnapshotDevice("vnd_b", &target));
+    ASSERT_EQ(DeviceMapper::GetTargetType(target.spec), "user");
+
+    // Complete the merge; "sys" and "vnd" should resume the merge
+    // even though merge was interrupted after update_status was updated to
+    // SECOND_PHASE
+    ASSERT_EQ(UpdateState::MergeCompleted, init->ProcessUpdateState());
+
+    // Make sure the second phase ran and deleted snapshots.
+    {
+        ASSERT_TRUE(AcquireLock());
+        auto local_lock = std::move(lock_);
+        std::vector<std::string> snapshots;
+        ASSERT_TRUE(init->ListSnapshots(local_lock.get(), &snapshots));
+        ASSERT_TRUE(snapshots.empty());
+    }
+
+    // Check that the target partitions have the same content after the merge.
+    for (const auto& name : {"sys_b", "vnd_b", "prd_b"}) {
+        ASSERT_TRUE(IsPartitionUnchanged(name))
+                << "Content of " << name << " changes after the merge";
+    }
+}
+
 // Test that if new system partitions uses empty space in super, that region is not snapshotted.
 TEST_F(SnapshotUpdateTest, DirectWriteEmptySpace) {
     GTEST_SKIP() << "b/141889746";
diff --git a/fs_mgr/libsnapshot/snapshotctl.cpp b/fs_mgr/libsnapshot/snapshotctl.cpp
index 97a8cb2..46de991 100644
--- a/fs_mgr/libsnapshot/snapshotctl.cpp
+++ b/fs_mgr/libsnapshot/snapshotctl.cpp
@@ -105,7 +105,7 @@
     bool FinishSnapshotWrites();
     bool UnmapCowImagePath(std::string& name);
     bool DeleteSnapshots();
-    bool CleanupSnapshot() { return sm_->PrepareDeviceToBootWithoutSnapshot(); }
+    bool CleanupSnapshot();
     bool BeginUpdate();
     bool ApplyUpdate();
 
@@ -495,6 +495,11 @@
     return sm_->UnmapCowImage(name);
 }
 
+bool MapSnapshots::CleanupSnapshot() {
+    sm_ = SnapshotManager::New();
+    return sm_->PrepareDeviceToBootWithoutSnapshot();
+}
+
 bool MapSnapshots::DeleteSnapshots() {
     sm_ = SnapshotManager::New();
     lock_ = sm_->LockExclusive();
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 083068b..e4d2d04 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -15,6 +15,7 @@
 //
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/init/Android.bp b/init/Android.bp
index 8da2e7c..4025a6b 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -389,6 +389,7 @@
         "libsnapshot_init",
         "update_metadata-protos",
         "libprocinfo",
+        "libbootloader_message",
     ],
 
     static_executable: true,
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 99bf0de..4f1af30 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -32,9 +32,12 @@
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/parseint.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android/avf_cc_flags.h>
+#include <bootloader_message/bootloader_message.h>
+#include <cutils/android_reboot.h>
 #include <fs_avb/fs_avb.h>
 #include <fs_mgr.h>
 #include <fs_mgr_dm_linear.h>
@@ -46,6 +49,7 @@
 
 #include "block_dev_initializer.h"
 #include "devices.h"
+#include "reboot_utils.h"
 #include "result.h"
 #include "snapuserd_transition.h"
 #include "switch_root.h"
@@ -111,6 +115,8 @@
     bool GetDmVerityDevices(std::set<std::string>* devices);
     bool SetUpDmVerity(FstabEntry* fstab_entry);
 
+    void RequestTradeInModeWipeIfNeeded();
+
     bool InitAvbHandle();
 
     bool need_dm_verity_;
@@ -263,6 +269,8 @@
 }
 
 bool FirstStageMountVBootV2::DoFirstStageMount() {
+    RequestTradeInModeWipeIfNeeded();
+
     if (!IsDmLinearEnabled() && fstab_.empty()) {
         // Nothing to mount.
         LOG(INFO) << "First stage mount skipped (missing/incompatible/empty fstab in device tree)";
@@ -878,6 +886,55 @@
     return true;
 }
 
+void FirstStageMountVBootV2::RequestTradeInModeWipeIfNeeded() {
+    static constexpr const char* kWipeIndicator = "/metadata/tradeinmode/wipe";
+    static constexpr size_t kWipeAttempts = 3;
+
+    if (access(kWipeIndicator, R_OK) == -1) {
+        return;
+    }
+
+    // Write a counter to the wipe indicator, to try and prevent boot loops if
+    // recovery fails to wipe data.
+    uint32_t counter = 0;
+    std::string contents;
+    if (ReadFileToString(kWipeIndicator, &contents)) {
+        android::base::ParseUint(contents, &counter);
+        contents = std::to_string(++counter);
+        if (android::base::WriteStringToFile(contents, kWipeIndicator)) {
+            sync();
+        } else {
+            PLOG(ERROR) << "Failed to update " << kWipeIndicator;
+        }
+    } else {
+        PLOG(ERROR) << "Failed to read " << kWipeIndicator;
+    }
+
+    std::string err;
+    auto misc_device = get_misc_blk_device(&err);
+    if (misc_device.empty()) {
+        LOG(FATAL) << "Could not find misc device: " << err;
+    }
+
+    auto misc_name = android::base::Basename(misc_device);
+    if (!block_dev_init_.InitDevices({misc_name})) {
+        LOG(FATAL) << "Could not find misc device: " << misc_device;
+    }
+
+    // If we've failed to wipe three times, don't include the wipe command. This
+    // will force us to boot into the recovery menu instead where a manual wipe
+    // can be attempted.
+    std::vector<std::string> options;
+    if (counter <= kWipeAttempts) {
+        options.emplace_back("--wipe_data");
+        options.emplace_back("--reason=tradeinmode");
+    }
+    if (!write_bootloader_message(options, &err)) {
+        LOG(FATAL) << "Could not issue wipe: " << err;
+    }
+    RebootSystem(ANDROID_RB_RESTART2, "recovery", "reboot,tradeinmode,wipe");
+}
+
 void SetInitAvbVersionInRecovery() {
     if (!IsRecoveryMode()) {
         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not in recovery mode)";
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index e6f3af6..ec3b176 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -538,12 +538,9 @@
 // when we migrate to cgroups v2 while these hardcoded paths stay the same.
 static std::optional<const std::string> ConvertTaskFileToProfile(const std::string& file) {
     static const std::map<const std::string, const std::string> map = {
-            {"/dev/stune/top-app/tasks", "MaxPerformance"},
-            {"/dev/stune/foreground/tasks", "HighPerformance"},
             {"/dev/cpuset/camera-daemon/tasks", "CameraServiceCapacity"},
             {"/dev/cpuset/foreground/tasks", "ProcessCapacityHigh"},
             {"/dev/cpuset/system-background/tasks", "ServiceCapacityLow"},
-            {"/dev/stune/nnapi-hal/tasks", "NNApiHALPerformance"},
             {"/dev/blkio/background/tasks", "LowIoPriority"},
     };
     auto iter = map.find(file);
diff --git a/libprocessgroup/OWNERS b/libprocessgroup/OWNERS
index d5aa721..accd7df 100644
--- a/libprocessgroup/OWNERS
+++ b/libprocessgroup/OWNERS
@@ -1,4 +1,3 @@
 # Bug component: 1293033
 surenb@google.com
-tjmercier@google.com
-carlosgalo@google.com
+tjmercier@google.com
\ No newline at end of file
diff --git a/libprocessgroup/profiles/Android.bp b/libprocessgroup/profiles/Android.bp
index 1ec9f7f..baa4546 100644
--- a/libprocessgroup/profiles/Android.bp
+++ b/libprocessgroup/profiles/Android.bp
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 package {
+    default_team: "trendy_team_android_kernel",
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 411c38c..feda3b4 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -572,33 +572,6 @@
     },
 
     {
-      "Name": "PerfBoost",
-      "Actions": [
-        {
-          "Name": "SetClamps",
-          "Params":
-          {
-            "Boost": "50%",
-            "Clamp": "0"
-          }
-        }
-      ]
-    },
-    {
-      "Name": "PerfClamp",
-      "Actions": [
-        {
-          "Name": "SetClamps",
-          "Params":
-          {
-            "Boost": "0",
-            "Clamp": "30%"
-          }
-        }
-      ]
-    },
-
-    {
       "Name": "LowMemoryUsage",
       "Actions": [
         {
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 67ecc1d..cc675b3 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -17,11 +17,16 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "libprocessgroup"
 
+#include <task_profiles.h>
+
+#include <map>
+#include <string>
+
 #include <dirent.h>
 #include <fcntl.h>
+#include <sched.h>
+#include <sys/resource.h>
 #include <unistd.h>
-#include <task_profiles.h>
-#include <string>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
@@ -30,18 +35,13 @@
 #include <android-base/strings.h>
 #include <android-base/threads.h>
 
+#include <build_flags.h>
+
 #include <cutils/android_filesystem_config.h>
 
 #include <json/reader.h>
 #include <json/value.h>
 
-#include <build_flags.h>
-
-// To avoid issues in sdk_mac build
-#if defined(__ANDROID__)
-#include <sys/prctl.h>
-#endif
-
 using android::base::GetThreadId;
 using android::base::GetUintProperty;
 using android::base::StringPrintf;
@@ -188,48 +188,18 @@
     return true;
 }
 
-bool SetClampsAction::ExecuteForProcess(uid_t, pid_t) const {
-    // TODO: add support when kernel supports util_clamp
-    LOG(WARNING) << "SetClampsAction::ExecuteForProcess is not supported";
-    return false;
-}
-
-bool SetClampsAction::ExecuteForTask(int) const {
-    // TODO: add support when kernel supports util_clamp
-    LOG(WARNING) << "SetClampsAction::ExecuteForTask is not supported";
-    return false;
-}
-
 // To avoid issues in sdk_mac build
 #if defined(__ANDROID__)
 
-bool SetTimerSlackAction::IsTimerSlackSupported(pid_t tid) {
-    auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
-
-    return (access(file.c_str(), W_OK) == 0);
-}
-
 bool SetTimerSlackAction::ExecuteForTask(pid_t tid) const {
-    static bool sys_supports_timerslack = IsTimerSlackSupported(tid);
-
-    // v4.6+ kernels support the /proc/<tid>/timerslack_ns interface.
-    // TODO: once we've backported this, log if the open(2) fails.
-    if (sys_supports_timerslack) {
-        auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
-        if (!WriteStringToFile(std::to_string(slack_), file)) {
-            if (errno == ENOENT) {
-                // This happens when process is already dead
-                return true;
-            }
-            PLOG(ERROR) << "set_timerslack_ns write failed";
+    const auto file = StringPrintf("/proc/%d/timerslack_ns", tid);
+    if (!WriteStringToFile(std::to_string(slack_), file)) {
+        if (errno == ENOENT) {
+            // This happens when process is already dead
+            return true;
         }
-    }
-
-    // TODO: Remove when /proc/<tid>/timerslack_ns interface is backported.
-    if (tid == 0 || tid == GetThreadId()) {
-        if (prctl(PR_SET_TIMERSLACK, slack_) == -1) {
-            PLOG(ERROR) << "set_timerslack_ns prctl failed";
-        }
+        PLOG(ERROR) << "set_timerslack_ns write failed";
+        return false;
     }
 
     return true;
@@ -672,6 +642,57 @@
     return access(task_path_.c_str(), W_OK) == 0;
 }
 
+bool SetSchedulerPolicyAction::isNormalPolicy(int policy) {
+    return policy == SCHED_OTHER || policy == SCHED_BATCH || policy == SCHED_IDLE;
+}
+
+bool SetSchedulerPolicyAction::toPriority(int policy, int virtual_priority, int& priority_out) {
+    constexpr int VIRTUAL_PRIORITY_MIN = 1;
+    constexpr int VIRTUAL_PRIORITY_MAX = 99;
+
+    if (virtual_priority < VIRTUAL_PRIORITY_MIN || virtual_priority > VIRTUAL_PRIORITY_MAX) {
+        LOG(WARNING) << "SetSchedulerPolicy: invalid priority (" << virtual_priority
+                     << ") for policy (" << policy << ")";
+        return false;
+    }
+
+    const int min = sched_get_priority_min(policy);
+    if (min == -1) {
+        PLOG(ERROR) << "SetSchedulerPolicy: Cannot get min sched priority for policy " << policy;
+        return false;
+    }
+
+    const int max = sched_get_priority_max(policy);
+    if (max == -1) {
+        PLOG(ERROR) << "SetSchedulerPolicy: Cannot get max sched priority for policy " << policy;
+        return false;
+    }
+
+    priority_out = min + (virtual_priority - VIRTUAL_PRIORITY_MIN) * (max - min) /
+        (VIRTUAL_PRIORITY_MAX - VIRTUAL_PRIORITY_MIN);
+
+    return true;
+}
+
+bool SetSchedulerPolicyAction::ExecuteForTask(pid_t tid) const {
+    struct sched_param param = {};
+    param.sched_priority = isNormalPolicy(policy_) ? 0 : *priority_or_nice_;
+    if (sched_setscheduler(tid, policy_, &param) == -1) {
+        PLOG(WARNING) << "SetSchedulerPolicy: Failed to apply scheduler policy (" << policy_
+                      << ") with priority (" << *priority_or_nice_ << ") to tid " << tid;
+        return false;
+    }
+
+    if (isNormalPolicy(policy_) && priority_or_nice_ &&
+        setpriority(PRIO_PROCESS, tid, *priority_or_nice_) == -1) {
+        PLOG(WARNING) << "SetSchedulerPolicy: Failed to apply nice (" << *priority_or_nice_
+                      << ") to tid " << tid;
+        return false;
+    }
+
+    return true;
+}
+
 bool ApplyProfileAction::ExecuteForProcess(uid_t uid, pid_t pid) const {
     for (const auto& profile : profiles_) {
         profile->ExecuteForProcess(uid, pid);
@@ -925,23 +946,6 @@
                 } else {
                     LOG(WARNING) << "SetAttribute: unknown attribute: " << attr_name;
                 }
-            } else if (action_name == "SetClamps") {
-                std::string boost_value = params_val["Boost"].asString();
-                std::string clamp_value = params_val["Clamp"].asString();
-                char* end;
-                unsigned long boost;
-
-                boost = strtoul(boost_value.c_str(), &end, 10);
-                if (end > boost_value.c_str()) {
-                    unsigned long clamp = strtoul(clamp_value.c_str(), &end, 10);
-                    if (end > clamp_value.c_str()) {
-                        profile->Add(std::make_unique<SetClampsAction>(boost, clamp));
-                    } else {
-                        LOG(WARNING) << "SetClamps: invalid parameter " << clamp_value;
-                    }
-                } else {
-                    LOG(WARNING) << "SetClamps: invalid parameter: " << boost_value;
-                }
             } else if (action_name == "WriteFile") {
                 std::string attr_filepath = params_val["FilePath"].asString();
                 std::string attr_procfilepath = params_val["ProcFilePath"].asString();
@@ -959,6 +963,62 @@
                     LOG(WARNING) << "WriteFile: invalid parameter: "
                                  << "empty value";
                 }
+            } else if (action_name == "SetSchedulerPolicy") {
+                const std::map<std::string, int> POLICY_MAP = {
+                    {"SCHED_OTHER", SCHED_OTHER},
+                    {"SCHED_BATCH", SCHED_BATCH},
+                    {"SCHED_IDLE", SCHED_IDLE},
+                    {"SCHED_FIFO", SCHED_FIFO},
+                    {"SCHED_RR", SCHED_RR},
+                };
+                const std::string policy_str = params_val["Policy"].asString();
+
+                const auto it = POLICY_MAP.find(policy_str);
+                if (it == POLICY_MAP.end()) {
+                    LOG(WARNING) << "SetSchedulerPolicy: invalid policy " << policy_str;
+                    continue;
+                }
+
+                const int policy = it->second;
+
+                if (SetSchedulerPolicyAction::isNormalPolicy(policy)) {
+                    if (params_val.isMember("Priority")) {
+                        LOG(WARNING) << "SetSchedulerPolicy: Normal policies (" << policy_str
+                                     << ") use Nice values, not Priority values";
+                    }
+
+                    if (params_val.isMember("Nice")) {
+                        // If present, this optional value will be passed in an additional syscall
+                        // to setpriority(), since the sched_priority value must be 0 for calls to
+                        // sched_setscheduler() with "normal" policies.
+                        const int nice = params_val["Nice"].asInt();
+
+                        const int LINUX_MIN_NICE = -20;
+                        const int LINUX_MAX_NICE = 19;
+                        if (nice < LINUX_MIN_NICE || nice > LINUX_MAX_NICE) {
+                            LOG(WARNING) << "SetSchedulerPolicy: Provided nice (" << nice
+                                         << ") appears out of range.";
+                        }
+                        profile->Add(std::make_unique<SetSchedulerPolicyAction>(policy, nice));
+                    } else {
+                        profile->Add(std::make_unique<SetSchedulerPolicyAction>(policy));
+                    }
+                } else {
+                    if (params_val.isMember("Nice")) {
+                        LOG(WARNING) << "SetSchedulerPolicy: Real-time policies (" << policy_str
+                                     << ") use Priority values, not Nice values";
+                    }
+
+                    // This is a "virtual priority" as described by `man 2 sched_get_priority_min`
+                    // that will be mapped onto the following range for the provided policy:
+                    // [sched_get_priority_min(), sched_get_priority_max()]
+                    const int virtual_priority = params_val["Priority"].asInt();
+
+                    int priority;
+                    if (SetSchedulerPolicyAction::toPriority(policy, virtual_priority, priority)) {
+                        profile->Add(std::make_unique<SetSchedulerPolicyAction>(policy, priority));
+                    }
+                }
             } else {
                 LOG(WARNING) << "Unknown profile action: " << action_name;
             }
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index abb3ca5..d0b5043 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -21,6 +21,7 @@
 #include <map>
 #include <memory>
 #include <mutex>
+#include <optional>
 #include <span>
 #include <string>
 #include <string_view>
@@ -77,7 +78,7 @@
 
     // Default implementations will fail
     virtual bool ExecuteForProcess(uid_t, pid_t) const { return false; }
-    virtual bool ExecuteForTask(int) const { return false; }
+    virtual bool ExecuteForTask(pid_t) const { return false; }
     virtual bool ExecuteForUID(uid_t) const { return false; }
 
     virtual void EnableResourceCaching(ResourceCacheType) {}
@@ -90,19 +91,6 @@
 };
 
 // Profile actions
-class SetClampsAction : public ProfileAction {
-  public:
-    SetClampsAction(int boost, int clamp) noexcept : boost_(boost), clamp_(clamp) {}
-
-    const char* Name() const override { return "SetClamps"; }
-    bool ExecuteForProcess(uid_t uid, pid_t pid) const override;
-    bool ExecuteForTask(pid_t tid) const override;
-
-  protected:
-    int boost_;
-    int clamp_;
-};
-
 class SetTimerSlackAction : public ProfileAction {
   public:
     SetTimerSlackAction(unsigned long slack) noexcept : slack_(slack) {}
@@ -114,8 +102,6 @@
 
   private:
     unsigned long slack_;
-
-    static bool IsTimerSlackSupported(pid_t tid);
 };
 
 // Set attribute profile element
@@ -189,6 +175,25 @@
     CacheUseResult UseCachedFd(ResourceCacheType cache_type, const std::string& value) const;
 };
 
+// Set scheduler policy action
+class SetSchedulerPolicyAction : public ProfileAction {
+  public:
+    SetSchedulerPolicyAction(int policy)
+        : policy_(policy) {}
+    SetSchedulerPolicyAction(int policy, int priority_or_nice)
+        : policy_(policy), priority_or_nice_(priority_or_nice) {}
+
+    const char* Name() const override { return "SetSchedulerPolicy"; }
+    bool ExecuteForTask(pid_t tid) const override;
+
+    static bool isNormalPolicy(int policy);
+    static bool toPriority(int policy, int virtual_priority, int& priority_out);
+
+  private:
+    int policy_;
+    std::optional<int> priority_or_nice_;
+};
+
 class TaskProfile {
   public:
     TaskProfile(const std::string& name) : name_(name), res_cached_(false) {}
diff --git a/libutils/binder/RefBase.cpp b/libutils/binder/RefBase.cpp
index 2d2e40b..4291f1e 100644
--- a/libutils/binder/RefBase.cpp
+++ b/libutils/binder/RefBase.cpp
@@ -787,7 +787,7 @@
             // sp<T>(T*) constructor, assuming that if the object is around, it is already
             // owned by an sp<>.
             ALOGW("RefBase: Explicit destruction, weak count = %d (in %p). Use sp<> to manage this "
-                  "object.",
+                  "object. Note - if weak count is 0, this leaks mRefs (weakref_impl).",
                   mRefs->mWeak.load(), this);
 
 #if ANDROID_UTILS_CALLSTACK_ENABLED
diff --git a/libutils/binder/VectorImpl.cpp b/libutils/binder/VectorImpl.cpp
index d951b8b..a62664f 100644
--- a/libutils/binder/VectorImpl.cpp
+++ b/libutils/binder/VectorImpl.cpp
@@ -463,7 +463,8 @@
     size_t new_size;
     LOG_ALWAYS_FATAL_IF(__builtin_sub_overflow(mCount, amount, &new_size));
 
-    if (new_size < (capacity() / 2)) {
+    const size_t prev_capacity = capacity();
+    if (new_size < (prev_capacity / 2) && prev_capacity > kMinVectorCapacity) {
         // NOTE: (new_size * 2) is safe because capacity didn't overflow and
         // new_size < (capacity / 2)).
         const size_t new_capacity = max(kMinVectorCapacity, new_size * 2);
diff --git a/libvendorsupport/include_llndk/android/llndk-versioning.h b/libvendorsupport/include_llndk/android/llndk-versioning.h
index 0402c28..81d165f 100644
--- a/libvendorsupport/include_llndk/android/llndk-versioning.h
+++ b/libvendorsupport/include_llndk/android/llndk-versioning.h
@@ -25,15 +25,15 @@
     __attribute__((annotate("introduced_in_llndk=" #vendor_api_level)))
 #endif
 
-#if defined(__ANDROID_VNDK__)
-
+#if defined(__ANDROID_VENDOR_API__)
+// __ANDROID_VENDOR_API__ is defined only for vendor or product variant modules.
 // Use this macro as an `if` statement to call an API that are available to both NDK and LLNDK.
-// This returns true for the vendor modules if the vendor_api_level is less than or equal to the
-// ro.board.api_level.
+// This returns true for vendor or product modules if the vendor_api_level is less than or equal to
+// the ro.board.api_level.
 #define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
     constexpr(__ANDROID_VENDOR_API__ >= vendor_api_level)
 
-#else  // __ANDROID_VNDK__
+#else  // __ANDROID_VENDOR_API__
 
 // For non-vendor modules, API_LEVEL_AT_LEAST is replaced with __builtin_available(sdk_api_level) to
 // guard the API for __INTRODUCED_IN.
@@ -42,4 +42,4 @@
     (__builtin_available(android sdk_api_level, *))
 #endif
 
-#endif  // __ANDROID_VNDK__
+#endif  // __ANDROID_VENDOR_API__
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 339f1be..12d9c43 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -112,37 +112,6 @@
     # Create socket dir for ot-daemon
     mkdir /dev/socket/ot-daemon 0770 thread_network thread_network
 
-    # Create energy-aware scheduler tuning nodes
-    mkdir /dev/stune/foreground
-    mkdir /dev/stune/background
-    mkdir /dev/stune/top-app
-    mkdir /dev/stune/rt
-    chown system system /dev/stune
-    chown system system /dev/stune/foreground
-    chown system system /dev/stune/background
-    chown system system /dev/stune/top-app
-    chown system system /dev/stune/rt
-    chown system system /dev/stune/tasks
-    chown system system /dev/stune/foreground/tasks
-    chown system system /dev/stune/background/tasks
-    chown system system /dev/stune/top-app/tasks
-    chown system system /dev/stune/rt/tasks
-    chown system system /dev/stune/cgroup.procs
-    chown system system /dev/stune/foreground/cgroup.procs
-    chown system system /dev/stune/background/cgroup.procs
-    chown system system /dev/stune/top-app/cgroup.procs
-    chown system system /dev/stune/rt/cgroup.procs
-    chmod 0664 /dev/stune/tasks
-    chmod 0664 /dev/stune/foreground/tasks
-    chmod 0664 /dev/stune/background/tasks
-    chmod 0664 /dev/stune/top-app/tasks
-    chmod 0664 /dev/stune/rt/tasks
-    chmod 0664 /dev/stune/cgroup.procs
-    chmod 0664 /dev/stune/foreground/cgroup.procs
-    chmod 0664 /dev/stune/background/cgroup.procs
-    chmod 0664 /dev/stune/top-app/cgroup.procs
-    chmod 0664 /dev/stune/rt/cgroup.procs
-
     # cpuctl hierarchy for devices using utilclamp
     mkdir /dev/cpuctl/foreground
     mkdir /dev/cpuctl/foreground_window
@@ -216,24 +185,6 @@
     chmod 0664 /dev/cpuctl/camera-daemon/tasks
     chmod 0664 /dev/cpuctl/camera-daemon/cgroup.procs
 
-    # Create an stune group for camera-specific processes
-    mkdir /dev/stune/camera-daemon
-    chown system system /dev/stune/camera-daemon
-    chown system system /dev/stune/camera-daemon/tasks
-    chown system system /dev/stune/camera-daemon/cgroup.procs
-    chmod 0664 /dev/stune/camera-daemon/tasks
-    chmod 0664 /dev/stune/camera-daemon/cgroup.procs
-
-    # Create an stune group for NNAPI HAL processes
-    mkdir /dev/stune/nnapi-hal
-    chown system system /dev/stune/nnapi-hal
-    chown system system /dev/stune/nnapi-hal/tasks
-    chown system system /dev/stune/nnapi-hal/cgroup.procs
-    chmod 0664 /dev/stune/nnapi-hal/tasks
-    chmod 0664 /dev/stune/nnapi-hal/cgroup.procs
-    write /dev/stune/nnapi-hal/schedtune.boost 1
-    write /dev/stune/nnapi-hal/schedtune.prefer_idle 1
-
     # Create blkio group and apply initial settings.
     # This feature needs kernel to support it, and the
     # device's init.rc must actually set the correct values.
@@ -644,6 +595,7 @@
     mkdir /metadata/ota 0750 root system
     mkdir /metadata/ota/snapshots 0750 root system
     mkdir /metadata/watchdog 0770 root system
+    mkdir /metadata/tradeinmode 0770 root system
 
     mkdir /metadata/apex 0700 root system
     mkdir /metadata/apex/sessions 0700 root system
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index d5893de..1f5c179 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -58,6 +58,7 @@
         "toolbox_vendor",
         "toybox_vendor",
     ],
+    vendor: true,
 }
 
 // shell and utilities for first stage console. The list of binaries are
diff --git a/trusty/libtrusty/tipc-test/tipc_test.c b/trusty/libtrusty/tipc-test/tipc_test.c
index 3cf0c05..121837d 100644
--- a/trusty/libtrusty/tipc-test/tipc_test.c
+++ b/trusty/libtrusty/tipc-test/tipc_test.c
@@ -67,7 +67,7 @@
 static const char* receiver_name = "com.android.trusty.memref.receiver";
 static const size_t memref_chunk_size = 4096;
 
-static const char* _sopts = "hsvDS:t:r:m:b:B:";
+static const char* _sopts = "hsvD:S:t:r:m:b:B:";
 /* clang-format off */
 static const struct option _lopts[] =  {
     {"help",    no_argument,       0, 'h'},