Snap for 12623742 from 6d1271340a21c42e3035fa4280090970a7c51c58 to 25Q1-release

Change-Id: I7d3f0b6522af87c62822e4c1ce30b62d9f2d0c4d
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 7d00195..aac4acb 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -39,6 +39,33 @@
      `device_id` is `uevent MINOR % 128 + 1`.
   3. All other devices are created as `/dev/<basename uevent DEVPATH>`
 
+Whether a device is considered a "boot device" is a bit complicated.
+
+ - The recommended way to specify the boot device is to provide the "partition UUID" containing the
+   kernel (or, really, any parition on the boot device) and then boot device is the block device
+   containing that partition. This is passed via `androidboot.boot_part_uuid` which can be provided
+   either via the kernel bootconfig or via the kernel commandline. As an example, you could set
+   `androidboot.boot_part_uuid=12345678-abcd-ef01-0234-6789abcdef01`.
+ - Though using `boot_part_uuid` is preferred, you can also specify the boot device via
+   `androidboot.boot_device` or `androidboot.boot_devices`. These can be passed via the kernel
+   bootconfig or the kernel command line. It is also possible to pass this via device tree by
+   creating a `boot_devices` property in the Android firmware node. In most cases the `boot_device`
+   is the sysfs path (without the `/sys/devices` or `/sys/devices/platform` prefix) to the closest
+   parent of the block device that's on the "platform" bus. As an example, if the block device is
+   `/sys/devices/platform/soc@0/7c4000.mmc/mmc_host/mmc1/mmc1:0001/block/mmcblk1` then the
+   `boot_device` is `soc@0/7c4000.mmc` since we strip off the `/sys/devices/platform` and nothing
+   past the `7c4000.mmc` directory represents a device on the "platform" bus. In the case that none
+   of the parents are on the "platform" bus there are special rules for block devices under PCI
+   and VBD (Virtual Block Device). NOTE: sysfs paths for block devices are not guaranteed to be
+   stable between kernel versions, which is one of the reasons why it is suggested to use
+   `boot_part_uuid` instead of `boot_devices`. ALSO NOTE: If more than one device matches (either
+   because multiple `boot_devices` were listed or because there was more than one block device
+   under the found sysfs directory) and these multiple matching devices provide some of the same
+   named partitions then the behavior is unspecified.
+ - There is a further fallback to determine "boot devices" via the vstab, but providing at least
+   `boot_devices` has been required since Android 12 so this further fallback will not be described
+   here.
+
 The permissions can be modified using a ueventd.rc script and a line that beings with `/dev`. These
 lines take the format of
 
diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp
index 8f52158..7f83037 100644
--- a/init/block_dev_initializer.cpp
+++ b/init/block_dev_initializer.cpp
@@ -33,7 +33,49 @@
     auto boot_devices = android::fs_mgr::GetBootDevices();
     device_handler_ = std::make_unique<DeviceHandler>(
             std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
-            std::move(boot_devices), false);
+            std::move(boot_devices), android::fs_mgr::GetBootPartUuid(), false);
+}
+
+// If boot_part_uuid is specified, use it to set boot_devices
+//
+// When `androidboot.boot_part_uuid` is specified then that's the partition UUID
+// of the kernel. Look for that partition and then set `boot_devices` to be
+// exactly one item: the block device containing that partition.
+//
+// NOTE that `boot_part_uuid` is only specified on newer devices. Older devices
+// specified `boot_devices` directly.
+bool BlockDevInitializer::InitBootDevicesFromPartUuid() {
+    bool uuid_check_done = false;
+
+    auto boot_part_callback = [&, this](const Uevent& uevent) -> ListenerAction {
+        uuid_check_done = device_handler_->CheckUeventForBootPartUuid(uevent);
+        return uuid_check_done ? ListenerAction::kStop : ListenerAction::kContinue;
+    };
+
+    // Re-run already arrived uevents looking for the boot partition UUID.
+    //
+    // NOTE: If we're not using the boot partition UUID to find the boot
+    // device then the first uevent we analyze will cause us to stop looking
+    // and set `uuid_check_done`. This will shortcut all of the UUID logic.
+    // Replaying one uevent is not expected to be slow.
+    uevent_listener_.RegenerateUevents(boot_part_callback);
+
+    // If we're not done looking, poll for uevents for longer
+    if (!uuid_check_done) {
+        Timer t;
+        uevent_listener_.Poll(boot_part_callback, 10s);
+        LOG(INFO) << "Wait for boot partition returned after " << t;
+    }
+
+    // Give a nicer error message if we were expecting to find the kernel boot
+    // partition but didn't. Later code would fail too but the message there
+    // is a bit further from the root cause of the problem.
+    if (!uuid_check_done) {
+        LOG(ERROR) << __PRETTY_FUNCTION__ << ": boot partition not found after polling timeout.";
+        return false;
+    }
+
+    return true;
 }
 
 bool BlockDevInitializer::InitDeviceMapper() {
@@ -98,11 +140,43 @@
 
     LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;
 
-    devices->erase(iter);
+    // Remove the partition from the list of partitions we're waiting for.
+    //
+    // Partitions that we're waiting for here are expected to be on the boot
+    // device, so only remove from the list if they're on the boot device.
+    // This prevents us from being confused if there are multiple disks (some
+    // perhaps connected via USB) that have matching partition names.
+    //
+    // ...but...
+    //
+    // Some products (especialy emulators) don't seem to set up boot_devices
+    // or possibly not all the partitions that we need to wait for are on the
+    // specified boot device. Thus, only require partitions to be on the boot
+    // device in "strict" mode, which should be used on newer systems.
+    if (device_handler_->IsBootDevice(uevent) || !device_handler_->IsBootDeviceStrict()) {
+        devices->erase(iter);
+    }
+
     device_handler_->HandleUevent(uevent);
     return devices->empty() ? ListenerAction::kStop : ListenerAction::kContinue;
 }
 
+// Wait for partitions that are expected to be on the "boot device" to initialize.
+//
+// Wait (for up to 10 seconds) for partitions passed in `devices` to show up.
+// All block devices found while waiting will be initialized, which includes
+// creating symlinks for them in /dev/block. Once all `devices` are found we'll
+// return success (true). If any devices aren't found we'll return failure
+// (false). As devices are found they will be removed from `devices`.
+//
+// The contents of `devices` is the names of the partitions. This can be:
+// - The `partition_name` reported by a uevent, or the final component in the
+//   `path` reported by a uevent if the `partition_name` is blank.
+// - The result of DeviceHandler::GetPartitionNameForDevice() on the
+//   `device_name` reported by a uevent.
+//
+// NOTE: on newer systems partitions _must_ be on the "boot device". See
+// comments inside HandleUevent().
 bool BlockDevInitializer::InitDevices(std::set<std::string> devices) {
     auto uevent_callback = [&, this](const Uevent& uevent) -> ListenerAction {
         return HandleUevent(uevent, &devices);
diff --git a/init/block_dev_initializer.h b/init/block_dev_initializer.h
index cb1d365..25107c9 100644
--- a/init/block_dev_initializer.h
+++ b/init/block_dev_initializer.h
@@ -29,6 +29,7 @@
   public:
     BlockDevInitializer();
 
+    bool InitBootDevicesFromPartUuid();
     bool InitDeviceMapper();
     bool InitDmUser(const std::string& name);
     bool InitDevices(std::set<std::string> devices);
diff --git a/init/devices.cpp b/init/devices.cpp
index 0af843f..4de1e20 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -45,6 +45,7 @@
 using namespace std::chrono_literals;
 
 using android::base::Basename;
+using android::base::ConsumePrefix;
 using android::base::Dirname;
 using android::base::ReadFileToString;
 using android::base::Readlink;
@@ -188,6 +189,52 @@
     }
 }
 
