Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/about_flags.h" | 5 #include "chrome/browser/about_flags.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/memory/singleton.h" | 13 #include "base/memory/singleton.h" |
| 14 #include "base/metrics/sparse_histogram.h" | |
| 14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/values.h" | 18 #include "base/values.h" |
| 18 #include "cc/base/switches.h" | 19 #include "cc/base/switches.h" |
| 19 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h" | 20 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h" |
| 20 #include "chrome/browser/flags_storage.h" | 21 #include "chrome/browser/flags_storage.h" |
| 21 #include "chrome/common/chrome_content_client.h" | 22 #include "chrome/common/chrome_content_client.h" |
| 22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
| 23 #include "components/autofill/core/common/autofill_switches.h" | 24 #include "components/autofill/core/common/autofill_switches.h" |
| 24 #include "components/cloud_devices/common/cloud_devices_switches.h" | 25 #include "components/cloud_devices/common/cloud_devices_switches.h" |
| 25 #include "components/nacl/common/nacl_switches.h" | 26 #include "components/nacl/common/nacl_switches.h" |
| 26 #include "content/public/browser/user_metrics.h" | 27 #include "content/public/browser/user_metrics.h" |
| 27 #include "extensions/common/switches.h" | 28 #include "extensions/common/switches.h" |
| 28 #include "grit/chromium_strings.h" | 29 #include "grit/chromium_strings.h" |
| 29 #include "grit/generated_resources.h" | 30 #include "grit/generated_resources.h" |
| 30 #include "grit/google_chrome_strings.h" | 31 #include "grit/google_chrome_strings.h" |
| 31 #include "media/base/media_switches.h" | 32 #include "media/base/media_switches.h" |
| 33 #include "third_party/zlib/zlib.h" | |
| 32 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
| 33 #include "ui/base/ui_base_switches.h" | 35 #include "ui/base/ui_base_switches.h" |
| 34 #include "ui/display/display_switches.h" | 36 #include "ui/display/display_switches.h" |
| 35 #include "ui/events/event_switches.h" | 37 #include "ui/events/event_switches.h" |
| 36 #include "ui/gfx/switches.h" | 38 #include "ui/gfx/switches.h" |
| 37 #include "ui/gl/gl_switches.h" | 39 #include "ui/gl/gl_switches.h" |
| 38 #include "ui/keyboard/keyboard_switches.h" | 40 #include "ui/keyboard/keyboard_switches.h" |
| 39 #include "ui/native_theme/native_theme_switches.h" | 41 #include "ui/native_theme/native_theme_switches.h" |
| 40 #include "ui/views/views_switches.h" | 42 #include "ui/views/views_switches.h" |
| 41 | 43 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 54 #endif | 56 #endif |
| 55 | 57 |
| 56 #if defined(ENABLE_APP_LIST) | 58 #if defined(ENABLE_APP_LIST) |
| 57 #include "ui/app_list/app_list_switches.h" | 59 #include "ui/app_list/app_list_switches.h" |
| 58 #endif | 60 #endif |
| 59 | 61 |
| 60 using base::UserMetricsAction; | 62 using base::UserMetricsAction; |
| 61 | 63 |
| 62 namespace about_flags { | 64 namespace about_flags { |
| 63 | 65 |
| 66 const uint32_t kBadSwitchFormatHistogramId = 0; | |
| 67 | |
| 64 // Macros to simplify specifying the type. | 68 // Macros to simplify specifying the type. |
| 65 #define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \ | 69 #define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \ |
| 66 Experiment::SINGLE_VALUE, \ | 70 Experiment::SINGLE_VALUE, \ |
| 67 command_line_switch, switch_value, NULL, NULL, NULL, 0 | 71 command_line_switch, switch_value, NULL, NULL, NULL, 0 |
| 68 #define SINGLE_VALUE_TYPE(command_line_switch) \ | 72 #define SINGLE_VALUE_TYPE(command_line_switch) \ |
| 69 SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, "") | 73 SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, "") |
| 70 #define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \ | 74 #define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \ |
| 71 disable_switch, disable_value) \ | 75 disable_switch, disable_value) \ |
| 72 Experiment::ENABLE_DISABLE_VALUE, enable_switch, enable_value, \ | 76 Experiment::ENABLE_DISABLE_VALUE, enable_switch, enable_value, \ |
| 73 disable_switch, disable_value, NULL, 3 | 77 disable_switch, disable_value, NULL, 3 |
| (...skipping 1435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1509 }, | 1513 }, |
| 1510 #endif | 1514 #endif |
| 1511 #if defined(OS_ANDROID) | 1515 #if defined(OS_ANDROID) |
| 1512 { | 1516 { |
| 1513 "enable-accessibility-tab-switcher", | 1517 "enable-accessibility-tab-switcher", |
| 1514 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_NAME, | 1518 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_NAME, |
| 1515 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_DESCRIPTION, | 1519 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_DESCRIPTION, |
| 1516 kOsAndroid, | 1520 kOsAndroid, |
| 1517 SINGLE_VALUE_TYPE(switches::kEnableAccessibilityTabSwitcher) | 1521 SINGLE_VALUE_TYPE(switches::kEnableAccessibilityTabSwitcher) |
| 1518 }, | 1522 }, |
| 1519 { | |
| 1520 // TODO(dmazzoni): remove this flag when native android accessibility | |
| 1521 // ships in the stable channel. http://crbug.com/356775 | |
| 1522 "enable-accessibility-script-injection", | |
| 1523 IDS_FLAGS_ENABLE_ACCESSIBILITY_SCRIPT_INJECTION_NAME, | |
| 1524 IDS_FLAGS_ENABLE_ACCESSIBILITY_SCRIPT_INJECTION_DESCRIPTION, | |
| 1525 kOsAndroid, | |
| 1526 // Java-only switch: ContentSwitches.ENABLE_ACCESSIBILITY_SCRIPT_INJECTION. | |
| 1527 SINGLE_VALUE_TYPE("enable-accessibility-script-injection") | |
| 1528 }, | |
|
Ilya Sherman
2014/08/05 20:14:46
This diff seems unrelated to your CL.
Alexander Alekseev
2014/08/07 23:24:55
As this CL doesn't have explicit UMA IDs, this par
Ilya Sherman
2014/08/08 03:49:45
If this switch is obsolete, I'd prefer that you re
Alexander Alekseev
2014/08/09 01:30:00
Done.
| |
| 1529 #endif | 1523 #endif |
| 1530 { | 1524 { |
| 1531 "enable-one-copy", | 1525 "enable-one-copy", |
| 1532 IDS_FLAGS_ONE_COPY_NAME, | 1526 IDS_FLAGS_ONE_COPY_NAME, |
| 1533 IDS_FLAGS_ONE_COPY_DESCRIPTION, | 1527 IDS_FLAGS_ONE_COPY_DESCRIPTION, |
| 1534 kOsAll, | 1528 kOsAll, |
| 1535 SINGLE_VALUE_TYPE(switches::kEnableOneCopy) | 1529 SINGLE_VALUE_TYPE(switches::kEnableOneCopy) |
| 1536 }, | 1530 }, |
| 1537 { | 1531 { |
| 1538 "enable-zero-copy", | 1532 "enable-zero-copy", |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1947 SentinelsMode sentinels); | 1941 SentinelsMode sentinels); |
| 1948 bool IsRestartNeededToCommitChanges(); | 1942 bool IsRestartNeededToCommitChanges(); |
| 1949 void SetExperimentEnabled( | 1943 void SetExperimentEnabled( |
| 1950 FlagsStorage* flags_storage, | 1944 FlagsStorage* flags_storage, |
| 1951 const std::string& internal_name, | 1945 const std::string& internal_name, |
| 1952 bool enable); | 1946 bool enable); |
| 1953 void RemoveFlagsSwitches( | 1947 void RemoveFlagsSwitches( |
| 1954 std::map<std::string, CommandLine::StringType>* switch_list); | 1948 std::map<std::string, CommandLine::StringType>* switch_list); |
| 1955 void ResetAllFlags(FlagsStorage* flags_storage); | 1949 void ResetAllFlags(FlagsStorage* flags_storage); |
| 1956 void reset(); | 1950 void reset(); |
| 1951 std::set<std::string> GetAllSwitchesForTesting() const; | |
| 1957 | 1952 |
| 1958 // Returns the singleton instance of this class | 1953 // Returns the singleton instance of this class |
| 1959 static FlagsState* GetInstance() { | 1954 static FlagsState* GetInstance() { |
| 1960 return Singleton<FlagsState>::get(); | 1955 return Singleton<FlagsState>::get(); |
| 1961 } | 1956 } |
| 1962 | 1957 |
| 1963 private: | 1958 private: |
| 1964 bool needs_restart_; | 1959 bool needs_restart_; |
| 1965 std::map<std::string, std::string> flags_switches_; | 1960 std::map<std::string, std::string> flags_switches_; |
| 1966 | 1961 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2137 | 2132 |
| 2138 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, | 2133 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, |
| 2139 CommandLine* command_line, | 2134 CommandLine* command_line, |
| 2140 SentinelsMode sentinels) { | 2135 SentinelsMode sentinels) { |
| 2141 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage, | 2136 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage, |
| 2142 command_line, | 2137 command_line, |
| 2143 sentinels); | 2138 sentinels); |
| 2144 } | 2139 } |
| 2145 | 2140 |
| 2146 bool AreSwitchesIdenticalToCurrentCommandLine( | 2141 bool AreSwitchesIdenticalToCurrentCommandLine( |
| 2147 const CommandLine& new_cmdline, const CommandLine& active_cmdline) { | 2142 const CommandLine& new_cmdline, |
| 2143 const CommandLine& active_cmdline, | |
| 2144 std::set<CommandLine::StringType>* out_difference) { | |
| 2148 std::set<CommandLine::StringType> new_flags = | 2145 std::set<CommandLine::StringType> new_flags = |
| 2149 ExtractFlagsFromCommandLine(new_cmdline); | 2146 ExtractFlagsFromCommandLine(new_cmdline); |
| 2150 std::set<CommandLine::StringType> active_flags = | 2147 std::set<CommandLine::StringType> active_flags = |
| 2151 ExtractFlagsFromCommandLine(active_cmdline); | 2148 ExtractFlagsFromCommandLine(active_cmdline); |
| 2152 | 2149 |
| 2150 bool result = false; | |
| 2153 // Needed because std::equal doesn't check if the 2nd set is empty. | 2151 // Needed because std::equal doesn't check if the 2nd set is empty. |
| 2154 if (new_flags.size() != active_flags.size()) | 2152 if (new_flags.size() == active_flags.size()) { |
| 2155 return false; | 2153 result = |
| 2154 std::equal(new_flags.begin(), new_flags.end(), active_flags.begin()); | |
| 2155 } | |
| 2156 | 2156 |
| 2157 return std::equal(new_flags.begin(), new_flags.end(), active_flags.begin()); | 2157 if (out_difference && !result) { |
| 2158 std::set_symmetric_difference( | |
| 2159 new_flags.begin(), | |
| 2160 new_flags.end(), | |
| 2161 active_flags.begin(), | |
| 2162 active_flags.end(), | |
| 2163 std::inserter(*out_difference, out_difference->begin())); | |
| 2164 } | |
| 2165 | |
| 2166 return result; | |
| 2158 } | 2167 } |
| 2159 | 2168 |
| 2160 void GetFlagsExperimentsData(FlagsStorage* flags_storage, | 2169 void GetFlagsExperimentsData(FlagsStorage* flags_storage, |
| 2161 FlagAccess access, | 2170 FlagAccess access, |
| 2162 base::ListValue* supported_experiments, | 2171 base::ListValue* supported_experiments, |
| 2163 base::ListValue* unsupported_experiments) { | 2172 base::ListValue* unsupported_experiments) { |
| 2164 std::set<std::string> enabled_experiments; | 2173 std::set<std::string> enabled_experiments; |
| 2165 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); | 2174 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); |
| 2166 | 2175 |
| 2167 int current_platform = GetCurrentPlatform(); | 2176 int current_platform = GetCurrentPlatform(); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2255 action += *it; | 2264 action += *it; |
| 2256 content::RecordComputedAction(action); | 2265 content::RecordComputedAction(action); |
| 2257 } | 2266 } |
| 2258 // Since flag metrics are recorded every startup, add a tick so that the | 2267 // Since flag metrics are recorded every startup, add a tick so that the |
| 2259 // stats can be made meaningful. | 2268 // stats can be made meaningful. |
| 2260 if (flags.size()) | 2269 if (flags.size()) |
| 2261 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick")); | 2270 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick")); |
| 2262 content::RecordAction(UserMetricsAction("StartupTick")); | 2271 content::RecordAction(UserMetricsAction("StartupTick")); |
| 2263 } | 2272 } |
| 2264 | 2273 |
| 2274 uint32 GetSwitchUMAId(const std::string& switch_name) { | |
| 2275 return static_cast<unsigned>( | |
|
Ilya Sherman
2014/08/05 20:14:46
Please cast directly to the returned type, i.e. ui
Alexander Alekseev
2014/08/07 23:24:56
Done.
| |
| 2276 crc32(0, | |
|
Ilya Sherman
2014/08/05 20:14:46
Optional: md5 is more commonly used for UMA code.
Alexander Alekseev
2014/08/07 23:24:56
On a server-side it looks like uint32, so it doesn
Ilya Sherman
2014/08/08 03:49:45
The only reason that special support might be usef
| |
| 2277 reinterpret_cast<const Bytef*>(switch_name.c_str()), | |
| 2278 switch_name.length())); | |
| 2279 } | |
| 2280 | |
| 2281 void ReportCustomFlags(const std::string& uma_histogram_hame, | |
| 2282 const std::set<std::string>& command_line_difference) { | |
| 2283 for (std::set<std::string>::const_iterator it = | |
| 2284 command_line_difference.begin(); | |
| 2285 it != command_line_difference.end(); | |
| 2286 ++it) { | |
| 2287 int uma_id = about_flags::kBadSwitchFormatHistogramId; | |
| 2288 if (it->size() > 2) { | |
|
Ilya Sherman
2014/08/05 20:14:46
It seems more appropriate to check the actual char
Alexander Alekseev
2014/08/07 23:24:56
Done.
| |
| 2289 // Skip '--' before switch name. | |
| 2290 std::string switch_name(it->substr(2)); | |
| 2291 | |
| 2292 // Kill value, if any. | |
| 2293 const size_t value_pos = switch_name.find('='); | |
| 2294 if (value_pos != std::string::npos) | |
| 2295 switch_name.resize(value_pos); | |
| 2296 | |
| 2297 uma_id = GetSwitchUMAId(switch_name); | |
| 2298 } else { | |
| 2299 NOTREACHED() << "ReportCustomFlags(): flag '" << *it | |
| 2300 << "' has incorrect format."; | |
| 2301 } | |
| 2302 VLOG(1) << "ReportCustomFlags(): histogram='" << uma_histogram_hame << "' '" | |
| 2303 << *it << "', uma_id=" << uma_id; | |
| 2304 | |
| 2305 // Sparse histogram macro does not cache the histogram, so it's safe | |
| 2306 // to use macro with non-static histogram name here. | |
| 2307 UMA_HISTOGRAM_SPARSE_SLOWLY(uma_histogram_hame, uma_id); | |
| 2308 } | |
| 2309 } | |
| 2310 | |
| 2311 std::set<std::string> GetAllSwitchesForTesting() { | |
| 2312 return FlagsState::GetInstance()->GetAllSwitchesForTesting(); | |
| 2313 } | |
| 2314 | |
| 2265 ////////////////////////////////////////////////////////////////////////////// | 2315 ////////////////////////////////////////////////////////////////////////////// |
| 2266 // FlagsState implementation. | 2316 // FlagsState implementation. |
| 2267 | 2317 |
| 2268 namespace { | 2318 namespace { |
| 2269 | 2319 |
| 2270 typedef std::map<std::string, std::pair<std::string, std::string> > | 2320 typedef std::map<std::string, std::pair<std::string, std::string> > |
| 2271 NameToSwitchAndValueMap; | 2321 NameToSwitchAndValueMap; |
| 2272 | 2322 |
| 2273 void SetFlagToSwitchMapping(const std::string& key, | 2323 void SetFlagToSwitchMapping(const std::string& key, |
| 2274 const std::string& switch_name, | 2324 const std::string& switch_name, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2424 | 2474 |
| 2425 std::set<std::string> no_experiments; | 2475 std::set<std::string> no_experiments; |
| 2426 flags_storage->SetFlags(no_experiments); | 2476 flags_storage->SetFlags(no_experiments); |
| 2427 } | 2477 } |
| 2428 | 2478 |
| 2429 void FlagsState::reset() { | 2479 void FlagsState::reset() { |
| 2430 needs_restart_ = false; | 2480 needs_restart_ = false; |
| 2431 flags_switches_.clear(); | 2481 flags_switches_.clear(); |
| 2432 } | 2482 } |
| 2433 | 2483 |
| 2484 std::set<std::string> FlagsState::GetAllSwitchesForTesting() const { | |
| 2485 std::set<std::string> result; | |
| 2486 | |
| 2487 for (size_t i = 0; i < num_experiments; ++i) { | |
| 2488 const Experiment& e = experiments[i]; | |
|
Ilya Sherman
2014/08/05 20:14:46
nit: Please use complete variable names rather tha
Alexander Alekseev
2014/08/07 23:24:56
Done.
| |
| 2489 if (e.type == Experiment::SINGLE_VALUE) { | |
| 2490 result.insert(e.command_line_switch); | |
| 2491 } else if (e.type == Experiment::MULTI_VALUE) { | |
| 2492 for (int j = 0; j < e.num_choices; ++j) { | |
| 2493 result.insert(e.choices[j].command_line_switch); | |
| 2494 } | |
| 2495 } else { | |
| 2496 DCHECK_EQ(e.type, Experiment::ENABLE_DISABLE_VALUE); | |
| 2497 result.insert(e.command_line_switch); | |
| 2498 result.insert(e.disable_command_line_switch); | |
| 2499 } | |
| 2500 } | |
| 2501 return result; | |
| 2502 } | |
|
Ilya Sherman
2014/08/05 20:14:46
Why isn't this in the testing namespace below? In
Alexander Alekseev
2014/08/07 23:24:56
Done.
| |
| 2503 | |
| 2434 } // namespace | 2504 } // namespace |
| 2435 | 2505 |
| 2436 namespace testing { | 2506 namespace testing { |
| 2437 | 2507 |
| 2438 // WARNING: '@' is also used in the html file. If you update this constant you | 2508 // WARNING: '@' is also used in the html file. If you update this constant you |
| 2439 // also need to update the html file. | 2509 // also need to update the html file. |
| 2440 const char kMultiSeparator[] = "@"; | 2510 const char kMultiSeparator[] = "@"; |
| 2441 | 2511 |
| 2442 void ClearState() { | 2512 void ClearState() { |
| 2443 FlagsState::GetInstance()->reset(); | 2513 FlagsState::GetInstance()->reset(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2454 } | 2524 } |
| 2455 | 2525 |
| 2456 const Experiment* GetExperiments(size_t* count) { | 2526 const Experiment* GetExperiments(size_t* count) { |
| 2457 *count = num_experiments; | 2527 *count = num_experiments; |
| 2458 return experiments; | 2528 return experiments; |
| 2459 } | 2529 } |
| 2460 | 2530 |
| 2461 } // namespace testing | 2531 } // namespace testing |
| 2462 | 2532 |
| 2463 } // namespace about_flags | 2533 } // namespace about_flags |
| OLD | NEW |