Use SetFeatureFlagsForUser when applying flags.

On Chrome OS, Chrome asks session_manager to apply feature flags on
restart. Previously the flags would be passed as raw command line
switches, but session_manager now maintains a separate set of feature
flags that it passes in encoded form in a command line switch. This
change adjusts Chrome to make use of that facility and deletes a bunch
of support code for the legacy Chrome OS approach.

BUG=chromium:1073940
TEST=Existing tests (e.g. SiteIsolationFlagHandlingTest), additional manual testing

Change-Id: I311960e2fad45136b3cc14a1fc99581b0d2d9001
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2762738
Reviewed-by: Xiyuan Xia <[email protected]>
Reviewed-by: Marc Treib <[email protected]>
Reviewed-by: Alexei Svitkine <[email protected]>
Commit-Queue: Mattias Nissler <[email protected]>
Cr-Commit-Position: refs/heads/master@{#865178}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 3ed8bdf..4517f72 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1656,6 +1656,7 @@
     "signin/signin_promo_util.h",
     "signin/signin_util.cc",
     "signin/signin_util.h",
+    "site_isolation/about_flags.h",
     "site_isolation/prefs_observer.cc",
     "site_isolation/prefs_observer.h",
     "site_isolation/site_details.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 4e3953a..7258887c 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -53,6 +53,7 @@
 #include "chrome/browser/sharing/shared_clipboard/feature_flags.h"
 #include "chrome/browser/sharing/sms/sms_flags.h"
 #include "chrome/browser/signin/signin_features.h"
+#include "chrome/browser/site_isolation/about_flags.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/unexpire_flags.h"
 #include "chrome/browser/unexpire_flags_gen.h"
@@ -3462,7 +3463,7 @@
     {"isolate-origins", flag_descriptions::kIsolateOriginsName,
      flag_descriptions::kIsolateOriginsDescription, kOsAll,
      ORIGIN_LIST_VALUE_TYPE(switches::kIsolateOrigins, "")},
-    {"site-isolation-trial-opt-out",
+    {about_flags::kSiteIsolationTrialOptOutInternalName,
      flag_descriptions::kSiteIsolationOptOutName,
      flag_descriptions::kSiteIsolationOptOutDescription, kOsAll,
      MULTI_VALUE_TYPE(kSiteIsolationOptOutChoices)},
@@ -7366,24 +7367,6 @@
       ->RegisterAllFeatureVariationParameters(flags_storage, feature_list);
 }
 
-bool AreSwitchesIdenticalToCurrentCommandLine(
-    const base::CommandLine& new_cmdline,
-    const base::CommandLine& active_cmdline,
-    std::set<base::CommandLine::StringType>* out_difference) {
-  const char* extra_flag_sentinel_begin_flag_name = nullptr;
-  const char* extra_flag_sentinel_end_flag_name = nullptr;
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Put the flags between --policy-switches--begin and --policy-switches-end on
-  // ChromeOS.
-  extra_flag_sentinel_begin_flag_name =
-      chromeos::switches::kPolicySwitchesBegin;
-  extra_flag_sentinel_end_flag_name = chromeos::switches::kPolicySwitchesEnd;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-  return flags_ui::FlagsState::AreSwitchesIdenticalToCurrentCommandLine(
-      new_cmdline, active_cmdline, out_difference,
-      extra_flag_sentinel_begin_flag_name, extra_flag_sentinel_end_flag_name);
-}
-
 void GetFlagFeatureEntries(flags_ui::FlagsStorage* flags_storage,
                            flags_ui::FlagAccess access,
                            base::ListValue* supported_entries,
@@ -7436,13 +7419,13 @@
   FlagsStateSingleton::GetFlagsState()->ResetAllFlags(flags_storage);
 }
 
-void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage) {
+void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage,
+                         const std::string& histogram_name) {
   std::set<std::string> switches;
   std::set<std::string> features;
   FlagsStateSingleton::GetFlagsState()->GetSwitchesAndFeaturesFromFlags(
       flags_storage, &switches, &features);
-  flags_ui::ReportAboutFlagsHistogram("Launch.FlagsAtStartup", switches,
-                                      features);
+  flags_ui::ReportAboutFlagsHistogram(histogram_name, switches, features);
 }
 
 namespace testing {
diff --git a/chrome/browser/about_flags.h b/chrome/browser/about_flags.h
index b3fc382..db89eaca 100644
--- a/chrome/browser/about_flags.h
+++ b/chrome/browser/about_flags.h
@@ -49,15 +49,6 @@
     flags_ui::FlagsStorage* flags_storage,
     base::FeatureList* feature_list);
 
