Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(172)

Side by Side Diff: chrome/browser/about_flags.cc

Issue 344883002: Collect UMA statistics on which chrome://flags lead to chrome restart on ChromeOS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Report hash(switch name). Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 kOsCrOS, 1511 kOsCrOS,
1508 SINGLE_VALUE_TYPE(app_list::switches::kDisableVoiceSearch) 1512 SINGLE_VALUE_TYPE(app_list::switches::kDisableVoiceSearch)
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 UMA_HISTOGRAM_ID_kEnableAccessibilityTabSwitcher)
sky 2014/08/05 16:49:14 Why are you doing this change?
Alexander Alekseev 2014/08/05 17:03:07 It is a bug. Thank you for pointing out. Fixed.
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 }, 1523 },
1529 #endif 1524 #endif
1530 { 1525 {
1531 "enable-one-copy", 1526 "enable-one-copy",
1532 IDS_FLAGS_ONE_COPY_NAME, 1527 IDS_FLAGS_ONE_COPY_NAME,
1533 IDS_FLAGS_ONE_COPY_DESCRIPTION, 1528 IDS_FLAGS_ONE_COPY_DESCRIPTION,
1534 kOsAll, 1529 kOsAll,
1535 SINGLE_VALUE_TYPE(switches::kEnableOneCopy) 1530 SINGLE_VALUE_TYPE(switches::kEnableOneCopy)
1536 }, 1531 },
1537 { 1532 {
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 SentinelsMode sentinels); 1942 SentinelsMode sentinels);
1948 bool IsRestartNeededToCommitChanges(); 1943 bool IsRestartNeededToCommitChanges();
1949 void SetExperimentEnabled( 1944 void SetExperimentEnabled(
1950 FlagsStorage* flags_storage, 1945 FlagsStorage* flags_storage,
1951 const std::string& internal_name, 1946 const std::string& internal_name,
1952 bool enable); 1947 bool enable);
1953 void RemoveFlagsSwitches( 1948 void RemoveFlagsSwitches(
1954 std::map<std::string, CommandLine::StringType>* switch_list); 1949 std::map<std::string, CommandLine::StringType>* switch_list);
1955 void ResetAllFlags(FlagsStorage* flags_storage); 1950 void ResetAllFlags(FlagsStorage* flags_storage);
1956 void reset(); 1951 void reset();
1952 std::set<std::string> GetAllSwitchesForTesting() const;
1957 1953
1958 // Returns the singleton instance of this class 1954 // Returns the singleton instance of this class
1959 static FlagsState* GetInstance() { 1955 static FlagsState* GetInstance() {
1960 return Singleton<FlagsState>::get(); 1956 return Singleton<FlagsState>::get();
1961 } 1957 }
1962 1958
1963 private: 1959 private:
1964 bool needs_restart_; 1960 bool needs_restart_;
1965 std::map<std::string, std::string> flags_switches_; 1961 std::map<std::string, std::string> flags_switches_;
1966 1962
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 2133
2138 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, 2134 void ConvertFlagsToSwitches(FlagsStorage* flags_storage,
2139 CommandLine* command_line, 2135 CommandLine* command_line,
2140 SentinelsMode sentinels) { 2136 SentinelsMode sentinels) {
2141 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage, 2137 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage,
2142 command_line, 2138 command_line,
2143 sentinels); 2139 sentinels);
2144 } 2140 }
2145 2141
2146 bool AreSwitchesIdenticalToCurrentCommandLine( 2142 bool AreSwitchesIdenticalToCurrentCommandLine(
2147 const CommandLine& new_cmdline, const CommandLine& active_cmdline) { 2143 const CommandLine& new_cmdline,
2144 const CommandLine& active_cmdline,
2145 std::set<CommandLine::StringType>* out_difference) {
2148 std::set<CommandLine::StringType> new_flags = 2146 std::set<CommandLine::StringType> new_flags =
2149 ExtractFlagsFromCommandLine(new_cmdline); 2147 ExtractFlagsFromCommandLine(new_cmdline);
2150 std::set<CommandLine::StringType> active_flags = 2148 std::set<CommandLine::StringType> active_flags =
2151 ExtractFlagsFromCommandLine(active_cmdline); 2149 ExtractFlagsFromCommandLine(active_cmdline);
2152 2150
2151 bool result = false;
2153 // Needed because std::equal doesn't check if the 2nd set is empty. 2152 // Needed because std::equal doesn't check if the 2nd set is empty.
2154 if (new_flags.size() != active_flags.size()) 2153 if (new_flags.size() == active_flags.size()) {
2155 return false; 2154 result =
2155 std::equal(new_flags.begin(), new_flags.end(), active_flags.begin());
2156 }
2156 2157
2157 return std::equal(new_flags.begin(), new_flags.end(), active_flags.begin()); 2158 if (out_difference && !result) {
2159 std::set_symmetric_difference(
2160 new_flags.begin(),
2161 new_flags.end(),
2162 active_flags.begin(),
2163 active_flags.end(),
2164 std::inserter(*out_difference, out_difference->begin()));
2165 }
2166
2167 return result;
2158 } 2168 }
2159 2169
2160 void GetFlagsExperimentsData(FlagsStorage* flags_storage, 2170 void GetFlagsExperimentsData(FlagsStorage* flags_storage,
2161 FlagAccess access, 2171 FlagAccess access,
2162 base::ListValue* supported_experiments, 2172 base::ListValue* supported_experiments,
2163 base::ListValue* unsupported_experiments) { 2173 base::ListValue* unsupported_experiments) {
2164 std::set<std::string> enabled_experiments; 2174 std::set<std::string> enabled_experiments;
2165 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2175 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments);
2166 2176
2167 int current_platform = GetCurrentPlatform(); 2177 int current_platform = GetCurrentPlatform();
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 action += *it; 2265 action += *it;
2256 content::RecordComputedAction(action); 2266 content::RecordComputedAction(action);
2257 } 2267 }
2258 // Since flag metrics are recorded every startup, add a tick so that the 2268 // Since flag metrics are recorded every startup, add a tick so that the
2259 // stats can be made meaningful. 2269 // stats can be made meaningful.
2260 if (flags.size()) 2270 if (flags.size())
2261 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick")); 2271 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick"));
2262 content::RecordAction(UserMetricsAction("StartupTick")); 2272 content::RecordAction(UserMetricsAction("StartupTick"));
2263 } 2273 }
2264 2274
2275 uint32 GetSwitchUMAId(const std::string& switch_name) {
2276 return static_cast<unsigned>(
2277 crc32(0,
2278 reinterpret_cast<const Bytef*>(switch_name.c_str()),
2279 switch_name.length()));
2280 }
2281
2282 void ReportCustomFlags(const std::string& uma_histogram_hame,
2283 const std::set<std::string>& command_line_difference) {
2284 for (std::set<std::string>::const_iterator it =
2285 command_line_difference.begin();
2286 it != command_line_difference.end();
2287 ++it) {
2288 int uma_id = about_flags::kBadSwitchFormatHistogramId;
2289 if (it->size() > 2) {
2290 // Skip '--' before switch name.
2291 std::string switch_name(it->substr(2));
2292
2293 // Kill value, if any.
2294 const size_t value_pos = switch_name.find('=');
2295 if (value_pos != std::string::npos)
2296 switch_name.resize(value_pos);
2297
2298 uma_id = GetSwitchUMAId(switch_name);
2299 } else {
2300 NOTREACHED() << "ReportCustomFlags(): flag '" << *it
2301 << "' has incorrect format.";
2302 }
2303 VLOG(1) << "ReportCustomFlags(): histogram='" << uma_histogram_hame << "' '"
2304 << *it << "', uma_id=" << uma_id;
2305
2306 // Sparse histogram macro does not cache the histogram, so it's safe
2307 // to use macro with non-static histogram name here.
2308 UMA_HISTOGRAM_SPARSE_SLOWLY(uma_histogram_hame, uma_id);
2309 }
2310 }
2311
2312 std::set<std::string> GetAllSwitchesForTesting() {
2313 return FlagsState::GetInstance()->GetAllSwitchesForTesting();
2314 }
2315
2265 ////////////////////////////////////////////////////////////////////////////// 2316 //////////////////////////////////////////////////////////////////////////////
2266 // FlagsState implementation. 2317 // FlagsState implementation.
2267 2318
2268 namespace { 2319 namespace {
2269 2320
2270 typedef std::map<std::string, std::pair<std::string, std::string> > 2321 typedef std::map<std::string, std::pair<std::string, std::string> >
2271 NameToSwitchAndValueMap; 2322 NameToSwitchAndValueMap;
2272 2323
2273 void SetFlagToSwitchMapping(const std::string& key, 2324 void SetFlagToSwitchMapping(const std::string& key,
2274 const std::string& switch_name, 2325 const std::string& switch_name,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2424 2475
2425 std::set<std::string> no_experiments; 2476 std::set<std::string> no_experiments;
2426 flags_storage->SetFlags(no_experiments); 2477 flags_storage->SetFlags(no_experiments);
2427 } 2478 }
2428 2479
2429 void FlagsState::reset() { 2480 void FlagsState::reset() {
2430 needs_restart_ = false; 2481 needs_restart_ = false;
2431 flags_switches_.clear(); 2482 flags_switches_.clear();
2432 } 2483 }
2433 2484
2485 std::set<std::string> FlagsState::GetAllSwitchesForTesting() const {
2486 std::set<std::string> result;
2487
2488 for (size_t i = 0; i < num_experiments; ++i) {
2489 const Experiment& e = experiments[i];
2490 if (e.type == Experiment::SINGLE_VALUE) {
2491 result.insert(e.command_line_switch);
2492 } else if (e.type == Experiment::MULTI_VALUE) {
2493 for (int j = 0; j < e.num_choices; ++j) {
2494 result.insert(e.choices[j].command_line_switch);
2495 }
2496 } else {
2497 DCHECK_EQ(e.type, Experiment::ENABLE_DISABLE_VALUE);
2498 result.insert(e.command_line_switch);
2499 result.insert(e.disable_command_line_switch);
2500 }
2501 }
2502 return result;
2503 }
2504
2434 } // namespace 2505 } // namespace
2435 2506
2436 namespace testing { 2507 namespace testing {
2437 2508
2438 // WARNING: '@' is also used in the html file. If you update this constant you 2509 // WARNING: '@' is also used in the html file. If you update this constant you
2439 // also need to update the html file. 2510 // also need to update the html file.
2440 const char kMultiSeparator[] = "@"; 2511 const char kMultiSeparator[] = "@";
2441 2512
2442 void ClearState() { 2513 void ClearState() {
2443 FlagsState::GetInstance()->reset(); 2514 FlagsState::GetInstance()->reset();
(...skipping 10 matching lines...) Expand all
2454 } 2525 }
2455 2526
2456 const Experiment* GetExperiments(size_t* count) { 2527 const Experiment* GetExperiments(size_t* count) {
2457 *count = num_experiments; 2528 *count = num_experiments;
2458 return experiments; 2529 return experiments;
2459 } 2530 }
2460 2531
2461 } // namespace testing 2532 } // namespace testing
2462 2533
2463 } // namespace about_flags 2534 } // namespace about_flags
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698