+BlockDeviceInfo DeviceHandler::GetBlockDeviceInfo(const std::string& uevent_path) const {
+    BlockDeviceInfo info;
+
+    if (!boot_part_uuid_.empty()) {
+        // Only use the more specific "MMC" or "SCSI" match if a partition UUID
+        // was passed. Old bootloaders that aren't passing the partition UUID
+        // instead pass the path to the closest "platform" device. It would
+        // break them if we chose this deeper (more specific) path.
+        //
+        // When we have a UUID we _want_ the more specific path since it can
+        // handle, for instance, differentiating two USB disks that are on
+        // the same USB controller. Using the closest platform device would
+        // classify them both the same by using the path to the USB controller.
+        if (FindMmcDevice(uevent_path, &info.str)) {
+            info.type = "mmc";
+        } else if (FindScsiDevice(uevent_path, &info.str)) {
+            info.type = "scsi";
+        }
+    } else if (FindPlatformDevice(uevent_path, &info.str)) {
+        info.type = "platform";
+    } else if (FindPciDevicePrefix(uevent_path, &info.str)) {
+        info.type = "pci";
+    } else if (FindVbdDevicePrefix(uevent_path, &info.str)) {
+        info.type = "vbd";
+    } else {
+        // Re-clear device to be extra certain in case one of the FindXXX()
+        // functions returned false but still modified it.
+        info.str = "";
+    }
+
+    info.is_boot_device = boot_devices_.find(info.str) != boot_devices_.end();
+
+    return info;
+}
+
+bool DeviceHandler::IsBootDeviceStrict() const {
+    // When using the newer "boot_part_uuid" to specify the boot device then
+    // we require all core system partitions to be on the boot device.
+    return !boot_part_uuid_.empty();
+}
+
+bool DeviceHandler::IsBootDevice(const Uevent& uevent) const {
+    auto device = GetBlockDeviceInfo(uevent.path);
+    return device.is_boot_device;
+}
+
 std::string DeviceHandler::GetPartitionNameForDevice(const std::string& query_device) {
     static const auto partition_map = [] {
         std::vector<std::pair<std::string, std::string>> partition_map;
@@ -218,11 +265,12 @@
     return {};
 }
 
-// Given a path that may start with a platform device, find the parent platform device by finding a
-// parent directory with a 'subsystem' symlink that points to the platform bus.
-// If it doesn't start with a platform device, return false
-bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_device_path) const {
-    platform_device_path->clear();
+// Given a path to a device that may have a parent in the passed set of
+// subsystems, find the parent device that's in the passed set of subsystems.
+// If we don't find a parent in the passed set of subsystems, return false.
+bool DeviceHandler::FindSubsystemDevice(std::string path, std::string* device_path,
+                                        const std::set<std::string>& subsystem_paths) const {
+    device_path->clear();
 
     // Uevents don't contain the mount point, so we need to add it here.
     path.insert(0, sysfs_mount_point_);
@@ -232,11 +280,20 @@
     while (directory != "/" && directory != ".") {
         std::string subsystem_link_path;
         if (Realpath(directory + "/subsystem", &subsystem_link_path) &&
-            (subsystem_link_path == sysfs_mount_point_ + "/bus/platform" ||
-             subsystem_link_path == sysfs_mount_point_ + "/bus/amba")) {
+            subsystem_paths.find(subsystem_link_path) != subsystem_paths.end()) {
             // We need to remove the mount point that we added above before returning.
             directory.erase(0, sysfs_mount_point_.size());
-            *platform_device_path = directory;
+
+            // Skip /devices/platform or /devices/ if present
+            static constexpr std::string_view devices_platform_prefix = "/devices/platform/";
+            static constexpr std::string_view devices_prefix = "/devices/";
+            std::string_view sv = directory;
+
+            if (!ConsumePrefix(&sv, devices_platform_prefix)) {
+                ConsumePrefix(&sv, devices_prefix);
+            }
+            *device_path = sv;
+
             return true;
         }
 
@@ -250,6 +307,31 @@
     return false;
 }
 
+bool DeviceHandler::FindPlatformDevice(std::string path, std::string* platform_device_path) const {
+    const std::set<std::string> subsystem_paths = {
+            sysfs_mount_point_ + "/bus/platform",
+            sysfs_mount_point_ + "/bus/amba",
+    };
+
+    return FindSubsystemDevice(path, platform_device_path, subsystem_paths);
+}
+
+bool DeviceHandler::FindMmcDevice(std::string path, std::string* mmc_device_path) const {
+    const std::set<std::string> subsystem_paths = {
+            sysfs_mount_point_ + "/bus/mmc",
+    };
+
+    return FindSubsystemDevice(path, mmc_device_path, subsystem_paths);
+}
+
+bool DeviceHandler::FindScsiDevice(std::string path, std::string* scsi_device_path) const {
+    const std::set<std::string> subsystem_paths = {
+            sysfs_mount_point_ + "/bus/scsi",
+    };
+
+    return FindSubsystemDevice(path, scsi_device_path, subsystem_paths);
+}
+
 void DeviceHandler::FixupSysPermissions(const std::string& upath,
                                         const std::string& subsystem) const {
     // upaths omit the "/sys" that paths in this list
@@ -371,8 +453,7 @@
 }
 
 std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uevent) const {
-    std::string device;
-    std::string type;
+    BlockDeviceInfo info;
     std::string partition;
     std::string uuid;
 
@@ -382,33 +463,20 @@
             symlinks.emplace_back("/dev/block/mapper/by-uuid/" + uuid);
         }
         return symlinks;
-    } else if (FindPlatformDevice(uevent.path, &device)) {
-        // Skip /devices/platform or /devices/ if present
-        static constexpr std::string_view devices_platform_prefix = "/devices/platform/";
-        static constexpr std::string_view devices_prefix = "/devices/";
+    }
 