-// Compares a set of switches of the two provided command line objects and
-// returns true if they are the same and false otherwise.
-// If |out_difference| is not NULL, it's filled with set_symmetric_difference
-// between sets.
-bool AreSwitchesIdenticalToCurrentCommandLine(
-    const base::CommandLine& new_cmdline,
-    const base::CommandLine& active_cmdline,
-    std::set<base::CommandLine::StringType>* out_difference);
-
 // Gets the list of feature entries. Entries that are available for the current
 // platform are appended to |supported_entries|; all other entries are appended
 // to |unsupported_entries|.
@@ -107,7 +98,8 @@
 
 // Sends UMA stats about experimental flag usage. This should be called once per
 // startup.
-void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage);
+void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage,
+                         const std::string& histogram_name);
 
 namespace testing {
 
diff --git a/chrome/browser/ash/app_mode/kiosk_app_manager.cc b/chrome/browser/ash/app_mode/kiosk_app_manager.cc
index 73f7b65..5248333 100644
--- a/chrome/browser/ash/app_mode/kiosk_app_manager.cc
+++ b/chrome/browser/ash/app_mode/kiosk_app_manager.cc
@@ -225,7 +225,7 @@
     chromeos::UserSessionManager::GetInstance()->SetSwitchesForUser(
         user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
         chromeos::UserSessionManager::CommandLineSwitchesType::
-            kPolicyAndFlagsAndKioskControl,
+            kPolicyAndKioskControl,
         flags);
   }
 
diff --git a/chrome/browser/ash/login/guest_login_browsertest.cc b/chrome/browser/ash/login/guest_login_browsertest.cc
index 38232ddd..b6ff951 100644
--- a/chrome/browser/ash/login/guest_login_browsertest.cc
+++ b/chrome/browser/ash/login/guest_login_browsertest.cc
@@ -4,14 +4,17 @@
 
 #include "ash/public/cpp/keyboard/keyboard_controller.h"
 #include "ash/public/cpp/login_screen_test_api.h"
+#include "chrome/browser/about_flags.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
+#include "components/flags_ui/feature_entry_macros.h"
 #include "components/user_manager/user_manager.h"
 #include "content/public/test/browser_test.h"
