Componentize internal class FlagsState in flags_ui component.

Move FlagsState class definition to components/flags_ui so that it can
be shared with iOS but leave the global FeatureEntry list definition
in the embedder.

Slightly change FlagsState interface to take the name of embedder
specific switches (switches::kEnableFeatures, ...) and use dummy values
for unit testing.

Split the unit tests moving all those that have no dependency on the
global FeatureEntry to flags_state_unittest.cc. Remove helper testing
function that are no longer useful (overridding global state).

BUG=551954

Review URL: https://codereview.chromium.org/1411453004

Cr-Commit-Position: refs/heads/master@{#361295}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e2ff266..cac5aec 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -9,6 +9,8 @@
 #include <set>
 #include <utility>
 
+#include "base/bind.h"
+#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/memory/singleton.h"
@@ -33,6 +35,7 @@
 #include "components/enhanced_bookmarks/enhanced_bookmark_switches.h"
 #include "components/flags_ui/feature_entry_macros.h"
 #include "components/flags_ui/flags_storage.h"
+#include "components/flags_ui/flags_ui_switches.h"
 #include "components/metrics/metrics_hashes.h"
 #include "components/nacl/common/nacl_switches.h"
 #include "components/offline_pages/offline_page_switches.h"
@@ -90,77 +93,20 @@
 #endif
 
 using flags_ui::FeatureEntry;
+using flags_ui::kOsMac;
+using flags_ui::kOsWin;
+using flags_ui::kOsLinux;
+using flags_ui::kOsCrOS;
+using flags_ui::kOsAndroid;
+using flags_ui::kOsCrOSOwnerOnly;
 
 namespace about_flags {
 
 namespace {
 
-// Enumeration of OSs.
-enum {
-  kOsMac = 1 << 0,
-  kOsWin = 1 << 1,
-  kOsLinux = 1 << 2,
-  kOsCrOS = 1 << 3,
-  kOsAndroid = 1 << 4,
-  kOsCrOSOwnerOnly = 1 << 5
-};
-
 const unsigned kOsAll = kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid;
 const unsigned kOsDesktop = kOsMac | kOsWin | kOsLinux | kOsCrOS;
 
-// Adds a |StringValue| to |list| for each platform where |bitmask| indicates
-// whether the entry is available on that platform.
-void AddOsStrings(unsigned bitmask, base::ListValue* list) {
-  struct {
-    unsigned bit;
-    const char* const name;
-  } kBitsToOs[] = {
-    {kOsMac, "Mac"},
-    {kOsWin, "Windows"},
-    {kOsLinux, "Linux"},
-    {kOsCrOS, "Chrome OS"},
-    {kOsAndroid, "Android"},
-    {kOsCrOSOwnerOnly, "Chrome OS (owner only)"},
-  };
-  for (size_t i = 0; i < arraysize(kBitsToOs); ++i) {
-    if (bitmask & kBitsToOs[i].bit)
-      list->Append(new base::StringValue(kBitsToOs[i].name));
-  }
-}
-
-// Convert switch constants to proper CommandLine::StringType strings.
-base::CommandLine::StringType GetSwitchString(const std::string& flag) {
-  base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
-  cmd_line.AppendSwitch(flag);
-  DCHECK_EQ(2U, cmd_line.argv().size());
-  return cmd_line.argv()[1];
-}
-
-// Scoops flags from a command line.
-std::set<base::CommandLine::StringType> ExtractFlagsFromCommandLine(
-    const base::CommandLine& cmdline) {
-  std::set<base::CommandLine::StringType> flags;
-  // First do the ones between --flag-switches-begin and --flag-switches-end.
-  base::CommandLine::StringVector::const_iterator first =
-      std::find(cmdline.argv().begin(), cmdline.argv().end(),
-                GetSwitchString(switches::kFlagSwitchesBegin));
-  base::CommandLine::StringVector::const_iterator last =
-      std::find(cmdline.argv().begin(), cmdline.argv().end(),
-                GetSwitchString(switches::kFlagSwitchesEnd));
-  if (first != cmdline.argv().end() && last != cmdline.argv().end())
-    flags.insert(first + 1, last);
-#if defined(OS_CHROMEOS)
-  // Then add those between --policy-switches-begin and --policy-switches-end.
-  first = std::find(cmdline.argv().begin(), cmdline.argv().end(),
-                    GetSwitchString(chromeos::switches::kPolicySwitchesBegin));
-  last = std::find(cmdline.argv().begin(), cmdline.argv().end(),
-                   GetSwitchString(chromeos::switches::kPolicySwitchesEnd));
-  if (first != cmdline.argv().end() && last != cmdline.argv().end())
-    flags.insert(first + 1, last);
-#endif
-  return flags;
-}
-
 const FeatureEntry::Choice kTouchEventsChoices[] = {
   { IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC, "", "" },
   { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED,
@@ -2112,193 +2058,28 @@
     // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test.
 };
 
-// Stores and encapsulates the little state that about:flags has.
-class FlagsState {
+class FlagsStateSingleton {
  public:
-  FlagsState()
-      : feature_entries(kFeatureEntries),
-        num_feature_entries(arraysize(kFeatureEntries)),
-        needs_restart_(false) {}
-  void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
-                              base::CommandLine* command_line,
-                              SentinelsMode sentinels);
-  bool IsRestartNeededToCommitChanges();
-  void SetFeatureEntryEnabled(flags_ui::FlagsStorage* flags_storage,
-                            const std::string& internal_name,
-                            bool enable);
-  void RemoveFlagsSwitches(
-      std::map<std::string, base::CommandLine::StringType>* switch_list);
-  void ResetAllFlags(flags_ui::FlagsStorage* flags_storage);
-  void Reset();
+  FlagsStateSingleton()
+      : flags_state_(kFeatureEntries, arraysize(kFeatureEntries)) {}
+  ~FlagsStateSingleton() {}
 
-  // 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|.
-  void GetFlagFeatureEntries(flags_ui::FlagsStorage* flags_storage,
-                             FlagAccess access,
-                             base::ListValue* supported_entries,
-                             base::ListValue* unsupported_entries);
+  static FlagsStateSingleton* GetInstance() {
+    return base::Singleton<FlagsStateSingleton>::get();
+  }
 
-  void SetFeatureEntries(const FeatureEntry* entries, size_t count);
-  const FeatureEntry* GetFeatureEntries(size_t* count);
-
-  // Returns the singleton instance of this class
-  static FlagsState* GetInstance() {
-    return base::Singleton<FlagsState>::get();
+  static flags_ui::FlagsState* GetFlagsState() {
+    return &GetInstance()->flags_state_;
   }
 
  private:
-  // Keeps track of affected switches for each FeatureEntry, based on which
-  // choice is selected for it.
-  struct SwitchEntry {
-    // Corresponding base::Feature to toggle.
-    std::string feature_name;
+  flags_ui::FlagsState flags_state_;
 
-    // If |feature_name| is not empty, the state (enable/disabled) to set.
-    bool feature_state;
-
-    // The name of the switch to add.
-    std::string switch_name;
-
-    // If |switch_name| is not empty, the value of the switch to set.
-    std::string switch_value;
-
-    SwitchEntry() : feature_state(false) {}
-  };
-
-  // Adds mapping to |name_to_switch_map| to set the given switch name/value.
-  void AddSwitchMapping(const std::string& key,
-                        const std::string& switch_name,
-                        const std::string& switch_value,
-                        std::map<std::string, SwitchEntry>* name_to_switch_map);
-
-  // Adds mapping to |name_to_switch_map| to toggle base::Feature |feature_name|
-  // to state |feature_state|.
-  void AddFeatureMapping(
-      const std::string& key,
-      const std::string& feature_name,
-      bool feature_state,
-      std::map<std::string, SwitchEntry>* name_to_switch_map);
-
-  // Updates the switches in |command_line| by applying the modifications
-  // specified in |name_to_switch_map| for each entry in |enabled_entries|.
-  void AddSwitchesToCommandLine(
-      const std::set<std::string>& enabled_entries,
-      const std::map<std::string, SwitchEntry>& name_to_switch_map,
-      SentinelsMode sentinels,
-      base::CommandLine* command_line);
-
-  // Updates |command_line| by merging the value of the --enable-features= or
-  // --disable-features= list (per the |switch_name| param) with corresponding
-  // entries in |feature_switches| that have value |feature_state|. Keeps track
-  // of the changes by updating |appended_switches|.
-  void MergeFeatureCommandLineSwitch(
-      const std::map<std::string, bool>& feature_switches,
-      const char* switch_name,
-      bool feature_state,
-      base::CommandLine* command_line);
-
-  // Removes all entries from prefs::kEnabledLabsExperiments that are unknown,
-  // to prevent this list to become very long as entries are added and removed.
-  void SanitizeList(flags_ui::FlagsStorage* flags_storage);
-
-  void GetSanitizedEnabledFlags(flags_ui::FlagsStorage* flags_storage,
-                                std::set<std::string>* result);
-
-  // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't
-  // enabled on the current platform.
-  void GetSanitizedEnabledFlagsForCurrentPlatform(
-      flags_ui::FlagsStorage* flags_storage,
-      std::set<std::string>* result);
-
-  const FeatureEntry* feature_entries;
-  size_t num_feature_entries;
-
-  bool needs_restart_;
-  std::map<std::string, std::string> flags_switches_;
-
-  // Map from switch name to a set of string, that keeps track which strings
-  // were appended to existing (list value) switches.
-  std::map<std::string, std::set<std::string>> appended_switches_;
-
-  DISALLOW_COPY_AND_ASSIGN(FlagsState);
+  DISALLOW_COPY_AND_ASSIGN(FlagsStateSingleton);
 };
 
-// Adds the internal names for the specified entry to |names|.
-void AddInternalName(const FeatureEntry& e, std::set<std::string>* names) {
-  switch (e.type) {
-    case FeatureEntry::SINGLE_VALUE:
-    case FeatureEntry::SINGLE_DISABLE_VALUE:
-      names->insert(e.internal_name);
-      break;
-    case FeatureEntry::MULTI_VALUE:
-    case FeatureEntry::ENABLE_DISABLE_VALUE:
-    case FeatureEntry::FEATURE_VALUE:
-      for (int i = 0; i < e.num_choices; ++i)
-        names->insert(e.NameForChoice(i));
-      break;
-  }
-}
-
-// Confirms that an entry is valid, used in a DCHECK in
-// SanitizeList below.
-bool ValidateFeatureEntry(const FeatureEntry& e) {
-  switch (e.type) {
-    case FeatureEntry::SINGLE_VALUE:
-    case FeatureEntry::SINGLE_DISABLE_VALUE:
-      DCHECK_EQ(0, e.num_choices);
-      DCHECK(!e.choices);
-      return true;
-    case FeatureEntry::MULTI_VALUE:
-      DCHECK_GT(e.num_choices, 0);
-      DCHECK(e.choices);
-      DCHECK(e.choices[0].command_line_switch);
-      DCHECK_EQ('\0', e.choices[0].command_line_switch[0]);
-      return true;
-    case FeatureEntry::ENABLE_DISABLE_VALUE:
-      DCHECK_EQ(3, e.num_choices);
-      DCHECK(!e.choices);
-      DCHECK(e.command_line_switch);
-      DCHECK(e.command_line_value);
-      DCHECK(e.disable_command_line_switch);
-      DCHECK(e.disable_command_line_value);
-      return true;
-    case FeatureEntry::FEATURE_VALUE:
-      DCHECK_EQ(3, e.num_choices);
-      DCHECK(!e.choices);
-      DCHECK(e.feature);
-      return true;
-  }
-  NOTREACHED();
-  return false;
-}
-
-void FlagsState::SanitizeList(flags_ui::FlagsStorage* flags_storage) {
-  std::set<std::string> known_entries;
-  for (size_t i = 0; i < num_feature_entries; ++i) {
-    DCHECK(ValidateFeatureEntry(feature_entries[i]));
-    AddInternalName(feature_entries[i], &known_entries);
-  }
-
-  std::set<std::string> enabled_entries = flags_storage->GetFlags();
-
-  std::set<std::string> new_enabled_entries =
-      base::STLSetIntersection<std::set<std::string> >(
-          known_entries, enabled_entries);
-
-  if (new_enabled_entries != enabled_entries)
-    flags_storage->SetFlags(new_enabled_entries);
-}
-
-void FlagsState::GetSanitizedEnabledFlags(flags_ui::FlagsStorage* flags_storage,
-                                          std::set<std::string>* result) {
-  SanitizeList(flags_storage);
-  *result = flags_storage->GetFlags();
-}
-
 bool SkipConditionalFeatureEntry(const FeatureEntry& entry) {
   version_info::Channel channel = chrome::GetChannel();
-
 #if defined(OS_ANDROID)
   // enable-data-reduction-proxy-dev is only available for the Dev/Beta channel.
   if (!strcmp("enable-data-reduction-proxy-dev", entry.internal_name) &&
@@ -2357,214 +2138,64 @@
   return false;
 }
 
-void FlagsState::GetSanitizedEnabledFlagsForCurrentPlatform(
-    flags_ui::FlagsStorage* flags_storage,
-    std::set<std::string>* result) {
-  GetSanitizedEnabledFlags(flags_storage, result);
-
-  // Filter out any entries that aren't enabled on the current platform.  We
-  // don't remove these from prefs else syncing to a platform with a different
-  // set of entries would be lossy.
-  std::set<std::string> platform_entries;
-  int current_platform = GetCurrentPlatform();
-  for (size_t i = 0; i < num_feature_entries; ++i) {
-    const FeatureEntry& entry = feature_entries[i];
-    if (entry.supported_platforms & current_platform)
-      AddInternalName(entry, &platform_entries);
-#if defined(OS_CHROMEOS)
-    if (feature_entries[i].supported_platforms & kOsCrOSOwnerOnly)
-      AddInternalName(entry, &platform_entries);
-#endif
-  }
-
-  std::set<std::string> new_enabled_entries =
-      base::STLSetIntersection<std::set<std::string> >(
-          platform_entries, *result);
-
-  result->swap(new_enabled_entries);
-}
-
-// Returns true if none of this entry's options have been enabled.
-bool IsDefaultValue(
-    const FeatureEntry& entry,
-    const std::set<std::string>& enabled_entries) {
-  switch (entry.type) {
-    case FeatureEntry::SINGLE_VALUE:
-    case FeatureEntry::SINGLE_DISABLE_VALUE:
-      return enabled_entries.count(entry.internal_name) == 0;
-    case FeatureEntry::MULTI_VALUE:
-    case FeatureEntry::ENABLE_DISABLE_VALUE:
-    case FeatureEntry::FEATURE_VALUE:
-      for (int i = 0; i < entry.num_choices; ++i) {
-        if (enabled_entries.count(entry.NameForChoice(i)) > 0)
-          return false;
-      }
-      return true;
-  }
-  NOTREACHED();
-  return true;
-}
-
-// Returns the Value representing the choice data in the specified entry.
-base::Value* CreateChoiceData(
-    const FeatureEntry& entry,
-    const std::set<std::string>& enabled_entries) {
-  DCHECK(entry.type == FeatureEntry::MULTI_VALUE ||
-         entry.type == FeatureEntry::ENABLE_DISABLE_VALUE ||
-         entry.type == FeatureEntry::FEATURE_VALUE);
-  base::ListValue* result = new base::ListValue;
-  for (int i = 0; i < entry.num_choices; ++i) {
-    base::DictionaryValue* value = new base::DictionaryValue;
-    const std::string name = entry.NameForChoice(i);
-    value->SetString("internal_name", name);
-    value->SetString("description", entry.DescriptionForChoice(i));
-    value->SetBoolean("selected", enabled_entries.count(name) > 0);
-    result->Append(value);
-  }
-  return result;
-}
-
 }  // namespace
 
 void ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
                             base::CommandLine* command_line,
-                            SentinelsMode sentinels) {
-  FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage,
-                                                    command_line,
-                                                    sentinels);
+                            flags_ui::SentinelsMode sentinels) {
+  if (command_line->HasSwitch(switches::kNoExperiments))
+    return;
+
+  FlagsStateSingleton::GetFlagsState()->ConvertFlagsToSwitches(
+      flags_storage, command_line, sentinels, switches::kEnableFeatures,
+      switches::kDisableFeatures);
 }
 
 bool AreSwitchesIdenticalToCurrentCommandLine(
     const base::CommandLine& new_cmdline,
     const base::CommandLine& active_cmdline,
     std::set<base::CommandLine::StringType>* out_difference) {
-  std::set<base::CommandLine::StringType> new_flags =
-      ExtractFlagsFromCommandLine(new_cmdline);
-  std::set<base::CommandLine::StringType> active_flags =
-      ExtractFlagsFromCommandLine(active_cmdline);
-
-  bool result = false;
-  // Needed because std::equal doesn't check if the 2nd set is empty.
-  if (new_flags.size() == active_flags.size()) {
-    result =
-        std::equal(new_flags.begin(), new_flags.end(), active_flags.begin());
-  }
-
-  if (out_difference && !result) {
-    std::set_symmetric_difference(
-        new_flags.begin(),
-        new_flags.end(),
-        active_flags.begin(),
-        active_flags.end(),
-        std::inserter(*out_difference, out_difference->begin()));
-  }
-
-  return result;
-}
-
-void FlagsState::GetFlagFeatureEntries(flags_ui::FlagsStorage* flags_storage,
-                                       FlagAccess access,
-                                       base::ListValue* supported_entries,
-                                       base::ListValue* unsupported_entries) {
-  std::set<std::string> enabled_entries;
-  GetSanitizedEnabledFlags(flags_storage, &enabled_entries);
-
-  int current_platform = GetCurrentPlatform();
-
-  for (size_t i = 0; i < num_feature_entries; ++i) {
-    const FeatureEntry& entry = feature_entries[i];
-    if (SkipConditionalFeatureEntry(entry))
-      continue;
-
-    base::DictionaryValue* data = new base::DictionaryValue();
-    data->SetString("internal_name", entry.internal_name);
-    data->SetString("name",
-                    l10n_util::GetStringUTF16(entry.visible_name_id));
-    data->SetString("description",
-                    l10n_util::GetStringUTF16(
-                        entry.visible_description_id));
-
-    base::ListValue* supported_platforms = new base::ListValue();
-    AddOsStrings(entry.supported_platforms, supported_platforms);
-    data->Set("supported_platforms", supported_platforms);
-    // True if the switch is not currently passed.
-    bool is_default_value = IsDefaultValue(entry, enabled_entries);
-    data->SetBoolean("is_default", is_default_value);
-
-    switch (entry.type) {
-      case FeatureEntry::SINGLE_VALUE:
-      case FeatureEntry::SINGLE_DISABLE_VALUE:
-        data->SetBoolean(
-            "enabled",
-            (!is_default_value &&
-             entry.type == FeatureEntry::SINGLE_VALUE) ||
-            (is_default_value &&
-             entry.type == FeatureEntry::SINGLE_DISABLE_VALUE));
-        break;
-      case FeatureEntry::MULTI_VALUE:
-      case FeatureEntry::ENABLE_DISABLE_VALUE:
-      case FeatureEntry::FEATURE_VALUE:
-        data->Set("choices", CreateChoiceData(entry, enabled_entries));
-        break;
-    }
-
-    bool supported = (entry.supported_platforms & current_platform) != 0;
+  const char* extra_flag_sentinel_begin_flag_name = nullptr;
+  const char* extra_flag_sentinel_end_flag_name = nullptr;
 #if defined(OS_CHROMEOS)
-    if (access == kOwnerAccessToFlags &&
-        (entry.supported_platforms & kOsCrOSOwnerOnly) != 0) {
-      supported = true;
-    }
+  // 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
-    if (supported)
-      supported_entries->Append(data);
-    else
-      unsupported_entries->Append(data);
-  }
+  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,
-                           FlagAccess access,
+                           flags_ui::FlagAccess access,
                            base::ListValue* supported_entries,
                            base::ListValue* unsupported_entries) {
-  FlagsState::GetInstance()->GetFlagFeatureEntries(flags_storage, access,
-                                                   supported_entries,
-                                                   unsupported_entries);
+  FlagsStateSingleton::GetFlagsState()->GetFlagFeatureEntries(
+      flags_storage, access, supported_entries, unsupported_entries,
+      base::Bind(&SkipConditionalFeatureEntry));
 }
 
 bool IsRestartNeededToCommitChanges() {
-  return FlagsState::GetInstance()->IsRestartNeededToCommitChanges();
+  return FlagsStateSingleton::GetFlagsState()->IsRestartNeededToCommitChanges();
 }
 
 void SetFeatureEntryEnabled(flags_ui::FlagsStorage* flags_storage,
                             const std::string& internal_name,
                             bool enable) {
-  FlagsState::GetInstance()->SetFeatureEntryEnabled(flags_storage,
-                                                  internal_name, enable);
+  FlagsStateSingleton::GetFlagsState()->SetFeatureEntryEnabled(
+      flags_storage, internal_name, enable);
 }
 
 void RemoveFlagsSwitches(
     std::map<std::string, base::CommandLine::StringType>* switch_list) {
-  FlagsState::GetInstance()->RemoveFlagsSwitches(switch_list);
+  FlagsStateSingleton::GetFlagsState()->RemoveFlagsSwitches(switch_list);
 }
 
 void ResetAllFlags(flags_ui::FlagsStorage* flags_storage) {
-  FlagsState::GetInstance()->ResetAllFlags(flags_storage);
-}
-
-int GetCurrentPlatform() {
-#if defined(OS_MACOSX)
-  return kOsMac;
-#elif defined(OS_WIN)
-  return kOsWin;
-#elif defined(OS_CHROMEOS)  // Needs to be before the OS_LINUX check.
-  return kOsCrOS;
-#elif defined(OS_LINUX) || defined(OS_OPENBSD)
-  return kOsLinux;
-#elif defined(OS_ANDROID)
-  return kOsAndroid;
-#else
-#error Unknown platform
-#endif
+  FlagsStateSingleton::GetFlagsState()->ResetAllFlags(flags_storage);
 }
 
 void RecordUMAStatistics(flags_ui::FlagsStorage* flags_storage) {
@@ -2613,310 +2244,13 @@
   }
 }
 
-//////////////////////////////////////////////////////////////////////////////
-// FlagsState implementation.
-
-namespace {
-
-void FlagsState::ConvertFlagsToSwitches(flags_ui::FlagsStorage* flags_storage,
-                                        base::CommandLine* command_line,
-                                        SentinelsMode sentinels) {
-  if (command_line->HasSwitch(switches::kNoExperiments))
-    return;
-
-  std::set<std::string> enabled_entries;
-
-  GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, &enabled_entries);
-
-  std::map<std::string, SwitchEntry> name_to_switch_map;
-  for (size_t i = 0; i < num_feature_entries; ++i) {
-    const FeatureEntry& e = feature_entries[i];
-    switch (e.type) {
-      case FeatureEntry::SINGLE_VALUE:
-      case FeatureEntry::SINGLE_DISABLE_VALUE:
-        AddSwitchMapping(e.internal_name, e.command_line_switch,
-                         e.command_line_value, &name_to_switch_map);
-        break;
-      case FeatureEntry::MULTI_VALUE:
-        for (int j = 0; j < e.num_choices; ++j) {
-          AddSwitchMapping(e.NameForChoice(j), e.choices[j].command_line_switch,
-                           e.choices[j].command_line_value,
-                           &name_to_switch_map);
-        }
-        break;
-      case FeatureEntry::ENABLE_DISABLE_VALUE:
-        AddSwitchMapping(e.NameForChoice(0), std::string(), std::string(),
-                         &name_to_switch_map);
-        AddSwitchMapping(e.NameForChoice(1), e.command_line_switch,
-                         e.command_line_value, &name_to_switch_map);
-        AddSwitchMapping(e.NameForChoice(2), e.disable_command_line_switch,
-                         e.disable_command_line_value, &name_to_switch_map);
-        break;
-      case FeatureEntry::FEATURE_VALUE:
-        AddFeatureMapping(e.NameForChoice(0), std::string(), false,
-                          &name_to_switch_map);
-        AddFeatureMapping(e.NameForChoice(1), e.feature->name, true,
-                          &name_to_switch_map);
-        AddFeatureMapping(e.NameForChoice(2), e.feature->name, false,
-                          &name_to_switch_map);
-        break;
-    }
-  }
-
-  AddSwitchesToCommandLine(enabled_entries, name_to_switch_map, sentinels,
-                           command_line);
-}
-
-bool FlagsState::IsRestartNeededToCommitChanges() {
-  return needs_restart_;
-}
-
-void FlagsState::SetFeatureEntryEnabled(flags_ui::FlagsStorage* flags_storage,
-                                        const std::string& internal_name,
-                                        bool enable) {
-  size_t at_index = internal_name.find(flags_ui::testing::kMultiSeparator);
-  if (at_index != std::string::npos) {
-    DCHECK(enable);
-    // We're being asked to enable a multi-choice entry. Disable the
-    // currently selected choice.
-    DCHECK_NE(at_index, 0u);
-    const std::string entry_name = internal_name.substr(0, at_index);
-    SetFeatureEntryEnabled(flags_storage, entry_name, false);
-
-    // And enable the new choice, if it is not the default first choice.
-    if (internal_name != entry_name + "@0") {
-      std::set<std::string> enabled_entries;
-      GetSanitizedEnabledFlags(flags_storage, &enabled_entries);
-      needs_restart_ |= enabled_entries.insert(internal_name).second;
-      flags_storage->SetFlags(enabled_entries);
-    }
-    return;
-  }
-
-  std::set<std::string> enabled_entries;
-  GetSanitizedEnabledFlags(flags_storage, &enabled_entries);
-
-  const FeatureEntry* e = nullptr;
-  for (size_t i = 0; i < num_feature_entries; ++i) {
-    if (feature_entries[i].internal_name == internal_name) {
-      e = feature_entries + i;
-      break;
-    }
-  }
-  DCHECK(e);
-
-  if (e->type == FeatureEntry::SINGLE_VALUE) {
-    if (enable)
-      needs_restart_ |= enabled_entries.insert(internal_name).second;
-    else
-      needs_restart_ |= (enabled_entries.erase(internal_name) > 0);
-  } else if (e->type == FeatureEntry::SINGLE_DISABLE_VALUE) {
-    if (!enable)
-      needs_restart_ |= enabled_entries.insert(internal_name).second;
-    else
-      needs_restart_ |= (enabled_entries.erase(internal_name) > 0);
-  } else {
-    if (enable) {
-      // Enable the first choice.
-      needs_restart_ |= enabled_entries.insert(e->NameForChoice(0)).second;
-    } else {
-      // Find the currently enabled choice and disable it.
-      for (int i = 0; i < e->num_choices; ++i) {
-        std::string choice_name = e->NameForChoice(i);
-        if (enabled_entries.find(choice_name) !=
-            enabled_entries.end()) {
-          needs_restart_ = true;
-          enabled_entries.erase(choice_name);
-          // Continue on just in case there's a bug and more than one
-          // entry for this choice was enabled.
-        }
-      }
-    }
-  }
-
-  flags_storage->SetFlags(enabled_entries);
-}
-
-void FlagsState::RemoveFlagsSwitches(
-    std::map<std::string, base::CommandLine::StringType>* switch_list) {
-  for (const auto& entry : flags_switches_)
-    switch_list->erase(entry.first);
-
-  // If feature entries were added to --enable-features= or --disable-features=
-  // lists, remove them here while preserving existing values.
-  for (const auto& entry : appended_switches_) {
-    const auto& switch_name = entry.first;
-    const auto& switch_added_values = entry.second;
-
-    // The below is either a std::string or a base::string16 based on platform.
-    const auto& existing_value = (*switch_list)[switch_name];
-#if defined(OS_WIN)
-    const std::string existing_value_utf8 = base::UTF16ToUTF8(existing_value);
-#else
-    const std::string& existing_value_utf8 = existing_value;
-#endif
-
-    std::vector<std::string> features =
-        base::FeatureList::SplitFeatureListString(existing_value_utf8);
-    std::vector<std::string> remaining_features;
-    // For any featrue name in |features| that is not in |switch_added_values| -
-    // i.e. it wasn't added by about_flags code, add it to |remaining_features|.
-    for (const std::string& feature : features) {
-      if (!ContainsKey(switch_added_values, feature))
-        remaining_features.push_back(feature);
-    }
-
-    // Either remove the flag entirely if |remaining_features| is empty, or set
-    // the new list.
-    if (remaining_features.empty()) {
-      switch_list->erase(switch_name);
-    } else {
-      std::string switch_value = base::JoinString(remaining_features, ",");
-#if defined(OS_WIN)
-      (*switch_list)[switch_name] = base::UTF8ToUTF16(switch_value);
-#else
-      (*switch_list)[switch_name] = switch_value;
-#endif
-    }
-  }
-}
-
-void FlagsState::ResetAllFlags(flags_ui::FlagsStorage* flags_storage) {
-  needs_restart_ = true;
-
-  std::set<std::string> no_entries;
-  flags_storage->SetFlags(no_entries);
-}
-
-void FlagsState::Reset() {
-  needs_restart_ = false;
-  flags_switches_.clear();
-  appended_switches_.clear();
-}
-
-void FlagsState::SetFeatureEntries(const FeatureEntry* entries, size_t count) {
-  feature_entries = entries;
-  num_feature_entries = count;
-}
-
-const FeatureEntry* FlagsState::GetFeatureEntries(size_t* count) {
-  *count = num_feature_entries;
-  return feature_entries;
-}
-
-void FlagsState::AddSwitchMapping(
-    const std::string& key,
-    const std::string& switch_name,
-    const std::string& switch_value,
-    std::map<std::string, SwitchEntry>* name_to_switch_map) {
-  DCHECK(!ContainsKey(*name_to_switch_map, key));
-
-  SwitchEntry* entry = &(*name_to_switch_map)[key];
-  entry->switch_name = switch_name;
-  entry->switch_value = switch_value;
-}
-
-void FlagsState::AddFeatureMapping(
-    const std::string& key,
-    const std::string& feature_name,
-    bool feature_state,
-    std::map<std::string, SwitchEntry>* name_to_switch_map) {
-  DCHECK(!ContainsKey(*name_to_switch_map, key));
-
-  SwitchEntry* entry = &(*name_to_switch_map)[key];
-  entry->feature_name = feature_name;
-  entry->feature_state = feature_state;
-}
-
-void FlagsState::AddSwitchesToCommandLine(
-    const std::set<std::string>& enabled_entries,
-    const std::map<std::string, SwitchEntry>& name_to_switch_map,
-    SentinelsMode sentinels,
-    base::CommandLine* command_line) {
-  std::map<std::string, bool> feature_switches;
-  if (sentinels == kAddSentinels) {
-    command_line->AppendSwitch(switches::kFlagSwitchesBegin);
-    flags_switches_[switches::kFlagSwitchesBegin] = std::string();
-  }
-
-  for (const std::string& entry_name : enabled_entries) {
-    const auto& entry_it = name_to_switch_map.find(entry_name);
-    if (entry_it == name_to_switch_map.end()) {
-      NOTREACHED();
-      continue;
-    }
-
-    const SwitchEntry& entry = entry_it->second;
-    if (!entry.feature_name.empty()) {
-      feature_switches[entry.feature_name] = entry.feature_state;
-    } else if (!entry.switch_name.empty()) {
-      command_line->AppendSwitchASCII(entry.switch_name, entry.switch_value);
-      flags_switches_[entry.switch_name] = entry.switch_value;
-    }
-    // If an entry doesn't match either of the above, then it is likely the
-    // default entry for a FEATURE_VALUE entry. Safe to ignore.
-  }
-
-  if (!feature_switches.empty()) {
-    MergeFeatureCommandLineSwitch(feature_switches, switches::kEnableFeatures,
-                                  true, command_line);
-    MergeFeatureCommandLineSwitch(feature_switches, switches::kDisableFeatures,
-                                  false, command_line);
-  }
-
-  if (sentinels == kAddSentinels) {
-    command_line->AppendSwitch(switches::kFlagSwitchesEnd);
-    flags_switches_[switches::kFlagSwitchesEnd] = std::string();
-  }
-}
-
-void FlagsState::MergeFeatureCommandLineSwitch(
-    const std::map<std::string, bool>& feature_switches,
-    const char* switch_name,
-    bool feature_state,
-    base::CommandLine* command_line) {
-  std::string original_switch_value =
-      command_line->GetSwitchValueASCII(switch_name);
-  std::vector<std::string> features =
-      base::FeatureList::SplitFeatureListString(original_switch_value);
-  // Only add features that don't already exist in the lists.
-  // Note: The ContainsValue() call results in O(n^2) performance, but in
-  // practice n should be very small.
-  for (const auto& entry : feature_switches) {
-    if (entry.second == feature_state &&
-        !ContainsValue(features, entry.first)) {
-      features.push_back(entry.first);
-      appended_switches_[switch_name].insert(entry.first);
-    }
-  }
-  // Update the switch value only if it didn't change. This avoids setting an
-  // empty list or duplicating the same list (since AppendSwitch() adds the
-  // switch to the end but doesn't remove previous ones).
-  std::string switch_value = base::JoinString(features, ",");
-  if (switch_value != original_switch_value)
-    command_line->AppendSwitchASCII(switch_name, switch_value);
-}
-
-}  // namespace
-
 namespace testing {
 
 const base::HistogramBase::Sample kBadSwitchFormatHistogramId = 0;
 
-void ClearState() {
-  FlagsState::GetInstance()->Reset();
-}
-
-void SetFeatureEntries(const FeatureEntry* entries, size_t count) {
-  if (!entries) {
-    entries = kFeatureEntries;
-    count = arraysize(kFeatureEntries);
-  }
-  FlagsState::GetInstance()->SetFeatureEntries(entries, count);
-}
-
 const FeatureEntry* GetFeatureEntries(size_t* count) {
-  return FlagsState::GetInstance()->GetFeatureEntries(count);
+  *count = arraysize(kFeatureEntries);
+  return kFeatureEntries;
 }
 
 }  // namespace testing