Index: chrome/browser/about_flags.cc |
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc |
index c08171cf1579d0883f188aa8bce0662500a99952..eb7ae85e7310ef5bb4b1bd54ee49a3b161e5e1da 100644 |
--- a/chrome/browser/about_flags.cc |
+++ b/chrome/browser/about_flags.cc |
@@ -48,6 +48,10 @@ |
#include "third_party/cros_system_api/switches/chrome_switches.h" |
#endif |
+#if defined(OS_WIN) |
+#include "base/win/registry.h" |
+#endif |
+ |
#if defined(ENABLE_APP_LIST) |
#include "ui/app_list/app_list_switches.h" |
#endif |
@@ -72,6 +76,64 @@ namespace about_flags { |
Experiment::MULTI_VALUE, NULL, NULL, NULL, NULL, choices, arraysize(choices) |
namespace { |
+#if defined(OS_WIN) |
+const wchar_t kRegistryBasePath[] = L"SOFTWARE\\Google\\Chrome"; |
+const wchar_t kRegistryProfilePath[] = L"SOFTWARE\\Google\\Chrome\\Profile"; |
+const wchar_t kRegistryProfileSubkey[] = L"Profile"; |
+ |
+std::wstring ConvertToWString(const std::string& s) { |
sky
2014/02/11 14:57:00
There is a bunch of code for reading/writing to th
girard
2014/02/11 18:51:48
I'm using those functions below. Those functions (
|
+ std::wstring result; |
+ result.assign(s.begin(),s.end()); |
+ return result; |
+} |
+ |
+bool FlagIsStoredInRegistry(const std::string& flagname) { |
+ return strncmp(flagname.c_str(),switches::kHighDPISupport, |
+ strlen(switches::kHighDPISupport))==0; |
+} |
+ |
+DWORD ReadRegistryValue(HKEY root, |
+ const wchar_t* base_key, const wchar_t* sub_key, |
+ const std::string& value_name, DWORD default_value) { |
+ base::win::RegKey regKey(HKEY_CURRENT_USER, |
+ base_key, |
+ KEY_CREATE_SUB_KEY); |
+ if (regKey.Valid() && |
+ regKey.OpenKey(sub_key, KEY_QUERY_VALUE) == ERROR_SUCCESS) { |
+ DWORD value; |
+ if (regKey.Valid() && |
+ regKey.ReadValueDW(ConvertToWString(value_name).c_str(),&value) == |
+ ERROR_SUCCESS) { |
+ return value; |
+ } |
+ } |
+ return default_value; |
+} |
+ |
+// WriteRegistryValue |
+bool WriteRegistryValue(HKEY root, |
+ const wchar_t* base_key, const wchar_t* sub_key, |
+ const std::string& value_name, const char* value_string) { |
+ DWORD value = atoi(value_string); |
+ base::win::RegKey regKey(root, |
+ base_key, |
+ KEY_CREATE_SUB_KEY); |
+ return regKey.Valid() && |
+ (regKey.CreateKey(sub_key, KEY_SET_VALUE) == ERROR_SUCCESS) && |
+ (regKey.WriteValue(ConvertToWString(value_name).c_str(),value) == |
+ ERROR_SUCCESS); |
+} |
+ |
+bool DeleteRegistryValue( |
+ HKEY root, const wchar_t* subkey_name, const std::string& value_name) { |
+ base::win::RegKey regKey(HKEY_CURRENT_USER, |
+ subkey_name, |
+ KEY_ALL_ACCESS); |
+ return regKey.Valid() && |
+ regKey.DeleteValue(ConvertToWString(value_name).c_str()) == ERROR_SUCCESS; |
+} |
+ |
+#endif |
const unsigned kOsAll = kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid; |
const unsigned kOsDesktop = kOsMac | kOsWin | kOsLinux | kOsCrOS; |
@@ -2168,6 +2230,26 @@ base::Value* CreateChoiceData( |
return result; |
} |
+base::Value* CreateChoiceDataFromRegistry( |
+ const Experiment& experiment) { |
+ DCHECK(experiment.type == Experiment::MULTI_VALUE || |
+ experiment.type == Experiment::ENABLE_DISABLE_VALUE); |
+ |
+ DWORD registry_value = ReadRegistryValue( |
girard
2014/02/11 20:29:00
Self-review: This logic depends on other code that
|
+ HKEY_CURRENT_USER,kRegistryBasePath, |
+ kRegistryProfileSubkey,experiment.internal_name,FALSE); |
+ base::ListValue* result = new base::ListValue; |
+ for (int i = 0; i < experiment.num_choices; ++i) { |
+ base::DictionaryValue* value = new base::DictionaryValue; |
+ const std::string name = experiment.NameForChoice(i); |
+ value->SetString("internal_name", name); |
+ value->SetString("description", experiment.DescriptionForChoice(i)); |
+ value->SetBoolean("selected", i == static_cast<int>(registry_value)); |
+ result->Append(value); |
+ } |
+ return result; |
+} |
+ |
} // namespace |
std::string Experiment::NameForChoice(int index) const { |
@@ -2252,7 +2334,12 @@ void GetFlagsExperimentsData(FlagsStorage* flags_storage, |
break; |
case Experiment::MULTI_VALUE: |
case Experiment::ENABLE_DISABLE_VALUE: |
- data->Set("choices", CreateChoiceData(experiment, enabled_experiments)); |
+ if (FlagIsStoredInRegistry(experiment.internal_name)) { |
+ data->Set("choices", CreateChoiceDataFromRegistry(experiment)); |
+ } else { |
+ data->Set("choices", |
+ CreateChoiceData(experiment, enabled_experiments)); |
+ } |
break; |
default: |
NOTREACHED(); |
@@ -2429,6 +2516,13 @@ void FlagsState::SetExperimentEnabled(FlagsStorage* flags_storage, |
GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); |
needs_restart_ |= enabled_experiments.insert(internal_name).second; |
flags_storage->SetFlags(enabled_experiments); |
+#if defined(OS_WIN) |
+ if (FlagIsStoredInRegistry(experiment_name)) { |
+ WriteRegistryValue(HKEY_CURRENT_USER,kRegistryBasePath, |
+ kRegistryProfileSubkey,experiment_name.c_str(), |
+ internal_name.substr(at_index+1,1).c_str()); |
+ } |
+#endif |
} |
return; |
} |
@@ -2469,6 +2563,12 @@ void FlagsState::SetExperimentEnabled(FlagsStorage* flags_storage, |
} |
} |
+#if defined(OS_WIN) |
+ if (FlagIsStoredInRegistry(internal_name)) { |
+ DeleteRegistryValue(HKEY_CURRENT_USER,kRegistryProfilePath, |
+ internal_name); |
+ } |
+#endif |
flags_storage->SetFlags(enabled_experiments); |
} |