+#include "third_party/cros_system_api/switches/chrome_switches.h"
 
 namespace chromeos {
 
@@ -42,15 +45,22 @@
 
 class GuestLoginWithLoginSwitchesTest : public GuestLoginTest {
  public:
-  GuestLoginWithLoginSwitchesTest() = default;
+  GuestLoginWithLoginSwitchesTest()
+      : scoped_feature_entries_({{"feature-name", "name-1", "description-1", -1,
+                                  SINGLE_VALUE_TYPE("feature-switch")}}) {}
   ~GuestLoginWithLoginSwitchesTest() override = default;
 
   // GuestLoginTest:
   void SetDefaultLoginSwitches() override {
     login_manager_.SetDefaultLoginSwitches(
-        {std::make_pair("test_switch_1", ""),
+        {std::make_pair(chromeos::switches::kFeatureFlags,
+                        "[\"feature-name\"]"),
+         std::make_pair("test_switch_1", ""),
          std::make_pair("test_switch_2", "test_switch_2_value")});
   }
+
+ private:
+  about_flags::testing::ScopedFeatureEntries scoped_feature_entries_;
 };
 
 IN_PROC_BROWSER_TEST_F(GuestLoginTest, PRE_Login) {
@@ -129,6 +139,8 @@
   FakeSessionManagerClient::Get()->set_restart_job_callback(
       restart_job_waiter.QuitClosure());
 
+  EXPECT_TRUE(
+      base::CommandLine::ForCurrentProcess()->HasSwitch("feature-switch"));
   ASSERT_TRUE(ash::LoginScreenTestApi::ClickGuestButton());
 
   restart_job_waiter.Run();
@@ -143,6 +155,8 @@
   EXPECT_TRUE(user_manager->IsLoggedInAsGuest());
 
   EXPECT_FALSE(
+      base::CommandLine::ForCurrentProcess()->HasSwitch("feature-switch"));
+  EXPECT_FALSE(
       base::CommandLine::ForCurrentProcess()->HasSwitch("test_switch_1"));
   EXPECT_FALSE(
       base::CommandLine::ForCurrentProcess()->HasSwitch("test_switch_2"));
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc
index ff87891e..ee53d25 100644
--- a/chrome/browser/ash/login/session/user_session_manager.cc
+++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -67,6 +67,7 @@
 #include "chrome/browser/ash/login/wizard_controller.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/settings/cros_settings.h"
+#include "chrome/browser/ash/settings/owner_flags_storage.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part_chromeos.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -96,6 +97,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/site_isolation/about_flags.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service.h"
 #include "chrome/browser/supervised_user/child_accounts/child_account_service_factory.h"
 #include "chrome/browser/sync/profile_sync_service_factory.h"
@@ -280,36 +282,6 @@
   prefs->SetBoolean(::prefs::kLanguageShouldMergeInputMethods, true);
 }
 
-// Returns new CommandLine with per-user flags.
-base::CommandLine CreatePerSessionCommandLine(Profile* profile) {
-  base::CommandLine user_flags(base::CommandLine::NO_PROGRAM);
-  flags_ui::PrefServiceFlagsStorage flags_storage(profile->GetPrefs());
-  about_flags::ConvertFlagsToSwitches(&flags_storage, &user_flags,
-                                      flags_ui::kAddSentinels);
-
-  UserSessionManager::ApplyUserPolicyToSwitches(profile->GetPrefs(),
-                                                &user_flags);
-
-  return user_flags;
-}
-
-// Returns true if restart is needed to apply per-session flags.
-bool NeedRestartToApplyPerSessionFlags(
-    const base::CommandLine& user_flags,
-    std::set<base::CommandLine::StringType>* out_command_line_difference) {
-  // Don't restart browser if it is not first profile in session.
-  if (user_manager::UserManager::Get()->GetLoggedInUsers().size() != 1)
-    return false;
-
-  auto* current_command_line = base::CommandLine::ForCurrentProcess();
-  if (about_flags::AreSwitchesIdenticalToCurrentCommandLine(
-          user_flags, *current_command_line, out_command_line_difference)) {
-    return false;
-  }
-
-  return true;
-}
-
 bool CanPerformEarlyRestart() {
   const ExistingUserController* controller =
       ExistingUserController::current_controller();
@@ -331,13 +303,15 @@
   return true;
 }
 
-void LogCustomSwitches(const std::set<std::string>& switches) {
-  if (!VLOG_IS_ON(1))
-    return;
-  for (std::set<std::string>::const_iterator it = switches.begin();
-       it != switches.end(); ++it) {
-    VLOG(1) << "Switch leading to restart: '" << *it << "'";
+void LogCustomFeatureFlags(const std::set<std::string>& feature_flags) {
+  if (VLOG_IS_ON(1)) {
+    for (const auto& feature_flag : feature_flags) {
+      VLOG(1) << "Feature flag leading to restart: '" << feature_flag << "'";
+    }
   }
+
+  ash::about_flags::ReadOnlyFlagsStorage flags_storage(feature_flags);
+  ::about_flags::RecordUMAStatistics(&flags_storage, "Login.CustomFlags");
 }
 
 // Calls the real AttemptRestart method. This is used to avoid taking a function
@@ -448,9 +422,8 @@
 }
 
 // static
-void UserSessionManager::ApplyUserPolicyToSwitches(
-    PrefService* user_profile_prefs,
-    base::CommandLine* user_flags) {
+void UserSessionManager::ApplyUserPolicyToFlags(PrefService* user_profile_prefs,
+                                                std::set<std::string>* flags) {
   // Get target value for --site-per-process for the user session according to
   // policy. If it is supposed to be enabled, make sure it can not be disabled
   // using flags-induced command-line switches.
@@ -458,17 +431,8 @@
       user_profile_prefs->FindPreference(::prefs::kSitePerProcess);
   if (site_per_process_pref->IsManaged() &&
       site_per_process_pref->GetValue()->GetBool()) {
-    user_flags->RemoveSwitch(::switches::kDisableSiteIsolation);
+    flags->erase(::about_flags::SiteIsolationTrialOptOutChoiceEnabled());
   }
-
-  // Note: If a user policy is introduced again which translates to command-line
-  // switches, make sure to wrap the policy-added command-line switches in
-  // `"--policy-switches-begin"` / `"--policy-switches-end"` sentinels.
-  // This is important, because only command-line switches between the
-  // `"--policy-switches-begin"` / `"--policy-switches-end"` and the
-  // `"--flag-switches-begin"` / `"--flag-switches-end"` sentinels will be
-  // compared when comparing the current command line and the user session
-  // command line in order to decide if chrome should be restarted.
 }
 
 UserSessionManager::UserSessionManager()
@@ -585,19 +549,10 @@
   // the guest profile session flags will not match the current command line and
   // another restart will be attempted in order to reset the user flags for the
   // guest user.
-  const base::CommandLine user_flags(base::CommandLine::NO_PROGRAM);
-  if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine(
-          user_flags, *base::CommandLine::ForCurrentProcess(), NULL)) {
-    SessionManagerClient::Get()->SetFeatureFlagsForUser(
-        cryptohome::CreateAccountIdentifierFromAccountId(
-            user_manager::GuestAccountId()),
-        {});
-
-    SessionManagerClient::Get()->SetFlagsForUser(
-        cryptohome::CreateAccountIdentifierFromAccountId(
-            user_manager::GuestAccountId()),
-        base::CommandLine::StringVector());
-  }
+  SessionManagerClient::Get()->SetFeatureFlagsForUser(
+      cryptohome::CreateAccountIdentifierFromAccountId(
+          user_manager::GuestAccountId()),
+      {});
 
   RestartChrome(command_line, RestartChromeReason::kGuest);
 }
@@ -921,23 +876,33 @@
   if (user_manager::UserManager::Get()->GetLoggedInUsers().size() > 1)
     return false;
 
-  const base::CommandLine user_flags(CreatePerSessionCommandLine(profile));
-  std::set<base::CommandLine::StringType> command_line_difference;
-  if (!NeedRestartToApplyPerSessionFlags(user_flags, &command_line_difference))
+  // Don't restart browser if it is not the first profile in the session.
+  if (user_manager::UserManager::Get()->GetLoggedInUsers().size() != 1)
     return false;
 
-  LogCustomSwitches(command_line_difference);
+  // Compare feature flags configured for the device vs. user. Restart is only
+  // required when there's a difference.
+  std::set<std::string> designated_flags =
+      flags_ui::PrefServiceFlagsStorage(profile->GetPrefs()).GetFlags();
+  ApplyUserPolicyToFlags(profile->GetPrefs(), &designated_flags);
+  std::set<std::string> actual_flags =
+      ash::about_flags::ParseFlagsFromCommandLine();
+  std::set<std::string> flags_difference;
+  std::set_symmetric_difference(
+      designated_flags.begin(), designated_flags.end(), actual_flags.begin(),
+      actual_flags.end(),
+      std::inserter(flags_difference, flags_difference.begin()));
+  if (flags_difference.empty())
+    return false;
 
-  flags_ui::ReportAboutFlagsHistogram(
-      "Login.CustomFlags", command_line_difference, std::set<std::string>());
-
-  base::CommandLine::StringVector flags;
-  // argv[0] is the program name `base::CommandLine::NO_PROGRAM`.
-  flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
+  // Restart is required. Emit metrics and logs and trigger the restart.
+  LogCustomFeatureFlags(flags_difference);
   LOG(WARNING) << "Restarting to apply per-session flags...";
-  SetSwitchesForUser(
-      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId(),
-      CommandLineSwitchesType::kPolicyAndFlagsAndKioskControl, flags);
+
+  auto account_id = cryptohome::CreateAccountIdentifierFromAccountId(
+      user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
+  SessionManagerClient::Get()->SetFeatureFlagsForUser(
+      account_id, {designated_flags.begin(), designated_flags.end()});
   attempt_restart_closure_.Run();
   return true;
 }
@@ -2300,13 +2265,6 @@
                         pair.second.end());
   }
 