-        if (StartsWith(device, devices_platform_prefix)) {
-            device = device.substr(devices_platform_prefix.length());
-        } else if (StartsWith(device, devices_prefix)) {
-            device = device.substr(devices_prefix.length());
-        }
+    info = GetBlockDeviceInfo(uevent.path);
 
-        type = "platform";
-    } else if (FindPciDevicePrefix(uevent.path, &device)) {
-        type = "pci";
-    } else if (FindVbdDevicePrefix(uevent.path, &device)) {
-        type = "vbd";
-    } else {
+    if (info.type.empty()) {
         return {};
     }
 
     std::vector<std::string> links;
 
-    LOG(VERBOSE) << "found " << type << " device " << device;
+    LOG(VERBOSE) << "found " << info.type << " device " << info.str;
 
-    auto link_path = "/dev/block/" + type + "/" + device;
+    auto link_path = "/dev/block/" + info.type + "/" + info.str;
 
-    bool is_boot_device = boot_devices_.find(device) != boot_devices_.end();
     if (!uevent.partition_name.empty()) {
         std::string partition_name_sanitized(uevent.partition_name);
         SanitizePartitionName(&partition_name_sanitized);
@@ -418,10 +486,10 @@
         }
         links.emplace_back(link_path + "/by-name/" + partition_name_sanitized);
         // Adds symlink: /dev/block/by-name/<partition_name>.
-        if (is_boot_device) {
+        if (info.is_boot_device) {
             links.emplace_back("/dev/block/by-name/" + partition_name_sanitized);
         }
-    } else if (is_boot_device) {
+    } else if (info.is_boot_device) {
         // If we don't have a partition name but we are a partition on a boot device, create a
         // symlink of /dev/block/by-name/<device_name> for symmetry.
         links.emplace_back("/dev/block/by-name/" + uevent.device_name);
@@ -541,6 +609,48 @@
     }
 }
 
