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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/about_flags.h" 6 7 #include <iterator> 8 #include <map> 9 #include <set> 10 #include <utility> 11 12 #include "base/command_line.h" 13 #include "base/memory/singleton.h" 14 #include "base/metrics/sparse_histogram.h" 15 #include "base/numerics/safe_conversions.h" 16 #include "base/stl_util.h" 17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_util.h" 19 #include "base/strings/utf_string_conversions.h" 20 #include "base/values.h" 21 #include "cc/base/switches.h" 22 #include "chrome/browser/bookmarks/enhanced_bookmarks_features.h" 23 #include "chrome/browser/flags_storage.h" 24 #include "chrome/common/chrome_content_client.h" 25 #include "chrome/common/chrome_switches.h" 26 #include "chrome/grit/generated_resources.h" 27 #include "components/autofill/core/common/autofill_switches.h" 28 #include "components/cloud_devices/common/cloud_devices_switches.h" 29 #include "components/metrics/metrics_hashes.h" 30 #include "components/nacl/common/nacl_switches.h" 31 #include "components/search/search_switches.h" 32 #include "content/public/browser/user_metrics.h" 33 #include "media/base/media_switches.h" 34 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/ui_base_switches.h" 36 #include "ui/display/display_switches.h" 37 #include "ui/events/event_switches.h" 38 #include "ui/gfx/switches.h" 39 #include "ui/gl/gl_switches.h" 40 #include "ui/keyboard/keyboard_switches.h" 41 #include "ui/native_theme/native_theme_switches.h" 42 #include "ui/views/views_switches.h" 43 44 #if defined(OS_ANDROID) 45 #include "chrome/common/chrome_version_info.h" 46 #include "components/data_reduction_proxy/common/data_reduction_proxy_switches.h" 47 #include "components/omnibox/omnibox_switches.h" 48 #else 49 #include "ui/message_center/message_center_switches.h" 50 #endif 51 52 #if defined(USE_ASH) 53 #include "ash/ash_switches.h" 54 #endif 55 56 #if defined(OS_CHROMEOS) 57 #include "chromeos/chromeos_switches.h" 58 #include "third_party/cros_system_api/switches/chrome_switches.h" 59 #endif 60 61 #if defined(ENABLE_APP_LIST) 62 #include "ui/app_list/app_list_switches.h" 63 #endif 64 65 #if defined(ENABLE_EXTENSIONS) 66 #include "extensions/common/switches.h" 67 #endif 68 69 using base::UserMetricsAction; 70 71 namespace about_flags { 72 73 const base::HistogramBase::Sample kBadSwitchFormatHistogramId = 0; 74 75 // Macros to simplify specifying the type. 76 #define SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, switch_value) \ 77 Experiment::SINGLE_VALUE, \ 78 command_line_switch, switch_value, NULL, NULL, NULL, 0 79 #define SINGLE_VALUE_TYPE(command_line_switch) \ 80 SINGLE_VALUE_TYPE_AND_VALUE(command_line_switch, "") 81 #define ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, enable_value, \ 82 disable_switch, disable_value) \ 83 Experiment::ENABLE_DISABLE_VALUE, enable_switch, enable_value, \ 84 disable_switch, disable_value, NULL, 3 85 #define ENABLE_DISABLE_VALUE_TYPE(enable_switch, disable_switch) \ 86 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE(enable_switch, "", disable_switch, "") 87 #define MULTI_VALUE_TYPE(choices) \ 88 Experiment::MULTI_VALUE, NULL, NULL, NULL, NULL, choices, arraysize(choices) 89 90 namespace { 91 92 const unsigned kOsAll = kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid; 93 const unsigned kOsDesktop = kOsMac | kOsWin | kOsLinux | kOsCrOS; 94 95 // Adds a |StringValue| to |list| for each platform where |bitmask| indicates 96 // whether the experiment is available on that platform. 97 void AddOsStrings(unsigned bitmask, base::ListValue* list) { 98 struct { 99 unsigned bit; 100 const char* const name; 101 } kBitsToOs[] = { 102 {kOsMac, "Mac"}, 103 {kOsWin, "Windows"}, 104 {kOsLinux, "Linux"}, 105 {kOsCrOS, "Chrome OS"}, 106 {kOsAndroid, "Android"}, 107 {kOsCrOSOwnerOnly, "Chrome OS (owner only)"}, 108 }; 109 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kBitsToOs); ++i) 110 if (bitmask & kBitsToOs[i].bit) 111 list->Append(new base::StringValue(kBitsToOs[i].name)); 112 } 113 114 // Convert switch constants to proper CommandLine::StringType strings. 115 CommandLine::StringType GetSwitchString(const std::string& flag) { 116 CommandLine cmd_line(CommandLine::NO_PROGRAM); 117 cmd_line.AppendSwitch(flag); 118 DCHECK_EQ(2U, cmd_line.argv().size()); 119 return cmd_line.argv()[1]; 120 } 121 122 // Scoops flags from a command line. 123 std::set<CommandLine::StringType> ExtractFlagsFromCommandLine( 124 const CommandLine& cmdline) { 125 std::set<CommandLine::StringType> flags; 126 // First do the ones between --flag-switches-begin and --flag-switches-end. 127 CommandLine::StringVector::const_iterator first = 128 std::find(cmdline.argv().begin(), cmdline.argv().end(), 129 GetSwitchString(switches::kFlagSwitchesBegin)); 130 CommandLine::StringVector::const_iterator last = 131 std::find(cmdline.argv().begin(), cmdline.argv().end(), 132 GetSwitchString(switches::kFlagSwitchesEnd)); 133 if (first != cmdline.argv().end() && last != cmdline.argv().end()) 134 flags.insert(first + 1, last); 135 #if defined(OS_CHROMEOS) 136 // Then add those between --policy-switches-begin and --policy-switches-end. 137 first = std::find(cmdline.argv().begin(), cmdline.argv().end(), 138 GetSwitchString(chromeos::switches::kPolicySwitchesBegin)); 139 last = std::find(cmdline.argv().begin(), cmdline.argv().end(), 140 GetSwitchString(chromeos::switches::kPolicySwitchesEnd)); 141 if (first != cmdline.argv().end() && last != cmdline.argv().end()) 142 flags.insert(first + 1, last); 143 #endif 144 return flags; 145 } 146 147 const Experiment::Choice kEnableDisplayList2DcanvasChoices[] = { 148 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 149 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 150 switches::kEnableDisplayList2dCanvas, ""}, 151 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 152 switches::kDisableDisplayList2dCanvas, ""}, 153 }; 154 155 const Experiment::Choice kEnableCompositingForTransitionChoices[] = { 156 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 157 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 158 switches::kEnableCompositingForTransition, ""}, 159 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 160 switches::kDisableCompositingForTransition, ""}, 161 }; 162 163 const Experiment::Choice kTouchEventsChoices[] = { 164 { IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC, "", "" }, 165 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 166 switches::kTouchEvents, 167 switches::kTouchEventsEnabled }, 168 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 169 switches::kTouchEvents, 170 switches::kTouchEventsDisabled } 171 }; 172 173 #if defined(USE_AURA) 174 const Experiment::Choice kOverscrollHistoryNavigationChoices[] = { 175 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, "", "" }, 176 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 177 switches::kOverscrollHistoryNavigation, 178 "0" }, 179 { IDS_OVERSCROLL_HISTORY_NAVIGATION_SIMPLE_UI, 180 switches::kOverscrollHistoryNavigation, 181 "2" } 182 }; 183 #endif 184 185 #if !defined(DISABLE_NACL) 186 const Experiment::Choice kNaClDebugMaskChoices[] = { 187 // Secure shell can be used on ChromeOS for forwarding the TCP port opened by 188 // debug stub to a remote machine. Since secure shell uses NaCl, we usually 189 // want to avoid debugging that. The PNaCl translator is also a NaCl module, 190 // so by default we want to avoid debugging that. 191 // NOTE: As the default value must be the empty string, the mask excluding 192 // the PNaCl translator and secure shell is substituted elsewhere. 193 { IDS_NACL_DEBUG_MASK_CHOICE_EXCLUDE_UTILS_PNACL, "", "" }, 194 { IDS_NACL_DEBUG_MASK_CHOICE_DEBUG_ALL, switches::kNaClDebugMask, "*://*" }, 195 { IDS_NACL_DEBUG_MASK_CHOICE_INCLUDE_DEBUG, 196 switches::kNaClDebugMask, "*://*/*debug.nmf" } 197 }; 198 #endif 199 200 const Experiment::Choice kImplSidePaintingChoices[] = { 201 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 202 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 203 switches::kEnableImplSidePainting, ""}, 204 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 205 switches::kDisableImplSidePainting, ""} 206 }; 207 208 const Experiment::Choice kLCDTextChoices[] = { 209 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 210 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, switches::kEnableLCDText, ""}, 211 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kDisableLCDText, ""} 212 }; 213 214 const Experiment::Choice kDistanceFieldTextChoices[] = { 215 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 216 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 217 switches::kEnableDistanceFieldText, "" }, 218 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 219 switches::kDisableDistanceFieldText, "" } 220 }; 221 222 #ifndef USE_AURA 223 const Experiment::Choice kDelegatedRendererChoices[] = { 224 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 225 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 226 switches::kEnableDelegatedRenderer, ""}, 227 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 228 switches::kDisableDelegatedRenderer, ""} 229 }; 230 #endif 231 232 const Experiment::Choice kMaxTilesForInterestAreaChoices[] = { 233 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 234 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_SHORT, 235 cc::switches::kMaxTilesForInterestArea, "64"}, 236 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_TALL, 237 cc::switches::kMaxTilesForInterestArea, "128"}, 238 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_GRANDE, 239 cc::switches::kMaxTilesForInterestArea, "256"}, 240 { IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_VENTI, 241 cc::switches::kMaxTilesForInterestArea, "512"} 242 }; 243 244 const Experiment::Choice kDefaultTileWidthChoices[] = { 245 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 246 { IDS_FLAGS_DEFAULT_TILE_WIDTH_SHORT, 247 switches::kDefaultTileWidth, "128"}, 248 { IDS_FLAGS_DEFAULT_TILE_WIDTH_TALL, 249 switches::kDefaultTileWidth, "256"}, 250 { IDS_FLAGS_DEFAULT_TILE_WIDTH_GRANDE, 251 switches::kDefaultTileWidth, "512"}, 252 { IDS_FLAGS_DEFAULT_TILE_WIDTH_VENTI, 253 switches::kDefaultTileWidth, "1024"} 254 }; 255 256 const Experiment::Choice kDefaultTileHeightChoices[] = { 257 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 258 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_SHORT, 259 switches::kDefaultTileHeight, "128"}, 260 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_TALL, 261 switches::kDefaultTileHeight, "256"}, 262 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_GRANDE, 263 switches::kDefaultTileHeight, "512"}, 264 { IDS_FLAGS_DEFAULT_TILE_HEIGHT_VENTI, 265 switches::kDefaultTileHeight, "1024"} 266 }; 267 268 const Experiment::Choice kSimpleCacheBackendChoices[] = { 269 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 270 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 271 switches::kUseSimpleCacheBackend, "off" }, 272 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 273 switches::kUseSimpleCacheBackend, "on"} 274 }; 275 276 #if defined(USE_AURA) 277 const Experiment::Choice kTabCaptureUpscaleQualityChoices[] = { 278 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 279 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_FAST, 280 switches::kTabCaptureUpscaleQuality, "fast" }, 281 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_GOOD, 282 switches::kTabCaptureUpscaleQuality, "good" }, 283 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_BEST, 284 switches::kTabCaptureUpscaleQuality, "best" }, 285 }; 286 287 const Experiment::Choice kTabCaptureDownscaleQualityChoices[] = { 288 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 289 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_FAST, 290 switches::kTabCaptureDownscaleQuality, "fast" }, 291 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_GOOD, 292 switches::kTabCaptureDownscaleQuality, "good" }, 293 { IDS_FLAGS_TAB_CAPTURE_SCALE_QUALITY_BEST, 294 switches::kTabCaptureDownscaleQuality, "best" }, 295 }; 296 #endif 297 298 #if defined(USE_AURA) || defined(OS_LINUX) 299 const Experiment::Choice kOverlayScrollbarChoices[] = { 300 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 301 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 302 switches::kEnableOverlayScrollbar, ""}, 303 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 304 switches::kDisableOverlayScrollbar, ""} 305 }; 306 #endif 307 308 const Experiment::Choice kZeroCopyChoices[] = { 309 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 310 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 311 switches::kEnableZeroCopy, ""}, 312 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 313 switches::kDisableZeroCopy, ""} 314 }; 315 316 #if defined(OS_ANDROID) 317 const Experiment::Choice kZeroSuggestExperimentsChoices[] = { 318 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 319 { IDS_FLAGS_ZERO_SUGGEST_MOST_VISITED, 320 switches::kEnableZeroSuggestMostVisited, ""}, 321 { IDS_FLAGS_ZERO_SUGGEST_ETHER_SERP, 322 switches::kEnableZeroSuggestEtherSerp, ""}, 323 { IDS_FLAGS_ZERO_SUGGEST_ETHER_NO_SERP, 324 switches::kEnableZeroSuggestEtherNoSerp, ""}, 325 { IDS_FLAGS_ZERO_SUGGEST_PERSONALIZED, 326 switches::kEnableZeroSuggestPersonalized, ""}, 327 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 328 switches::kDisableZeroSuggest, ""} 329 }; 330 #endif 331 332 const Experiment::Choice kNumRasterThreadsChoices[] = { 333 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 334 { IDS_FLAGS_NUM_RASTER_THREADS_ONE, switches::kNumRasterThreads, "1" }, 335 { IDS_FLAGS_NUM_RASTER_THREADS_TWO, switches::kNumRasterThreads, "2" }, 336 { IDS_FLAGS_NUM_RASTER_THREADS_THREE, switches::kNumRasterThreads, "3" }, 337 { IDS_FLAGS_NUM_RASTER_THREADS_FOUR, switches::kNumRasterThreads, "4" } 338 }; 339 340 const Experiment::Choice kEnableGpuRasterizationChoices[] = { 341 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 342 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 343 switches::kEnableGpuRasterization, "" }, 344 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 345 switches::kDisableGpuRasterization, "" }, 346 { IDS_FLAGS_FORCE_GPU_RASTERIZATION, 347 switches::kForceGpuRasterization, "" }, 348 }; 349 350 // We're using independent flags here (as opposed to a common flag with 351 // different values) to be able to enable/disable the entire experience 352 // associated with this feature server-side from the FieldTrial (the complete 353 // experience includes other flag changes as well). It is not currently possible 354 // to do that with "flag=value" flags. 355 const Experiment::Choice kSearchButtonInOmniboxChoices[] = { 356 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 357 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 358 switches::kDisableSearchButtonInOmnibox, ""}, 359 { IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_ENABLE_FOR_STR, 360 switches::kEnableSearchButtonInOmniboxForStr, ""}, 361 { IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_ENABLE_FOR_STR_OR_IIP, 362 switches::kEnableSearchButtonInOmniboxForStrOrIip, ""}, 363 { IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_ENABLED, 364 switches::kEnableSearchButtonInOmniboxAlways, ""} 365 }; 366 367 // See comment above for kSearchButtonInOmniboxChoices. The same reasoning 368 // applies here. 369 const Experiment::Choice kOriginChipChoices[] = { 370 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 371 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kDisableOriginChip, ""}, 372 { IDS_FLAGS_ORIGIN_CHIP_ALWAYS, switches::kEnableOriginChipAlways, ""}, 373 { IDS_FLAGS_ORIGIN_CHIP_ON_SRP, switches::kEnableOriginChipOnSrp, ""} 374 }; 375 376 const Experiment::Choice kTouchScrollingModeChoices[] = { 377 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 378 { IDS_FLAGS_TOUCH_SCROLLING_MODE_TOUCHCANCEL, 379 switches::kTouchScrollingMode, 380 switches::kTouchScrollingModeTouchcancel }, 381 { IDS_FLAGS_TOUCH_SCROLLING_MODE_ASYNC_TOUCHMOVE, 382 switches::kTouchScrollingMode, 383 switches::kTouchScrollingModeAsyncTouchmove }, 384 { IDS_FLAGS_TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE, 385 switches::kTouchScrollingMode, 386 switches::kTouchScrollingModeSyncTouchmove }, 387 }; 388 389 #if defined(ENABLE_APP_LIST) 390 const Experiment::Choice kEnableSyncAppListChoices[] = { 391 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 392 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 393 app_list::switches::kEnableSyncAppList, "" }, 394 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 395 app_list::switches::kDisableSyncAppList, "" }, 396 }; 397 #endif 398 399 const Experiment::Choice kExtensionContentVerificationChoices[] = { 400 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 401 { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_BOOTSTRAP, 402 switches::kExtensionContentVerification, 403 switches::kExtensionContentVerificationBootstrap }, 404 { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE, 405 switches::kExtensionContentVerification, 406 switches::kExtensionContentVerificationEnforce }, 407 { IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_ENFORCE_STRICT, 408 switches::kExtensionContentVerification, 409 switches::kExtensionContentVerificationEnforceStrict }, 410 }; 411 412 #if defined(OS_ANDROID) 413 const Experiment::Choice kAnswersInSuggestChoices[] = { 414 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 415 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 416 switches::kEnableAnswersInSuggest, ""}, 417 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 418 switches::kDisableAnswersInSuggest, ""} 419 }; 420 #endif 421 422 const Experiment::Choice kEnableSettingsWindowChoices[] = { 423 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 424 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 425 ::switches::kEnableSettingsWindow, "" }, 426 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 427 ::switches::kDisableSettingsWindow, "" }, 428 }; 429 430 // Note that the value is specified in seconds (where 0 is equivalent to 431 // disabled). 432 const Experiment::Choice kRememberCertificateErrorDecisionsChoices[] = { 433 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 434 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 435 switches::kRememberCertErrorDecisions, 436 "-1" }, 437 { IDS_REMEMBER_CERTIFICATE_ERROR_DECISION_CHOICE_ONE_DAY, 438 switches::kRememberCertErrorDecisions, 439 "86400" }, 440 { IDS_REMEMBER_CERTIFICATE_ERROR_DECISION_CHOICE_THREE_DAYS, 441 switches::kRememberCertErrorDecisions, 442 "259200" }, 443 { IDS_REMEMBER_CERTIFICATE_ERROR_DECISION_CHOICE_ONE_WEEK, 444 switches::kRememberCertErrorDecisions, 445 "604800" }, 446 { IDS_REMEMBER_CERTIFICATE_ERROR_DECISION_CHOICE_ONE_MONTH, 447 switches::kRememberCertErrorDecisions, 448 "2592000" }, 449 { IDS_REMEMBER_CERTIFICATE_ERROR_DECISION_CHOICE_THREE_MONTHS, 450 switches::kRememberCertErrorDecisions, 451 "7776000" }, 452 }; 453 454 const Experiment::Choice kEnableDropSyncCredentialChoices[] = { 455 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""}, 456 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 457 password_manager::switches::kEnableDropSyncCredential, "" }, 458 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 459 password_manager::switches::kDisableDropSyncCredential, "" }, 460 }; 461 462 #if defined(OS_MACOSX) 463 const Experiment::Choice kEnableAVFoundationChoices[] = { 464 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", "" }, 465 { IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, switches::kEnableAVFoundation, ""}, 466 { IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, switches::kForceQTKit, ""} 467 }; 468 #endif 469 470 const Experiment::Choice kAutofillSyncCredentialChoices[] = { 471 { IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, "", ""}, 472 { IDS_ALLOW_AUTOFILL_SYNC_CREDENTIAL, 473 password_manager::switches::kAllowAutofillSyncCredential, ""}, 474 { IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL_FOR_REAUTH, 475 password_manager::switches::kDisallowAutofillSyncCredentialForReauth, ""}, 476 { IDS_DISALLOW_AUTOFILL_SYNC_CREDENTIAL, 477 password_manager::switches::kDisallowAutofillSyncCredential, ""}, 478 }; 479 480 // RECORDING USER METRICS FOR FLAGS: 481 // ----------------------------------------------------------------------------- 482 // The first line of the experiment is the internal name. If you'd like to 483 // gather statistics about the usage of your flag, you should append a marker 484 // comment to the end of the feature name, like so: 485 // "my-special-feature", // FLAGS:RECORD_UMA 486 // 487 // After doing that, run 488 // tools/metrics/actions/extract_actions.py 489 // to add the metric to actions.xml (which will enable UMA to record your 490 // feature flag), then update the <owner>s and <description> sections. Make sure 491 // to include the actions.xml file when you upload your code for review! 492 // 493 // After your feature has shipped under a flag, you can locate the metrics under 494 // the action name AboutFlags_internal-action-name. Actions are recorded once 495 // per startup, so you should divide this number by AboutFlags_StartupTick to 496 // get a sense of usage. Note that this will not be the same as number of users 497 // with a given feature enabled because users can quit and relaunch the 498 // application multiple times over a given time interval. The dashboard also 499 // shows you how many (metrics reporting) users have enabled the flag over the 500 // last seven days. However, note that this is not the same as the number of 501 // users who have the flag enabled, since enabling the flag happens once, 502 // whereas running with the flag enabled happens until the user flips the flag 503 // again. 504 505 // To add a new experiment add to the end of kExperiments. There are two 506 // distinct types of experiments: 507 // . SINGLE_VALUE: experiment is either on or off. Use the SINGLE_VALUE_TYPE 508 // macro for this type supplying the command line to the macro. 509 // . MULTI_VALUE: a list of choices, the first of which should correspond to a 510 // deactivated state for this lab (i.e. no command line option). To specify 511 // this type of experiment use the macro MULTI_VALUE_TYPE supplying it the 512 // array of choices. 513 // See the documentation of Experiment for details on the fields. 514 // 515 // Command-line switches must have entries in enum "LoginCustomFlags" in 516 // histograms.xml. See note in histograms.xml and don't forget to run 517 // AboutFlagsHistogramTest unit test to calculate and verify checksum. 518 // 519 // When adding a new choice, add it to the end of the list. 520 const Experiment kExperiments[] = { 521 { 522 "ignore-gpu-blacklist", 523 IDS_FLAGS_IGNORE_GPU_BLACKLIST_NAME, 524 IDS_FLAGS_IGNORE_GPU_BLACKLIST_DESCRIPTION, 525 kOsAll, 526 SINGLE_VALUE_TYPE(switches::kIgnoreGpuBlacklist) 527 }, 528 { 529 "disable_layer_squashing", 530 IDS_FLAGS_DISABLE_LAYER_SQUASHING_NAME, 531 IDS_FLAGS_DISABLE_LAYER_SQUASHING_DESCRIPTION, 532 kOsAll, 533 SINGLE_VALUE_TYPE(switches::kDisableLayerSquashing) 534 }, 535 #if defined(OS_WIN) 536 { 537 "disable-direct-write", 538 IDS_FLAGS_DISABLE_DIRECT_WRITE_NAME, 539 IDS_FLAGS_DISABLE_DIRECT_WRITE_DESCRIPTION, 540 kOsWin, 541 SINGLE_VALUE_TYPE(switches::kDisableDirectWrite) 542 }, 543 #endif 544 { 545 "enable-experimental-canvas-features", 546 IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME, 547 IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_DESCRIPTION, 548 kOsAll, 549 SINGLE_VALUE_TYPE(switches::kEnableExperimentalCanvasFeatures) 550 }, 551 { 552 "disable-accelerated-2d-canvas", 553 IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_NAME, 554 IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_DESCRIPTION, 555 kOsAll, 556 SINGLE_VALUE_TYPE(switches::kDisableAccelerated2dCanvas) 557 }, 558 { 559 "enable-display-list-2d-canvas", 560 IDS_FLAGS_ENABLE_DISPLAY_LIST_2D_CANVAS_NAME, 561 IDS_FLAGS_ENABLE_DISPLAY_LIST_2D_CANVAS_DESCRIPTION, 562 kOsAll, 563 MULTI_VALUE_TYPE(kEnableDisplayList2DcanvasChoices) 564 }, 565 { 566 "composited-layer-borders", 567 IDS_FLAGS_COMPOSITED_LAYER_BORDERS, 568 IDS_FLAGS_COMPOSITED_LAYER_BORDERS_DESCRIPTION, 569 kOsAll, 570 SINGLE_VALUE_TYPE(cc::switches::kShowCompositedLayerBorders) 571 }, 572 { 573 "show-fps-counter", 574 IDS_FLAGS_SHOW_FPS_COUNTER, 575 IDS_FLAGS_SHOW_FPS_COUNTER_DESCRIPTION, 576 kOsAll, 577 SINGLE_VALUE_TYPE(cc::switches::kShowFPSCounter) 578 }, 579 { 580 "disable-webgl", 581 IDS_FLAGS_DISABLE_WEBGL_NAME, 582 IDS_FLAGS_DISABLE_WEBGL_DESCRIPTION, 583 kOsAll, 584 SINGLE_VALUE_TYPE(switches::kDisableExperimentalWebGL) 585 }, 586 { 587 "disable-webrtc", 588 IDS_FLAGS_DISABLE_WEBRTC_NAME, 589 IDS_FLAGS_DISABLE_WEBRTC_DESCRIPTION, 590 kOsAndroid, 591 #if defined(OS_ANDROID) 592 SINGLE_VALUE_TYPE(switches::kDisableWebRTC) 593 #else 594 SINGLE_VALUE_TYPE("") 595 #endif 596 }, 597 #if defined(ENABLE_WEBRTC) 598 { 599 "disable-webrtc-hw-decoding", 600 IDS_FLAGS_DISABLE_WEBRTC_HW_DECODING_NAME, 601 IDS_FLAGS_DISABLE_WEBRTC_HW_DECODING_DESCRIPTION, 602 kOsAndroid | kOsCrOS, 603 SINGLE_VALUE_TYPE(switches::kDisableWebRtcHWDecoding) 604 }, 605 { 606 "disable-webrtc-hw-encoding", 607 IDS_FLAGS_DISABLE_WEBRTC_HW_ENCODING_NAME, 608 IDS_FLAGS_DISABLE_WEBRTC_HW_ENCODING_DESCRIPTION, 609 kOsAndroid | kOsCrOS, 610 SINGLE_VALUE_TYPE(switches::kDisableWebRtcHWEncoding) 611 }, 612 #endif 613 #if defined(OS_ANDROID) 614 { 615 "disable-webaudio", 616 IDS_FLAGS_DISABLE_WEBAUDIO_NAME, 617 IDS_FLAGS_DISABLE_WEBAUDIO_DESCRIPTION, 618 kOsAndroid, 619 SINGLE_VALUE_TYPE(switches::kDisableWebAudio) 620 }, 621 #endif 622 { 623 "enable-compositing-for-transition", 624 IDS_FLAGS_COMPOSITING_FOR_TRANSITION_NAME, 625 IDS_FLAGS_COMPOSITING_FOR_TRANSITION_DESCRIPTION, 626 kOsAll, 627 MULTI_VALUE_TYPE(kEnableCompositingForTransitionChoices) 628 }, 629 // Native client is compiled out when DISABLE_NACL is defined. 630 #if !defined(DISABLE_NACL) 631 { 632 "enable-nacl", // FLAGS:RECORD_UMA 633 IDS_FLAGS_ENABLE_NACL_NAME, 634 IDS_FLAGS_ENABLE_NACL_DESCRIPTION, 635 kOsAll, 636 SINGLE_VALUE_TYPE(switches::kEnableNaCl) 637 }, 638 { 639 "enable-nacl-debug", // FLAGS:RECORD_UMA 640 IDS_FLAGS_ENABLE_NACL_DEBUG_NAME, 641 IDS_FLAGS_ENABLE_NACL_DEBUG_DESCRIPTION, 642 kOsDesktop, 643 SINGLE_VALUE_TYPE(switches::kEnableNaClDebug) 644 }, 645 { 646 "nacl-debug-mask", // FLAGS:RECORD_UMA 647 IDS_FLAGS_NACL_DEBUG_MASK_NAME, 648 IDS_FLAGS_NACL_DEBUG_MASK_DESCRIPTION, 649 kOsDesktop, 650 MULTI_VALUE_TYPE(kNaClDebugMaskChoices) 651 }, 652 #endif 653 #if defined(ENABLE_EXTENSIONS) 654 { 655 "extension-apis", // FLAGS:RECORD_UMA 656 IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_NAME, 657 IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_DESCRIPTION, 658 kOsDesktop, 659 SINGLE_VALUE_TYPE(extensions::switches::kEnableExperimentalExtensionApis) 660 }, 661 { 662 "extensions-on-chrome-urls", 663 IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_NAME, 664 IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_DESCRIPTION, 665 kOsAll, 666 SINGLE_VALUE_TYPE(extensions::switches::kExtensionsOnChromeURLs) 667 }, 668 #endif 669 { 670 "enable-fast-unload", 671 IDS_FLAGS_ENABLE_FAST_UNLOAD_NAME, 672 IDS_FLAGS_ENABLE_FAST_UNLOAD_DESCRIPTION, 673 kOsAll, 674 SINGLE_VALUE_TYPE(switches::kEnableFastUnload) 675 }, 676 #if defined(ENABLE_EXTENSIONS) 677 { 678 "enable-app-window-controls", 679 IDS_FLAGS_ENABLE_APP_WINDOW_CONTROLS_NAME, 680 IDS_FLAGS_ENABLE_APP_WINDOW_CONTROLS_DESCRIPTION, 681 kOsDesktop, 682 SINGLE_VALUE_TYPE(extensions::switches::kEnableAppWindowControls) 683 }, 684 #endif 685 { 686 "disable-hyperlink-auditing", 687 IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_NAME, 688 IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_DESCRIPTION, 689 kOsAll, 690 SINGLE_VALUE_TYPE(switches::kNoPings) 691 }, 692 #if defined(OS_ANDROID) 693 { 694 "contextual-search", 695 IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH, 696 IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH_DESCRIPTION, 697 kOsAndroid, 698 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableContextualSearch, 699 switches::kDisableContextualSearch) 700 }, 701 #endif 702 { 703 "show-autofill-type-predictions", 704 IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_NAME, 705 IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_DESCRIPTION, 706 kOsAll, 707 SINGLE_VALUE_TYPE(autofill::switches::kShowAutofillTypePredictions) 708 }, 709 { 710 "enable-smooth-scrolling", // FLAGS:RECORD_UMA 711 IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_NAME, 712 IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_DESCRIPTION, 713 // Can't expose the switch unless the code is compiled in. 714 // On by default for the Mac (different implementation in WebKit). 715 kOsLinux, 716 SINGLE_VALUE_TYPE(switches::kEnableSmoothScrolling) 717 }, 718 #if defined(USE_AURA) || defined(OS_LINUX) 719 { 720 "overlay-scrollbars", 721 IDS_FLAGS_ENABLE_OVERLAY_SCROLLBARS_NAME, 722 IDS_FLAGS_ENABLE_OVERLAY_SCROLLBARS_DESCRIPTION, 723 // Uses the system preference on Mac (a different implementation). 724 // On Android, this is always enabled. 725 kOsLinux | kOsCrOS | kOsWin, 726 MULTI_VALUE_TYPE(kOverlayScrollbarChoices) 727 }, 728 #endif 729 { 730 "enable-panels", 731 IDS_FLAGS_ENABLE_PANELS_NAME, 732 IDS_FLAGS_ENABLE_PANELS_DESCRIPTION, 733 kOsDesktop, 734 SINGLE_VALUE_TYPE(switches::kEnablePanels) 735 }, 736 { 737 // See http://crbug.com/120416 for how to remove this flag. 738 "save-page-as-mhtml", // FLAGS:RECORD_UMA 739 IDS_FLAGS_SAVE_PAGE_AS_MHTML_NAME, 740 IDS_FLAGS_SAVE_PAGE_AS_MHTML_DESCRIPTION, 741 kOsMac | kOsWin | kOsLinux, 742 SINGLE_VALUE_TYPE(switches::kSavePageAsMHTML) 743 }, 744 { 745 "enable-quic", 746 IDS_FLAGS_ENABLE_QUIC_NAME, 747 IDS_FLAGS_ENABLE_QUIC_DESCRIPTION, 748 kOsAll, 749 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableQuic, 750 switches::kDisableQuic) 751 }, 752 { 753 "enable-spdy4", 754 IDS_FLAGS_ENABLE_SPDY4_NAME, 755 IDS_FLAGS_ENABLE_SPDY4_DESCRIPTION, 756 kOsAll, 757 SINGLE_VALUE_TYPE(switches::kEnableSpdy4) 758 }, 759 { 760 "enable-async-dns", 761 IDS_FLAGS_ENABLE_ASYNC_DNS_NAME, 762 IDS_FLAGS_ENABLE_ASYNC_DNS_DESCRIPTION, 763 kOsWin | kOsMac | kOsLinux | kOsCrOS, 764 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAsyncDns, 765 switches::kDisableAsyncDns) 766 }, 767 { 768 "disable-media-source", 769 IDS_FLAGS_DISABLE_MEDIA_SOURCE_NAME, 770 IDS_FLAGS_DISABLE_MEDIA_SOURCE_DESCRIPTION, 771 kOsAll, 772 SINGLE_VALUE_TYPE(switches::kDisableMediaSource) 773 }, 774 { 775 "enable-encrypted-media", 776 IDS_FLAGS_ENABLE_ENCRYPTED_MEDIA_NAME, 777 IDS_FLAGS_ENABLE_ENCRYPTED_MEDIA_DESCRIPTION, 778 kOsAll, 779 SINGLE_VALUE_TYPE(switches::kEnableEncryptedMedia) 780 }, 781 { 782 "disable-prefixed-encrypted-media", 783 IDS_FLAGS_DISABLE_PREFIXED_ENCRYPTED_MEDIA_NAME, 784 IDS_FLAGS_DISABLE_PREFIXED_ENCRYPTED_MEDIA_DESCRIPTION, 785 kOsAll, 786 SINGLE_VALUE_TYPE(switches::kDisablePrefixedEncryptedMedia) 787 }, 788 #if defined(OS_ANDROID) 789 { 790 "disable-infobar-for-protected-media-identifier", 791 IDS_FLAGS_DISABLE_INFOBAR_FOR_PROTECTED_MEDIA_IDENTIFIER_NAME, 792 IDS_FLAGS_DISABLE_INFOBAR_FOR_PROTECTED_MEDIA_IDENTIFIER_DESCRIPTION, 793 kOsAndroid, 794 SINGLE_VALUE_TYPE(switches::kDisableInfobarForProtectedMediaIdentifier) 795 }, 796 { 797 "mediadrm-enable-non-compositing", 798 IDS_FLAGS_MEDIADRM_ENABLE_NON_COMPOSITING_NAME, 799 IDS_FLAGS_MEDIADRM_ENABLE_NON_COMPOSITING_DESCRIPTION, 800 kOsAndroid, 801 SINGLE_VALUE_TYPE(switches::kMediaDrmEnableNonCompositing) 802 }, 803 #endif // defined(OS_ANDROID) 804 { 805 "enable-javascript-harmony", 806 IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_NAME, 807 IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_DESCRIPTION, 808 kOsAll, 809 SINGLE_VALUE_TYPE(switches::kJavaScriptHarmony) 810 }, 811 { 812 "disable-software-rasterizer", 813 IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_NAME, 814 IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_DESCRIPTION, 815 #if defined(ENABLE_SWIFTSHADER) 816 kOsAll, 817 #else 818 0, 819 #endif 820 SINGLE_VALUE_TYPE(switches::kDisableSoftwareRasterizer) 821 }, 822 { 823 "enable-gpu-rasterization", 824 IDS_FLAGS_ENABLE_GPU_RASTERIZATION_NAME, 825 IDS_FLAGS_ENABLE_GPU_RASTERIZATION_DESCRIPTION, 826 kOsAndroid, 827 MULTI_VALUE_TYPE(kEnableGpuRasterizationChoices) 828 }, 829 { 830 "enable-experimental-web-platform-features", 831 IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_NAME, 832 IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_DESCRIPTION, 833 kOsAll, 834 SINGLE_VALUE_TYPE(switches::kEnableExperimentalWebPlatformFeatures) 835 }, 836 { 837 "disable-ntp-other-sessions-menu", 838 IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_NAME, 839 IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_DESCRIPTION, 840 kOsDesktop, 841 SINGLE_VALUE_TYPE(switches::kDisableNTPOtherSessionsMenu) 842 }, 843 { 844 "enable-material-design-ntp", 845 IDS_FLAGS_ENABLE_MATERIAL_DESIGN_NTP_NAME, 846 IDS_FLAGS_ENABLE_MATERIAL_DESIGN_NTP_DESCRIPTION, 847 kOsDesktop, 848 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableMaterialDesignNTP, 849 switches::kDisableMaterialDesignNTP) 850 }, 851 { 852 "enable-devtools-experiments", 853 IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_NAME, 854 IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_DESCRIPTION, 855 kOsDesktop, 856 SINGLE_VALUE_TYPE(switches::kEnableDevToolsExperiments) 857 }, 858 { 859 "silent-debugger-extension-api", 860 IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_NAME, 861 IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_DESCRIPTION, 862 kOsDesktop, 863 SINGLE_VALUE_TYPE(switches::kSilentDebuggerExtensionAPI) 864 }, 865 { 866 "spellcheck-autocorrect", 867 IDS_FLAGS_SPELLCHECK_AUTOCORRECT, 868 IDS_FLAGS_SPELLCHECK_AUTOCORRECT_DESCRIPTION, 869 kOsWin | kOsLinux | kOsCrOS, 870 SINGLE_VALUE_TYPE(switches::kEnableSpellingAutoCorrect) 871 }, 872 { 873 "enable-scroll-prediction", 874 IDS_FLAGS_ENABLE_SCROLL_PREDICTION_NAME, 875 IDS_FLAGS_ENABLE_SCROLL_PREDICTION_DESCRIPTION, 876 kOsDesktop, 877 SINGLE_VALUE_TYPE(switches::kEnableScrollPrediction) 878 }, 879 { 880 "touch-events", 881 IDS_TOUCH_EVENTS_NAME, 882 IDS_TOUCH_EVENTS_DESCRIPTION, 883 kOsDesktop, 884 MULTI_VALUE_TYPE(kTouchEventsChoices) 885 }, 886 { 887 "disable-touch-adjustment", 888 IDS_DISABLE_TOUCH_ADJUSTMENT_NAME, 889 IDS_DISABLE_TOUCH_ADJUSTMENT_DESCRIPTION, 890 kOsWin | kOsLinux | kOsCrOS | kOsAndroid, 891 SINGLE_VALUE_TYPE(switches::kDisableTouchAdjustment) 892 }, 893 #if defined(OS_CHROMEOS) 894 { 895 "network-portal-notification", 896 IDS_FLAGS_NETWORK_PORTAL_NOTIFICATION_NAME, 897 IDS_FLAGS_NETWORK_PORTAL_NOTIFICATION_DESCRIPTION, 898 kOsCrOS, 899 ENABLE_DISABLE_VALUE_TYPE( 900 chromeos::switches::kEnableNetworkPortalNotification, 901 chromeos::switches::kDisableNetworkPortalNotification) 902 }, 903 #endif 904 { 905 "enable-download-resumption", 906 IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_NAME, 907 IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_DESCRIPTION, 908 kOsDesktop, 909 SINGLE_VALUE_TYPE(switches::kEnableDownloadResumption) 910 }, 911 #if defined(ENABLE_PLUGINS) 912 { 913 "allow-nacl-socket-api", 914 IDS_FLAGS_ALLOW_NACL_SOCKET_API_NAME, 915 IDS_FLAGS_ALLOW_NACL_SOCKET_API_DESCRIPTION, 916 kOsDesktop, 917 SINGLE_VALUE_TYPE_AND_VALUE(switches::kAllowNaClSocketAPI, "*") 918 }, 919 #endif 920 #if defined(OS_CHROMEOS) 921 { 922 "allow-touchpad-three-finger-click", 923 IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_NAME, 924 IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_DESCRIPTION, 925 kOsCrOS, 926 SINGLE_VALUE_TYPE(chromeos::switches::kEnableTouchpadThreeFingerClick) 927 }, 928 { 929 "disable-easy-signin", 930 IDS_FLAGS_DISABLE_EASY_SIGNIN_NAME, 931 IDS_FLAGS_DISABLE_EASY_SIGNIN_DESCRIPTION, 932 kOsCrOSOwnerOnly, 933 SINGLE_VALUE_TYPE(chromeos::switches::kDisableEasySignin), 934 }, 935 #endif 936 #if defined(USE_ASH) 937 { 938 "disable-minimize-on-second-launcher-item-click", 939 IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_NAME, 940 IDS_FLAGS_DISABLE_MINIMIZE_ON_SECOND_LAUNCHER_ITEM_CLICK_DESCRIPTION, 941 kOsAll, 942 SINGLE_VALUE_TYPE(switches::kDisableMinimizeOnSecondLauncherItemClick) 943 }, 944 { 945 "show-touch-hud", 946 IDS_FLAGS_SHOW_TOUCH_HUD_NAME, 947 IDS_FLAGS_SHOW_TOUCH_HUD_DESCRIPTION, 948 kOsAll, 949 SINGLE_VALUE_TYPE(ash::switches::kAshTouchHud) 950 }, 951 { 952 "enable-pinch", 953 IDS_FLAGS_ENABLE_PINCH_SCALE_NAME, 954 IDS_FLAGS_ENABLE_PINCH_SCALE_DESCRIPTION, 955 kOsLinux | kOsWin | kOsCrOS, 956 ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePinch, switches::kDisablePinch), 957 }, 958 #endif // defined(USE_ASH) 959 { 960 "enable-pinch-virtual-viewport", 961 IDS_FLAGS_ENABLE_PINCH_VIRTUAL_VIEWPORT_NAME, 962 IDS_FLAGS_ENABLE_PINCH_VIRTUAL_VIEWPORT_DESCRIPTION, 963 kOsLinux | kOsWin | kOsCrOS | kOsAndroid, 964 ENABLE_DISABLE_VALUE_TYPE( 965 cc::switches::kEnablePinchVirtualViewport, 966 cc::switches::kDisablePinchVirtualViewport), 967 }, 968 { 969 "enable-viewport-meta", 970 IDS_FLAGS_ENABLE_VIEWPORT_META_NAME, 971 IDS_FLAGS_ENABLE_VIEWPORT_META_DESCRIPTION, 972 kOsLinux | kOsWin | kOsCrOS | kOsMac, 973 SINGLE_VALUE_TYPE(switches::kEnableViewportMeta), 974 }, 975 #if defined(OS_CHROMEOS) 976 { 977 "disable-boot-animation", 978 IDS_FLAGS_DISABLE_BOOT_ANIMATION, 979 IDS_FLAGS_DISABLE_BOOT_ANIMATION_DESCRIPTION, 980 kOsCrOSOwnerOnly, 981 SINGLE_VALUE_TYPE(chromeos::switches::kDisableBootAnimation), 982 }, 983 { 984 "enable-video-player-chromecast-support", 985 IDS_FLAGS_ENABLE_VIDEO_PLAYER_CHROMECAST_SUPPORT_NAME, 986 IDS_FLAGS_ENABLE_VIDEO_PLAYER_CHROMECAST_SUPPORT_DESCRIPTION, 987 kOsCrOS, 988 SINGLE_VALUE_TYPE(chromeos::switches::kEnableVideoPlayerChromecastSupport) 989 }, 990 { 991 "disable-office-editing-component-app", 992 IDS_FLAGS_DISABLE_OFFICE_EDITING_COMPONENT_APP_NAME, 993 IDS_FLAGS_DISABLE_OFFICE_EDITING_COMPONENT_APP_DESCRIPTION, 994 kOsCrOS, 995 SINGLE_VALUE_TYPE(chromeos::switches::kDisableOfficeEditingComponentApp), 996 }, 997 { 998 "disable-display-color-calibration", 999 IDS_FLAGS_DISABLE_DISPLAY_COLOR_CALIBRATION_NAME, 1000 IDS_FLAGS_DISABLE_DISPLAY_COLOR_CALIBRATION_DESCRIPTION, 1001 kOsCrOS, 1002 SINGLE_VALUE_TYPE(ui::switches::kDisableDisplayColorCalibration), 1003 }, 1004 #endif // defined(OS_CHROMEOS) 1005 { "disable-accelerated-video-decode", 1006 IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_NAME, 1007 IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_DESCRIPTION, 1008 kOsWin | kOsCrOS, 1009 SINGLE_VALUE_TYPE(switches::kDisableAcceleratedVideoDecode), 1010 }, 1011 #if defined(USE_ASH) 1012 { 1013 "ash-debug-shortcuts", 1014 IDS_FLAGS_DEBUG_SHORTCUTS_NAME, 1015 IDS_FLAGS_DEBUG_SHORTCUTS_DESCRIPTION, 1016 kOsAll, 1017 SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts), 1018 }, 1019 { "ash-enable-touch-view-testing", 1020 IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_NAME, 1021 IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TESTING_DESCRIPTION, 1022 kOsCrOS, 1023 SINGLE_VALUE_TYPE(ash::switches::kAshEnableTouchViewTesting), 1024 }, 1025 { 1026 "ash-enable-touch-view-touch-feedback", 1027 IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TOUCH_FEEDBACK_NAME, 1028 IDS_FLAGS_ASH_ENABLE_TOUCH_VIEW_TOUCH_FEEDBACK_DESCRIPTION, 1029 kOsCrOS, 1030 SINGLE_VALUE_TYPE(ash::switches::kAshEnableTouchViewTouchFeedback), 1031 }, 1032 { "ash-disable-text-filtering-in-overview-mode", 1033 IDS_FLAGS_ASH_DISABLE_TEXT_FILTERING_IN_OVERVIEW_MODE_NAME, 1034 IDS_FLAGS_ASH_DISABLE_TEXT_FILTERING_IN_OVERVIEW_MODE_DESCRIPTION, 1035 kOsCrOS, 1036 SINGLE_VALUE_TYPE(ash::switches::kAshDisableTextFilteringInOverviewMode), 1037 }, 1038 #endif // defined(USE_ASH) 1039 #if defined(OS_CHROMEOS) 1040 { 1041 "enable-carrier-switching", 1042 IDS_FLAGS_ENABLE_CARRIER_SWITCHING, 1043 IDS_FLAGS_ENABLE_CARRIER_SWITCHING_DESCRIPTION, 1044 kOsCrOS, 1045 SINGLE_VALUE_TYPE(chromeos::switches::kEnableCarrierSwitching) 1046 }, 1047 { 1048 "enable-request-tablet-site", 1049 IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_NAME, 1050 IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_DESCRIPTION, 1051 kOsCrOS, 1052 SINGLE_VALUE_TYPE(chromeos::switches::kEnableRequestTabletSite) 1053 }, 1054 #endif 1055 { 1056 "debug-packed-apps", 1057 IDS_FLAGS_DEBUG_PACKED_APP_NAME, 1058 IDS_FLAGS_DEBUG_PACKED_APP_DESCRIPTION, 1059 kOsDesktop, 1060 SINGLE_VALUE_TYPE(switches::kDebugPackedApps) 1061 }, 1062 { 1063 "enable-password-generation", 1064 IDS_FLAGS_ENABLE_PASSWORD_GENERATION_NAME, 1065 IDS_FLAGS_ENABLE_PASSWORD_GENERATION_DESCRIPTION, 1066 kOsWin | kOsLinux | kOsCrOS | kOsMac, 1067 ENABLE_DISABLE_VALUE_TYPE(autofill::switches::kEnablePasswordGeneration, 1068 autofill::switches::kDisablePasswordGeneration) 1069 }, 1070 { 1071 "enable-automatic-password-saving", 1072 IDS_FLAGS_ENABLE_AUTOMATIC_PASSWORD_SAVING_NAME, 1073 IDS_FLAGS_ENABLE_AUTOMATIC_PASSWORD_SAVING_DESCRIPTION, 1074 kOsDesktop, 1075 SINGLE_VALUE_TYPE( 1076 password_manager::switches::kEnableAutomaticPasswordSaving) 1077 }, 1078 { 1079 "password-manager-reauthentication", 1080 IDS_FLAGS_PASSWORD_MANAGER_REAUTHENTICATION_NAME, 1081 IDS_FLAGS_PASSWORD_MANAGER_REAUTHENTICATION_DESCRIPTION, 1082 kOsMac | kOsWin, 1083 SINGLE_VALUE_TYPE(switches::kDisablePasswordManagerReauthentication) 1084 }, 1085 { 1086 "enable-android-password-link", 1087 IDS_FLAGS_PASSWORD_MANAGER_ANDROID_LINK_NAME, 1088 IDS_FLAGS_PASSWORD_MANAGER_ANDROID_LINK_DESCRIPTION, 1089 kOsAndroid, 1090 ENABLE_DISABLE_VALUE_TYPE( 1091 password_manager::switches::kEnableAndroidPasswordLink, 1092 password_manager::switches::kDisableAndroidPasswordLink) 1093 }, 1094 { 1095 "enable-deferred-image-decoding", 1096 IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_NAME, 1097 IDS_FLAGS_ENABLE_DEFERRED_IMAGE_DECODING_DESCRIPTION, 1098 kOsMac | kOsLinux | kOsCrOS, 1099 SINGLE_VALUE_TYPE(switches::kEnableDeferredImageDecoding) 1100 }, 1101 { 1102 "wallet-service-use-sandbox", 1103 IDS_FLAGS_WALLET_SERVICE_USE_SANDBOX_NAME, 1104 IDS_FLAGS_WALLET_SERVICE_USE_SANDBOX_DESCRIPTION, 1105 kOsAndroid | kOsDesktop, 1106 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1107 autofill::switches::kWalletServiceUseSandbox, "1", 1108 autofill::switches::kWalletServiceUseSandbox, "0") 1109 }, 1110 #if defined(USE_AURA) 1111 { 1112 "overscroll-history-navigation", 1113 IDS_FLAGS_OVERSCROLL_HISTORY_NAVIGATION_NAME, 1114 IDS_FLAGS_OVERSCROLL_HISTORY_NAVIGATION_DESCRIPTION, 1115 kOsAll, 1116 MULTI_VALUE_TYPE(kOverscrollHistoryNavigationChoices) 1117 }, 1118 #endif 1119 { 1120 "scroll-end-effect", 1121 IDS_FLAGS_SCROLL_END_EFFECT_NAME, 1122 IDS_FLAGS_SCROLL_END_EFFECT_DESCRIPTION, 1123 kOsCrOS, 1124 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1125 switches::kScrollEndEffect, "1", 1126 switches::kScrollEndEffect, "0") 1127 }, 1128 { 1129 "enable-renderer-mojo-channel", 1130 IDS_FLAGS_ENABLE_RENDERER_MOJO_CHANNEL_NAME, 1131 IDS_FLAGS_ENABLE_RENDERER_MOJO_CHANNEL_DESCRIPTION, 1132 kOsAll, 1133 SINGLE_VALUE_TYPE(switches::kEnableRendererMojoChannel) 1134 }, 1135 { 1136 "enable-touch-drag-drop", 1137 IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_NAME, 1138 IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_DESCRIPTION, 1139 kOsWin | kOsCrOS, 1140 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTouchDragDrop, 1141 switches::kDisableTouchDragDrop) 1142 }, 1143 { 1144 "enable-touch-editing", 1145 IDS_FLAGS_ENABLE_TOUCH_EDITING_NAME, 1146 IDS_FLAGS_ENABLE_TOUCH_EDITING_DESCRIPTION, 1147 kOsCrOS | kOsWin | kOsLinux, 1148 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTouchEditing, 1149 switches::kDisableTouchEditing) 1150 }, 1151 { 1152 "enable-suggestions-service", 1153 IDS_FLAGS_ENABLE_SUGGESTIONS_SERVICE_NAME, 1154 IDS_FLAGS_ENABLE_SUGGESTIONS_SERVICE_DESCRIPTION, 1155 kOsAndroid | kOsCrOS, 1156 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSuggestionsService, 1157 switches::kDisableSuggestionsService) 1158 }, 1159 { 1160 "enable-supervised-user-blacklist", 1161 IDS_FLAGS_ENABLE_SUPERVISED_USER_BLACKLIST_NAME, 1162 IDS_FLAGS_ENABLE_SUPERVISED_USER_BLACKLIST_DESCRIPTION, 1163 kOsAndroid | kOsMac | kOsWin | kOsLinux | kOsCrOS, 1164 SINGLE_VALUE_TYPE(switches::kEnableSupervisedUserBlacklist) 1165 }, 1166 { 1167 "enable-sync-synced-notifications", 1168 IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_NAME, 1169 IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_DESCRIPTION, 1170 kOsDesktop, 1171 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSyncSyncedNotifications, 1172 switches::kDisableSyncSyncedNotifications) 1173 }, 1174 #if defined(ENABLE_APP_LIST) 1175 { 1176 "enable-sync-app-list", 1177 IDS_FLAGS_ENABLE_SYNC_APP_LIST_NAME, 1178 IDS_FLAGS_ENABLE_SYNC_APP_LIST_DESCRIPTION, 1179 kOsDesktop, 1180 MULTI_VALUE_TYPE(kEnableSyncAppListChoices) 1181 }, 1182 #endif 1183 #if defined(OS_MACOSX) 1184 { 1185 "enable-avfoundation", 1186 IDS_FLAGS_ENABLE_AVFOUNDATION_NAME, 1187 IDS_FLAGS_ENABLE_AVFOUNDATION_DESCRIPTION, 1188 kOsMac, 1189 MULTI_VALUE_TYPE(kEnableAVFoundationChoices) 1190 }, 1191 #endif 1192 { 1193 "impl-side-painting", 1194 IDS_FLAGS_IMPL_SIDE_PAINTING_NAME, 1195 IDS_FLAGS_IMPL_SIDE_PAINTING_DESCRIPTION, 1196 kOsAll, 1197 MULTI_VALUE_TYPE(kImplSidePaintingChoices) 1198 }, 1199 { 1200 "lcd-text-aa", 1201 IDS_FLAGS_LCD_TEXT_NAME, 1202 IDS_FLAGS_LCD_TEXT_DESCRIPTION, 1203 kOsDesktop, 1204 MULTI_VALUE_TYPE(kLCDTextChoices) 1205 }, 1206 #if defined(OS_ANDROID) || defined(OS_MACOSX) 1207 { 1208 "delegated-renderer", 1209 IDS_FLAGS_DELEGATED_RENDERER_NAME, 1210 IDS_FLAGS_DELEGATED_RENDERER_DESCRIPTION, 1211 kOsAndroid, // TODO(ccameron) Add mac support soon. 1212 MULTI_VALUE_TYPE(kDelegatedRendererChoices) 1213 }, 1214 #endif 1215 { 1216 "max-tiles-for-interest-area", 1217 IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_NAME, 1218 IDS_FLAGS_MAX_TILES_FOR_INTEREST_AREA_DESCRIPTION, 1219 kOsAll, 1220 MULTI_VALUE_TYPE(kMaxTilesForInterestAreaChoices) 1221 }, 1222 { 1223 "enable-offline-auto-reload", 1224 IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_NAME, 1225 IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_DESCRIPTION, 1226 kOsAll, 1227 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflineAutoReload, 1228 switches::kDisableOfflineAutoReload) 1229 }, 1230 { 1231 "enable-offline-auto-reload-visible-only", 1232 IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_VISIBLE_ONLY_NAME, 1233 IDS_FLAGS_ENABLE_OFFLINE_AUTO_RELOAD_VISIBLE_ONLY_DESCRIPTION, 1234 kOsAll, 1235 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflineAutoReloadVisibleOnly, 1236 switches::kDisableOfflineAutoReloadVisibleOnly) 1237 }, 1238 { 1239 "enable-offline-load-stale-cache", 1240 IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_NAME, 1241 IDS_FLAGS_ENABLE_OFFLINE_LOAD_STALE_DESCRIPTION, 1242 kOsLinux | kOsMac | kOsWin | kOsAndroid, 1243 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableOfflineLoadStaleCache, 1244 switches::kDisableOfflineLoadStaleCache) 1245 }, 1246 { 1247 "default-tile-width", 1248 IDS_FLAGS_DEFAULT_TILE_WIDTH_NAME, 1249 IDS_FLAGS_DEFAULT_TILE_WIDTH_DESCRIPTION, 1250 kOsAll, 1251 MULTI_VALUE_TYPE(kDefaultTileWidthChoices) 1252 }, 1253 { 1254 "default-tile-height", 1255 IDS_FLAGS_DEFAULT_TILE_HEIGHT_NAME, 1256 IDS_FLAGS_DEFAULT_TILE_HEIGHT_DESCRIPTION, 1257 kOsAll, 1258 MULTI_VALUE_TYPE(kDefaultTileHeightChoices) 1259 }, 1260 #if defined(OS_ANDROID) 1261 { 1262 "disable-gesture-requirement-for-media-playback", 1263 IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_NAME, 1264 IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_DESCRIPTION, 1265 kOsAndroid, 1266 SINGLE_VALUE_TYPE(switches::kDisableGestureRequirementForMediaPlayback) 1267 }, 1268 #endif 1269 #if defined(OS_CHROMEOS) 1270 { 1271 "enable-virtual-keyboard", 1272 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_NAME, 1273 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_DESCRIPTION, 1274 kOsCrOS, 1275 SINGLE_VALUE_TYPE(keyboard::switches::kEnableVirtualKeyboard) 1276 }, 1277 { 1278 "enable-virtual-keyboard-overscroll", 1279 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_OVERSCROLL_NAME, 1280 IDS_FLAGS_ENABLE_VIRTUAL_KEYBOARD_OVERSCROLL_DESCRIPTION, 1281 kOsCrOS, 1282 ENABLE_DISABLE_VALUE_TYPE( 1283 keyboard::switches::kEnableVirtualKeyboardOverscroll, 1284 keyboard::switches::kDisableVirtualKeyboardOverscroll) 1285 }, 1286 { 1287 "enable-swipe-selection", 1288 IDS_FLAGS_ENABLE_SWIPE_SELECTION_NAME, 1289 IDS_FLAGS_ENABLE_SWIPE_SELECTION_DESCRIPTION, 1290 kOsCrOS, 1291 SINGLE_VALUE_TYPE(keyboard::switches::kEnableSwipeSelection) 1292 }, 1293 { 1294 "enable-input-view", 1295 IDS_FLAGS_ENABLE_INPUT_VIEW_NAME, 1296 IDS_FLAGS_ENABLE_INPUT_VIEW_DESCRIPTION, 1297 kOsCrOS, 1298 ENABLE_DISABLE_VALUE_TYPE(keyboard::switches::kEnableInputView, 1299 keyboard::switches::kDisableInputView) 1300 }, 1301 { 1302 "enable-experimental-input-view-features", 1303 IDS_FLAGS_ENABLE_EXPERIMENTAL_INPUT_VIEW_FEATURES_NAME, 1304 IDS_FLAGS_ENABLE_EXPERIMENTAL_INPUT_VIEW_FEATURES_DESCRIPTION, 1305 kOsCrOS, 1306 SINGLE_VALUE_TYPE(keyboard::switches::kEnableExperimentalInputViewFeatures) 1307 }, 1308 #endif 1309 { 1310 "enable-simple-cache-backend", 1311 IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_NAME, 1312 IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_DESCRIPTION, 1313 kOsWin | kOsMac | kOsLinux | kOsCrOS, 1314 MULTI_VALUE_TYPE(kSimpleCacheBackendChoices) 1315 }, 1316 { 1317 "enable-tcp-fast-open", 1318 IDS_FLAGS_ENABLE_TCP_FAST_OPEN_NAME, 1319 IDS_FLAGS_ENABLE_TCP_FAST_OPEN_DESCRIPTION, 1320 kOsLinux | kOsCrOS | kOsAndroid, 1321 SINGLE_VALUE_TYPE(switches::kEnableTcpFastOpen) 1322 }, 1323 #if defined(ENABLE_SERVICE_DISCOVERY) 1324 { 1325 "device-discovery-notifications", 1326 IDS_FLAGS_DEVICE_DISCOVERY_NOTIFICATIONS_NAME, 1327 IDS_FLAGS_DEVICE_DISCOVERY_NOTIFICATIONS_DESCRIPTION, 1328 kOsDesktop, 1329 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableDeviceDiscoveryNotifications, 1330 switches::kDisableDeviceDiscoveryNotifications) 1331 }, 1332 { 1333 "enable-cloud-devices", 1334 IDS_FLAGS_ENABLE_CLOUD_DEVICES_NAME, 1335 IDS_FLAGS_ENABLE_CLOUD_DEVICES_DESCRIPTION, 1336 kOsDesktop, 1337 SINGLE_VALUE_TYPE(switches::kEnableCloudDevices) 1338 }, 1339 { 1340 "enable-print-preview-register-promos", 1341 IDS_FLAGS_ENABLE_PRINT_PREVIEW_REGISTER_PROMOS_NAME, 1342 IDS_FLAGS_ENABLE_PRINT_PREVIEW_REGISTER_PROMOS_DESCRIPTION, 1343 kOsDesktop, 1344 SINGLE_VALUE_TYPE(switches::kEnablePrintPreviewRegisterPromos) 1345 }, 1346 #endif // ENABLE_SERVICE_DISCOVERY 1347 #if defined(OS_WIN) 1348 { 1349 "enable-cloud-print-xps", 1350 IDS_FLAGS_ENABLE_CLOUD_PRINT_XPS_NAME, 1351 IDS_FLAGS_ENABLE_CLOUD_PRINT_XPS_DESCRIPTION, 1352 kOsWin, 1353 SINGLE_VALUE_TYPE(switches::kEnableCloudPrintXps) 1354 }, 1355 #endif 1356 #if defined(USE_AURA) 1357 { 1358 "tab-capture-upscale-quality", 1359 IDS_FLAGS_TAB_CAPTURE_UPSCALE_QUALITY_NAME, 1360 IDS_FLAGS_TAB_CAPTURE_UPSCALE_QUALITY_DESCRIPTION, 1361 kOsAll, 1362 MULTI_VALUE_TYPE(kTabCaptureUpscaleQualityChoices) 1363 }, 1364 { 1365 "tab-capture-downscale-quality", 1366 IDS_FLAGS_TAB_CAPTURE_DOWNSCALE_QUALITY_NAME, 1367 IDS_FLAGS_TAB_CAPTURE_DOWNSCALE_QUALITY_DESCRIPTION, 1368 kOsAll, 1369 MULTI_VALUE_TYPE(kTabCaptureDownscaleQualityChoices) 1370 }, 1371 #endif 1372 { 1373 "enable-spelling-feedback-field-trial", 1374 IDS_FLAGS_ENABLE_SPELLING_FEEDBACK_FIELD_TRIAL_NAME, 1375 IDS_FLAGS_ENABLE_SPELLING_FEEDBACK_FIELD_TRIAL_DESCRIPTION, 1376 kOsAll, 1377 SINGLE_VALUE_TYPE(switches::kEnableSpellingFeedbackFieldTrial) 1378 }, 1379 { 1380 "enable-webgl-draft-extensions", 1381 IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_NAME, 1382 IDS_FLAGS_ENABLE_WEBGL_DRAFT_EXTENSIONS_DESCRIPTION, 1383 kOsAll, 1384 SINGLE_VALUE_TYPE(switches::kEnableWebGLDraftExtensions) 1385 }, 1386 { 1387 "enable-web-midi", 1388 IDS_FLAGS_ENABLE_WEB_MIDI_NAME, 1389 IDS_FLAGS_ENABLE_WEB_MIDI_DESCRIPTION, 1390 kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsAndroid, 1391 SINGLE_VALUE_TYPE(switches::kEnableWebMIDI) 1392 }, 1393 { 1394 "enable-new-profile-management", 1395 IDS_FLAGS_ENABLE_NEW_PROFILE_MANAGEMENT_NAME, 1396 IDS_FLAGS_ENABLE_NEW_PROFILE_MANAGEMENT_DESCRIPTION, 1397 kOsAndroid | kOsMac | kOsWin | kOsLinux | kOsCrOS, 1398 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableNewProfileManagement, 1399 switches::kDisableNewProfileManagement) 1400 }, 1401 { 1402 "enable-account-consistency", 1403 IDS_FLAGS_ENABLE_ACCOUNT_CONSISTENCY_NAME, 1404 IDS_FLAGS_ENABLE_ACCOUNT_CONSISTENCY_DESCRIPTION, 1405 kOsAndroid | kOsMac | kOsWin | kOsLinux | kOsCrOS, 1406 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableAccountConsistency, 1407 switches::kDisableAccountConsistency) 1408 }, 1409 { 1410 "enable-fast-user-switching", 1411 IDS_FLAGS_ENABLE_FAST_USER_SWITCHING_NAME, 1412 IDS_FLAGS_ENABLE_FAST_USER_SWITCHING_DESCRIPTION, 1413 kOsMac | kOsWin | kOsLinux, 1414 SINGLE_VALUE_TYPE(switches::kFastUserSwitching) 1415 }, 1416 { 1417 "enable-new-avatar-menu", 1418 IDS_FLAGS_ENABLE_NEW_AVATAR_MENU_NAME, 1419 IDS_FLAGS_ENABLE_NEW_AVATAR_MENU_DESCRIPTION, 1420 kOsMac | kOsWin | kOsLinux, 1421 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableNewAvatarMenu, 1422 switches::kDisableNewAvatarMenu) 1423 }, 1424 { 1425 "enable-web-based-signin", 1426 IDS_FLAGS_ENABLE_WEB_BASED_SIGNIN_NAME, 1427 IDS_FLAGS_ENABLE_WEB_BASED_SIGNIN_DESCRIPTION, 1428 kOsMac | kOsWin | kOsLinux, 1429 SINGLE_VALUE_TYPE(switches::kEnableWebBasedSignin) 1430 }, 1431 { 1432 "enable-google-profile-info", 1433 IDS_FLAGS_ENABLE_GOOGLE_PROFILE_INFO_NAME, 1434 IDS_FLAGS_ENABLE_GOOGLE_PROFILE_INFO_DESCRIPTION, 1435 kOsMac | kOsWin | kOsLinux, 1436 SINGLE_VALUE_TYPE(switches::kGoogleProfileInfo) 1437 }, 1438 { 1439 "reset-app-list-install-state", 1440 IDS_FLAGS_RESET_APP_LIST_INSTALL_STATE_NAME, 1441 IDS_FLAGS_RESET_APP_LIST_INSTALL_STATE_DESCRIPTION, 1442 kOsMac | kOsWin | kOsLinux, 1443 SINGLE_VALUE_TYPE(switches::kResetAppListInstallState) 1444 }, 1445 #if defined(ENABLE_APP_LIST) 1446 #if defined(OS_LINUX) 1447 { 1448 // This is compiled out on non-Linux platforms because otherwise it would be 1449 // visible on Win/Mac/CrOS but not on Linux GTK, which would be confusing. 1450 // TODO(mgiuca): Remove the #if when Aura is the default on Linux. 1451 "enable-app-list", 1452 IDS_FLAGS_ENABLE_APP_LIST_NAME, 1453 IDS_FLAGS_ENABLE_APP_LIST_DESCRIPTION, 1454 kOsLinux, 1455 SINGLE_VALUE_TYPE(switches::kEnableAppList) 1456 }, 1457 #endif 1458 #if defined(ENABLE_EXTENSIONS) 1459 { 1460 "enable-app-view", 1461 IDS_FLAGS_ENABLE_APP_VIEW_NAME, 1462 IDS_FLAGS_ENABLE_APP_VIEW_DESCRIPTION, 1463 kOsDesktop, 1464 SINGLE_VALUE_TYPE(extensions::switches::kEnableAppView) 1465 }, 1466 #endif 1467 { 1468 "disable-app-list-app-info", 1469 IDS_FLAGS_DISABLE_APP_INFO_IN_APP_LIST, 1470 IDS_FLAGS_DISABLE_APP_INFO_IN_APP_LIST_DESCRIPTION, 1471 kOsLinux | kOsWin | kOsCrOS, 1472 SINGLE_VALUE_TYPE(app_list::switches::kDisableAppInfo) 1473 }, 1474 #endif 1475 #if defined(OS_ANDROID) 1476 { 1477 "enable-accessibility-tab-switcher", 1478 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_NAME, 1479 IDS_FLAGS_ENABLE_ACCESSIBILITY_TAB_SWITCHER_DESCRIPTION, 1480 kOsAndroid, 1481 SINGLE_VALUE_TYPE(switches::kEnableAccessibilityTabSwitcher) 1482 }, 1483 { 1484 // TODO(dmazzoni): remove this flag when native android accessibility 1485 // ships in the stable channel. http://crbug.com/356775 1486 "enable-accessibility-script-injection", 1487 IDS_FLAGS_ENABLE_ACCESSIBILITY_SCRIPT_INJECTION_NAME, 1488 IDS_FLAGS_ENABLE_ACCESSIBILITY_SCRIPT_INJECTION_DESCRIPTION, 1489 kOsAndroid, 1490 // Java-only switch: ContentSwitches.ENABLE_ACCESSIBILITY_SCRIPT_INJECTION. 1491 SINGLE_VALUE_TYPE("enable-accessibility-script-injection") 1492 }, 1493 #endif 1494 { 1495 "enable-one-copy", 1496 IDS_FLAGS_ONE_COPY_NAME, 1497 IDS_FLAGS_ONE_COPY_DESCRIPTION, 1498 kOsAll, 1499 SINGLE_VALUE_TYPE(switches::kEnableOneCopy) 1500 }, 1501 { 1502 "enable-zero-copy", 1503 IDS_FLAGS_ZERO_COPY_NAME, 1504 IDS_FLAGS_ZERO_COPY_DESCRIPTION, 1505 kOsAll, 1506 MULTI_VALUE_TYPE(kZeroCopyChoices) 1507 }, 1508 #if defined(OS_CHROMEOS) 1509 { 1510 "enable-first-run-ui-transitions", 1511 IDS_FLAGS_ENABLE_FIRST_RUN_UI_TRANSITIONS_NAME, 1512 IDS_FLAGS_ENABLE_FIRST_RUN_UI_TRANSITIONS_DESCRIPTION, 1513 kOsCrOS, 1514 SINGLE_VALUE_TYPE(chromeos::switches::kEnableFirstRunUITransitions) 1515 }, 1516 #endif 1517 { 1518 "enable-streamlined-hosted-apps", 1519 IDS_FLAGS_ENABLE_STREAMLINED_HOSTED_APPS_NAME, 1520 IDS_FLAGS_ENABLE_STREAMLINED_HOSTED_APPS_DESCRIPTION, 1521 kOsWin | kOsCrOS | kOsLinux, 1522 SINGLE_VALUE_TYPE(switches::kEnableStreamlinedHostedApps) 1523 }, 1524 { 1525 "enable-ephemeral-apps", 1526 IDS_FLAGS_ENABLE_EPHEMERAL_APPS_NAME, 1527 IDS_FLAGS_ENABLE_EPHEMERAL_APPS_DESCRIPTION, 1528 kOsAll, 1529 SINGLE_VALUE_TYPE(switches::kEnableEphemeralApps) 1530 }, 1531 { 1532 "enable-linkable-ephemeral-apps", 1533 IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_NAME, 1534 IDS_FLAGS_ENABLE_LINKABLE_EPHEMERAL_APPS_DESCRIPTION, 1535 kOsAll, 1536 SINGLE_VALUE_TYPE(switches::kEnableLinkableEphemeralApps) 1537 }, 1538 { 1539 "enable-service-worker-sync", 1540 IDS_FLAGS_ENABLE_SERVICE_WORKER_SYNC_NAME, 1541 IDS_FLAGS_ENABLE_SERVICE_WORKER_SYNC_DESCRIPTION, 1542 kOsAll, 1543 SINGLE_VALUE_TYPE(switches::kEnableServiceWorkerSync) 1544 }, 1545 #if defined(OS_ANDROID) 1546 { 1547 "disable-click-delay", 1548 IDS_FLAGS_DISABLE_CLICK_DELAY_NAME, 1549 IDS_FLAGS_DISABLE_CLICK_DELAY_DESCRIPTION, 1550 kOsAndroid, 1551 // Java-only switch: CommandLine.DISABLE_CLICK_DELAY 1552 SINGLE_VALUE_TYPE("disable-click-delay") 1553 }, 1554 #endif 1555 #if defined(OS_MACOSX) 1556 { 1557 "enable-translate-new-ux", 1558 IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_NAME, 1559 IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_DESCRIPTION, 1560 kOsMac, 1561 SINGLE_VALUE_TYPE(switches::kEnableTranslateNewUX) 1562 }, 1563 #endif 1564 #if defined(TOOLKIT_VIEWS) 1565 { 1566 "disable-views-rect-based-targeting", // FLAGS:RECORD_UMA 1567 IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_NAME, 1568 IDS_FLAGS_DISABLE_VIEWS_RECT_BASED_TARGETING_DESCRIPTION, 1569 kOsCrOS | kOsWin | kOsLinux, 1570 SINGLE_VALUE_TYPE(views::switches::kDisableViewsRectBasedTargeting) 1571 }, 1572 { 1573 "enable-link-disambiguation-popup", 1574 IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_NAME, 1575 IDS_FLAGS_ENABLE_LINK_DISAMBIGUATION_POPUP_DESCRIPTION, 1576 kOsCrOS | kOsWin, 1577 SINGLE_VALUE_TYPE(switches::kEnableLinkDisambiguationPopup) 1578 }, 1579 #endif 1580 #if defined(ENABLE_EXTENSIONS) 1581 { 1582 "enable-apps-show-on-first-paint", 1583 IDS_FLAGS_ENABLE_APPS_SHOW_ON_FIRST_PAINT_NAME, 1584 IDS_FLAGS_ENABLE_APPS_SHOW_ON_FIRST_PAINT_DESCRIPTION, 1585 kOsDesktop, 1586 SINGLE_VALUE_TYPE(extensions::switches::kEnableAppsShowOnFirstPaint) 1587 }, 1588 #endif 1589 { 1590 "enhanced-bookmarks-experiment", 1591 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_NAME, 1592 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_DESCRIPTION, 1593 kOsDesktop | kOsAndroid, 1594 ENABLE_DISABLE_VALUE_TYPE_AND_VALUE( 1595 switches::kEnhancedBookmarksExperiment, "1", 1596 switches::kEnhancedBookmarksExperiment, "0") 1597 }, 1598 { 1599 "manual-enhanced-bookmarks", 1600 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_NAME, 1601 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_DESCRIPTION, 1602 kOsDesktop | kOsAndroid, 1603 SINGLE_VALUE_TYPE(switches::kManualEnhancedBookmarks) 1604 }, 1605 { 1606 "manual-enhanced-bookmarks-optout", 1607 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_NAME, 1608 IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_DESCRIPTION, 1609 kOsDesktop | kOsAndroid, 1610 SINGLE_VALUE_TYPE(switches::kManualEnhancedBookmarksOptout) 1611 }, 1612 #if defined(OS_ANDROID) 1613 { 1614 "enable-zero-suggest-experiment", 1615 IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_NAME, 1616 IDS_FLAGS_ZERO_SUGGEST_EXPERIMENT_DESCRIPTION, 1617 kOsAndroid, 1618 MULTI_VALUE_TYPE(kZeroSuggestExperimentsChoices) 1619 }, 1620 { 1621 "enable-reader-mode-toolbar-icon", 1622 IDS_FLAGS_READER_MODE_EXPERIMENT_NAME, 1623 IDS_FLAGS_READER_MODE_EXPERIMENT_DESCRIPTION, 1624 kOsAndroid, 1625 SINGLE_VALUE_TYPE(switches::kEnableReaderModeToolbarIcon) 1626 }, 1627 #endif 1628 { 1629 "num-raster-threads", 1630 IDS_FLAGS_NUM_RASTER_THREADS_NAME, 1631 IDS_FLAGS_NUM_RASTER_THREADS_DESCRIPTION, 1632 kOsAll, 1633 MULTI_VALUE_TYPE(kNumRasterThreadsChoices) 1634 }, 1635 { 1636 "origin-chip-in-omnibox", 1637 IDS_FLAGS_ORIGIN_CHIP_NAME, 1638 IDS_FLAGS_ORIGIN_CHIP_DESCRIPTION, 1639 kOsCrOS | kOsMac | kOsWin | kOsLinux, 1640 MULTI_VALUE_TYPE(kOriginChipChoices) 1641 }, 1642 { 1643 "search-button-in-omnibox", 1644 IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_NAME, 1645 IDS_FLAGS_SEARCH_BUTTON_IN_OMNIBOX_DESCRIPTION, 1646 kOsCrOS | kOsMac | kOsWin | kOsLinux, 1647 MULTI_VALUE_TYPE(kSearchButtonInOmniboxChoices) 1648 }, 1649 { 1650 "disable-ignore-autocomplete-off", 1651 IDS_FLAGS_DISABLE_IGNORE_AUTOCOMPLETE_OFF_NAME, 1652 IDS_FLAGS_DISABLE_IGNORE_AUTOCOMPLETE_OFF_DESCRIPTION, 1653 kOsAll, 1654 SINGLE_VALUE_TYPE(autofill::switches::kDisableIgnoreAutocompleteOff) 1655 }, 1656 { 1657 "enable-permissions-bubbles", 1658 IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_NAME, 1659 IDS_FLAGS_ENABLE_PERMISSIONS_BUBBLES_DESCRIPTION, 1660 kOsCrOS | kOsMac | kOsWin | kOsLinux, 1661 ENABLE_DISABLE_VALUE_TYPE(switches::kEnablePermissionsBubbles, 1662 switches::kDisablePermissionsBubbles) 1663 }, 1664 { 1665 "enable-session-crashed-bubble", 1666 IDS_FLAGS_ENABLE_SESSION_CRASHED_BUBBLE_NAME, 1667 IDS_FLAGS_ENABLE_SESSION_CRASHED_BUBBLE_DESCRIPTION, 1668 kOsWin | kOsLinux, 1669 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSessionCrashedBubble, 1670 switches::kDisableSessionCrashedBubble) 1671 }, 1672 { 1673 "out-of-process-pdf", 1674 IDS_FLAGS_OUT_OF_PROCESS_PDF_NAME, 1675 IDS_FLAGS_OUT_OF_PROCESS_PDF_DESCRIPTION, 1676 kOsDesktop, 1677 SINGLE_VALUE_TYPE(switches::kOutOfProcessPdf) 1678 }, 1679 #if defined(OS_ANDROID) 1680 { 1681 "disable-cast", 1682 IDS_FLAGS_DISABLE_CAST_NAME, 1683 IDS_FLAGS_DISABLE_CAST_DESCRIPTION, 1684 kOsAndroid, 1685 SINGLE_VALUE_TYPE(switches::kDisableCast) 1686 }, 1687 { 1688 "prefetch-search-results", 1689 IDS_FLAGS_PREFETCH_SEARCH_RESULTS_NAME, 1690 IDS_FLAGS_PREFETCH_SEARCH_RESULTS_DESCRIPTION, 1691 kOsAndroid, 1692 SINGLE_VALUE_TYPE(switches::kPrefetchSearchResults) 1693 }, 1694 #endif 1695 #if defined(ENABLE_APP_LIST) 1696 { 1697 "enable-experimental-app-list", 1698 IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_NAME, 1699 IDS_FLAGS_ENABLE_EXPERIMENTAL_APP_LIST_DESCRIPTION, 1700 kOsWin | kOsLinux | kOsCrOS, 1701 SINGLE_VALUE_TYPE(app_list::switches::kEnableExperimentalAppList) 1702 }, 1703 { 1704 "enable-centered-app-list", 1705 IDS_FLAGS_ENABLE_CENTERED_APP_LIST_NAME, 1706 IDS_FLAGS_ENABLE_CENTERED_APP_LIST_DESCRIPTION, 1707 kOsWin | kOsLinux | kOsCrOS, 1708 SINGLE_VALUE_TYPE(app_list::switches::kEnableCenteredAppList) 1709 }, 1710 #endif 1711 { 1712 "touch-scrolling-mode", 1713 IDS_FLAGS_TOUCH_SCROLLING_MODE_NAME, 1714 IDS_FLAGS_TOUCH_SCROLLING_MODE_DESCRIPTION, 1715 kOsWin | kOsLinux | kOsCrOS | kOsAndroid, 1716 MULTI_VALUE_TYPE(kTouchScrollingModeChoices) 1717 }, 1718 { 1719 "disable-threaded-scrolling", 1720 IDS_FLAGS_DISABLE_THREADED_SCROLLING_NAME, 1721 IDS_FLAGS_DISABLE_THREADED_SCROLLING_DESCRIPTION, 1722 kOsWin | kOsLinux | kOsCrOS | kOsAndroid, 1723 SINGLE_VALUE_TYPE(switches::kDisableThreadedScrolling) 1724 }, 1725 { 1726 "bleeding-edge-renderer-mode", 1727 IDS_FLAGS_BLEEDING_RENDERER_NAME, 1728 IDS_FLAGS_BLEEDING_RENDERER_DESCRIPTION, 1729 kOsAndroid, 1730 SINGLE_VALUE_TYPE(switches::kEnableBleedingEdgeRenderingFastPaths) 1731 }, 1732 { 1733 "enable-settings-window", 1734 IDS_FLAGS_ENABLE_SETTINGS_WINDOW_NAME, 1735 IDS_FLAGS_ENABLE_SETTINGS_WINDOW_DESCRIPTION, 1736 kOsDesktop, 1737 MULTI_VALUE_TYPE(kEnableSettingsWindowChoices) 1738 }, 1739 #if defined(OS_ANDROID) 1740 { 1741 "enable-instant-search-clicks", 1742 IDS_FLAGS_ENABLE_INSTANT_SEARCH_CLICKS_NAME, 1743 IDS_FLAGS_ENABLE_INSTANT_SEARCH_CLICKS_DESCRIPTION, 1744 kOsAndroid, 1745 SINGLE_VALUE_TYPE(switches::kEnableInstantSearchClicks) 1746 }, 1747 #endif 1748 { 1749 "enable-save-password-bubble", 1750 IDS_FLAGS_ENABLE_SAVE_PASSWORD_BUBBLE_NAME, 1751 IDS_FLAGS_ENABLE_SAVE_PASSWORD_BUBBLE_DESCRIPTION, 1752 kOsWin | kOsLinux | kOsCrOS | kOsMac, 1753 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableSavePasswordBubble, 1754 switches::kDisableSavePasswordBubble) 1755 }, 1756 // TODO(tyoshino): Remove this temporary flag and command line switch. See 1757 // crbug.com/366483 for the target milestone. 1758 { 1759 "allow-insecure-websocket-from-https-origin", 1760 IDS_FLAGS_ALLOW_INSECURE_WEBSOCKET_FROM_HTTPS_ORIGIN_NAME, 1761 IDS_FLAGS_ALLOW_INSECURE_WEBSOCKET_FROM_HTTPS_ORIGIN_DESCRIPTION, 1762 kOsAll, 1763 SINGLE_VALUE_TYPE(switches::kAllowInsecureWebSocketFromHttpsOrigin) 1764 }, 1765 { 1766 "enable-apps-file-associations", 1767 IDS_FLAGS_ENABLE_APPS_FILE_ASSOCIATIONS_NAME, 1768 IDS_FLAGS_ENABLE_APPS_FILE_ASSOCIATIONS_DESCRIPTION, 1769 kOsMac, 1770 SINGLE_VALUE_TYPE(switches::kEnableAppsFileAssociations) 1771 }, 1772 #if defined(OS_ANDROID) 1773 { 1774 "enable-embeddedsearch-api", 1775 IDS_FLAGS_ENABLE_EMBEDDEDSEARCH_API_NAME, 1776 IDS_FLAGS_ENABLE_EMBEDDEDSEARCH_API_DESCRIPTION, 1777 kOsAndroid, 1778 SINGLE_VALUE_TYPE(switches::kEnableEmbeddedSearchAPI) 1779 }, 1780 { 1781 "enable-app-install-alerts", 1782 IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_NAME, 1783 IDS_FLAGS_ENABLE_APP_INSTALL_ALERTS_DESCRIPTION, 1784 kOsAndroid, 1785 SINGLE_VALUE_TYPE(switches::kEnableAppInstallAlerts) 1786 }, 1787 #endif 1788 { 1789 "distance-field-text", 1790 IDS_FLAGS_DISTANCE_FIELD_TEXT_NAME, 1791 IDS_FLAGS_DISTANCE_FIELD_TEXT_DESCRIPTION, 1792 kOsAll, 1793 MULTI_VALUE_TYPE(kDistanceFieldTextChoices) 1794 }, 1795 { 1796 "extension-content-verification", 1797 IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_NAME, 1798 IDS_FLAGS_EXTENSION_CONTENT_VERIFICATION_DESCRIPTION, 1799 kOsDesktop, 1800 MULTI_VALUE_TYPE(kExtensionContentVerificationChoices) 1801 }, 1802 #if defined(USE_AURA) 1803 { 1804 "text-input-focus-manager", 1805 IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_NAME, 1806 IDS_FLAGS_TEXT_INPUT_FOCUS_MANAGER_DESCRIPTION, 1807 kOsCrOS | kOsLinux | kOsWin, 1808 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableTextInputFocusManager, 1809 switches::kDisableTextInputFocusManager) 1810 }, 1811 #endif 1812 #if defined(ENABLE_EXTENSIONS) 1813 { 1814 "extension-active-script-permission", 1815 IDS_FLAGS_USER_CONSENT_FOR_EXTENSION_SCRIPTS_NAME, 1816 IDS_FLAGS_USER_CONSENT_FOR_EXTENSION_SCRIPTS_DESCRIPTION, 1817 kOsAll, 1818 SINGLE_VALUE_TYPE(extensions::switches::kEnableScriptsRequireAction) 1819 }, 1820 #endif 1821 { 1822 "harfbuzz-rendertext", 1823 IDS_FLAGS_HARFBUZZ_RENDERTEXT_NAME, 1824 IDS_FLAGS_HARFBUZZ_RENDERTEXT_DESCRIPTION, 1825 kOsDesktop, 1826 ENABLE_DISABLE_VALUE_TYPE(switches::kEnableHarfBuzzRenderText, 1827 switches::kDisableHarfBuzzRenderText) 1828 }, 1829 #if defined(OS_ANDROID) 1830 { 1831 "answers-in-suggest", 1832 IDS_FLAGS_ENABLE_ANSWERS_IN_SUGGEST_NAME, 1833 IDS_FLAGS_ENABLE_ANSWERS_IN_SUGGEST_DESCRIPTION, 1834 kOsAndroid, 1835 MULTI_VALUE_TYPE(kAnswersInSuggestChoices) 1836 }, 1837 #endif 1838 #if defined(OS_ANDROID) 1839 { 1840 "enable-data-reduction-proxy-dev", 1841 IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_DEV_NAME, 1842 IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_DEV_DESCRIPTION, 1843 kOsAndroid, 1844 ENABLE_DISABLE_VALUE_TYPE( 1845 data_reduction_proxy::switches::kEnableDataReductionProxyDev, 1846 data_reduction_proxy::switches::kDisableDataReductionProxyDev) 1847 }, 1848 { 1849 "enable-data-reduction-proxy-alt", 1850 IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_NAME, 1851 IDS_FLAGS_ENABLE_DATA_REDUCTION_PROXY_ALTERNATIVE_DESCRIPTION, 1852 kOsAndroid, 1853 SINGLE_VALUE_TYPE( 1854 data_reduction_proxy::switches::kEnableDataReductionProxyAlt) 1855 }, 1856 #endif 1857 { 1858 "enable-experimental-hotwording", 1859 IDS_FLAGS_ENABLE_EXPERIMENTAL_HOTWORDING_NAME, 1860 IDS_FLAGS_ENABLE_EXPERIMENTAL_HOTWORDING_DESCRIPTION, 1861 kOsDesktop, 1862 SINGLE_VALUE_TYPE(switches::kEnableExperimentalHotwording) 1863 }, 1864 #if defined(ENABLE_EXTENSIONS) 1865 { 1866 "enable-embedded-extension-options", 1867 IDS_FLAGS_ENABLE_EMBEDDED_EXTENSION_OPTIONS_NAME, 1868 IDS_FLAGS_ENABLE_EMBEDDED_EXTENSION_OPTIONS_DESCRIPTION, 1869 kOsDesktop, 1870 SINGLE_VALUE_TYPE(extensions::switches::kEnableEmbeddedExtensionOptions) 1871 }, 1872 #endif 1873 { 1874 "enable-website-settings-manager", 1875 IDS_FLAGS_ENABLE_WEBSITE_SETTINGS_NAME, 1876 IDS_FLAGS_ENABLE_WEBSITE_SETTINGS_DESCRIPTION, 1877 kOsDesktop, 1878 SINGLE_VALUE_TYPE(switches::kEnableWebsiteSettingsManager) 1879 }, 1880 { 1881 "remember-cert-error-decisions", 1882 IDS_FLAGS_REMEMBER_CERTIFICATE_ERROR_DECISIONS_NAME, 1883 IDS_FLAGS_REMEMBER_CERTIFICATE_ERROR_DECISIONS_DESCRIPTION, 1884 kOsAll, 1885 MULTI_VALUE_TYPE(kRememberCertificateErrorDecisionsChoices) 1886 }, 1887 { 1888 "enable-drop-sync-credential", 1889 IDS_FLAGS_ENABLE_DROP_SYNC_CREDENTIAL_NAME, 1890 IDS_FLAGS_ENABLE_DROP_SYNC_CREDENTIAL_DESCRIPTION, 1891 kOsAll, 1892 MULTI_VALUE_TYPE(kEnableDropSyncCredentialChoices) 1893 }, 1894 #if defined(ENABLE_EXTENSIONS) 1895 { 1896 "enable-extension-action-redesign", 1897 IDS_FLAGS_ENABLE_EXTENSION_ACTION_REDESIGN_NAME, 1898 IDS_FLAGS_ENABLE_EXTENSION_ACTION_REDESIGN_DESCRIPTION, 1899 kOsWin | kOsLinux | kOsCrOS, 1900 SINGLE_VALUE_TYPE(extensions::switches::kEnableExtensionActionRedesign) 1901 }, 1902 #endif 1903 { 1904 "autofill-sync-credential", 1905 IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_NAME, 1906 IDS_FLAGS_AUTOFILL_SYNC_CREDENTIAL_DESCRIPTION, 1907 kOsAll, 1908 MULTI_VALUE_TYPE(kAutofillSyncCredentialChoices) 1909 }, 1910 #if !defined(OS_ANDROID) 1911 { 1912 "enable-message-center-always-scroll-up-upon-notification-removal", 1913 IDS_FLAGS_ENABLE_MESSAGE_CENTER_ALWAYS_SCROLL_UP_UPON_REMOVAL_NAME, 1914 IDS_FLAGS_ENABLE_MESSAGE_CENTER_ALWAYS_SCROLL_UP_UPON_REMOVAL_DESCRIPTION, 1915 kOsDesktop, 1916 SINGLE_VALUE_TYPE( 1917 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval) 1918 }, 1919 #endif 1920 #if defined(OS_CHROMEOS) 1921 { 1922 "wake-on-packets", 1923 IDS_FLAGS_WAKE_ON_PACKETS_NAME, 1924 IDS_FLAGS_WAKE_ON_PACKETS_DESCRIPTION, 1925 kOsCrOSOwnerOnly, 1926 SINGLE_VALUE_TYPE(chromeos::switches::kWakeOnPackets) 1927 }, 1928 #endif // OS_CHROMEOS 1929 #if defined(USE_AURA) 1930 { 1931 "enable-tab-audio-muting", 1932 IDS_FLAGS_ENABLE_TAB_AUDIO_MUTING_NAME, 1933 IDS_FLAGS_ENABLE_TAB_AUDIO_MUTING_DESCRIPTION, 1934 kOsWin | kOsLinux | kOsCrOS, 1935 SINGLE_VALUE_TYPE(switches::kEnableTabAudioMuting) 1936 }, 1937 #endif // defined(USE_AURA) 1938 1939 // NOTE: Adding new command-line switches requires adding corresponding 1940 // entries to enum "LoginCustomFlags" in histograms.xml. See note in 1941 // histograms.xml and don't forget to run AboutFlagsHistogramTest unit test. 1942 }; 1943 1944 const Experiment* experiments = kExperiments; 1945 size_t num_experiments = arraysize(kExperiments); 1946 1947 // Stores and encapsulates the little state that about:flags has. 1948 class FlagsState { 1949 public: 1950 FlagsState() : needs_restart_(false) {} 1951 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, 1952 CommandLine* command_line, 1953 SentinelsMode sentinels); 1954 bool IsRestartNeededToCommitChanges(); 1955 void SetExperimentEnabled( 1956 FlagsStorage* flags_storage, 1957 const std::string& internal_name, 1958 bool enable); 1959 void RemoveFlagsSwitches( 1960 std::map<std::string, CommandLine::StringType>* switch_list); 1961 void ResetAllFlags(FlagsStorage* flags_storage); 1962 void reset(); 1963 1964 // Returns the singleton instance of this class 1965 static FlagsState* GetInstance() { 1966 return Singleton<FlagsState>::get(); 1967 } 1968 1969 private: 1970 bool needs_restart_; 1971 std::map<std::string, std::string> flags_switches_; 1972 1973 DISALLOW_COPY_AND_ASSIGN(FlagsState); 1974 }; 1975 1976 // Adds the internal names for the specified experiment to |names|. 1977 void AddInternalName(const Experiment& e, std::set<std::string>* names) { 1978 if (e.type == Experiment::SINGLE_VALUE) { 1979 names->insert(e.internal_name); 1980 } else { 1981 DCHECK(e.type == Experiment::MULTI_VALUE || 1982 e.type == Experiment::ENABLE_DISABLE_VALUE); 1983 for (int i = 0; i < e.num_choices; ++i) 1984 names->insert(e.NameForChoice(i)); 1985 } 1986 } 1987 1988 // Confirms that an experiment is valid, used in a DCHECK in 1989 // SanitizeList below. 1990 bool ValidateExperiment(const Experiment& e) { 1991 switch (e.type) { 1992 case Experiment::SINGLE_VALUE: 1993 DCHECK_EQ(0, e.num_choices); 1994 DCHECK(!e.choices); 1995 break; 1996 case Experiment::MULTI_VALUE: 1997 DCHECK_GT(e.num_choices, 0); 1998 DCHECK(e.choices); 1999 DCHECK(e.choices[0].command_line_switch); 2000 DCHECK_EQ('\0', e.choices[0].command_line_switch[0]); 2001 break; 2002 case Experiment::ENABLE_DISABLE_VALUE: 2003 DCHECK_EQ(3, e.num_choices); 2004 DCHECK(!e.choices); 2005 DCHECK(e.command_line_switch); 2006 DCHECK(e.command_line_value); 2007 DCHECK(e.disable_command_line_switch); 2008 DCHECK(e.disable_command_line_value); 2009 break; 2010 default: 2011 NOTREACHED(); 2012 } 2013 return true; 2014 } 2015 2016 // Removes all experiments from prefs::kEnabledLabsExperiments that are 2017 // unknown, to prevent this list to become very long as experiments are added 2018 // and removed. 2019 void SanitizeList(FlagsStorage* flags_storage) { 2020 std::set<std::string> known_experiments; 2021 for (size_t i = 0; i < num_experiments; ++i) { 2022 DCHECK(ValidateExperiment(experiments[i])); 2023 AddInternalName(experiments[i], &known_experiments); 2024 } 2025 2026 std::set<std::string> enabled_experiments = flags_storage->GetFlags(); 2027 2028 std::set<std::string> new_enabled_experiments = 2029 base::STLSetIntersection<std::set<std::string> >( 2030 known_experiments, enabled_experiments); 2031 2032 if (new_enabled_experiments != enabled_experiments) 2033 flags_storage->SetFlags(new_enabled_experiments); 2034 } 2035 2036 void GetSanitizedEnabledFlags( 2037 FlagsStorage* flags_storage, std::set<std::string>* result) { 2038 SanitizeList(flags_storage); 2039 *result = flags_storage->GetFlags(); 2040 } 2041 2042 bool SkipConditionalExperiment(const Experiment& experiment, 2043 FlagsStorage* flags_storage) { 2044 if (experiment.internal_name == 2045 std::string("enhanced-bookmarks-experiment")) { 2046 CommandLine* command_line = CommandLine::ForCurrentProcess(); 2047 // Dont't skip experiment if it has non default value. 2048 // It means user selected it. 2049 if (command_line->HasSwitch(switches::kEnhancedBookmarksExperiment)) 2050 return false; 2051 2052 return !IsEnhancedBookmarksExperimentEnabled(flags_storage); 2053 } 2054 2055 if ((experiment.internal_name == std::string("manual-enhanced-bookmarks")) || 2056 (experiment.internal_name == 2057 std::string("manual-enhanced-bookmarks-optout"))) { 2058 return true; 2059 } 2060 2061 #if defined(OS_ANDROID) 2062 // enable-data-reduction-proxy-dev is only available for the Dev channel. 2063 if (!strcmp("enable-data-reduction-proxy-dev", experiment.internal_name) && 2064 chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_DEV) { 2065 return true; 2066 } 2067 // enable-data-reduction-proxy-alt is only available for the Dev channel. 2068 if (!strcmp("enable-data-reduction-proxy-alt", experiment.internal_name) && 2069 chrome::VersionInfo::GetChannel() != chrome::VersionInfo::CHANNEL_DEV) { 2070 return true; 2071 } 2072 #endif 2073 2074 return false; 2075 } 2076 2077 2078 // Variant of GetSanitizedEnabledFlags that also removes any flags that aren't 2079 // enabled on the current platform. 2080 void GetSanitizedEnabledFlagsForCurrentPlatform( 2081 FlagsStorage* flags_storage, std::set<std::string>* result) { 2082 GetSanitizedEnabledFlags(flags_storage, result); 2083 2084 // Filter out any experiments that aren't enabled on the current platform. We 2085 // don't remove these from prefs else syncing to a platform with a different 2086 // set of experiments would be lossy. 2087 std::set<std::string> platform_experiments; 2088 int current_platform = GetCurrentPlatform(); 2089 for (size_t i = 0; i < num_experiments; ++i) { 2090 if (experiments[i].supported_platforms & current_platform) 2091 AddInternalName(experiments[i], &platform_experiments); 2092 #if defined(OS_CHROMEOS) 2093 if (experiments[i].supported_platforms & kOsCrOSOwnerOnly) 2094 AddInternalName(experiments[i], &platform_experiments); 2095 #endif 2096 } 2097 2098 std::set<std::string> new_enabled_experiments = 2099 base::STLSetIntersection<std::set<std::string> >( 2100 platform_experiments, *result); 2101 2102 result->swap(new_enabled_experiments); 2103 } 2104 2105 // Returns the Value representing the choice data in the specified experiment. 2106 base::Value* CreateChoiceData( 2107 const Experiment& experiment, 2108 const std::set<std::string>& enabled_experiments) { 2109 DCHECK(experiment.type == Experiment::MULTI_VALUE || 2110 experiment.type == Experiment::ENABLE_DISABLE_VALUE); 2111 base::ListValue* result = new base::ListValue; 2112 for (int i = 0; i < experiment.num_choices; ++i) { 2113 base::DictionaryValue* value = new base::DictionaryValue; 2114 const std::string name = experiment.NameForChoice(i); 2115 value->SetString("internal_name", name); 2116 value->SetString("description", experiment.DescriptionForChoice(i)); 2117 value->SetBoolean("selected", enabled_experiments.count(name) > 0); 2118 result->Append(value); 2119 } 2120 return result; 2121 } 2122 2123 } // namespace 2124 2125 std::string Experiment::NameForChoice(int index) const { 2126 DCHECK(type == Experiment::MULTI_VALUE || 2127 type == Experiment::ENABLE_DISABLE_VALUE); 2128 DCHECK_LT(index, num_choices); 2129 return std::string(internal_name) + testing::kMultiSeparator + 2130 base::IntToString(index); 2131 } 2132 2133 base::string16 Experiment::DescriptionForChoice(int index) const { 2134 DCHECK(type == Experiment::MULTI_VALUE || 2135 type == Experiment::ENABLE_DISABLE_VALUE); 2136 DCHECK_LT(index, num_choices); 2137 int description_id; 2138 if (type == Experiment::ENABLE_DISABLE_VALUE) { 2139 const int kEnableDisableDescriptionIds[] = { 2140 IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT, 2141 IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED, 2142 IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED, 2143 }; 2144 description_id = kEnableDisableDescriptionIds[index]; 2145 } else { 2146 description_id = choices[index].description_id; 2147 } 2148 return l10n_util::GetStringUTF16(description_id); 2149 } 2150 2151 void ConvertFlagsToSwitches(FlagsStorage* flags_storage, 2152 CommandLine* command_line, 2153 SentinelsMode sentinels) { 2154 FlagsState::GetInstance()->ConvertFlagsToSwitches(flags_storage, 2155 command_line, 2156 sentinels); 2157 } 2158 2159 bool AreSwitchesIdenticalToCurrentCommandLine( 2160 const CommandLine& new_cmdline, 2161 const CommandLine& active_cmdline, 2162 std::set<CommandLine::StringType>* out_difference) { 2163 std::set<CommandLine::StringType> new_flags = 2164 ExtractFlagsFromCommandLine(new_cmdline); 2165 std::set<CommandLine::StringType> active_flags = 2166 ExtractFlagsFromCommandLine(active_cmdline); 2167 2168 bool result = false; 2169 // Needed because std::equal doesn't check if the 2nd set is empty. 2170 if (new_flags.size() == active_flags.size()) { 2171 result = 2172 std::equal(new_flags.begin(), new_flags.end(), active_flags.begin()); 2173 } 2174 2175 if (out_difference && !result) { 2176 std::set_symmetric_difference( 2177 new_flags.begin(), 2178 new_flags.end(), 2179 active_flags.begin(), 2180 active_flags.end(), 2181 std::inserter(*out_difference, out_difference->begin())); 2182 } 2183 2184 return result; 2185 } 2186 2187 void GetFlagsExperimentsData(FlagsStorage* flags_storage, 2188 FlagAccess access, 2189 base::ListValue* supported_experiments, 2190 base::ListValue* unsupported_experiments) { 2191 std::set<std::string> enabled_experiments; 2192 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2193 2194 int current_platform = GetCurrentPlatform(); 2195 2196 for (size_t i = 0; i < num_experiments; ++i) { 2197 const Experiment& experiment = experiments[i]; 2198 if (SkipConditionalExperiment(experiment, flags_storage)) 2199 continue; 2200 2201 base::DictionaryValue* data = new base::DictionaryValue(); 2202 data->SetString("internal_name", experiment.internal_name); 2203 data->SetString("name", 2204 l10n_util::GetStringUTF16(experiment.visible_name_id)); 2205 data->SetString("description", 2206 l10n_util::GetStringUTF16( 2207 experiment.visible_description_id)); 2208 2209 base::ListValue* supported_platforms = new base::ListValue(); 2210 AddOsStrings(experiment.supported_platforms, supported_platforms); 2211 data->Set("supported_platforms", supported_platforms); 2212 2213 switch (experiment.type) { 2214 case Experiment::SINGLE_VALUE: 2215 data->SetBoolean( 2216 "enabled", 2217 enabled_experiments.count(experiment.internal_name) > 0); 2218 break; 2219 case Experiment::MULTI_VALUE: 2220 case Experiment::ENABLE_DISABLE_VALUE: 2221 data->Set("choices", CreateChoiceData(experiment, enabled_experiments)); 2222 break; 2223 default: 2224 NOTREACHED(); 2225 } 2226 2227 bool supported = (experiment.supported_platforms & current_platform) != 0; 2228 #if defined(OS_CHROMEOS) 2229 if (access == kOwnerAccessToFlags && 2230 (experiment.supported_platforms & kOsCrOSOwnerOnly) != 0) { 2231 supported = true; 2232 } 2233 #endif 2234 if (supported) 2235 supported_experiments->Append(data); 2236 else 2237 unsupported_experiments->Append(data); 2238 } 2239 } 2240 2241 bool IsRestartNeededToCommitChanges() { 2242 return FlagsState::GetInstance()->IsRestartNeededToCommitChanges(); 2243 } 2244 2245 void SetExperimentEnabled(FlagsStorage* flags_storage, 2246 const std::string& internal_name, 2247 bool enable) { 2248 FlagsState::GetInstance()->SetExperimentEnabled(flags_storage, 2249 internal_name, enable); 2250 } 2251 2252 void RemoveFlagsSwitches( 2253 std::map<std::string, CommandLine::StringType>* switch_list) { 2254 FlagsState::GetInstance()->RemoveFlagsSwitches(switch_list); 2255 } 2256 2257 void ResetAllFlags(FlagsStorage* flags_storage) { 2258 FlagsState::GetInstance()->ResetAllFlags(flags_storage); 2259 } 2260 2261 int GetCurrentPlatform() { 2262 #if defined(OS_MACOSX) 2263 return kOsMac; 2264 #elif defined(OS_WIN) 2265 return kOsWin; 2266 #elif defined(OS_CHROMEOS) // Needs to be before the OS_LINUX check. 2267 return kOsCrOS; 2268 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 2269 return kOsLinux; 2270 #elif defined(OS_ANDROID) 2271 return kOsAndroid; 2272 #else 2273 #error Unknown platform 2274 #endif 2275 } 2276 2277 void RecordUMAStatistics(FlagsStorage* flags_storage) { 2278 std::set<std::string> flags = flags_storage->GetFlags(); 2279 for (std::set<std::string>::iterator it = flags.begin(); it != flags.end(); 2280 ++it) { 2281 std::string action("AboutFlags_"); 2282 action += *it; 2283 content::RecordComputedAction(action); 2284 } 2285 // Since flag metrics are recorded every startup, add a tick so that the 2286 // stats can be made meaningful. 2287 if (flags.size()) 2288 content::RecordAction(UserMetricsAction("AboutFlags_StartupTick")); 2289 content::RecordAction(UserMetricsAction("StartupTick")); 2290 } 2291 2292 base::HistogramBase::Sample GetSwitchUMAId(const std::string& switch_name) { 2293 return static_cast<base::HistogramBase::Sample>( 2294 metrics::HashMetricName(switch_name)); 2295 } 2296 2297 void ReportCustomFlags(const std::string& uma_histogram_hame, 2298 const std::set<std::string>& command_line_difference) { 2299 for (std::set<std::string>::const_iterator it = 2300 command_line_difference.begin(); 2301 it != command_line_difference.end(); 2302 ++it) { 2303 int uma_id = about_flags::kBadSwitchFormatHistogramId; 2304 if (StartsWithASCII(*it, "--", true /* case_sensitive */)) { 2305 // Skip '--' before switch name. 2306 std::string switch_name(it->substr(2)); 2307 2308 // Kill value, if any. 2309 const size_t value_pos = switch_name.find('='); 2310 if (value_pos != std::string::npos) 2311 switch_name.resize(value_pos); 2312 2313 uma_id = GetSwitchUMAId(switch_name); 2314 } else { 2315 NOTREACHED() << "ReportCustomFlags(): flag '" << *it 2316 << "' has incorrect format."; 2317 } 2318 DVLOG(1) << "ReportCustomFlags(): histogram='" << uma_histogram_hame 2319 << "' '" << *it << "', uma_id=" << uma_id; 2320 2321 // Sparse histogram macro does not cache the histogram, so it's safe 2322 // to use macro with non-static histogram name here. 2323 UMA_HISTOGRAM_SPARSE_SLOWLY(uma_histogram_hame, uma_id); 2324 } 2325 } 2326 2327 ////////////////////////////////////////////////////////////////////////////// 2328 // FlagsState implementation. 2329 2330 namespace { 2331 2332 typedef std::map<std::string, std::pair<std::string, std::string> > 2333 NameToSwitchAndValueMap; 2334 2335 void SetFlagToSwitchMapping(const std::string& key, 2336 const std::string& switch_name, 2337 const std::string& switch_value, 2338 NameToSwitchAndValueMap* name_to_switch_map) { 2339 DCHECK(name_to_switch_map->end() == name_to_switch_map->find(key)); 2340 (*name_to_switch_map)[key] = std::make_pair(switch_name, switch_value); 2341 } 2342 2343 void FlagsState::ConvertFlagsToSwitches(FlagsStorage* flags_storage, 2344 CommandLine* command_line, 2345 SentinelsMode sentinels) { 2346 if (command_line->HasSwitch(switches::kNoExperiments)) 2347 return; 2348 2349 std::set<std::string> enabled_experiments; 2350 2351 GetSanitizedEnabledFlagsForCurrentPlatform(flags_storage, 2352 &enabled_experiments); 2353 2354 NameToSwitchAndValueMap name_to_switch_map; 2355 for (size_t i = 0; i < num_experiments; ++i) { 2356 const Experiment& e = experiments[i]; 2357 if (e.type == Experiment::SINGLE_VALUE) { 2358 SetFlagToSwitchMapping(e.internal_name, e.command_line_switch, 2359 e.command_line_value, &name_to_switch_map); 2360 } else if (e.type == Experiment::MULTI_VALUE) { 2361 for (int j = 0; j < e.num_choices; ++j) { 2362 SetFlagToSwitchMapping(e.NameForChoice(j), 2363 e.choices[j].command_line_switch, 2364 e.choices[j].command_line_value, 2365 &name_to_switch_map); 2366 } 2367 } else { 2368 DCHECK_EQ(e.type, Experiment::ENABLE_DISABLE_VALUE); 2369 SetFlagToSwitchMapping(e.NameForChoice(0), std::string(), std::string(), 2370 &name_to_switch_map); 2371 SetFlagToSwitchMapping(e.NameForChoice(1), e.command_line_switch, 2372 e.command_line_value, &name_to_switch_map); 2373 SetFlagToSwitchMapping(e.NameForChoice(2), e.disable_command_line_switch, 2374 e.disable_command_line_value, &name_to_switch_map); 2375 } 2376 } 2377 2378 if (sentinels == kAddSentinels) { 2379 command_line->AppendSwitch(switches::kFlagSwitchesBegin); 2380 flags_switches_.insert( 2381 std::pair<std::string, std::string>(switches::kFlagSwitchesBegin, 2382 std::string())); 2383 } 2384 for (std::set<std::string>::iterator it = enabled_experiments.begin(); 2385 it != enabled_experiments.end(); 2386 ++it) { 2387 const std::string& experiment_name = *it; 2388 NameToSwitchAndValueMap::const_iterator name_to_switch_it = 2389 name_to_switch_map.find(experiment_name); 2390 if (name_to_switch_it == name_to_switch_map.end()) { 2391 NOTREACHED(); 2392 continue; 2393 } 2394 2395 #if defined(OS_CHROMEOS) 2396 // On Chrome OS setting command line flag may make browser to restart on 2397 // user login. As this flag eventually will be set to a significant number 2398 // of users skip manual-enhanced-bookmarks to avoid restart. 2399 if (experiment_name == "manual-enhanced-bookmarks") 2400 continue; 2401 #endif 2402 2403 const std::pair<std::string, std::string>& 2404 switch_and_value_pair = name_to_switch_it->second; 2405 2406 CHECK(!switch_and_value_pair.first.empty()); 2407 command_line->AppendSwitchASCII(switch_and_value_pair.first, 2408 switch_and_value_pair.second); 2409 flags_switches_[switch_and_value_pair.first] = switch_and_value_pair.second; 2410 } 2411 if (sentinels == kAddSentinels) { 2412 command_line->AppendSwitch(switches::kFlagSwitchesEnd); 2413 flags_switches_.insert( 2414 std::pair<std::string, std::string>(switches::kFlagSwitchesEnd, 2415 std::string())); 2416 } 2417 } 2418 2419 bool FlagsState::IsRestartNeededToCommitChanges() { 2420 return needs_restart_; 2421 } 2422 2423 void FlagsState::SetExperimentEnabled(FlagsStorage* flags_storage, 2424 const std::string& internal_name, 2425 bool enable) { 2426 size_t at_index = internal_name.find(testing::kMultiSeparator); 2427 if (at_index != std::string::npos) { 2428 DCHECK(enable); 2429 // We're being asked to enable a multi-choice experiment. Disable the 2430 // currently selected choice. 2431 DCHECK_NE(at_index, 0u); 2432 const std::string experiment_name = internal_name.substr(0, at_index); 2433 SetExperimentEnabled(flags_storage, experiment_name, false); 2434 2435 // And enable the new choice, if it is not the default first choice. 2436 if (internal_name != experiment_name + "@0") { 2437 std::set<std::string> enabled_experiments; 2438 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2439 needs_restart_ |= enabled_experiments.insert(internal_name).second; 2440 flags_storage->SetFlags(enabled_experiments); 2441 } 2442 return; 2443 } 2444 2445 std::set<std::string> enabled_experiments; 2446 GetSanitizedEnabledFlags(flags_storage, &enabled_experiments); 2447 2448 const Experiment* e = NULL; 2449 for (size_t i = 0; i < num_experiments; ++i) { 2450 if (experiments[i].internal_name == internal_name) { 2451 e = experiments + i; 2452 break; 2453 } 2454 } 2455 DCHECK(e); 2456 2457 if (e->type == Experiment::SINGLE_VALUE) { 2458 if (enable) 2459 needs_restart_ |= enabled_experiments.insert(internal_name).second; 2460 else 2461 needs_restart_ |= (enabled_experiments.erase(internal_name) > 0); 2462 } else { 2463 if (enable) { 2464 // Enable the first choice. 2465 needs_restart_ |= enabled_experiments.insert(e->NameForChoice(0)).second; 2466 } else { 2467 // Find the currently enabled choice and disable it. 2468 for (int i = 0; i < e->num_choices; ++i) { 2469 std::string choice_name = e->NameForChoice(i); 2470 if (enabled_experiments.find(choice_name) != 2471 enabled_experiments.end()) { 2472 needs_restart_ = true; 2473 enabled_experiments.erase(choice_name); 2474 // Continue on just in case there's a bug and more than one 2475 // experiment for this choice was enabled. 2476 } 2477 } 2478 } 2479 } 2480 2481 flags_storage->SetFlags(enabled_experiments); 2482 } 2483 2484 void FlagsState::RemoveFlagsSwitches( 2485 std::map<std::string, CommandLine::StringType>* switch_list) { 2486 for (std::map<std::string, std::string>::const_iterator 2487 it = flags_switches_.begin(); it != flags_switches_.end(); ++it) { 2488 switch_list->erase(it->first); 2489 } 2490 } 2491 2492 void FlagsState::ResetAllFlags(FlagsStorage* flags_storage) { 2493 needs_restart_ = true; 2494 2495 std::set<std::string> no_experiments; 2496 flags_storage->SetFlags(no_experiments); 2497 } 2498 2499 void FlagsState::reset() { 2500 needs_restart_ = false; 2501 flags_switches_.clear(); 2502 } 2503 2504 } // namespace 2505 2506 namespace testing { 2507 2508 // WARNING: '@' is also used in the html file. If you update this constant you 2509 // also need to update the html file. 2510 const char kMultiSeparator[] = "@"; 2511 2512 void ClearState() { 2513 FlagsState::GetInstance()->reset(); 2514 } 2515 2516 void SetExperiments(const Experiment* e, size_t count) { 2517 if (!e) { 2518 experiments = kExperiments; 2519 num_experiments = arraysize(kExperiments); 2520 } else { 2521 experiments = e; 2522 num_experiments = count; 2523 } 2524 } 2525 2526 const Experiment* GetExperiments(size_t* count) { 2527 *count = num_experiments; 2528 return experiments; 2529 } 2530 2531 } // namespace testing 2532 2533 } // namespace about_flags 2534