-  // Clear session_manager's feature flag state so it doesn't pass flags on
-  // restart. This is necessary until in-session feature flags have been
-  // converted to use the new way.
-  // TODO(crbug.com/1073940): Remove after conversion is complete.
-  SessionManagerClient::Get()->SetFeatureFlagsForUser(
-      cryptohome::CreateAccountIdentifierFromAccountId(account_id), {});
-
   SessionManagerClient::Get()->SetFlagsForUser(
       cryptohome::CreateAccountIdentifierFromAccountId(account_id),
       all_switches);
diff --git a/chrome/browser/ash/login/session/user_session_manager.h b/chrome/browser/ash/login/session/user_session_manager.h
index 153d8382..ba3828c 100644
--- a/chrome/browser/ash/login/session/user_session_manager.h
+++ b/chrome/browser/ash/login/session/user_session_manager.h
@@ -48,10 +48,6 @@
 class TokenHandleFetcher;
 class TurnSyncOnHelper;
 
-namespace base {
-class CommandLine;
-}
-
 namespace user_manager {
 class User;
 }  // namespace user_manager
@@ -123,13 +119,12 @@
     // Switches for controlling session initialization, such as if the profile
     // requires enterprise policy.
     kSessionControl,
-    // Switches derived from user policy, from user-set flags and kiosk app
-    // control switches.
+    // Switches derived from user policy and kiosk app control switches.
     // TODO(pmarko): Split this into multiple categories, such as kPolicy,