+// Check Uevents looking for the kernel's boot partition UUID
+//
+// When we can stop checking uevents (either because we're done or because
+// we weren't looking for the kernel's boot partition UUID) then return
+// true. Return false if we're not done yet.
+bool DeviceHandler::CheckUeventForBootPartUuid(const Uevent& uevent) {
+    // If we aren't using boot_part_uuid then we're done.
+    if (boot_part_uuid_.empty()) {
+        return true;
+    }
+
+    // Finding the boot partition is a one-time thing that we do at init
+    // time, not steady state. This is because the boot partition isn't
+    // allowed to go away or change. Once we found the boot partition we don't
+    // expect to run again.
+    if (found_boot_part_uuid_) {
+        LOG(WARNING) << __PRETTY_FUNCTION__
+                     << " shouldn't run after kernel boot partition is found";
+        return true;
+    }
+
+    // We only need to look at newly-added block devices. Note that if someone
+    // is replaying events all existing devices will get "add"ed.
+    if (uevent.subsystem != "block" || uevent.action != "add") {
+        return false;
+    }
+
+    // If it's not the partition we care about then move on.
+    if (uevent.partition_uuid != boot_part_uuid_) {
+        return false;
+    }
+
+    auto device = GetBlockDeviceInfo(uevent.path);
+
+    LOG(INFO) << "Boot device " << device.str << " found via partition UUID";
+    found_boot_part_uuid_ = true;
+    boot_devices_.clear();
+    boot_devices_.insert(device.str);
+
+    return true;
+}
+
 void DeviceHandler::HandleUevent(const Uevent& uevent) {
     if (uevent.action == "add" || uevent.action == "change" || uevent.action == "bind" ||
         uevent.action == "online") {
@@ -603,17 +713,25 @@
 DeviceHandler::DeviceHandler(std::vector<Permissions> dev_permissions,
                              std::vector<SysfsPermissions> sysfs_permissions,
                              std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
-                             bool skip_restorecon)
+                             std::string boot_part_uuid, bool skip_restorecon)
     : dev_permissions_(std::move(dev_permissions)),
       sysfs_permissions_(std::move(sysfs_permissions)),
       subsystems_(std::move(subsystems)),
       boot_devices_(std::move(boot_devices)),
+      boot_part_uuid_(boot_part_uuid),
       skip_restorecon_(skip_restorecon),
-      sysfs_mount_point_("/sys") {}
+      sysfs_mount_point_("/sys") {
+    // If both a boot partition UUID and a list of boot devices are
+    // specified then we ignore the boot_devices in favor of boot_part_uuid.
+    if (boot_devices_.size() && !boot_part_uuid.empty()) {
+        LOG(WARNING) << "Both boot_devices and boot_part_uuid provided; ignoring bootdevices";
+        boot_devices_.clear();
+    }
+}
 
 DeviceHandler::DeviceHandler()
     : DeviceHandler(std::vector<Permissions>{}, std::vector<SysfsPermissions>{},
-                    std::vector<Subsystem>{}, std::set<std::string>{}, false) {}
+                    std::vector<Subsystem>{}, std::set<std::string>{}, "", false) {}
 
 }  // namespace init
 }  // namespace android
diff --git a/init/devices.h b/init/devices.h
index 6da1232..8b6cf6c 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -116,16 +116,24 @@
     std::string dir_name_ = "/dev";
 };
 
+struct BlockDeviceInfo {
+    std::string str;
+    std::string type;
+    bool is_boot_device;
+};
+
 class DeviceHandler : public UeventHandler {
   public:
     friend class DeviceHandlerTester;
 
     DeviceHandler();
     DeviceHandler(std::vector<Permissions> dev_permissions,
-                  std::vector<SysfsPermissions> sysfs_permissions, std::vector<Subsystem> subsystems,
-                  std::set<std::string> boot_devices, bool skip_restorecon);
+                  std::vector<SysfsPermissions> sysfs_permissions,
+                  std::vector<Subsystem> subsystems, std::set<std::string> boot_devices,
+                  std::string boot_part_uuid, bool skip_restorecon);
     virtual ~DeviceHandler() = default;
 
+    bool CheckUeventForBootPartUuid(const Uevent& uevent);
     void HandleUevent(const Uevent& uevent) override;
 
     // `androidboot.partition_map` allows associating a partition name for a raw block device
@@ -133,10 +141,17 @@
     // `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
     // `userdata`.
     static std::string GetPartitionNameForDevice(const std::string& device);
+    bool IsBootDeviceStrict() const;
+    bool IsBootDevice(const Uevent& uevent) const;
 
   private:
     void ColdbootDone() override;
+    BlockDeviceInfo GetBlockDeviceInfo(const std::string& uevent_path) const;
+    bool FindSubsystemDevice(std::string path, std::string* device_path,
+                             const std::set<std::string>& subsystem_paths) const;
     bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