-    // kFlags, kKioskControl. Consider also adding sentinels automatically and
+    // kKioskControl. Consider also adding sentinels automatically and
     // pre-filling these switches from the command-line if the chrome has been
     // started with the --login-user flag (https://crbug.com/832857).
-    kPolicyAndFlagsAndKioskControl
+    kPolicyAndKioskControl
   };
 
   // To keep track of which systems need the login password to be stored in the
@@ -156,11 +151,11 @@
   // Registers session related preferences.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
-  // Applies user policies to `user_flags` .
-  // This could mean removing command-line switchis that have been added by the
-  // flag handling logic or appending additional switches due to policy.
-  static void ApplyUserPolicyToSwitches(PrefService* user_profile_prefs,
-                                        base::CommandLine* user_flags);
+  // Applies user policies to `flags`. This could mean removing flags that have
+  // been added by the flag handling logic or appending additional flags due to
+  // enterprise policy.
+  static void ApplyUserPolicyToFlags(PrefService* user_profile_prefs,
+                                     std::set<std::string>* flags);
 
   // Invoked after the tmpfs is successfully mounted.
   // Asks session_manager to restart Chrome in Guest session mode.
diff --git a/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc b/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc
index a8baef8..e7cb6d1 100644
--- a/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc
+++ b/chrome/browser/chromeos/policy/site_isolation_flag_handling_browsertest.cc
@@ -26,6 +26,7 @@
 #include "chrome/browser/ash/login/wizard_controller.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
+#include "chrome/browser/site_isolation/about_flags.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
 #include "chrome/test/base/in_process_browser_test.h"
@@ -138,7 +139,8 @@
         std::string() /* login_screen_isolate_origins */,
         std::string() /* user_policy_isolate_origins */,
         false /* user_policy_site_per_process */,
-        {"site-isolation-trial-opt-out@1"} /* user_flag_internal_names */,
+        /* user_flag_internal_names */
+        {about_flags::SiteIsolationTrialOptOutChoiceEnabled()},
         false /* ephemeral_users */,
         true /* expected_request_restart */,
         {"--disable-site-isolation-trials"} /* expected_switches_for_user */),
@@ -148,7 +150,8 @@
     Params(std::string() /* login_screen_isolate_origins */,
            std::string() /* user_policy_isolate_origins */,
            true /* user_policy_site_per_process */,
-           {"site-isolation-trial-opt-out@1"} /* user_flag_internal_names */,
+           /* user_flag_internal_names */
+           {about_flags::SiteIsolationTrialOptOutChoiceEnabled()},
            false /* ephemeral_users */,
            false /* expected_request_restart */,
            {} /* expected_switches_for_user */),
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index 4ba10c3..9904f78 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -511,7 +511,7 @@
 void ChromeBrowserMainExtraPartsMetrics::PreBrowserStart() {
   flags_ui::PrefServiceFlagsStorage flags_storage(
       g_browser_process->local_state());
-  about_flags::RecordUMAStatistics(&flags_storage);
+  about_flags::RecordUMAStatistics(&flags_storage, "Launch.FlagsAtStartup");
 
   // Log once here at browser start rather than at each renderer launch.
   ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial("ClangPGO",
diff --git a/chrome/browser/site_isolation/about_flags.h b/chrome/browser/site_isolation/about_flags.h
new file mode 100644
index 0000000..a8679d972
--- /dev/null
+++ b/chrome/browser/site_isolation/about_flags.h
@@ -0,0 +1,23 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SITE_ISOLATION_ABOUT_FLAGS_H_
+#define CHROME_BROWSER_SITE_ISOLATION_ABOUT_FLAGS_H_
+
+#include <string>
+
+#include "base/strings/strcat.h"
+
+namespace about_flags {
+
+constexpr char kSiteIsolationTrialOptOutInternalName[] =
+    "site-isolation-trial-opt-out";
+
+inline std::string SiteIsolationTrialOptOutChoiceEnabled() {
+  return base::StrCat({kSiteIsolationTrialOptOutInternalName, "@1"});
+}
+
+}  // namespace about_flags
+
+#endif  // CHROME_BROWSER_SITE_ISOLATION_ABOUT_FLAGS_H_
diff --git a/chrome/browser/ui/webui/flags/flags_ui_handler.cc b/chrome/browser/ui/webui/flags/flags_ui_handler.cc
index e6ef5230..bc332ed 100644
--- a/chrome/browser/ui/webui/flags/flags_ui_handler.cc
+++ b/chrome/browser/ui/webui/flags/flags_ui_handler.cc
@@ -14,10 +14,10 @@
 #include "components/version_info/channel.h"
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "base/system/sys_info.h"
 #include "chrome/browser/ash/login/session/user_session_manager.h"
+#include "chromeos/cryptohome/cryptohome_parameters.h"
+#include "chromeos/dbus/session_manager/session_manager_client.h"
 #include "components/account_id/account_id.h"
-#include "components/pref_registry/pref_registry_syncable.h"
 #include "components/user_manager/user_manager.h"
 #endif
 
@@ -149,28 +149,21 @@
 void FlagsUIHandler::HandleRestartBrowser(const base::ListValue* args) {
   DCHECK(flags_storage_);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  // On ChromeOS be less intrusive and restart inside the user session after
+  // On Chrome OS be less intrusive and restart inside the user session after
   // we apply the newly selected flags.
-  base::CommandLine user_flags(base::CommandLine::NO_PROGRAM);
-  about_flags::ConvertFlagsToSwitches(flags_storage_.get(), &user_flags,
-                                      flags_ui::kAddSentinels);
-
-  // Adhere to policy-enforced command-line switch handling when
-  // applying modified flags..
-  chromeos::UserSessionManager::ApplyUserPolicyToSwitches(
-      Profile::FromWebUI(web_ui())->GetPrefs(), &user_flags);
-
-  base::CommandLine::StringVector flags;
-  // argv[0] is the program name |base::CommandLine::NO_PROGRAM|.
-  flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end());
   VLOG(1) << "Restarting to apply per-session flags...";
+
+  // Adhere to policy-enforced command-line switch handling when applying
+  // modified flags.
+  auto flags = flags_storage_->GetFlags();
+  chromeos::UserSessionManager::ApplyUserPolicyToFlags(
+      Profile::FromWebUI(web_ui())->GetPrefs(), &flags);
+
   AccountId account_id =
       user_manager::UserManager::Get()->GetActiveUser()->GetAccountId();
-  chromeos::UserSessionManager::GetInstance()->SetSwitchesForUser(
-      account_id,
-      chromeos::UserSessionManager::CommandLineSwitchesType::
-          kPolicyAndFlagsAndKioskControl,
-      flags);
+  chromeos::SessionManagerClient::Get()->SetFeatureFlagsForUser(
+      cryptohome::CreateAccountIdentifierFromAccountId(account_id),
+      {flags.begin(), flags.end()});
 #endif
   chrome::AttemptRestart();
 }