+    bool FindMmcDevice(std::string path, std::string* mmc_device_path) const;
+    bool FindScsiDevice(std::string path, std::string* scsi_device_path) const;
     std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(
         const std::string& path, const std::vector<std::string>& links) const;
     void MakeDevice(const std::string& path, bool block, int major, int minor,
@@ -151,6 +166,8 @@
     std::vector<SysfsPermissions> sysfs_permissions_;
     std::vector<Subsystem> subsystems_;
     std::set<std::string> boot_devices_;
+    std::string boot_part_uuid_;
+    bool found_boot_part_uuid_;
     bool skip_restorecon_;
     std::string sysfs_mount_point_;
 };
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 4f1af30..aa6b551 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -288,6 +288,10 @@
 }
 
 bool FirstStageMountVBootV2::InitDevices() {
+    if (!block_dev_init_.InitBootDevicesFromPartUuid()) {
+        return false;
+    }
+
     std::set<std::string> devices;
     GetSuperDeviceName(&devices);
 
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 3f0d0e9..286e472 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -353,10 +353,25 @@
 
     auto ueventd_configuration = GetConfiguration();
 
-    uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
+    UeventListener uevent_listener(ueventd_configuration.uevent_socket_rcvbuf_size);
+
+    // Right after making DeviceHandler, replay all events looking for which
+    // block device has the boot partition. This lets us make symlinks
+    // for all of the other partitions on the same disk. Note that by the time
+    // we get here we know that the boot partition has already shown up (if
+    // we're looking for it) so just regenerating events is enough to know
+    // we'll see it.
+    std::unique_ptr<DeviceHandler> device_handler = std::make_unique<DeviceHandler>(
             std::move(ueventd_configuration.dev_permissions),
             std::move(ueventd_configuration.sysfs_permissions),
-            std::move(ueventd_configuration.subsystems), android::fs_mgr::GetBootDevices(), true));
+            std::move(ueventd_configuration.subsystems), android::fs_mgr::GetBootDevices(),
+            android::fs_mgr::GetBootPartUuid(), true);
+    uevent_listener.RegenerateUevents([&](const Uevent& uevent) -> ListenerAction {
+        bool uuid_check_done = device_handler->CheckUeventForBootPartUuid(uevent);
+        return uuid_check_done ? ListenerAction::kStop : ListenerAction::kContinue;
+    });
+
+    uevent_handlers.emplace_back(std::move(device_handler));
     uevent_handlers.emplace_back(std::make_unique<FirmwareHandler>(
             std::move(ueventd_configuration.firmware_directories),
             std::move(ueventd_configuration.external_firmware_handlers)));
@@ -365,8 +380,6 @@
         std::vector<std::string> base_paths = {"/odm/lib/modules", "/vendor/lib/modules"};
         uevent_handlers.emplace_back(std::make_unique<ModaliasHandler>(base_paths));
     }
-    UeventListener uevent_listener(ueventd_configuration.uevent_socket_rcvbuf_size);
-
     if (!android::base::GetBoolProperty(kColdBootDoneProp, false)) {
         ColdBoot cold_boot(uevent_listener, uevent_handlers,
                            ueventd_configuration.enable_parallel_restorecon,
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index d61939f..feda3b4 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -203,19 +203,6 @@
       ]
     },
     {
-      "Name": "RealTimeInputScheduling",
-      "Actions": [
-        {
-          "Name": "SetSchedulerPolicy",
-          "Params":
-          {
-            "Policy": "SCHED_FIFO",
-            "Priority": "98"
-          }
-        }
-      ]
-    },
-    {
       "Name": "CameraServicePerformance",
       "Actions": [
         {
@@ -717,7 +704,7 @@
     },
     {
       "Name": "InputPolicy",
-      "Profiles": [ "RealTimeInputScheduling", "MaxPerformance", "ProcessCapacityMax", "TimerSlackNormal" ]
+      "Profiles": [ "MaxPerformance", "ProcessCapacityMax", "TimerSlackNormal" ]
     }
   ]
 }